aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/Makefile1
-rw-r--r--drivers/gpu/pvr/Kconfig90
-rw-r--r--drivers/gpu/pvr/Makefile141
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.c3881
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.h232
-rw-r--r--drivers/gpu/pvr/bridged_support.c85
-rw-r--r--drivers/gpu/pvr/bridged_support.h43
-rw-r--r--drivers/gpu/pvr/buffer_manager.c2040
-rw-r--r--drivers/gpu/pvr/buffer_manager.h210
-rw-r--r--drivers/gpu/pvr/device.h316
-rw-r--r--drivers/gpu/pvr/deviceclass.c2012
-rw-r--r--drivers/gpu/pvr/deviceid.h36
-rw-r--r--drivers/gpu/pvr/devicemem.c1554
-rw-r--r--drivers/gpu/pvr/display/omap_display.c1078
-rw-r--r--drivers/gpu/pvr/display/omap_display.h109
-rw-r--r--drivers/gpu/pvr/display/omap_sgx_displayclass.c1638
-rw-r--r--drivers/gpu/pvr/display/omap_sgx_displayclass.h123
-rw-r--r--drivers/gpu/pvr/env_data.h66
-rw-r--r--drivers/gpu/pvr/env_perproc.h56
-rw-r--r--drivers/gpu/pvr/event.c274
-rw-r--r--drivers/gpu/pvr/event.h32
-rw-r--r--drivers/gpu/pvr/handle.c1723
-rw-r--r--drivers/gpu/pvr/handle.h383
-rw-r--r--drivers/gpu/pvr/hash.c477
-rw-r--r--drivers/gpu/pvr/hash.h73
-rw-r--r--drivers/gpu/pvr/img_defs.h118
-rw-r--r--drivers/gpu/pvr/img_types.h138
-rw-r--r--drivers/gpu/pvr/ioctldef.h98
-rw-r--r--drivers/gpu/pvr/kernelbuffer.h72
-rw-r--r--drivers/gpu/pvr/kerneldisplay.h165
-rw-r--r--drivers/gpu/pvr/linkage.h52
-rw-r--r--drivers/gpu/pvr/lists.c99
-rw-r--r--drivers/gpu/pvr/lists.h244
-rw-r--r--drivers/gpu/pvr/lock.h32
-rw-r--r--drivers/gpu/pvr/mem.c151
-rw-r--r--drivers/gpu/pvr/mem_debug.c250
-rw-r--r--drivers/gpu/pvr/metrics.c160
-rw-r--r--drivers/gpu/pvr/metrics.h130
-rw-r--r--drivers/gpu/pvr/mm.c2012
-rw-r--r--drivers/gpu/pvr/mm.h333
-rw-r--r--drivers/gpu/pvr/mmap.c1132
-rw-r--r--drivers/gpu/pvr/mmap.h113
-rw-r--r--drivers/gpu/pvr/module.c744
-rw-r--r--drivers/gpu/pvr/mutex.c136
-rw-r--r--drivers/gpu/pvr/mutex.h70
-rw-r--r--drivers/gpu/pvr/mutils.c133
-rw-r--r--drivers/gpu/pvr/mutils.h101
-rw-r--r--drivers/gpu/pvr/ocpdefs.h271
-rw-r--r--drivers/gpu/pvr/omap3/oemfuncs.h56
-rw-r--r--drivers/gpu/pvr/omap3/sysconfig.c970
-rw-r--r--drivers/gpu/pvr/omap3/sysconfig.h59
-rw-r--r--drivers/gpu/pvr/omap3/sysinfo.h40
-rw-r--r--drivers/gpu/pvr/omap3/syslocal.h135
-rw-r--r--drivers/gpu/pvr/omap3/sysutils.c33
-rw-r--r--drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c489
-rw-r--r--drivers/gpu/pvr/omap4/oemfuncs.h56
-rw-r--r--drivers/gpu/pvr/omap4/sysconfig.c978
-rw-r--r--drivers/gpu/pvr/omap4/sysconfig.h67
-rw-r--r--drivers/gpu/pvr/omap4/sysinfo.h40
-rw-r--r--drivers/gpu/pvr/omap4/syslocal.h137
-rw-r--r--drivers/gpu/pvr/omap4/sysutils.c33
-rw-r--r--drivers/gpu/pvr/omap4/sysutils_linux_wqueue_compat.c238
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb.h166
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c1723
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_linux.c437
-rw-r--r--drivers/gpu/pvr/osfunc.c2906
-rw-r--r--drivers/gpu/pvr/osfunc.h576
-rw-r--r--drivers/gpu/pvr/osfunc_common.c31
-rw-r--r--drivers/gpu/pvr/osperproc.c113
-rw-r--r--drivers/gpu/pvr/osperproc.h76
-rw-r--r--drivers/gpu/pvr/pdump.c627
-rw-r--r--drivers/gpu/pvr/pdump.h37
-rw-r--r--drivers/gpu/pvr/pdump_common.c2248
-rw-r--r--drivers/gpu/pvr/pdump_int.h67
-rw-r--r--drivers/gpu/pvr/pdump_km.h403
-rw-r--r--drivers/gpu/pvr/pdump_osfunc.h135
-rw-r--r--drivers/gpu/pvr/pdumpdefs.h99
-rw-r--r--drivers/gpu/pvr/perproc.c283
-rw-r--r--drivers/gpu/pvr/perproc.h113
-rw-r--r--drivers/gpu/pvr/power.c727
-rw-r--r--drivers/gpu/pvr/power.h120
-rw-r--r--drivers/gpu/pvr/private_data.h67
-rw-r--r--drivers/gpu/pvr/proc.c833
-rw-r--r--drivers/gpu/pvr/proc.h108
-rw-r--r--drivers/gpu/pvr/pvr_bridge.h1450
-rw-r--r--drivers/gpu/pvr/pvr_bridge_k.c570
-rw-r--r--drivers/gpu/pvr/pvr_bridge_km.h285
-rw-r--r--drivers/gpu/pvr/pvr_debug.c420
-rw-r--r--drivers/gpu/pvr/pvr_debug.h133
-rw-r--r--drivers/gpu/pvr/pvr_uaccess.h65
-rw-r--r--drivers/gpu/pvr/pvrmmap.h36
-rw-r--r--drivers/gpu/pvr/pvrmodule.h31
-rw-r--r--drivers/gpu/pvr/pvrsrv.c1253
-rw-r--r--drivers/gpu/pvr/pvrsrv_errors.h264
-rw-r--r--drivers/gpu/pvr/pvrversion.h38
-rw-r--r--drivers/gpu/pvr/queue.c1154
-rw-r--r--drivers/gpu/pvr/queue.h114
-rw-r--r--drivers/gpu/pvr/ra.c1725
-rw-r--r--drivers/gpu/pvr/ra.h159
-rw-r--r--drivers/gpu/pvr/regpaths.h43
-rw-r--r--drivers/gpu/pvr/resman.c736
-rw-r--r--drivers/gpu/pvr/resman.h114
-rw-r--r--drivers/gpu/pvr/services.h991
-rw-r--r--drivers/gpu/pvr/services_headers.h49
-rw-r--r--drivers/gpu/pvr/servicesext.h850
-rw-r--r--drivers/gpu/pvr/servicesint.h282
-rw-r--r--drivers/gpu/pvr/sgx/bridged_sgx_bridge.c2670
-rw-r--r--drivers/gpu/pvr/sgx/bridged_sgx_bridge.h42
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c2940
-rw-r--r--drivers/gpu/pvr/sgx/mmu.h144
-rw-r--r--drivers/gpu/pvr/sgx/pb.c459
-rw-r--r--drivers/gpu/pvr/sgx/sgx_bridge_km.h134
-rw-r--r--drivers/gpu/pvr/sgx/sgxconfig.h227
-rw-r--r--drivers/gpu/pvr/sgx/sgxinfokm.h369
-rw-r--r--drivers/gpu/pvr/sgx/sgxinit.c2507
-rw-r--r--drivers/gpu/pvr/sgx/sgxkick.c713
-rw-r--r--drivers/gpu/pvr/sgx/sgxpower.c472
-rw-r--r--drivers/gpu/pvr/sgx/sgxreset.c499
-rw-r--r--drivers/gpu/pvr/sgx/sgxtransfer.c573
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c955
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.h99
-rw-r--r--drivers/gpu/pvr/sgx530defs.h488
-rw-r--r--drivers/gpu/pvr/sgx540defs.h547
-rw-r--r--drivers/gpu/pvr/sgx_bridge.h466
-rw-r--r--drivers/gpu/pvr/sgx_mkif_km.h338
-rw-r--r--drivers/gpu/pvr/sgx_options.h224
-rw-r--r--drivers/gpu/pvr/sgxapi_km.h381
-rw-r--r--drivers/gpu/pvr/sgxdefs.h94
-rw-r--r--drivers/gpu/pvr/sgxerrata.h330
-rw-r--r--drivers/gpu/pvr/sgxfeaturedefs.h199
-rw-r--r--drivers/gpu/pvr/sgxinfo.h286
-rw-r--r--drivers/gpu/pvr/sgxmmu.h79
-rw-r--r--drivers/gpu/pvr/sgxscript.h81
-rw-r--r--drivers/gpu/pvr/srvkm.h78
-rw-r--r--drivers/gpu/pvr/syscommon.h223
135 files changed, 66032 insertions, 0 deletions
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index cc9277885dd..5a2011531b8 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
1obj-y += drm/ vga/ stub/ 1obj-y += drm/ vga/ stub/
2obj-y += pvr/
diff --git a/drivers/gpu/pvr/Kconfig b/drivers/gpu/pvr/Kconfig
new file mode 100644
index 00000000000..8479735bb2f
--- /dev/null
+++ b/drivers/gpu/pvr/Kconfig
@@ -0,0 +1,90 @@
1config SGX540
2 tristate "PowerVR SGX"
3 depends on ARCH_OMAP4
4 ---help---
5 Support for the PowerVR SGX 3D core.
6
7config SGX530
8 tristate "PowerVR SGX"
9 depends on ARCH_OMAP3
10 ---help---
11 Support for the PowerVR SGX 3D core.
12
13config VIRTUAL_DISPLAY_SUPPORT
14 tristate "Virtual display support"
15 depends on SGX540
16 ---help---
17 Support for showing one framebuffer split in 2 displays at the same
18 time. Each display will show a part of the framebuffer by updating
19 the corresponding overlay on each display. This feature requires
20 2 framebuffers so CONFIG_FB_OMAP2_NUM_FBS must be 2 and each
21 framebuffer must be initialized correctly.
22 The current implementation supports only panels of the same X and Y
23 resolutions and both panels must have the same bits per pixel values.
24 This feature is EXPERIMENTAL and might not be stable if power
25 management is added at the moment.
26 It is important to give enough memory to FB0 to allow at least
27 one buffer with twice the height of a normal single display buffer,
28 so if the panel needs 864x480x4 bytes for one single display buffer
29 you must give twice the size which is 864x960x4 with the bootargs
30 omapfb.vram='0:4M'. To enable double buffering you need to give
31 864x960x4x2 bytes for two buffers, the bootargs should have
32 omapfb.vram='0:8M'. Since FB1 must also be initialized properly be
33 sure to left enough memory for one single buffer (864x480x4 bytes).
34 The bootarg 'vram' must have the FB0 and FB1 memory requirements
35 combined. Example:
36 If you want FB0 with 4M (no double buffering) and FB1 with 2M, the
37 bootargs must have the following:
38 vram='6M' omapfb.vram='0:4M,1:2M'
39
40choice
41 prompt "SGX revision"
42 depends on SGX530
43 default SGX_REV125
44
45config SGX_REV121
46 bool "Revision 1.2.1 - Omap 3430"
47
48config SGX_REV125
49 bool "Revision 1.2.5 - Omap 3630"
50
51endchoice
52
53choice
54 prompt "SGX revision"
55 depends on SGX540
56 default SGX_REV120
57
58config SGX_REV110
59 bool "Revision 1.1.0 - Omap 4430 ES1"
60
61config SGX_REV120
62 bool "Revision 1.2.0 - Omap 4430 ES2"
63
64endchoice
65
66choice
67 prompt "PowerVR build type"
68 depends on SGX530
69 default SGX_530_BUILD_RELEASE
70
71config SGX_530_BUILD_RELEASE
72 bool "SGX530 RELEASE"
73
74config SGX_530_BUILD_DEBUG
75 bool "SGX530 DEBUG"
76
77endchoice
78
79choice
80 prompt "PowerVR build type"
81 depends on SGX540
82 default SGX_540_BUILD_RELEASE
83
84config SGX_540_BUILD_RELEASE
85 bool "SGX540 RELEASE"
86
87config SGX_540_BUILD_DEBUG
88 bool "SGX540 DEBUG"
89
90endchoice
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile
new file mode 100644
index 00000000000..b49aea59deb
--- /dev/null
+++ b/drivers/gpu/pvr/Makefile
@@ -0,0 +1,141 @@
1#
2ccflags-y = -DLINUX -D__linux__ -Idrivers/gpu/pvr \
3 -DANDROID \
4 -DPVR_BUILD_DIR="\"omap_sgx_android\"" \
5 -DSGX_DYNAMIC_TIMING_INFO \
6 -DSYS_CUSTOM_POWERLOCK_WRAP \
7 -DSERVICES4 \
8 -DSUPPORT_SRVINIT \
9 -DSUPPORT_PERCONTEXT_PB \
10 -DTRANSFER_QUEUE \
11 -DSYS_USING_INTERRUPTS \
12 -DPVR_SECURE_HANDLES \
13 -DPVR_SECURE_FD_EXPORT \
14 -DLDM_PLATFORM \
15 -DSUPPORT_SGX_HWPERF \
16 -DSUPPORT_MEMINFO_IDS \
17 -DDISPLAY_CONTROLLER=omaplfb \
18 -DSYS_SGX_ACTIVE_POWER_LATENCY_MS=100 \
19 -DPVR_BUILD_DATE="" \
20 -DSUPPORT_SGX \
21 -DCLIENT_DRIVER_DEFAULT_WAIT_RETRIES=50 \
22 -DPVR_LINUX_TIMERS_USING_WORKQUEUES \
23 -DFLIP_TECHNIQUE_OVERLAY \
24 -DPVR_LINUX_USING_WORKQUEUES \
25 -DSUPPORT_ANDROID_PLATFORM \
26 -DPVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE \
27 -DSYS_CUSTOM_POWERLOCK_WRAP \
28 -DSUPPORT_SGX_NEW_STATUS_VALS \
29 -DPVRSRV_MODNAME="\"pvrsrvkm"\"
30
31ccflags-$(CONFIG_SGX540) += -Idrivers/gpu/pvr/omap4 -Idrivers/gpu/pvr/sgx \
32 -DNO_OMAP_TIMER \
33 -DSGX_CLK_CORE_DIV5 \
34 -DSGX540 -DSUPPORT_SGX540
35
36ccflags-$(CONFIG_SGX_REV110) += -DSGX_CORE_REV=110
37ccflags-$(CONFIG_SGX_REV120) += -DSGX_CORE_REV=120
38
39ccflags-$(CONFIG_SGX530) += -Idrivers/gpu/pvr/omap3 -Idrivers/gpu/pvr/sgx \
40 -DSGX530 -DSUPPORT_SGX530
41
42ccflags-$(CONFIG_SGX_REV125) += -DSGX_CORE_REV=125
43ccflags-$(CONFIG_SGX_REV121) += -DSGX_CORE_REV=121
44
45ccflags-$(CONFIG_SGX_530_BUILD_RELEASE) += \
46 -DPVR_BUILD_TYPE="\"release\"" \
47 -DRELEASE \
48 -DSUPPORT_ACTIVE_POWER_MANAGEMENT \
49 -DSGX_EARLYSUSPEND \
50 -DSUPPORT_HW_RECOVERY \
51 -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING
52
53ccflags-$(CONFIG_SGX_530_BUILD_DEBUG) += \
54 -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG \
55 -DDEBUG_LINUX_MEMORY_ALLOCATIONS \
56 -DDEBUG_LINUX_MEM_AREAS \
57 -DDEBUG_LINUX_MMAP_AREAS \
58 -DDEBUG_BRIDGE_KM \
59 -DPVRSRV_USSE_EDM_STATUS_DEBUG \
60 -DPVRSRV_DUMP_MK_TRACE \
61 -DDEBUG_LOG_PATH_TRUNCATE="\"eurasia_km\""
62
63ccflags-$(CONFIG_SGX_540_BUILD_RELEASE) += \
64 -DPVR_BUILD_TYPE="\"release\"" \
65 -DRELEASE \
66 -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING
67
68ccflags-$(CONFIG_SGX_540_BUILD_DEBUG) += \
69 -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG \
70 -DDEBUG_LINUX_MEMORY_ALLOCATIONS \
71 -DDEBUG_LINUX_MEM_AREAS \
72 -DDEBUG_LINUX_MMAP_AREAS \
73 -DDEBUG_BRIDGE_KM \
74 -DPVRSRV_USSE_EDM_STATUS_DEBUG \
75 -DPVRSRV_DUMP_MK_TRACE \
76 -DDEBUG_LOG_PATH_TRUNCATE="\"eurasia_km\""
77
78pvr_common-y := \
79 osfunc.o \
80 mutils.o \
81 mmap.o \
82 module.o \
83 pdump.o \
84 proc.o \
85 pvr_bridge_k.o \
86 pvr_debug.o \
87 mm.o \
88 mutex.o \
89 event.o \
90 osperproc.o \
91 buffer_manager.o \
92 devicemem.o \
93 deviceclass.o \
94 handle.o \
95 hash.o \
96 metrics.o \
97 pvrsrv.o \
98 queue.o \
99 ra.o \
100 resman.o \
101 power.o \
102 mem.o \
103 pdump_common.o \
104 bridged_support.o \
105 bridged_pvr_bridge.o \
106 perproc.o \
107 lists.o \
108 mem_debug.o \
109 osfunc_common.o
110
111pvr540-$(CONFIG_SGX540) := \
112 omap4/sysconfig.o \
113 omap4/sysutils.o
114
115pvr530-$(CONFIG_SGX530) := \
116 omap3/sysconfig.o \
117 omap3/sysutils.o
118
119sgx-y := \
120 sgx/bridged_sgx_bridge.o \
121 sgx/sgxinit.o \
122 sgx/sgxpower.o \
123 sgx/sgxreset.o \
124 sgx/sgxutils.o \
125 sgx/sgxkick.o \
126 sgx/sgxtransfer.o \
127 sgx/mmu.o \
128 sgx/pb.o
129
130sgx_displayclass-y := \
131 display/omap_sgx_displayclass.o \
132 display/omap_display.o
133
134omaplfb-y := \
135 omaplfb/omaplfb_displayclass.o \
136 omaplfb/omaplfb_linux.o
137
138obj-$(CONFIG_SGX540) := pvr_common.o sgx.o omaplfb.o pvr540.o
139obj-$(CONFIG_SGX530) := pvr_common.o sgx.o omaplfb.o pvr530.o
140obj-$(CONFIG_VIRTUAL_DISPLAY_SUPPORT) := pvr_common.o sgx.o \
141 sgx_displayclass.o pvr540.o
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.c b/drivers/gpu/pvr/bridged_pvr_bridge.c
new file mode 100644
index 00000000000..2b6cb484e77
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.c
@@ -0,0 +1,3881 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27
28
29#include <stddef.h>
30
31#include "img_defs.h"
32#include "services.h"
33#include "pvr_bridge_km.h"
34#include "pvr_debug.h"
35#include "ra.h"
36#include "pvr_bridge.h"
37#if defined(SUPPORT_SGX)
38#include "sgx_bridge.h"
39#endif
40#if defined(SUPPORT_VGX)
41#include "vgx_bridge.h"
42#endif
43#if defined(SUPPORT_MSVDX)
44#include "msvdx_bridge.h"
45#endif
46#include "perproc.h"
47#include "device.h"
48#include "buffer_manager.h"
49
50#include "pdump_km.h"
51#include "syscommon.h"
52
53#include "bridged_pvr_bridge.h"
54#if defined(SUPPORT_SGX)
55#include "bridged_sgx_bridge.h"
56#endif
57#if defined(SUPPORT_VGX)
58#include "bridged_vgx_bridge.h"
59#endif
60#if defined(SUPPORT_MSVDX)
61#include "bridged_msvdx_bridge.h"
62#endif
63
64#include "env_data.h"
65
66#if defined (__linux__)
67#include "mmap.h"
68#endif
69
70
71#include "srvkm.h"
72
73PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
74
75#if defined(DEBUG_BRIDGE_KM)
76PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
77#endif
78
79#if defined(PVR_SECURE_HANDLES)
80static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
81static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
82#else
83static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL;
84#endif
85
86
87#if defined(DEBUG_BRIDGE_KM)
88PVRSRV_ERROR
89CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
90 IMG_UINT32 ui32BridgeID,
91 IMG_VOID *pvDest,
92 IMG_VOID *pvSrc,
93 IMG_UINT32 ui32Size)
94{
95 g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size;
96 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size;
97 return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
98}
99PVRSRV_ERROR
100CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
101 IMG_UINT32 ui32BridgeID,
102 IMG_VOID *pvDest,
103 IMG_VOID *pvSrc,
104 IMG_UINT32 ui32Size)
105{
106 g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size;
107 g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size;
108 return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
109}
110#endif
111
112
113static IMG_INT
114PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID,
115 IMG_VOID *psBridgeIn,
116 PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
117 PVRSRV_PER_PROCESS_DATA *psPerProc)
118{
119 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
120
121 PVR_UNREFERENCED_PARAMETER(psPerProc);
122 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
123
124 psEnumDeviceOUT->eError =
125 PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
126 psEnumDeviceOUT->asDeviceIdentifier);
127
128 return 0;
129}
130
131static IMG_INT
132PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID,
133 PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
134 PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
135 PVRSRV_PER_PROCESS_DATA *psPerProc)
136{
137 IMG_HANDLE hDevCookieInt;
138
139 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
140
141 psAcquireDevInfoOUT->eError =
142 PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
143 psAcquireDevInfoIN->eDeviceType,
144 &hDevCookieInt);
145 if(psAcquireDevInfoOUT->eError != PVRSRV_OK)
146 {
147 return 0;
148 }
149
150
151 psAcquireDevInfoOUT->eError =
152 PVRSRVAllocHandle(psPerProc->psHandleBase,
153 &psAcquireDevInfoOUT->hDevCookie,
154 hDevCookieInt,
155 PVRSRV_HANDLE_TYPE_DEV_NODE,
156 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
157
158 return 0;
159}
160
161
162static IMG_INT
163PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
164 PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
165 PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
166 PVRSRV_PER_PROCESS_DATA *psPerProc)
167{
168 IMG_HANDLE hDevCookieInt;
169 IMG_HANDLE hDevMemContextInt;
170 IMG_UINT32 i;
171 IMG_BOOL bCreated;
172
173 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
174
175
176 NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1)
177
178 psCreateDevMemContextOUT->eError =
179 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
180 psCreateDevMemContextIN->hDevCookie,
181 PVRSRV_HANDLE_TYPE_DEV_NODE);
182
183 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
184 {
185 return 0;
186 }
187
188 psCreateDevMemContextOUT->eError =
189 PVRSRVCreateDeviceMemContextKM(hDevCookieInt,
190 psPerProc,
191 &hDevMemContextInt,
192 &psCreateDevMemContextOUT->ui32ClientHeapCount,
193 &psCreateDevMemContextOUT->sHeapInfo[0],
194 &bCreated,
195 pbSharedDeviceMemHeap);
196
197 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
198 {
199 return 0;
200 }
201
202
203 if(bCreated)
204 {
205 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
206 &psCreateDevMemContextOUT->hDevMemContext,
207 hDevMemContextInt,
208 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
209 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
210 }
211 else
212 {
213 psCreateDevMemContextOUT->eError =
214 PVRSRVFindHandle(psPerProc->psHandleBase,
215 &psCreateDevMemContextOUT->hDevMemContext,
216 hDevMemContextInt,
217 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
218 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
219 {
220 return 0;
221 }
222 }
223
224 for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++)
225 {
226 IMG_HANDLE hDevMemHeapExt;
227
228#if defined(PVR_SECURE_HANDLES)
229 if(abSharedDeviceMemHeap[i])
230#endif
231 {
232
233 PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
234 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
235 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
236 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
237 }
238#if defined(PVR_SECURE_HANDLES)
239 else
240 {
241
242 if(bCreated)
243 {
244 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
245 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
246 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
247 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
248 psCreateDevMemContextOUT->hDevMemContext);
249 }
250 else
251 {
252 psCreateDevMemContextOUT->eError =
253 PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt,
254 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
255 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
256 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
257 {
258 return 0;
259 }
260 }
261 }
262#endif
263 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
264 }
265
266 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc)
267
268 return 0;
269}
270
271static IMG_INT
272PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
273 PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
274 PVRSRV_BRIDGE_RETURN *psRetOUT,
275 PVRSRV_PER_PROCESS_DATA *psPerProc)
276{
277 IMG_HANDLE hDevCookieInt;
278 IMG_HANDLE hDevMemContextInt;
279 IMG_BOOL bDestroyed;
280
281 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
282
283 psRetOUT->eError =
284 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
285 psDestroyDevMemContextIN->hDevCookie,
286 PVRSRV_HANDLE_TYPE_DEV_NODE);
287
288 if(psRetOUT->eError != PVRSRV_OK)
289 {
290 return 0;
291 }
292
293 psRetOUT->eError =
294 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
295 psDestroyDevMemContextIN->hDevMemContext,
296 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
297
298 if(psRetOUT->eError != PVRSRV_OK)
299 {
300 return 0;
301 }
302
303 psRetOUT->eError =
304 PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed);
305
306 if(psRetOUT->eError != PVRSRV_OK)
307 {
308 return 0;
309 }
310
311 if(bDestroyed)
312 {
313 psRetOUT->eError =
314 PVRSRVReleaseHandle(psPerProc->psHandleBase,
315 psDestroyDevMemContextIN->hDevMemContext,
316 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
317 }
318
319 return 0;
320}
321
322
323static IMG_INT
324PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID,
325 PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
326 PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
327 PVRSRV_PER_PROCESS_DATA *psPerProc)
328{
329 IMG_HANDLE hDevCookieInt;
330 IMG_HANDLE hDevMemContextInt;
331 IMG_UINT32 i;
332
333 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
334
335 NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS)
336
337 psGetDevMemHeapInfoOUT->eError =
338 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
339 psGetDevMemHeapInfoIN->hDevCookie,
340 PVRSRV_HANDLE_TYPE_DEV_NODE);
341
342 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
343 {
344 return 0;
345 }
346
347 psGetDevMemHeapInfoOUT->eError =
348 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
349 psGetDevMemHeapInfoIN->hDevMemContext,
350 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
351
352 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
353 {
354 return 0;
355 }
356
357 psGetDevMemHeapInfoOUT->eError =
358 PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
359 hDevMemContextInt,
360 &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
361 &psGetDevMemHeapInfoOUT->sHeapInfo[0],
362 pbSharedDeviceMemHeap);
363
364 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
365 {
366 return 0;
367 }
368
369 for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
370 {
371 IMG_HANDLE hDevMemHeapExt;
372
373#if defined(PVR_SECURE_HANDLES)
374 if(abSharedDeviceMemHeap[i])
375#endif
376 {
377
378 PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
379 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
380 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
381 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
382 }
383#if defined(PVR_SECURE_HANDLES)
384 else
385 {
386
387 psGetDevMemHeapInfoOUT->eError =
388 PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt,
389 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
390 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
391 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
392 {
393 return 0;
394 }
395 }
396#endif
397 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
398 }
399
400 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc)
401
402 return 0;
403}
404
405
406#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
407IMG_INT
408PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
409 PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
410 PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
411 PVRSRV_PER_PROCESS_DATA *psPerProc);
412#else
413static IMG_INT
414PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
415 PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
416 PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
417 PVRSRV_PER_PROCESS_DATA *psPerProc)
418{
419 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
420 IMG_HANDLE hDevCookieInt;
421 IMG_HANDLE hDevMemHeapInt;
422
423 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
424
425 NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2)
426
427 psAllocDeviceMemOUT->eError =
428 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
429 psAllocDeviceMemIN->hDevCookie,
430 PVRSRV_HANDLE_TYPE_DEV_NODE);
431
432 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
433 {
434 return 0;
435 }
436
437 psAllocDeviceMemOUT->eError =
438 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
439 psAllocDeviceMemIN->hDevMemHeap,
440 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
441
442 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
443 {
444 return 0;
445 }
446
447 psAllocDeviceMemOUT->eError =
448 PVRSRVAllocDeviceMemKM(hDevCookieInt,
449 psPerProc,
450 hDevMemHeapInt,
451 psAllocDeviceMemIN->ui32Attribs,
452 psAllocDeviceMemIN->ui32Size,
453 psAllocDeviceMemIN->ui32Alignment,
454 &psMemInfo,
455 "" );
456
457 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
458 {
459 return 0;
460 }
461
462 OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo,
463 0,
464 sizeof(psAllocDeviceMemOUT->sClientMemInfo));
465
466 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
467 psMemInfo->pvLinAddrKM;
468
469#if defined (__linux__)
470 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0;
471#else
472 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM;
473#endif
474 psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
475 psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
476 psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
477 psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
478
479 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
480 &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
481 psMemInfo,
482 PVRSRV_HANDLE_TYPE_MEM_INFO,
483 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
484
485 if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
486 {
487
488 OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
489 0,
490 sizeof (PVRSRV_CLIENT_SYNC_INFO));
491 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
492 }
493 else
494 {
495
496
497 psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
498 psMemInfo->psKernelSyncInfo->psSyncData;
499 psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
500 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
501 psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
502 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
503
504 psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
505 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
506
507 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
508 &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo,
509 psMemInfo->psKernelSyncInfo,
510 PVRSRV_HANDLE_TYPE_SYNC_INFO,
511 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
512 psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
513
514 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
515 &psAllocDeviceMemOUT->sClientSyncInfo;
516
517 }
518
519 COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc)
520
521 return 0;
522}
523
524#endif
525
526static IMG_INT
527PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
528 PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
529 PVRSRV_BRIDGE_RETURN *psRetOUT,
530 PVRSRV_PER_PROCESS_DATA *psPerProc)
531{
532 IMG_HANDLE hDevCookieInt;
533 IMG_VOID *pvKernelMemInfo;
534
535
536 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
537
538 psRetOUT->eError =
539 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
540 psFreeDeviceMemIN->hDevCookie,
541 PVRSRV_HANDLE_TYPE_DEV_NODE);
542
543 if(psRetOUT->eError != PVRSRV_OK)
544 {
545 return 0;
546 }
547
548 psRetOUT->eError =
549 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
550 psFreeDeviceMemIN->psKernelMemInfo,
551 PVRSRV_HANDLE_TYPE_MEM_INFO);
552
553 if(psRetOUT->eError != PVRSRV_OK)
554 {
555 return 0;
556 }
557
558 psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
559
560 if(psRetOUT->eError != PVRSRV_OK)
561 {
562 return 0;
563 }
564
565 psRetOUT->eError =
566 PVRSRVReleaseHandle(psPerProc->psHandleBase,
567 psFreeDeviceMemIN->psKernelMemInfo,
568 PVRSRV_HANDLE_TYPE_MEM_INFO);
569
570 return 0;
571}
572
573
574static IMG_INT
575PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID,
576 PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
577 PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
578 PVRSRV_PER_PROCESS_DATA *psPerProc)
579{
580 IMG_HANDLE hDevCookieInt;
581 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
582
583 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EXPORT_DEVICEMEM);
584
585
586 psExportDeviceMemOUT->eError =
587 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
588 psExportDeviceMemIN->hDevCookie,
589 PVRSRV_HANDLE_TYPE_DEV_NODE);
590
591 if(psExportDeviceMemOUT->eError != PVRSRV_OK)
592 {
593 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie"));
594 return 0;
595 }
596
597
598 psExportDeviceMemOUT->eError =
599 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo,
600 psExportDeviceMemIN->psKernelMemInfo,
601 PVRSRV_HANDLE_TYPE_MEM_INFO);
602
603 if(psExportDeviceMemOUT->eError != PVRSRV_OK)
604 {
605 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
606 return 0;
607 }
608
609
610 psExportDeviceMemOUT->eError =
611 PVRSRVFindHandle(KERNEL_HANDLE_BASE,
612 &psExportDeviceMemOUT->hMemInfo,
613 psKernelMemInfo,
614 PVRSRV_HANDLE_TYPE_MEM_INFO);
615 if(psExportDeviceMemOUT->eError == PVRSRV_OK)
616 {
617
618 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
619 return 0;
620 }
621
622
623 psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
624 &psExportDeviceMemOUT->hMemInfo,
625 psKernelMemInfo,
626 PVRSRV_HANDLE_TYPE_MEM_INFO,
627 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
628 if (psExportDeviceMemOUT->eError != PVRSRV_OK)
629 {
630 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list"));
631 return 0;
632 }
633
634
635 psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
636
637 return 0;
638}
639
640
641static IMG_INT
642PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
643 PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
644 PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
645 PVRSRV_PER_PROCESS_DATA *psPerProc)
646{
647 PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = IMG_NULL;
648 PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = IMG_NULL;
649 IMG_HANDLE hDstDevMemHeap = IMG_NULL;
650
651 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEV_MEMORY);
652
653 NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2)
654
655
656 psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
657 (IMG_VOID**)&psSrcKernelMemInfo,
658 psMapDevMemIN->hKernelMemInfo,
659 PVRSRV_HANDLE_TYPE_MEM_INFO);
660 if(psMapDevMemOUT->eError != PVRSRV_OK)
661 {
662 return 0;
663 }
664
665
666 psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
667 &hDstDevMemHeap,
668 psMapDevMemIN->hDstDevMemHeap,
669 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
670 if(psMapDevMemOUT->eError != PVRSRV_OK)
671 {
672 return 0;
673 }
674
675
676 psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
677 psSrcKernelMemInfo,
678 hDstDevMemHeap,
679 &psDstKernelMemInfo);
680 if(psMapDevMemOUT->eError != PVRSRV_OK)
681 {
682 return 0;
683 }
684
685 OSMemSet(&psMapDevMemOUT->sDstClientMemInfo,
686 0,
687 sizeof(psMapDevMemOUT->sDstClientMemInfo));
688 OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo,
689 0,
690 sizeof(psMapDevMemOUT->sDstClientSyncInfo));
691
692 psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
693 psDstKernelMemInfo->pvLinAddrKM;
694
695 psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0;
696 psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr;
697 psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags;
698 psMapDevMemOUT->sDstClientMemInfo.ui32AllocSize = psDstKernelMemInfo->ui32AllocSize;
699 psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
700
701
702 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
703 &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
704 psDstKernelMemInfo,
705 PVRSRV_HANDLE_TYPE_MEM_INFO,
706 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
707 psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
708
709
710 if(psDstKernelMemInfo->psKernelSyncInfo)
711 {
712 psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
713 psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
714 psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
715 psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
716 psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
717 psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
718
719 psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
720 psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
721
722 psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
723
724 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
725 &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo,
726 psDstKernelMemInfo->psKernelSyncInfo,
727 PVRSRV_HANDLE_TYPE_SYNC_INFO,
728 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
729 psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
730 }
731
732 COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc)
733
734 return 0;
735}
736
737
738static IMG_INT
739PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
740 PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
741 PVRSRV_BRIDGE_RETURN *psRetOUT,
742 PVRSRV_PER_PROCESS_DATA *psPerProc)
743{
744 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
745
746 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
747
748 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
749 (IMG_VOID**)&psKernelMemInfo,
750 psUnmapDevMemIN->psKernelMemInfo,
751 PVRSRV_HANDLE_TYPE_MEM_INFO);
752 if(psRetOUT->eError != PVRSRV_OK)
753 {
754 return 0;
755 }
756
757 psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
758 if(psRetOUT->eError != PVRSRV_OK)
759 {
760 return 0;
761 }
762
763 psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
764 psUnmapDevMemIN->psKernelMemInfo,
765 PVRSRV_HANDLE_TYPE_MEM_INFO);
766
767 return 0;
768}
769
770
771
772static IMG_INT
773PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
774 PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
775 PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
776 PVRSRV_PER_PROCESS_DATA *psPerProc)
777{
778 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
779 IMG_HANDLE hOSMapInfo;
780 IMG_HANDLE hDeviceClassBufferInt;
781 IMG_HANDLE hDevMemContextInt;
782 PVRSRV_HANDLE_TYPE eHandleType;
783
784 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
785
786 NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2)
787
788
789 psMapDevClassMemOUT->eError =
790 PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, &hDeviceClassBufferInt,
791 &eHandleType,
792 psMapDevClassMemIN->hDeviceClassBuffer);
793
794 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
795 {
796 return 0;
797 }
798
799
800 psMapDevClassMemOUT->eError =
801 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
802 psMapDevClassMemIN->hDevMemContext,
803 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
804
805 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
806 {
807 return 0;
808 }
809
810
811 switch(eHandleType)
812 {
813#if defined(PVR_SECURE_HANDLES)
814 case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
815 case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
816#else
817 case PVRSRV_HANDLE_TYPE_NONE:
818#endif
819 break;
820 default:
821 psMapDevClassMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
822 return 0;
823 }
824
825 psMapDevClassMemOUT->eError =
826 PVRSRVMapDeviceClassMemoryKM(psPerProc,
827 hDevMemContextInt,
828 hDeviceClassBufferInt,
829 &psMemInfo,
830 &hOSMapInfo);
831 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
832 {
833 return 0;
834 }
835
836 OSMemSet(&psMapDevClassMemOUT->sClientMemInfo,
837 0,
838 sizeof(psMapDevClassMemOUT->sClientMemInfo));
839 OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo,
840 0,
841 sizeof(psMapDevClassMemOUT->sClientSyncInfo));
842
843 psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
844 psMemInfo->pvLinAddrKM;
845
846 psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0;
847 psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
848 psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
849 psMapDevClassMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
850 psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
851
852 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
853 &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
854 psMemInfo,
855 PVRSRV_HANDLE_TYPE_MEM_INFO,
856 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
857 psMapDevClassMemIN->hDeviceClassBuffer);
858
859 psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
860
861
862 if(psMemInfo->psKernelSyncInfo)
863 {
864 psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
865 psMemInfo->psKernelSyncInfo->psSyncData;
866 psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
867 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
868 psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
869 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
870
871 psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
872 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
873
874 psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
875
876 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
877 &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo,
878 psMemInfo->psKernelSyncInfo,
879 PVRSRV_HANDLE_TYPE_SYNC_INFO,
880 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
881 psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
882 }
883
884 COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc)
885
886 return 0;
887}
888
889static IMG_INT
890PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
891 PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
892 PVRSRV_BRIDGE_RETURN *psRetOUT,
893 PVRSRV_PER_PROCESS_DATA *psPerProc)
894{
895 IMG_VOID *pvKernelMemInfo;
896
897 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
898
899 psRetOUT->eError =
900 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
901 psUnmapDevClassMemIN->psKernelMemInfo,
902 PVRSRV_HANDLE_TYPE_MEM_INFO);
903 if(psRetOUT->eError != PVRSRV_OK)
904 {
905 return 0;
906 }
907
908 psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
909
910 if(psRetOUT->eError != PVRSRV_OK)
911 {
912 return 0;
913 }
914
915 psRetOUT->eError =
916 PVRSRVReleaseHandle(psPerProc->psHandleBase,
917 psUnmapDevClassMemIN->psKernelMemInfo,
918 PVRSRV_HANDLE_TYPE_MEM_INFO);
919
920 return 0;
921}
922
923
924#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW)
925IMG_INT
926PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
927 PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
928 PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
929 PVRSRV_PER_PROCESS_DATA *psPerProc);
930#else
931static IMG_INT
932PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
933 PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
934 PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
935 PVRSRV_PER_PROCESS_DATA *psPerProc)
936{
937 IMG_HANDLE hDevCookieInt;
938 IMG_HANDLE hDevMemContextInt;
939 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
940 IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
941 IMG_UINT32 ui32PageTableSize = 0;
942
943 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
944
945 NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2)
946
947
948 psWrapExtMemOUT->eError =
949 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
950 psWrapExtMemIN->hDevCookie,
951 PVRSRV_HANDLE_TYPE_DEV_NODE);
952 if(psWrapExtMemOUT->eError != PVRSRV_OK)
953 {
954 return 0;
955 }
956
957
958 psWrapExtMemOUT->eError =
959 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
960 psWrapExtMemIN->hDevMemContext,
961 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
962
963 if(psWrapExtMemOUT->eError != PVRSRV_OK)
964 {
965 return 0;
966 }
967
968 if(psWrapExtMemIN->ui32NumPageTableEntries)
969 {
970 ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
971 * sizeof(IMG_SYS_PHYADDR);
972
973 ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
974 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
975 ui32PageTableSize,
976 (IMG_VOID **)&psSysPAddr, 0,
977 "Page Table"));
978
979 if(CopyFromUserWrapper(psPerProc,
980 ui32BridgeID,
981 psSysPAddr,
982 psWrapExtMemIN->psSysPAddr,
983 ui32PageTableSize) != PVRSRV_OK)
984 {
985 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
986
987 return -EFAULT;
988 }
989 }
990
991 psWrapExtMemOUT->eError =
992 PVRSRVWrapExtMemoryKM(hDevCookieInt,
993 psPerProc,
994 hDevMemContextInt,
995 psWrapExtMemIN->ui32ByteSize,
996 psWrapExtMemIN->ui32PageOffset,
997 psWrapExtMemIN->bPhysContig,
998 psSysPAddr,
999 psWrapExtMemIN->pvLinAddr,
1000 psWrapExtMemIN->ui32Flags,
1001 &psMemInfo);
1002
1003 if(psWrapExtMemIN->ui32NumPageTableEntries)
1004 {
1005 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1006 ui32PageTableSize,
1007 (IMG_VOID *)psSysPAddr, 0);
1008
1009 }
1010
1011 if(psWrapExtMemOUT->eError != PVRSRV_OK)
1012 {
1013 return 0;
1014 }
1015
1016 psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
1017 psMemInfo->pvLinAddrKM;
1018
1019
1020 psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
1021 psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
1022 psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
1023 psWrapExtMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
1024 psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
1025
1026 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1027 &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
1028 psMemInfo,
1029 PVRSRV_HANDLE_TYPE_MEM_INFO,
1030 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1031
1032
1033 psWrapExtMemOUT->sClientSyncInfo.psSyncData =
1034 psMemInfo->psKernelSyncInfo->psSyncData;
1035 psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
1036 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
1037 psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
1038 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
1039
1040 psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
1041 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
1042
1043 psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo;
1044
1045 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1046 &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo,
1047 (IMG_HANDLE)psMemInfo->psKernelSyncInfo,
1048 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1049 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1050 psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
1051
1052 COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc)
1053
1054 return 0;
1055}
1056#endif
1057
1058static IMG_INT
1059PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
1060 PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
1061 PVRSRV_BRIDGE_RETURN *psRetOUT,
1062 PVRSRV_PER_PROCESS_DATA *psPerProc)
1063{
1064 IMG_VOID *pvMemInfo;
1065
1066 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
1067
1068 psRetOUT->eError =
1069 PVRSRVLookupHandle(psPerProc->psHandleBase,
1070 &pvMemInfo,
1071 psUnwrapExtMemIN->hKernelMemInfo,
1072 PVRSRV_HANDLE_TYPE_MEM_INFO);
1073 if(psRetOUT->eError != PVRSRV_OK)
1074 {
1075 return 0;
1076 }
1077
1078 psRetOUT->eError =
1079 PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
1080 if(psRetOUT->eError != PVRSRV_OK)
1081 {
1082 return 0;
1083 }
1084
1085 psRetOUT->eError =
1086 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1087 psUnwrapExtMemIN->hKernelMemInfo,
1088 PVRSRV_HANDLE_TYPE_MEM_INFO);
1089
1090 return 0;
1091}
1092
1093static IMG_INT
1094PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
1095 PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
1096 PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
1097 PVRSRV_PER_PROCESS_DATA *psPerProc)
1098{
1099 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
1100
1101 PVR_UNREFERENCED_PARAMETER(psPerProc);
1102
1103 psGetFreeDeviceMemOUT->eError =
1104 PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
1105 &psGetFreeDeviceMemOUT->ui32Total,
1106 &psGetFreeDeviceMemOUT->ui32Free,
1107 &psGetFreeDeviceMemOUT->ui32LargestBlock);
1108
1109 return 0;
1110}
1111
1112static IMG_INT
1113PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID,
1114 PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
1115 PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
1116 PVRSRV_PER_PROCESS_DATA *psPerProc)
1117{
1118 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
1119
1120#if defined (__linux__)
1121 psMMapDataOUT->eError =
1122 PVRMMapOSMemHandleToMMapData(psPerProc,
1123 psMMapDataIN->hMHandle,
1124 &psMMapDataOUT->ui32MMapOffset,
1125 &psMMapDataOUT->ui32ByteOffset,
1126 &psMMapDataOUT->ui32RealByteSize,
1127 &psMMapDataOUT->ui32UserVAddr);
1128#else
1129 PVR_UNREFERENCED_PARAMETER(psPerProc);
1130 PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
1131
1132 psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1133#endif
1134 return 0;
1135}
1136
1137
1138static IMG_INT
1139PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID,
1140 PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
1141 PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
1142 PVRSRV_PER_PROCESS_DATA *psPerProc)
1143{
1144 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
1145
1146#if defined (__linux__)
1147 psMMapDataOUT->eError =
1148 PVRMMapReleaseMMapData(psPerProc,
1149 psMMapDataIN->hMHandle,
1150 &psMMapDataOUT->bMUnmap,
1151 &psMMapDataOUT->ui32RealByteSize,
1152 &psMMapDataOUT->ui32UserVAddr);
1153#else
1154
1155 PVR_UNREFERENCED_PARAMETER(psPerProc);
1156 PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
1157
1158 psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1159#endif
1160 return 0;
1161}
1162
1163
1164#ifdef PDUMP
1165static IMG_INT
1166PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID,
1167 IMG_VOID *psBridgeIn,
1168 PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
1169 PVRSRV_PER_PROCESS_DATA *psPerProc)
1170{
1171 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
1172 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1173 PVR_UNREFERENCED_PARAMETER(psPerProc);
1174
1175 psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
1176 psPDumpIsCapturingOUT->eError = PVRSRV_OK;
1177
1178 return 0;
1179}
1180
1181static IMG_INT
1182PDumpCommentBW(IMG_UINT32 ui32BridgeID,
1183 PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
1184 PVRSRV_BRIDGE_RETURN *psRetOUT,
1185 PVRSRV_PER_PROCESS_DATA *psPerProc)
1186{
1187 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
1188 PVR_UNREFERENCED_PARAMETER(psPerProc);
1189
1190 psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
1191 psPDumpCommentIN->ui32Flags);
1192 return 0;
1193}
1194
1195static IMG_INT
1196PDumpSetFrameBW(IMG_UINT32 ui32BridgeID,
1197 PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
1198 PVRSRV_BRIDGE_RETURN *psRetOUT,
1199 PVRSRV_PER_PROCESS_DATA *psPerProc)
1200{
1201 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
1202 PVR_UNREFERENCED_PARAMETER(psPerProc);
1203
1204 psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
1205
1206 return 0;
1207}
1208
1209static IMG_INT
1210PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID,
1211 PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
1212 PVRSRV_BRIDGE_RETURN *psRetOUT,
1213 PVRSRV_PER_PROCESS_DATA *psPerProc)
1214{
1215 PVRSRV_DEVICE_NODE *psDeviceNode;
1216
1217 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
1218
1219 psRetOUT->eError =
1220 PVRSRVLookupHandle(psPerProc->psHandleBase,
1221 (IMG_VOID **)&psDeviceNode,
1222 psPDumpRegDumpIN->hDevCookie,
1223 PVRSRV_HANDLE_TYPE_DEV_NODE);
1224 if(psRetOUT->eError != PVRSRV_OK)
1225 {
1226 return 0;
1227 }
1228
1229 psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion,
1230 psPDumpRegDumpIN->sHWReg.ui32RegAddr,
1231 psPDumpRegDumpIN->sHWReg.ui32RegVal,
1232 psPDumpRegDumpIN->ui32Flags);
1233
1234 return 0;
1235}
1236
1237static IMG_INT
1238PDumpRegPolBW(IMG_UINT32 ui32BridgeID,
1239 PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
1240 PVRSRV_BRIDGE_RETURN *psRetOUT,
1241 PVRSRV_PER_PROCESS_DATA *psPerProc)
1242{
1243 PVRSRV_DEVICE_NODE *psDeviceNode;
1244
1245 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
1246
1247 psRetOUT->eError =
1248 PVRSRVLookupHandle(psPerProc->psHandleBase,
1249 (IMG_VOID **)&psDeviceNode,
1250 psPDumpRegPolIN->hDevCookie,
1251 PVRSRV_HANDLE_TYPE_DEV_NODE);
1252 if(psRetOUT->eError != PVRSRV_OK)
1253 {
1254 return 0;
1255 }
1256
1257
1258 psRetOUT->eError =
1259 PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion,
1260 psPDumpRegPolIN->sHWReg.ui32RegAddr,
1261 psPDumpRegPolIN->sHWReg.ui32RegVal,
1262 psPDumpRegPolIN->ui32Mask,
1263 psPDumpRegPolIN->ui32Flags);
1264
1265 return 0;
1266}
1267
1268static IMG_INT
1269PDumpMemPolBW(IMG_UINT32 ui32BridgeID,
1270 PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
1271 PVRSRV_BRIDGE_RETURN *psRetOUT,
1272 PVRSRV_PER_PROCESS_DATA *psPerProc)
1273{
1274 IMG_VOID *pvMemInfo;
1275
1276 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
1277
1278 psRetOUT->eError =
1279 PVRSRVLookupHandle(psPerProc->psHandleBase,
1280 &pvMemInfo,
1281 psPDumpMemPolIN->psKernelMemInfo,
1282 PVRSRV_HANDLE_TYPE_MEM_INFO);
1283 if(psRetOUT->eError != PVRSRV_OK)
1284 {
1285 return 0;
1286 }
1287
1288 psRetOUT->eError =
1289 PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
1290 psPDumpMemPolIN->ui32Offset,
1291 psPDumpMemPolIN->ui32Value,
1292 psPDumpMemPolIN->ui32Mask,
1293 psPDumpMemPolIN->eOperator,
1294 psPDumpMemPolIN->ui32Flags,
1295 MAKEUNIQUETAG(pvMemInfo));
1296
1297 return 0;
1298}
1299
1300static IMG_INT
1301PDumpMemBW(IMG_UINT32 ui32BridgeID,
1302 PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
1303 PVRSRV_BRIDGE_RETURN *psRetOUT,
1304 PVRSRV_PER_PROCESS_DATA *psPerProc)
1305{
1306 IMG_VOID *pvMemInfo;
1307
1308 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
1309
1310 psRetOUT->eError =
1311 PVRSRVLookupHandle(psPerProc->psHandleBase,
1312 &pvMemInfo,
1313 psPDumpMemDumpIN->psKernelMemInfo,
1314 PVRSRV_HANDLE_TYPE_MEM_INFO);
1315 if(psRetOUT->eError != PVRSRV_OK)
1316 {
1317 return 0;
1318 }
1319
1320 psRetOUT->eError =
1321 PDumpMemUM(psPerProc,
1322 psPDumpMemDumpIN->pvAltLinAddr,
1323 psPDumpMemDumpIN->pvLinAddr,
1324 pvMemInfo,
1325 psPDumpMemDumpIN->ui32Offset,
1326 psPDumpMemDumpIN->ui32Bytes,
1327 psPDumpMemDumpIN->ui32Flags,
1328 MAKEUNIQUETAG(pvMemInfo));
1329
1330 return 0;
1331}
1332
1333static IMG_INT
1334PDumpBitmapBW(IMG_UINT32 ui32BridgeID,
1335 PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
1336 PVRSRV_BRIDGE_RETURN *psRetOUT,
1337 PVRSRV_PER_PROCESS_DATA *psPerProc)
1338{
1339 PVRSRV_DEVICE_NODE *psDeviceNode;
1340 IMG_HANDLE hDevMemContextInt;
1341
1342 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
1343
1344 psRetOUT->eError =
1345 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
1346 psPDumpBitmapIN->hDevCookie,
1347 PVRSRV_HANDLE_TYPE_DEV_NODE);
1348
1349 psRetOUT->eError =
1350 PVRSRVLookupHandle( psPerProc->psHandleBase,
1351 &hDevMemContextInt,
1352 psPDumpBitmapIN->hDevMemContext,
1353 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
1354
1355 if(psRetOUT->eError != PVRSRV_OK)
1356 {
1357 return 0;
1358 }
1359
1360 psRetOUT->eError =
1361 PDumpBitmapKM(psDeviceNode,
1362 &psPDumpBitmapIN->szFileName[0],
1363 psPDumpBitmapIN->ui32FileOffset,
1364 psPDumpBitmapIN->ui32Width,
1365 psPDumpBitmapIN->ui32Height,
1366 psPDumpBitmapIN->ui32StrideInBytes,
1367 psPDumpBitmapIN->sDevBaseAddr,
1368 hDevMemContextInt,
1369 psPDumpBitmapIN->ui32Size,
1370 psPDumpBitmapIN->ePixelFormat,
1371 psPDumpBitmapIN->eMemFormat,
1372 psPDumpBitmapIN->ui32Flags);
1373
1374 return 0;
1375}
1376
1377static IMG_INT
1378PDumpReadRegBW(IMG_UINT32 ui32BridgeID,
1379 PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
1380 PVRSRV_BRIDGE_RETURN *psRetOUT,
1381 PVRSRV_PER_PROCESS_DATA *psPerProc)
1382{
1383 PVRSRV_DEVICE_NODE *psDeviceNode;
1384
1385 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
1386
1387 psRetOUT->eError =
1388 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
1389 psPDumpReadRegIN->hDevCookie,
1390 PVRSRV_HANDLE_TYPE_DEV_NODE);
1391
1392 psRetOUT->eError =
1393 PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0],
1394 &psPDumpReadRegIN->szFileName[0],
1395 psPDumpReadRegIN->ui32FileOffset,
1396 psPDumpReadRegIN->ui32Address,
1397 psPDumpReadRegIN->ui32Size,
1398 psPDumpReadRegIN->ui32Flags);
1399
1400 return 0;
1401}
1402
1403static IMG_INT
1404PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID,
1405 PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
1406 PVRSRV_BRIDGE_RETURN *psRetOUT,
1407 PVRSRV_PER_PROCESS_DATA *psPerProc)
1408{
1409 IMG_UINT32 ui32PDumpFlags;
1410
1411 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
1412 PVR_UNREFERENCED_PARAMETER(psPerProc);
1413
1414 ui32PDumpFlags = 0;
1415 if(psPDumpDriverInfoIN->bContinuous)
1416 {
1417 ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
1418 }
1419 psRetOUT->eError =
1420 PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
1421 ui32PDumpFlags);
1422
1423 return 0;
1424}
1425
1426static IMG_INT
1427PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID,
1428 PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
1429 PVRSRV_BRIDGE_RETURN *psRetOUT,
1430 PVRSRV_PER_PROCESS_DATA *psPerProc)
1431{
1432 IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
1433 IMG_VOID *pvSyncInfo;
1434
1435 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
1436
1437 psRetOUT->eError =
1438 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1439 psPDumpSyncDumpIN->psKernelSyncInfo,
1440 PVRSRV_HANDLE_TYPE_SYNC_INFO);
1441 if(psRetOUT->eError != PVRSRV_OK)
1442 {
1443 return 0;
1444 }
1445
1446 psRetOUT->eError =
1447 PDumpMemUM(psPerProc,
1448 psPDumpSyncDumpIN->pvAltLinAddr,
1449 IMG_NULL,
1450 ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
1451 psPDumpSyncDumpIN->ui32Offset,
1452 ui32Bytes,
1453 0,
1454 MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
1455
1456 return 0;
1457}
1458
1459static IMG_INT
1460PDumpSyncPolBW(IMG_UINT32 ui32BridgeID,
1461 PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
1462 PVRSRV_BRIDGE_RETURN *psRetOUT,
1463 PVRSRV_PER_PROCESS_DATA *psPerProc)
1464{
1465 IMG_UINT32 ui32Offset;
1466 IMG_VOID *pvSyncInfo;
1467
1468 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
1469
1470 psRetOUT->eError =
1471 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1472 psPDumpSyncPolIN->psKernelSyncInfo,
1473 PVRSRV_HANDLE_TYPE_SYNC_INFO);
1474 if(psRetOUT->eError != PVRSRV_OK)
1475 {
1476 return 0;
1477 }
1478
1479 if(psPDumpSyncPolIN->bIsRead)
1480 {
1481 ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
1482 }
1483 else
1484 {
1485 ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
1486 }
1487
1488 psRetOUT->eError =
1489 PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
1490 ui32Offset,
1491 psPDumpSyncPolIN->ui32Value,
1492 psPDumpSyncPolIN->ui32Mask,
1493 PDUMP_POLL_OPERATOR_EQUAL,
1494 0,
1495 MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
1496
1497 return 0;
1498}
1499
1500
1501static IMG_INT
1502PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID,
1503 PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN,
1504 PVRSRV_BRIDGE_RETURN *psRetOUT,
1505 PVRSRV_PER_PROCESS_DATA *psPerProc)
1506{
1507 PVRSRV_DEVICE_NODE *psDeviceNode;
1508
1509 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
1510
1511 psRetOUT->eError =
1512 PVRSRVLookupHandle(psPerProc->psHandleBase,
1513 (IMG_VOID **)&psDeviceNode,
1514 psPDumpCycleCountRegReadIN->hDevCookie,
1515 PVRSRV_HANDLE_TYPE_DEV_NODE);
1516 if(psRetOUT->eError != PVRSRV_OK)
1517 {
1518 return 0;
1519 }
1520
1521 PDumpCycleCountRegRead(&psDeviceNode->sDevId,
1522 psPDumpCycleCountRegReadIN->ui32RegOffset,
1523 psPDumpCycleCountRegReadIN->bLastFrame);
1524
1525 psRetOUT->eError = PVRSRV_OK;
1526
1527 return 0;
1528}
1529
1530static IMG_INT
1531PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
1532 PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
1533 PVRSRV_BRIDGE_RETURN *psRetOUT,
1534 PVRSRV_PER_PROCESS_DATA *psPerProc)
1535{
1536 IMG_VOID *pvMemInfo;
1537
1538 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
1539
1540 psRetOUT->eError =
1541 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
1542 psPDumpPDDevPAddrIN->hKernelMemInfo,
1543 PVRSRV_HANDLE_TYPE_MEM_INFO);
1544 if(psRetOUT->eError != PVRSRV_OK)
1545 {
1546 return 0;
1547 }
1548
1549 psRetOUT->eError =
1550 PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
1551 psPDumpPDDevPAddrIN->ui32Offset,
1552 psPDumpPDDevPAddrIN->sPDDevPAddr,
1553 MAKEUNIQUETAG(pvMemInfo),
1554 PDUMP_PD_UNIQUETAG);
1555 return 0;
1556}
1557
1558static IMG_INT
1559PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID,
1560 IMG_VOID *psBridgeIn,
1561 PVRSRV_BRIDGE_RETURN *psRetOUT,
1562 PVRSRV_PER_PROCESS_DATA *psPerProc)
1563{
1564 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
1565 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1566 PVR_UNREFERENCED_PARAMETER(psPerProc);
1567
1568 psRetOUT->eError = PDumpStartInitPhaseKM();
1569
1570 return 0;
1571}
1572
1573static IMG_INT
1574PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID,
1575 IMG_VOID *psBridgeIn,
1576 PVRSRV_BRIDGE_RETURN *psRetOUT,
1577 PVRSRV_PER_PROCESS_DATA *psPerProc)
1578{
1579 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
1580 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1581 PVR_UNREFERENCED_PARAMETER(psPerProc);
1582
1583 psRetOUT->eError = PDumpStopInitPhaseKM();
1584
1585 return 0;
1586}
1587
1588#endif
1589
1590
1591static IMG_INT
1592PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
1593 PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
1594 PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
1595 PVRSRV_PER_PROCESS_DATA *psPerProc)
1596{
1597 PVRSRV_ERROR eError;
1598
1599 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
1600
1601 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
1602 &psGetMiscInfoIN->sMiscInfo,
1603 sizeof(PVRSRV_MISC_INFO));
1604
1605 if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
1606 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) &&
1607 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
1608 {
1609
1610 psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1611 return 0;
1612 }
1613
1614 if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
1615 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) ||
1616 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
1617 {
1618
1619 ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
1620 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1621 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1622 (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
1623 "Output string buffer"));
1624
1625 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1626
1627
1628 eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
1629 psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
1630 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1631 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
1632
1633
1634 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1635 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1636 (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
1637 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = IMG_NULL;
1638
1639
1640 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
1641
1642 if(eError != PVRSRV_OK)
1643 {
1644
1645 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
1646 return -EFAULT;
1647 }
1648 }
1649 else
1650 {
1651 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1652 }
1653
1654
1655 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1656 {
1657 return 0;
1658 }
1659
1660
1661 if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
1662 {
1663 psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
1664 &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
1665 psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
1666 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
1667 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1668
1669 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1670 {
1671 return 0;
1672 }
1673 }
1674
1675 if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
1676 {
1677
1678 psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
1679 &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
1680 psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
1681 PVRSRV_HANDLE_TYPE_SOC_TIMER,
1682 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1683
1684 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1685 {
1686 return 0;
1687 }
1688 }
1689
1690 return 0;
1691}
1692
1693static IMG_INT
1694PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
1695 PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN,
1696 PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
1697 PVRSRV_PER_PROCESS_DATA *psPerProc)
1698{
1699 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
1700
1701#if defined(PDUMP)
1702
1703 psPerProc->bPDumpPersistent |= ( (psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0) ? IMG_TRUE : IMG_FALSE;
1704#else
1705 PVR_UNREFERENCED_PARAMETER(psConnectServicesIN);
1706#endif
1707 psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
1708 psConnectServicesOUT->eError = PVRSRV_OK;
1709
1710 return 0;
1711}
1712
1713static IMG_INT
1714PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID,
1715 IMG_VOID *psBridgeIn,
1716 PVRSRV_BRIDGE_RETURN *psRetOUT,
1717 PVRSRV_PER_PROCESS_DATA *psPerProc)
1718{
1719 PVR_UNREFERENCED_PARAMETER(psPerProc);
1720 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1721
1722 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES);
1723
1724
1725 psRetOUT->eError = PVRSRV_OK;
1726
1727 return 0;
1728}
1729
1730static IMG_INT
1731PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID,
1732 PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
1733 PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
1734 PVRSRV_PER_PROCESS_DATA *psPerProc)
1735{
1736 PVR_UNREFERENCED_PARAMETER(psPerProc);
1737
1738 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
1739
1740 psEnumDispClassOUT->eError =
1741 PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
1742 &psEnumDispClassOUT->ui32NumDevices,
1743 &psEnumDispClassOUT->ui32DevID[0]);
1744
1745 return 0;
1746}
1747
1748static IMG_INT
1749PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID,
1750 PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
1751 PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
1752 PVRSRV_PER_PROCESS_DATA *psPerProc)
1753{
1754 IMG_HANDLE hDevCookieInt;
1755 IMG_HANDLE hDispClassInfoInt;
1756
1757 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
1758
1759 NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1)
1760
1761 psOpenDispClassDeviceOUT->eError =
1762 PVRSRVLookupHandle(psPerProc->psHandleBase,
1763 &hDevCookieInt,
1764 psOpenDispClassDeviceIN->hDevCookie,
1765 PVRSRV_HANDLE_TYPE_DEV_NODE);
1766 if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1767 {
1768 return 0;
1769 }
1770
1771 psOpenDispClassDeviceOUT->eError =
1772 PVRSRVOpenDCDeviceKM(psPerProc,
1773 psOpenDispClassDeviceIN->ui32DeviceID,
1774 hDevCookieInt,
1775 &hDispClassInfoInt);
1776
1777 if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1778 {
1779 return 0;
1780 }
1781
1782 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1783 &psOpenDispClassDeviceOUT->hDeviceKM,
1784 hDispClassInfoInt,
1785 PVRSRV_HANDLE_TYPE_DISP_INFO,
1786 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1787 COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc)
1788
1789 return 0;
1790}
1791
1792static IMG_INT
1793PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID,
1794 PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
1795 PVRSRV_BRIDGE_RETURN *psRetOUT,
1796 PVRSRV_PER_PROCESS_DATA *psPerProc)
1797{
1798 IMG_VOID *pvDispClassInfoInt;
1799
1800 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
1801
1802 psRetOUT->eError =
1803 PVRSRVLookupHandle(psPerProc->psHandleBase,
1804 &pvDispClassInfoInt,
1805 psCloseDispClassDeviceIN->hDeviceKM,
1806 PVRSRV_HANDLE_TYPE_DISP_INFO);
1807
1808 if(psRetOUT->eError != PVRSRV_OK)
1809 {
1810 return 0;
1811 }
1812
1813 psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
1814 if(psRetOUT->eError != PVRSRV_OK)
1815 {
1816 return 0;
1817 }
1818
1819 psRetOUT->eError =
1820 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1821 psCloseDispClassDeviceIN->hDeviceKM,
1822 PVRSRV_HANDLE_TYPE_DISP_INFO);
1823 return 0;
1824}
1825
1826static IMG_INT
1827PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID,
1828 PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
1829 PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
1830 PVRSRV_PER_PROCESS_DATA *psPerProc)
1831{
1832 IMG_VOID *pvDispClassInfoInt;
1833
1834 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
1835
1836 psEnumDispClassFormatsOUT->eError =
1837 PVRSRVLookupHandle(psPerProc->psHandleBase,
1838 &pvDispClassInfoInt,
1839 psEnumDispClassFormatsIN->hDeviceKM,
1840 PVRSRV_HANDLE_TYPE_DISP_INFO);
1841 if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
1842 {
1843 return 0;
1844 }
1845
1846 psEnumDispClassFormatsOUT->eError =
1847 PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
1848 &psEnumDispClassFormatsOUT->ui32Count,
1849 psEnumDispClassFormatsOUT->asFormat);
1850
1851 return 0;
1852}
1853
1854static IMG_INT
1855PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID,
1856 PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
1857 PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
1858 PVRSRV_PER_PROCESS_DATA *psPerProc)
1859{
1860 IMG_VOID *pvDispClassInfoInt;
1861
1862 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
1863
1864 psEnumDispClassDimsOUT->eError =
1865 PVRSRVLookupHandle(psPerProc->psHandleBase,
1866 &pvDispClassInfoInt,
1867 psEnumDispClassDimsIN->hDeviceKM,
1868 PVRSRV_HANDLE_TYPE_DISP_INFO);
1869
1870 if(psEnumDispClassDimsOUT->eError != PVRSRV_OK)
1871 {
1872 return 0;
1873 }
1874
1875 psEnumDispClassDimsOUT->eError =
1876 PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
1877 &psEnumDispClassDimsIN->sFormat,
1878 &psEnumDispClassDimsOUT->ui32Count,
1879 psEnumDispClassDimsOUT->asDim);
1880
1881 return 0;
1882}
1883
1884static IMG_INT
1885PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
1886 PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,
1887 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
1888 PVRSRV_PER_PROCESS_DATA *psPerProc)
1889{
1890 IMG_HANDLE hBufferInt;
1891 IMG_VOID *pvDispClassInfoInt;
1892
1893 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
1894
1895 NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1)
1896
1897 psGetDispClassSysBufferOUT->eError =
1898 PVRSRVLookupHandle(psPerProc->psHandleBase,
1899 &pvDispClassInfoInt,
1900 psGetDispClassSysBufferIN->hDeviceKM,
1901 PVRSRV_HANDLE_TYPE_DISP_INFO);
1902 if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1903 {
1904 return 0;
1905 }
1906
1907 psGetDispClassSysBufferOUT->eError =
1908 PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt,
1909 &hBufferInt);
1910
1911 if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1912 {
1913 return 0;
1914 }
1915
1916
1917 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1918 &psGetDispClassSysBufferOUT->hBuffer,
1919 hBufferInt,
1920 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1921 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
1922 psGetDispClassSysBufferIN->hDeviceKM);
1923
1924 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc)
1925
1926 return 0;
1927}
1928
1929static IMG_INT
1930PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID,
1931 PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
1932 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
1933 PVRSRV_PER_PROCESS_DATA *psPerProc)
1934{
1935 IMG_VOID *pvDispClassInfo;
1936
1937 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
1938
1939 psGetDispClassInfoOUT->eError =
1940 PVRSRVLookupHandle(psPerProc->psHandleBase,
1941 &pvDispClassInfo,
1942 psGetDispClassInfoIN->hDeviceKM,
1943 PVRSRV_HANDLE_TYPE_DISP_INFO);
1944 if(psGetDispClassInfoOUT->eError != PVRSRV_OK)
1945 {
1946 return 0;
1947 }
1948
1949 psGetDispClassInfoOUT->eError =
1950 PVRSRVGetDCInfoKM(pvDispClassInfo,
1951 &psGetDispClassInfoOUT->sDisplayInfo);
1952
1953 return 0;
1954}
1955
1956static IMG_INT
1957PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID,
1958 PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN,
1959 PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT,
1960 PVRSRV_PER_PROCESS_DATA *psPerProc)
1961{
1962 IMG_VOID *pvDispClassInfo;
1963 IMG_HANDLE hSwapChainInt;
1964 IMG_UINT32 ui32SwapChainID;
1965
1966 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
1967
1968 NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1)
1969
1970 psCreateDispClassSwapChainOUT->eError =
1971 PVRSRVLookupHandle(psPerProc->psHandleBase,
1972 &pvDispClassInfo,
1973 psCreateDispClassSwapChainIN->hDeviceKM,
1974 PVRSRV_HANDLE_TYPE_DISP_INFO);
1975
1976 if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1977 {
1978 return 0;
1979 }
1980
1981
1982 ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
1983
1984 psCreateDispClassSwapChainOUT->eError =
1985 PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
1986 psCreateDispClassSwapChainIN->ui32Flags,
1987 &psCreateDispClassSwapChainIN->sDstSurfAttrib,
1988 &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
1989 psCreateDispClassSwapChainIN->ui32BufferCount,
1990 psCreateDispClassSwapChainIN->ui32OEMFlags,
1991 &hSwapChainInt,
1992 &ui32SwapChainID);
1993
1994 if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1995 {
1996 return 0;
1997 }
1998
1999
2000 psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
2001
2002 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2003 &psCreateDispClassSwapChainOUT->hSwapChain,
2004 hSwapChainInt,
2005 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
2006 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
2007 psCreateDispClassSwapChainIN->hDeviceKM);
2008
2009 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc)
2010
2011 return 0;
2012}
2013
2014static IMG_INT
2015PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID,
2016 PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN,
2017 PVRSRV_BRIDGE_RETURN *psRetOUT,
2018 PVRSRV_PER_PROCESS_DATA *psPerProc)
2019{
2020 IMG_VOID *pvSwapChain;
2021
2022 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
2023
2024 psRetOUT->eError =
2025 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
2026 psDestroyDispClassSwapChainIN->hSwapChain,
2027 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2028 if(psRetOUT->eError != PVRSRV_OK)
2029 {
2030 return 0;
2031 }
2032
2033 psRetOUT->eError =
2034 PVRSRVDestroyDCSwapChainKM(pvSwapChain);
2035
2036 if(psRetOUT->eError != PVRSRV_OK)
2037 {
2038 return 0;
2039 }
2040
2041 psRetOUT->eError =
2042 PVRSRVReleaseHandle(psPerProc->psHandleBase,
2043 psDestroyDispClassSwapChainIN->hSwapChain,
2044 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2045
2046 return 0;
2047}
2048
2049static IMG_INT
2050PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID,
2051 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
2052 PVRSRV_BRIDGE_RETURN *psRetOUT,
2053 PVRSRV_PER_PROCESS_DATA *psPerProc)
2054{
2055 IMG_VOID *pvDispClassInfo;
2056 IMG_VOID *pvSwapChain;
2057
2058 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
2059
2060 psRetOUT->eError =
2061 PVRSRVLookupHandle(psPerProc->psHandleBase,
2062 &pvDispClassInfo,
2063 psSetDispClassDstRectIN->hDeviceKM,
2064 PVRSRV_HANDLE_TYPE_DISP_INFO);
2065 if(psRetOUT->eError != PVRSRV_OK)
2066 {
2067 return 0;
2068 }
2069
2070 psRetOUT->eError =
2071 PVRSRVLookupHandle(psPerProc->psHandleBase,
2072 &pvSwapChain,
2073 psSetDispClassDstRectIN->hSwapChain,
2074 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2075
2076 if(psRetOUT->eError != PVRSRV_OK)
2077 {
2078 return 0;
2079 }
2080
2081 psRetOUT->eError =
2082 PVRSRVSetDCDstRectKM(pvDispClassInfo,
2083 pvSwapChain,
2084 &psSetDispClassDstRectIN->sRect);
2085
2086 return 0;
2087}
2088
2089static IMG_INT
2090PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID,
2091 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
2092 PVRSRV_BRIDGE_RETURN *psRetOUT,
2093 PVRSRV_PER_PROCESS_DATA *psPerProc)
2094{
2095 IMG_VOID *pvDispClassInfo;
2096 IMG_VOID *pvSwapChain;
2097
2098 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
2099
2100 psRetOUT->eError =
2101 PVRSRVLookupHandle(psPerProc->psHandleBase,
2102 &pvDispClassInfo,
2103 psSetDispClassSrcRectIN->hDeviceKM,
2104 PVRSRV_HANDLE_TYPE_DISP_INFO);
2105 if(psRetOUT->eError != PVRSRV_OK)
2106 {
2107 return 0;
2108 }
2109
2110 psRetOUT->eError =
2111 PVRSRVLookupHandle(psPerProc->psHandleBase,
2112 &pvSwapChain,
2113 psSetDispClassSrcRectIN->hSwapChain,
2114 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2115 if(psRetOUT->eError != PVRSRV_OK)
2116 {
2117 return 0;
2118 }
2119
2120 psRetOUT->eError =
2121 PVRSRVSetDCSrcRectKM(pvDispClassInfo,
2122 pvSwapChain,
2123 &psSetDispClassSrcRectIN->sRect);
2124
2125 return 0;
2126}
2127
2128static IMG_INT
2129PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID,
2130 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
2131 PVRSRV_BRIDGE_RETURN *psRetOUT,
2132 PVRSRV_PER_PROCESS_DATA *psPerProc)
2133{
2134 IMG_VOID *pvDispClassInfo;
2135 IMG_VOID *pvSwapChain;
2136
2137 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
2138
2139 psRetOUT->eError =
2140 PVRSRVLookupHandle(psPerProc->psHandleBase,
2141 &pvDispClassInfo,
2142 psSetDispClassColKeyIN->hDeviceKM,
2143 PVRSRV_HANDLE_TYPE_DISP_INFO);
2144 if(psRetOUT->eError != PVRSRV_OK)
2145 {
2146 return 0;
2147 }
2148
2149 psRetOUT->eError =
2150 PVRSRVLookupHandle(psPerProc->psHandleBase,
2151 &pvSwapChain,
2152 psSetDispClassColKeyIN->hSwapChain,
2153 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2154 if(psRetOUT->eError != PVRSRV_OK)
2155 {
2156 return 0;
2157 }
2158
2159 psRetOUT->eError =
2160 PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
2161 pvSwapChain,
2162 psSetDispClassColKeyIN->ui32CKColour);
2163
2164 return 0;
2165}
2166
2167static IMG_INT
2168PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID,
2169 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
2170 PVRSRV_BRIDGE_RETURN *psRetOUT,
2171 PVRSRV_PER_PROCESS_DATA *psPerProc)
2172{
2173 IMG_VOID *pvDispClassInfo;
2174 IMG_VOID *pvSwapChain;
2175
2176 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
2177
2178 psRetOUT->eError =
2179 PVRSRVLookupHandle(psPerProc->psHandleBase,
2180 &pvDispClassInfo,
2181 psSetDispClassColKeyIN->hDeviceKM,
2182 PVRSRV_HANDLE_TYPE_DISP_INFO);
2183 if(psRetOUT->eError != PVRSRV_OK)
2184 {
2185 return 0;
2186 }
2187
2188 psRetOUT->eError =
2189 PVRSRVLookupHandle(psPerProc->psHandleBase,
2190 &pvSwapChain,
2191 psSetDispClassColKeyIN->hSwapChain,
2192 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2193 if(psRetOUT->eError != PVRSRV_OK)
2194 {
2195 return 0;
2196 }
2197
2198 psRetOUT->eError =
2199 PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
2200 pvSwapChain,
2201 psSetDispClassColKeyIN->ui32CKColour);
2202
2203 return 0;
2204}
2205
2206static IMG_INT
2207PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID,
2208 PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
2209 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
2210 PVRSRV_PER_PROCESS_DATA *psPerProc)
2211{
2212 IMG_VOID *pvDispClassInfo;
2213 IMG_VOID *pvSwapChain;
2214 IMG_UINT32 i;
2215
2216 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
2217
2218 NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
2219
2220 psGetDispClassBuffersOUT->eError =
2221 PVRSRVLookupHandle(psPerProc->psHandleBase,
2222 &pvDispClassInfo,
2223 psGetDispClassBuffersIN->hDeviceKM,
2224 PVRSRV_HANDLE_TYPE_DISP_INFO);
2225 if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
2226 {
2227 return 0;
2228 }
2229
2230 psGetDispClassBuffersOUT->eError =
2231 PVRSRVLookupHandle(psPerProc->psHandleBase,
2232 &pvSwapChain,
2233 psGetDispClassBuffersIN->hSwapChain,
2234 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
2235 if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
2236 {
2237 return 0;
2238 }
2239
2240 psGetDispClassBuffersOUT->eError =
2241 PVRSRVGetDCBuffersKM(pvDispClassInfo,
2242 pvSwapChain,
2243 &psGetDispClassBuffersOUT->ui32BufferCount,
2244 psGetDispClassBuffersOUT->ahBuffer);
2245 if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
2246 {
2247 return 0;
2248 }
2249
2250 PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
2251
2252 for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
2253 {
2254 IMG_HANDLE hBufferExt;
2255
2256
2257 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2258 &hBufferExt,
2259 psGetDispClassBuffersOUT->ahBuffer[i],
2260 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
2261 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
2262 psGetDispClassBuffersIN->hSwapChain);
2263
2264 psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
2265 }
2266
2267 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc)
2268
2269 return 0;
2270}
2271
2272static IMG_INT
2273PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID,
2274 PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
2275 PVRSRV_BRIDGE_RETURN *psRetOUT,
2276 PVRSRV_PER_PROCESS_DATA *psPerProc)
2277{
2278 IMG_VOID *pvDispClassInfo;
2279 IMG_VOID *pvSwapChainBuf;
2280
2281 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
2282
2283 psRetOUT->eError =
2284 PVRSRVLookupHandle(psPerProc->psHandleBase,
2285 &pvDispClassInfo,
2286 psSwapDispClassBufferIN->hDeviceKM,
2287 PVRSRV_HANDLE_TYPE_DISP_INFO);
2288 if(psRetOUT->eError != PVRSRV_OK)
2289 {
2290 return 0;
2291 }
2292
2293 psRetOUT->eError =
2294 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
2295 &pvSwapChainBuf,
2296 psSwapDispClassBufferIN->hBuffer,
2297 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
2298 psSwapDispClassBufferIN->hDeviceKM);
2299 if(psRetOUT->eError != PVRSRV_OK)
2300 {
2301 return 0;
2302 }
2303
2304 psRetOUT->eError =
2305 PVRSRVSwapToDCBufferKM(pvDispClassInfo,
2306 pvSwapChainBuf,
2307 psSwapDispClassBufferIN->ui32SwapInterval,
2308 psSwapDispClassBufferIN->hPrivateTag,
2309 psSwapDispClassBufferIN->ui32ClipRectCount,
2310 psSwapDispClassBufferIN->sClipRect);
2311
2312 return 0;
2313}
2314
2315static IMG_INT
2316PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID,
2317 PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
2318 PVRSRV_BRIDGE_RETURN *psRetOUT,
2319 PVRSRV_PER_PROCESS_DATA *psPerProc)
2320{
2321 IMG_VOID *pvDispClassInfo;
2322 IMG_VOID *pvSwapChain;
2323
2324 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
2325
2326 psRetOUT->eError =
2327 PVRSRVLookupHandle(psPerProc->psHandleBase,
2328 &pvDispClassInfo,
2329 psSwapDispClassSystemIN->hDeviceKM,
2330 PVRSRV_HANDLE_TYPE_DISP_INFO);
2331 if(psRetOUT->eError != PVRSRV_OK)
2332 {
2333 return 0;
2334 }
2335
2336 psRetOUT->eError =
2337 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
2338 &pvSwapChain,
2339 psSwapDispClassSystemIN->hSwapChain,
2340 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
2341 psSwapDispClassSystemIN->hDeviceKM);
2342 if(psRetOUT->eError != PVRSRV_OK)
2343 {
2344 return 0;
2345 }
2346 psRetOUT->eError =
2347 PVRSRVSwapToDCSystemKM(pvDispClassInfo,
2348 pvSwapChain);
2349
2350 return 0;
2351}
2352
2353static IMG_INT
2354PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID,
2355 PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
2356 PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
2357 PVRSRV_PER_PROCESS_DATA *psPerProc)
2358{
2359 IMG_HANDLE hDevCookieInt;
2360 IMG_HANDLE hBufClassInfo;
2361
2362 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
2363
2364 NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1)
2365
2366 psOpenBufferClassDeviceOUT->eError =
2367 PVRSRVLookupHandle(psPerProc->psHandleBase,
2368 &hDevCookieInt,
2369 psOpenBufferClassDeviceIN->hDevCookie,
2370 PVRSRV_HANDLE_TYPE_DEV_NODE);
2371 if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2372 {
2373 return 0;
2374 }
2375
2376 psOpenBufferClassDeviceOUT->eError =
2377 PVRSRVOpenBCDeviceKM(psPerProc,
2378 psOpenBufferClassDeviceIN->ui32DeviceID,
2379 hDevCookieInt,
2380 &hBufClassInfo);
2381 if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2382 {
2383 return 0;
2384 }
2385
2386 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2387 &psOpenBufferClassDeviceOUT->hDeviceKM,
2388 hBufClassInfo,
2389 PVRSRV_HANDLE_TYPE_BUF_INFO,
2390 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2391
2392 COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc)
2393
2394 return 0;
2395}
2396
2397static IMG_INT
2398PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID,
2399 PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
2400 PVRSRV_BRIDGE_RETURN *psRetOUT,
2401 PVRSRV_PER_PROCESS_DATA *psPerProc)
2402{
2403 IMG_VOID *pvBufClassInfo;
2404
2405 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
2406
2407 psRetOUT->eError =
2408 PVRSRVLookupHandle(psPerProc->psHandleBase,
2409 &pvBufClassInfo,
2410 psCloseBufferClassDeviceIN->hDeviceKM,
2411 PVRSRV_HANDLE_TYPE_BUF_INFO);
2412 if(psRetOUT->eError != PVRSRV_OK)
2413 {
2414 return 0;
2415 }
2416
2417 psRetOUT->eError =
2418 PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
2419
2420 if(psRetOUT->eError != PVRSRV_OK)
2421 {
2422 return 0;
2423 }
2424
2425 psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
2426 psCloseBufferClassDeviceIN->hDeviceKM,
2427 PVRSRV_HANDLE_TYPE_BUF_INFO);
2428
2429 return 0;
2430}
2431
2432static IMG_INT
2433PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID,
2434 PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
2435 PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
2436 PVRSRV_PER_PROCESS_DATA *psPerProc)
2437{
2438 IMG_VOID *pvBufClassInfo;
2439
2440 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
2441
2442 psGetBufferClassInfoOUT->eError =
2443 PVRSRVLookupHandle(psPerProc->psHandleBase,
2444 &pvBufClassInfo,
2445 psGetBufferClassInfoIN->hDeviceKM,
2446 PVRSRV_HANDLE_TYPE_BUF_INFO);
2447 if(psGetBufferClassInfoOUT->eError != PVRSRV_OK)
2448 {
2449 return 0;
2450 }
2451
2452 psGetBufferClassInfoOUT->eError =
2453 PVRSRVGetBCInfoKM(pvBufClassInfo,
2454 &psGetBufferClassInfoOUT->sBufferInfo);
2455 return 0;
2456}
2457
2458static IMG_INT
2459PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID,
2460 PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
2461 PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
2462 PVRSRV_PER_PROCESS_DATA *psPerProc)
2463{
2464 IMG_VOID *pvBufClassInfo;
2465 IMG_HANDLE hBufferInt;
2466
2467 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
2468
2469 NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1)
2470
2471 psGetBufferClassBufferOUT->eError =
2472 PVRSRVLookupHandle(psPerProc->psHandleBase,
2473 &pvBufClassInfo,
2474 psGetBufferClassBufferIN->hDeviceKM,
2475 PVRSRV_HANDLE_TYPE_BUF_INFO);
2476 if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2477 {
2478 return 0;
2479 }
2480
2481 psGetBufferClassBufferOUT->eError =
2482 PVRSRVGetBCBufferKM(pvBufClassInfo,
2483 psGetBufferClassBufferIN->ui32BufferIndex,
2484 &hBufferInt);
2485
2486 if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2487 {
2488 return 0;
2489 }
2490
2491
2492 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2493 &psGetBufferClassBufferOUT->hBuffer,
2494 hBufferInt,
2495 PVRSRV_HANDLE_TYPE_BUF_BUFFER,
2496 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
2497 psGetBufferClassBufferIN->hDeviceKM);
2498
2499 COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc)
2500
2501 return 0;
2502}
2503
2504
2505static IMG_INT
2506PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
2507 PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
2508 PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
2509 PVRSRV_PER_PROCESS_DATA *psPerProc)
2510{
2511 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2512
2513 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
2514
2515 NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1)
2516
2517 psAllocSharedSysMemOUT->eError =
2518 PVRSRVAllocSharedSysMemoryKM(psPerProc,
2519 psAllocSharedSysMemIN->ui32Flags,
2520 psAllocSharedSysMemIN->ui32Size,
2521 &psKernelMemInfo);
2522 if(psAllocSharedSysMemOUT->eError != PVRSRV_OK)
2523 {
2524 return 0;
2525 }
2526
2527 OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
2528 0,
2529 sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
2530
2531 psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
2532 psKernelMemInfo->pvLinAddrKM;
2533
2534 psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0;
2535 psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
2536 psKernelMemInfo->ui32Flags;
2537 psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize =
2538 psKernelMemInfo->ui32AllocSize;
2539 psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
2540
2541 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2542 &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
2543 psKernelMemInfo,
2544 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
2545 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2546
2547 COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc)
2548
2549 return 0;
2550}
2551
2552static IMG_INT
2553PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
2554 PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
2555 PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
2556 PVRSRV_PER_PROCESS_DATA *psPerProc)
2557{
2558 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2559
2560 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
2561
2562 psFreeSharedSysMemOUT->eError =
2563 PVRSRVLookupHandle(psPerProc->psHandleBase,
2564 (IMG_VOID **)&psKernelMemInfo,
2565 psFreeSharedSysMemIN->psKernelMemInfo,
2566 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2567
2568 if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2569 return 0;
2570
2571 psFreeSharedSysMemOUT->eError =
2572 PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
2573 if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2574 return 0;
2575
2576 psFreeSharedSysMemOUT->eError =
2577 PVRSRVReleaseHandle(psPerProc->psHandleBase,
2578 psFreeSharedSysMemIN->psKernelMemInfo,
2579 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2580 return 0;
2581}
2582
2583static IMG_INT
2584PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
2585 PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
2586 PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
2587 PVRSRV_PER_PROCESS_DATA *psPerProc)
2588{
2589 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2590 PVRSRV_HANDLE_TYPE eHandleType;
2591 IMG_HANDLE hParent;
2592 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
2593
2594 NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2)
2595
2596 psMapMemInfoMemOUT->eError =
2597 PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
2598 (IMG_VOID **)&psKernelMemInfo,
2599 &eHandleType,
2600 psMapMemInfoMemIN->hKernelMemInfo);
2601 if(psMapMemInfoMemOUT->eError != PVRSRV_OK)
2602 {
2603 return 0;
2604 }
2605
2606 switch (eHandleType)
2607 {
2608#if defined(PVR_SECURE_HANDLES)
2609 case PVRSRV_HANDLE_TYPE_MEM_INFO:
2610 case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
2611 case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
2612#else
2613 case PVRSRV_HANDLE_TYPE_NONE:
2614#endif
2615 break;
2616 default:
2617 psMapMemInfoMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
2618 return 0;
2619 }
2620
2621
2622 psMapMemInfoMemOUT->eError =
2623 PVRSRVGetParentHandle(psPerProc->psHandleBase,
2624 &hParent,
2625 psMapMemInfoMemIN->hKernelMemInfo,
2626 eHandleType);
2627 if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
2628 {
2629 return 0;
2630 }
2631 if (hParent == IMG_NULL)
2632 {
2633 hParent = psMapMemInfoMemIN->hKernelMemInfo;
2634 }
2635
2636 OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
2637 0,
2638 sizeof(psMapMemInfoMemOUT->sClientMemInfo));
2639
2640 psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
2641 psKernelMemInfo->pvLinAddrKM;
2642
2643 psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0;
2644 psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
2645 psKernelMemInfo->sDevVAddr;
2646 psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
2647 psKernelMemInfo->ui32Flags;
2648 psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize =
2649 psKernelMemInfo->ui32AllocSize;
2650 psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
2651
2652 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2653 &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
2654 psKernelMemInfo,
2655 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
2656 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
2657 hParent);
2658
2659 if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
2660 {
2661
2662 OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
2663 0,
2664 sizeof (PVRSRV_CLIENT_SYNC_INFO));
2665 }
2666 else
2667 {
2668
2669 psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
2670 psKernelMemInfo->psKernelSyncInfo->psSyncData;
2671 psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
2672 psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
2673 psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
2674 psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
2675
2676 psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
2677 psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
2678
2679 psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo;
2680
2681 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2682 &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
2683 psKernelMemInfo->psKernelSyncInfo,
2684 PVRSRV_HANDLE_TYPE_SYNC_INFO,
2685 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
2686 psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
2687 }
2688
2689 COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc)
2690
2691 return 0;
2692}
2693
2694
2695
2696static IMG_INT
2697MMU_GetPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
2698 PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN,
2699 PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT,
2700 PVRSRV_PER_PROCESS_DATA *psPerProc)
2701{
2702 IMG_HANDLE hDevMemContextInt;
2703
2704 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR);
2705
2706 psGetMmuPDDevPAddrOUT->eError =
2707 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
2708 psGetMmuPDDevPAddrIN->hDevMemContext,
2709 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
2710 if(psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK)
2711 {
2712 return 0;
2713 }
2714
2715 psGetMmuPDDevPAddrOUT->sPDDevPAddr =
2716 BM_GetDeviceNode(hDevMemContextInt)->pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext(hDevMemContextInt));
2717 if(psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr)
2718 {
2719 psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK;
2720 }
2721 else
2722 {
2723 psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_INVALID_PHYS_ADDR;
2724 }
2725 return 0;
2726}
2727
2728
2729
2730IMG_INT
2731DummyBW(IMG_UINT32 ui32BridgeID,
2732 IMG_VOID *psBridgeIn,
2733 IMG_VOID *psBridgeOut,
2734 PVRSRV_PER_PROCESS_DATA *psPerProc)
2735{
2736#if !defined(DEBUG)
2737 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2738#endif
2739 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2740 PVR_UNREFERENCED_PARAMETER(psBridgeOut);
2741 PVR_UNREFERENCED_PARAMETER(psPerProc);
2742
2743#if defined(DEBUG_BRIDGE_KM)
2744 PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u (%s) mapped to "
2745 "Dummy Wrapper (probably not what you want!)",
2746 __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
2747#else
2748 PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u mapped to "
2749 "Dummy Wrapper (probably not what you want!)",
2750 __FUNCTION__, ui32BridgeID));
2751#endif
2752 return -ENOTTY;
2753}
2754
2755
2756IMG_VOID
2757_SetDispatchTableEntry(IMG_UINT32 ui32Index,
2758 const IMG_CHAR *pszIOCName,
2759 BridgeWrapperFunction pfFunction,
2760 const IMG_CHAR *pszFunctionName)
2761{
2762 static IMG_UINT32 ui32PrevIndex = ~0UL;
2763#if !defined(DEBUG)
2764 PVR_UNREFERENCED_PARAMETER(pszIOCName);
2765#endif
2766#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
2767 PVR_UNREFERENCED_PARAMETER(pszFunctionName);
2768#endif
2769
2770#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
2771
2772 PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
2773#endif
2774
2775
2776 if(g_BridgeDispatchTable[ui32Index].pfFunction)
2777 {
2778#if defined(DEBUG_BRIDGE_KM)
2779 PVR_DPF((PVR_DBG_ERROR,
2780 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s",
2781 __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName));
2782#else
2783 PVR_DPF((PVR_DBG_ERROR,
2784 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%u)",
2785 __FUNCTION__, pszIOCName, ui32Index));
2786#endif
2787 PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
2788 }
2789
2790
2791 if((ui32PrevIndex != ~0UL) &&
2792 ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
2793 (ui32Index <= ui32PrevIndex)))
2794 {
2795#if defined(DEBUG_BRIDGE_KM)
2796 PVR_DPF((PVR_DBG_WARNING,
2797 "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)",
2798 __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
2799 ui32Index, pszIOCName));
2800#else
2801 PVR_DPF((PVR_DBG_WARNING,
2802 "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
2803 __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
2804#endif
2805 PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
2806 }
2807
2808 g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
2809#if defined(DEBUG_BRIDGE_KM)
2810 g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
2811 g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
2812 g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
2813 g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
2814#endif
2815
2816 ui32PrevIndex = ui32Index;
2817}
2818
2819static IMG_INT
2820PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID,
2821 IMG_VOID *psBridgeIn,
2822 PVRSRV_BRIDGE_RETURN *psRetOUT,
2823 PVRSRV_PER_PROCESS_DATA *psPerProc)
2824{
2825 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2826
2827 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
2828 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2829
2830
2831 if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
2832 {
2833 psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
2834 return 0;
2835 }
2836
2837#if defined (__linux__)
2838 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
2839#endif
2840 psPerProc->bInitProcess = IMG_TRUE;
2841
2842 psRetOUT->eError = PVRSRV_OK;
2843
2844 return 0;
2845}
2846
2847
2848static IMG_INT
2849PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID,
2850 PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
2851 PVRSRV_BRIDGE_RETURN *psRetOUT,
2852 PVRSRV_PER_PROCESS_DATA *psPerProc)
2853{
2854 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT);
2855
2856 if(!psPerProc->bInitProcess)
2857 {
2858 psRetOUT->eError = PVRSRV_ERROR_SRV_DISCONNECT_FAILED;
2859 return 0;
2860 }
2861
2862 psPerProc->bInitProcess = IMG_FALSE;
2863
2864 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
2865 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
2866
2867 psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
2868
2869 PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
2870 ((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))
2871 ? IMG_TRUE : IMG_FALSE);
2872
2873 return 0;
2874}
2875
2876
2877static IMG_INT
2878PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID,
2879 PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
2880 PVRSRV_BRIDGE_RETURN *psRetOUT,
2881 PVRSRV_PER_PROCESS_DATA *psPerProc)
2882{
2883 IMG_HANDLE hOSEventKM;
2884
2885 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
2886
2887 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2888 &hOSEventKM,
2889 psEventObjectWaitIN->hOSEventKM,
2890 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2891
2892 if(psRetOUT->eError != PVRSRV_OK)
2893 {
2894 return 0;
2895 }
2896
2897 psRetOUT->eError = OSEventObjectWait(hOSEventKM);
2898
2899 return 0;
2900}
2901
2902
2903static IMG_INT
2904PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID,
2905 PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
2906 PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
2907 PVRSRV_PER_PROCESS_DATA *psPerProc)
2908{
2909
2910 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
2911
2912 NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1)
2913
2914 psEventObjectOpenOUT->eError =
2915 PVRSRVLookupHandle(psPerProc->psHandleBase,
2916 &psEventObjectOpenIN->sEventObject.hOSEventKM,
2917 psEventObjectOpenIN->sEventObject.hOSEventKM,
2918 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2919
2920 if(psEventObjectOpenOUT->eError != PVRSRV_OK)
2921 {
2922 return 0;
2923 }
2924
2925 psEventObjectOpenOUT->eError = OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
2926
2927 if(psEventObjectOpenOUT->eError != PVRSRV_OK)
2928 {
2929 return 0;
2930 }
2931
2932 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2933 &psEventObjectOpenOUT->hOSEvent,
2934 psEventObjectOpenOUT->hOSEvent,
2935 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
2936 PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
2937
2938 COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc)
2939
2940 return 0;
2941}
2942
2943
2944static IMG_INT
2945PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID,
2946 PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
2947 PVRSRV_BRIDGE_RETURN *psRetOUT,
2948 PVRSRV_PER_PROCESS_DATA *psPerProc)
2949{
2950 IMG_HANDLE hOSEventKM;
2951
2952 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
2953
2954 psRetOUT->eError =
2955 PVRSRVLookupHandle(psPerProc->psHandleBase,
2956 &psEventObjectCloseIN->sEventObject.hOSEventKM,
2957 psEventObjectCloseIN->sEventObject.hOSEventKM,
2958 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2959 if(psRetOUT->eError != PVRSRV_OK)
2960 {
2961 return 0;
2962 }
2963
2964 psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
2965 &hOSEventKM,
2966 psEventObjectCloseIN->hOSEventKM,
2967 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2968
2969 if(psRetOUT->eError != PVRSRV_OK)
2970 {
2971 return 0;
2972 }
2973
2974 psRetOUT->eError = OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM);
2975
2976 return 0;
2977}
2978
2979
2980typedef struct _MODIFY_SYNC_OP_INFO
2981{
2982 IMG_HANDLE hResItem;
2983 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
2984 IMG_UINT32 ui32ModifyFlags;
2985 IMG_UINT32 ui32ReadOpsPendingSnapShot;
2986 IMG_UINT32 ui32WriteOpsPendingSnapShot;
2987} MODIFY_SYNC_OP_INFO;
2988
2989
2990static PVRSRV_ERROR DoQuerySyncOpsSatisfied(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
2991{
2992 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
2993
2994 psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
2995
2996 if (!psKernelSyncInfo)
2997 {
2998 return PVRSRV_ERROR_INVALID_PARAMS;
2999 }
3000
3001 if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
3002 && (psModSyncOpInfo->ui32ReadOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
3003 {
3004#if defined(PDUMP)
3005
3006 PDumpComment("Poll for read ops complete to reach value (%u)", psModSyncOpInfo->ui32ReadOpsPendingSnapShot);
3007 PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
3008 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
3009 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
3010 0xFFFFFFFF,
3011 PDUMP_POLL_OPERATOR_EQUAL,
3012 0,
3013 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
3014
3015
3016 PDumpComment("Poll for write ops complete to reach value (%u)", psModSyncOpInfo->ui32WriteOpsPendingSnapShot);
3017 PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
3018 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
3019 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
3020 0xFFFFFFFF,
3021 PDUMP_POLL_OPERATOR_EQUAL,
3022 0,
3023 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
3024#endif
3025 return PVRSRV_OK;
3026 }
3027 else
3028 {
3029 return PVRSRV_ERROR_RETRY;
3030 }
3031}
3032
3033static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
3034{
3035 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
3036
3037 psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
3038
3039 if (!psKernelSyncInfo)
3040 {
3041 return PVRSRV_ERROR_INVALID_PARAMS;
3042 }
3043
3044
3045 if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
3046 || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
3047 {
3048 return PVRSRV_ERROR_BAD_SYNC_STATE;
3049 }
3050
3051
3052 if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
3053 {
3054 psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
3055 }
3056
3057
3058 if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
3059 {
3060 psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
3061 }
3062
3063 return PVRSRV_OK;
3064}
3065
3066
3067static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam,
3068 IMG_UINT32 ui32Param)
3069{
3070 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3071
3072 PVR_UNREFERENCED_PARAMETER(ui32Param);
3073
3074 if (!pvParam)
3075 {
3076 PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
3077 return PVRSRV_ERROR_INVALID_PARAMS;
3078 }
3079
3080 psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
3081
3082 if (psModSyncOpInfo->psKernelSyncInfo)
3083 {
3084
3085 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
3086 {
3087 if (DoQuerySyncOpsSatisfied(psModSyncOpInfo) == PVRSRV_OK)
3088 {
3089 goto OpFlushedComplete;
3090 }
3091 PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush"));
3092 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
3093 } END_LOOP_UNTIL_TIMEOUT();
3094
3095 PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush."));
3096 PVR_DPF((PVR_DBG_ERROR, " Write ops pending snapshot = %d, write ops complete = %d",
3097 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
3098 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete));
3099 PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, write ops complete = %d",
3100 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
3101 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete));
3102
3103 return PVRSRV_ERROR_TIMEOUT;
3104
3105 OpFlushedComplete:
3106
3107 DoModifyCompleteSyncOps(psModSyncOpInfo);
3108 }
3109
3110 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
3111
3112
3113
3114 PVRSRVScheduleDeviceCallbacks();
3115
3116 return PVRSRV_OK;
3117}
3118
3119
3120static IMG_INT
3121PVRSRVCreateSyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
3122 IMG_VOID *psBridgeIn,
3123 PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ *psCreateSyncInfoModObjOUT,
3124 PVRSRV_PER_PROCESS_DATA *psPerProc)
3125{
3126 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3127
3128 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
3129
3130 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ);
3131
3132 NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1)
3133
3134 ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError,
3135 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
3136 sizeof(MODIFY_SYNC_OP_INFO),
3137 (IMG_VOID **)&psModSyncOpInfo, 0,
3138 "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
3139
3140 psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
3141
3142 psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
3143 &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj,
3144 psModSyncOpInfo,
3145 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
3146 PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
3147
3148 if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK)
3149 {
3150 return 0;
3151 }
3152
3153 psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
3154 RESMAN_TYPE_MODIFY_SYNC_OPS,
3155 psModSyncOpInfo,
3156 0,
3157 &ModifyCompleteSyncOpsCallBack);
3158
3159 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc)
3160
3161 return 0;
3162}
3163
3164
3165static IMG_INT
3166PVRSRVDestroySyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
3167 PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ *psDestroySyncInfoModObjIN,
3168 PVRSRV_BRIDGE_RETURN *psDestroySyncInfoModObjOUT,
3169 PVRSRV_PER_PROCESS_DATA *psPerProc)
3170{
3171 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3172
3173 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ);
3174
3175 psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3176 (IMG_VOID**)&psModSyncOpInfo,
3177 psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
3178 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
3179 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
3180 {
3181 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed"));
3182 return 0;
3183 }
3184
3185 if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL)
3186 {
3187
3188 psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
3189 return 0;
3190 }
3191
3192 psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
3193 psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
3194 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
3195
3196 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
3197 {
3198 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed"));
3199 return 0;
3200 }
3201
3202 psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem);
3203 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
3204 {
3205 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed"));
3206 return 0;
3207 }
3208
3209 return 0;
3210}
3211
3212
3213static IMG_INT
3214PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID,
3215 PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN,
3216 PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT,
3217 PVRSRV_PER_PROCESS_DATA *psPerProc)
3218{
3219 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
3220 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3221
3222 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
3223
3224 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3225 (IMG_VOID**)&psModSyncOpInfo,
3226 psModifySyncOpsIN->hKernelSyncInfoModObj,
3227 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
3228 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
3229 {
3230 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
3231 return 0;
3232 }
3233
3234 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3235 (IMG_VOID**)&psKernelSyncInfo,
3236 psModifySyncOpsIN->hKernelSyncInfo,
3237 PVRSRV_HANDLE_TYPE_SYNC_INFO);
3238 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
3239 {
3240 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
3241 return 0;
3242 }
3243
3244 if(psModSyncOpInfo->psKernelSyncInfo)
3245 {
3246
3247 psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
3248 PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty"));
3249 return 0;
3250 }
3251
3252
3253 psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
3254 psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
3255 psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
3256 psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
3257
3258
3259
3260 psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
3261 psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
3262
3263 if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
3264 {
3265 psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
3266 }
3267
3268 if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
3269 {
3270 psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
3271 }
3272
3273
3274 psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem,
3275 psPerProc->hResManContext);
3276
3277 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
3278 {
3279 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
3280 return 0;
3281 }
3282
3283 return 0;
3284}
3285
3286
3287static IMG_INT
3288PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID,
3289 PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN,
3290 PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT,
3291 PVRSRV_PER_PROCESS_DATA *psPerProc)
3292{
3293 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3294
3295 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
3296
3297 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3298 (IMG_VOID**)&psModSyncOpInfo,
3299 psModifySyncOpsIN->hKernelSyncInfoModObj,
3300 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
3301 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
3302 {
3303 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
3304 return 0;
3305 }
3306
3307 if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
3308 {
3309
3310 psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
3311 return 0;
3312 }
3313
3314 psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo);
3315
3316 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
3317 {
3318 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed"));
3319 return 0;
3320 }
3321
3322 psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
3323
3324
3325 PVRSRVScheduleDeviceCallbacks();
3326
3327 return 0;
3328}
3329
3330
3331static IMG_INT
3332PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32 ui32BridgeID,
3333 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ *psSyncOpsFlushToModObjIN,
3334 PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToModObjOUT,
3335 PVRSRV_PER_PROCESS_DATA *psPerProc)
3336{
3337 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
3338
3339 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ);
3340
3341 psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3342 (IMG_VOID**)&psModSyncOpInfo,
3343 psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj,
3344 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
3345 if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK)
3346 {
3347 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed"));
3348 return 0;
3349 }
3350
3351 if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
3352 {
3353
3354 psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
3355 return 0;
3356 }
3357
3358 psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo);
3359
3360 if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY)
3361 {
3362 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed"));
3363 return 0;
3364 }
3365
3366 return 0;
3367}
3368
3369
3370static IMG_INT
3371PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32 ui32BridgeID,
3372 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA *psSyncOpsFlushToDeltaIN,
3373 PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToDeltaOUT,
3374 PVRSRV_PER_PROCESS_DATA *psPerProc)
3375{
3376 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
3377 IMG_UINT32 ui32DeltaRead;
3378 IMG_UINT32 ui32DeltaWrite;
3379
3380 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA);
3381
3382 psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3383 (IMG_VOID**)&psSyncInfo,
3384 psSyncOpsFlushToDeltaIN->hKernelSyncInfo,
3385 PVRSRV_HANDLE_TYPE_SYNC_INFO);
3386 if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK)
3387 {
3388 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed"));
3389 return 0;
3390 }
3391
3392 ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete;
3393 ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete;
3394
3395 if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta)
3396 {
3397#if defined(PDUMP)
3398 IMG_UINT32 ui32MinimumReadOpsComplete;
3399
3400 ui32MinimumReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
3401 if (ui32MinimumReadOpsComplete < psSyncOpsFlushToDeltaIN->ui32Delta)
3402 {
3403 ui32MinimumReadOpsComplete = 0;
3404 }
3405 else
3406 {
3407 ui32MinimumReadOpsComplete = ui32MinimumReadOpsComplete - psSyncOpsFlushToDeltaIN->ui32Delta;
3408 }
3409
3410
3411 PDumpComment("Poll for read ops complete to delta (%u)", psSyncOpsFlushToDeltaIN->ui32Delta);
3412 psSyncOpsFlushToDeltaOUT->eError =
3413 PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
3414 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
3415 ui32MinimumReadOpsComplete,
3416 0xFFFFFFFF,
3417 PDUMP_POLL_OPERATOR_GREATEREQUAL,
3418 0,
3419 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
3420
3421
3422
3423
3424
3425#endif
3426
3427 psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK;
3428 }
3429 else
3430 {
3431 psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY;
3432 }
3433
3434 return 0;
3435}
3436
3437
3438static PVRSRV_ERROR
3439FreeSyncInfoCallback(IMG_PVOID pvParam,
3440 IMG_UINT32 ui32Param)
3441{
3442 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
3443 PVRSRV_ERROR eError;
3444
3445 PVR_UNREFERENCED_PARAMETER(ui32Param);
3446
3447 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
3448
3449 eError = PVRSRVFreeSyncInfoKM(psSyncInfo);
3450 if (eError != PVRSRV_OK)
3451 {
3452 return eError;
3453 }
3454
3455 return PVRSRV_OK;
3456}
3457
3458
3459static IMG_INT
3460PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32BridgeID,
3461 PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO *psAllocSyncInfoIN,
3462 PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO *psAllocSyncInfoOUT,
3463 PVRSRV_PER_PROCESS_DATA *psPerProc)
3464{
3465 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
3466 PVRSRV_ERROR eError;
3467 PVRSRV_DEVICE_NODE *psDeviceNode;
3468 IMG_HANDLE hDevMemContext;
3469
3470 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO);
3471
3472 NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1)
3473
3474 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3475 (IMG_HANDLE *)&psDeviceNode,
3476 psAllocSyncInfoIN->hDevCookie,
3477 PVRSRV_HANDLE_TYPE_DEV_NODE);
3478 if(eError != PVRSRV_OK)
3479 {
3480 goto allocsyncinfo_errorexit;
3481 }
3482
3483 hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext;
3484
3485 eError = PVRSRVAllocSyncInfoKM(psDeviceNode,
3486 hDevMemContext,
3487 &psSyncInfo);
3488
3489 if (eError != PVRSRV_OK)
3490 {
3491 goto allocsyncinfo_errorexit;
3492 }
3493
3494 eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
3495 &psAllocSyncInfoOUT->hKernelSyncInfo,
3496 psSyncInfo,
3497 PVRSRV_HANDLE_TYPE_SYNC_INFO,
3498 PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
3499
3500 if(eError != PVRSRV_OK)
3501 {
3502 goto allocsyncinfo_errorexit_freesyncinfo;
3503 }
3504
3505 psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
3506 RESMAN_TYPE_SYNC_INFO,
3507 psSyncInfo,
3508 0,
3509 FreeSyncInfoCallback);
3510
3511
3512 goto allocsyncinfo_commit;
3513
3514
3515 allocsyncinfo_errorexit_freesyncinfo:
3516 PVRSRVFreeSyncInfoKM(psSyncInfo);
3517
3518 allocsyncinfo_errorexit:
3519
3520
3521 allocsyncinfo_commit:
3522 psAllocSyncInfoOUT->eError = eError;
3523 COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc);
3524
3525 return 0;
3526}
3527
3528
3529static IMG_INT
3530PVRSRVFreeSyncInfoBW(IMG_UINT32 ui32BridgeID,
3531 PVRSRV_BRIDGE_IN_FREE_SYNC_INFO *psFreeSyncInfoIN,
3532 PVRSRV_BRIDGE_RETURN *psFreeSyncInfoOUT,
3533 PVRSRV_PER_PROCESS_DATA *psPerProc)
3534{
3535 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
3536 PVRSRV_ERROR eError;
3537
3538 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO);
3539
3540 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
3541 (IMG_VOID**)&psSyncInfo,
3542 psFreeSyncInfoIN->hKernelSyncInfo,
3543 PVRSRV_HANDLE_TYPE_SYNC_INFO);
3544 if (eError != PVRSRV_OK)
3545 {
3546 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed"));
3547 psFreeSyncInfoOUT->eError = eError;
3548 return 0;
3549 }
3550
3551 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
3552 psFreeSyncInfoIN->hKernelSyncInfo,
3553 PVRSRV_HANDLE_TYPE_SYNC_INFO);
3554
3555 if (eError != PVRSRV_OK)
3556 {
3557 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed"));
3558 psFreeSyncInfoOUT->eError = eError;
3559 return 0;
3560 }
3561
3562 eError = ResManFreeResByPtr(psSyncInfo->hResItem);
3563 if (eError != PVRSRV_OK)
3564 {
3565 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed"));
3566 psFreeSyncInfoOUT->eError = eError;
3567 return 0;
3568 }
3569
3570 return 0;
3571}
3572
3573
3574PVRSRV_ERROR
3575CommonBridgeInit(IMG_VOID)
3576{
3577 IMG_UINT32 i;
3578
3579 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW);
3580 SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW);
3581 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
3582 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW);
3583 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW);
3584 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW);
3585 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW);
3586 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW);
3587 SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW);
3588 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
3589 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
3590 SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW);
3591 SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
3592 SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW);
3593 SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
3594 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
3595 SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW);
3596 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
3597 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
3598 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
3599 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW);
3600 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW);
3601 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW);
3602 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW);
3603 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
3604 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
3605 SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW);
3606 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW);
3607
3608
3609 SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
3610 SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
3611 SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
3612
3613
3614 SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
3615 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
3616 SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
3617
3618 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
3619
3620
3621 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
3622 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
3623
3624
3625#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
3626 SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW);
3627 SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW);
3628#endif
3629
3630
3631
3632#if defined(PDUMP)
3633 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
3634 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
3635 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
3636 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
3637 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
3638 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
3639 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
3640 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW);
3641 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
3642 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW);
3643 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
3644 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
3645 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW);
3646 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW);
3647 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW);
3648 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW);
3649 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW);
3650#endif
3651
3652
3653 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
3654
3655
3656 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
3657
3658
3659 SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW);
3660 SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW);
3661 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW);
3662 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW);
3663 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
3664 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW);
3665 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW);
3666 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW);
3667 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW);
3668 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW);
3669 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW);
3670 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW);
3671 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW);
3672 SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW);
3673 SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
3674
3675
3676 SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW);
3677 SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW);
3678 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW);
3679 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW);
3680
3681
3682 SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
3683 SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
3684
3685
3686 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
3687 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
3688 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
3689
3690
3691 SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR, MMU_GetPDDevPAddrBW);
3692
3693
3694 SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW);
3695 SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW);
3696
3697
3698 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, &PVRSRVEventObjectWaitBW);
3699 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, &PVRSRVEventObjectOpenBW);
3700 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, &PVRSRVEventObjectCloseBW);
3701
3702 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW);
3703 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW);
3704 SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
3705 SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
3706 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW);
3707 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW);
3708 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW);
3709 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW);
3710
3711#if defined (SUPPORT_SGX)
3712 SetSGXDispatchTableEntry();
3713#endif
3714#if defined (SUPPORT_VGX)
3715 SetVGXDispatchTableEntry();
3716#endif
3717#if defined (SUPPORT_MSVDX)
3718 SetMSVDXDispatchTableEntry();
3719#endif
3720
3721
3722
3723
3724 for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
3725 {
3726 if(!g_BridgeDispatchTable[i].pfFunction)
3727 {
3728 g_BridgeDispatchTable[i].pfFunction = &DummyBW;
3729#if defined(DEBUG_BRIDGE_KM)
3730 g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
3731 g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
3732 g_BridgeDispatchTable[i].ui32CallCount = 0;
3733 g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
3734 g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
3735#endif
3736 }
3737 }
3738
3739 return PVRSRV_OK;
3740}
3741
3742IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
3743 PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM)
3744{
3745
3746 IMG_VOID * psBridgeIn;
3747 IMG_VOID * psBridgeOut;
3748 BridgeWrapperFunction pfBridgeHandler;
3749 IMG_UINT32 ui32BridgeID = psBridgePackageKM->ui32BridgeID;
3750 IMG_INT err = -EFAULT;
3751
3752#if defined(DEBUG_TRACE_BRIDGE_KM)
3753 PVR_DPF((PVR_DBG_ERROR, "%s: %s",
3754 __FUNCTION__,
3755 g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
3756#endif
3757
3758#if defined(DEBUG_BRIDGE_KM)
3759 g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++;
3760 g_BridgeGlobalStats.ui32IOCTLCount++;
3761#endif
3762
3763 if(!psPerProc->bInitProcess)
3764 {
3765 if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
3766 {
3767 if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
3768 {
3769 PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.",
3770 __FUNCTION__));
3771 goto return_fault;
3772 }
3773 }
3774 else
3775 {
3776 if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
3777 {
3778 PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
3779 __FUNCTION__));
3780 goto return_fault;
3781 }
3782 else
3783 {
3784
3785 switch(ui32BridgeID)
3786 {
3787 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES):
3788 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
3789 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT):
3790 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT):
3791 break;
3792 default:
3793 PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
3794 __FUNCTION__));
3795 goto return_fault;
3796 }
3797 }
3798 }
3799 }
3800
3801
3802
3803#if defined(__linux__)
3804 {
3805
3806 SYS_DATA *psSysData;
3807
3808 SysAcquireData(&psSysData);
3809
3810
3811 psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
3812 psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
3813
3814
3815#if defined(DEBUG)
3816 PVR_ASSERT(psBridgePackageKM->ui32InBufferSize < PVRSRV_MAX_BRIDGE_IN_SIZE);
3817 PVR_ASSERT(psBridgePackageKM->ui32OutBufferSize < PVRSRV_MAX_BRIDGE_OUT_SIZE);
3818#endif
3819
3820 if(psBridgePackageKM->ui32InBufferSize > 0)
3821 {
3822 if(!OSAccessOK(PVR_VERIFY_READ,
3823 psBridgePackageKM->pvParamIn,
3824 psBridgePackageKM->ui32InBufferSize))
3825 {
3826 PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__));
3827 }
3828
3829 if(CopyFromUserWrapper(psPerProc,
3830 ui32BridgeID,
3831 psBridgeIn,
3832 psBridgePackageKM->pvParamIn,
3833 psBridgePackageKM->ui32InBufferSize)
3834 != PVRSRV_OK)
3835 {
3836 goto return_fault;
3837 }
3838 }
3839 }
3840#else
3841 psBridgeIn = psBridgePackageKM->pvParamIn;
3842 psBridgeOut = psBridgePackageKM->pvParamOut;
3843#endif
3844
3845 if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
3846 {
3847 PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!",
3848 __FUNCTION__, ui32BridgeID));
3849 goto return_fault;
3850 }
3851 pfBridgeHandler =
3852 (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction;
3853 err = pfBridgeHandler(ui32BridgeID,
3854 psBridgeIn,
3855 psBridgeOut,
3856 psPerProc);
3857 if(err < 0)
3858 {
3859 goto return_fault;
3860 }
3861
3862
3863#if defined(__linux__)
3864
3865 if(CopyToUserWrapper(psPerProc,
3866 ui32BridgeID,
3867 psBridgePackageKM->pvParamOut,
3868 psBridgeOut,
3869 psBridgePackageKM->ui32OutBufferSize)
3870 != PVRSRV_OK)
3871 {
3872 goto return_fault;
3873 }
3874#endif
3875
3876 err = 0;
3877return_fault:
3878 ReleaseHandleBatch(psPerProc);
3879 return err;
3880}
3881
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.h b/drivers/gpu/pvr/bridged_pvr_bridge.h
new file mode 100644
index 00000000000..004257429bd
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.h
@@ -0,0 +1,232 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __BRIDGED_PVR_BRIDGE_H__
28#define __BRIDGED_PVR_BRIDGE_H__
29
30#include "pvr_bridge.h"
31
32#if defined(__cplusplus)
33extern "C" {
34#endif
35
36#if defined(__linux__)
37#define PVRSRV_GET_BRIDGE_ID(X) _IOC_NR(X)
38#else
39#define PVRSRV_GET_BRIDGE_ID(X) ((X) - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST))
40#endif
41
42#ifndef ENOMEM
43#define ENOMEM 12
44#endif
45#ifndef EFAULT
46#define EFAULT 14
47#endif
48#ifndef ENOTTY
49#define ENOTTY 25
50#endif
51
52#if defined(DEBUG_BRIDGE_KM)
53PVRSRV_ERROR
54CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
55 IMG_UINT32 ui32BridgeID,
56 IMG_VOID *pvDest,
57 IMG_VOID *pvSrc,
58 IMG_UINT32 ui32Size);
59PVRSRV_ERROR
60CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
61 IMG_UINT32 ui32BridgeID,
62 IMG_VOID *pvDest,
63 IMG_VOID *pvSrc,
64 IMG_UINT32 ui32Size);
65#else
66#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
67 OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size)
68#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
69 OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size)
70#endif
71
72
73#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \
74 do \
75 { \
76 (error) = (src); \
77 if ((error) != PVRSRV_OK) \
78 { \
79 return (res); \
80 } \
81 } while ((error) != PVRSRV_OK);
82
83#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \
84 ASSIGN_AND_RETURN_ON_ERROR(error, src, 0)
85
86#if defined (PVR_SECURE_HANDLES)
87#ifdef INLINE_IS_PRAGMA
88#pragma inline(NewHandleBatch)
89#endif
90static INLINE PVRSRV_ERROR
91NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc,
92 IMG_UINT32 ui32BatchSize)
93{
94 PVRSRV_ERROR eError;
95
96 PVR_ASSERT(!psPerProc->bHandlesBatched);
97
98 eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize);
99
100 if (eError == PVRSRV_OK)
101 {
102 psPerProc->bHandlesBatched = IMG_TRUE;
103 }
104
105 return eError;
106}
107
108#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \
109 ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize))
110
111#ifdef INLINE_IS_PRAGMA
112#pragma inline(CommitHandleBatch)
113#endif
114static INLINE PVRSRV_ERROR
115CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
116{
117 PVR_ASSERT(psPerProc->bHandlesBatched);
118
119 psPerProc->bHandlesBatched = IMG_FALSE;
120
121 return PVRSRVCommitHandleBatch(psPerProc->psHandleBase);
122}
123
124
125#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \
126 ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc))
127
128#ifdef INLINE_IS_PRAGMA
129#pragma inline(ReleaseHandleBatch)
130#endif
131static INLINE IMG_VOID
132ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
133{
134 if (psPerProc->bHandlesBatched)
135 {
136 psPerProc->bHandlesBatched = IMG_FALSE;
137
138 PVRSRVReleaseHandleBatch(psPerProc->psHandleBase);
139 }
140}
141#else
142#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)
143#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)
144#define ReleaseHandleBatch(psPerProc)
145#endif
146
147IMG_INT
148DummyBW(IMG_UINT32 ui32BridgeID,
149 IMG_VOID *psBridgeIn,
150 IMG_VOID *psBridgeOut,
151 PVRSRV_PER_PROCESS_DATA *psPerProc);
152
153typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID,
154 IMG_VOID *psBridgeIn,
155 IMG_VOID *psBridgeOut,
156 PVRSRV_PER_PROCESS_DATA *psPerProc);
157
158typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
159{
160 BridgeWrapperFunction pfFunction;
161#if defined(DEBUG_BRIDGE_KM)
162 const IMG_CHAR *pszIOCName;
163 const IMG_CHAR *pszFunctionName;
164 IMG_UINT32 ui32CallCount;
165 IMG_UINT32 ui32CopyFromUserTotalBytes;
166 IMG_UINT32 ui32CopyToUserTotalBytes;
167#endif
168}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
169
170#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX)
171 #if defined(SUPPORT_VGX)
172 #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1)
173 #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_VGX_CMD
174 #else
175 #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1)
176 #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_MSVDX_CMD
177 #endif
178#else
179 #if defined(SUPPORT_SGX)
180 #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1)
181 #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_SGX_CMD
182 #else
183 #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
184 #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD
185 #endif
186#endif
187
188extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
189
190IMG_VOID
191_SetDispatchTableEntry(IMG_UINT32 ui32Index,
192 const IMG_CHAR *pszIOCName,
193 BridgeWrapperFunction pfFunction,
194 const IMG_CHAR *pszFunctionName);
195
196
197
198#define SetDispatchTableEntry(ui32Index, pfFunction) \
199 _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction)
200
201#define DISPATCH_TABLE_GAP_THRESHOLD 5
202
203#if defined(DEBUG)
204#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y))
205#else
206#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X)
207#endif
208
209
210#if defined(DEBUG_BRIDGE_KM)
211typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS
212{
213 IMG_UINT32 ui32IOCTLCount;
214 IMG_UINT32 ui32TotalCopyFromUserBytes;
215 IMG_UINT32 ui32TotalCopyToUserBytes;
216}PVRSRV_BRIDGE_GLOBAL_STATS;
217
218extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
219#endif
220
221
222PVRSRV_ERROR CommonBridgeInit(IMG_VOID);
223
224IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
225 PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM);
226
227#if defined (__cplusplus)
228}
229#endif
230
231#endif
232
diff --git a/drivers/gpu/pvr/bridged_support.c b/drivers/gpu/pvr/bridged_support.c
new file mode 100644
index 00000000000..e10e577121f
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_support.c
@@ -0,0 +1,85 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "img_defs.h"
28#include "servicesint.h"
29#include "bridged_support.h"
30
31
32PVRSRV_ERROR
33PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle)
34{
35 IMG_HANDLE hMHandleInt;
36 PVRSRV_HANDLE_TYPE eHandleType;
37 PVRSRV_ERROR eError;
38
39
40 eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt,
41 &eHandleType,
42 hMHandle);
43 if(eError != PVRSRV_OK)
44 {
45 return eError;
46 }
47
48 switch(eHandleType)
49 {
50#if defined(PVR_SECURE_HANDLES)
51 case PVRSRV_HANDLE_TYPE_MEM_INFO:
52 case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
53 case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
54 {
55 PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt;
56
57 *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
58
59 break;
60 }
61 case PVRSRV_HANDLE_TYPE_SYNC_INFO:
62 {
63 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt;
64 PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM;
65
66 *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
67
68 break;
69 }
70 case PVRSRV_HANDLE_TYPE_SOC_TIMER:
71 {
72 *phOSMemHandle = (IMG_VOID *)hMHandleInt;
73 break;
74 }
75#else
76 case PVRSRV_HANDLE_TYPE_NONE:
77 *phOSMemHandle = (IMG_VOID *)hMHandleInt;
78 break;
79#endif
80 default:
81 return PVRSRV_ERROR_BAD_MAPPING;
82 }
83
84 return PVRSRV_OK;
85}
diff --git a/drivers/gpu/pvr/bridged_support.h b/drivers/gpu/pvr/bridged_support.h
new file mode 100644
index 00000000000..371715d6ea8
--- /dev/null
+++ b/drivers/gpu/pvr/bridged_support.h
@@ -0,0 +1,43 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __BRIDGED_SUPPORT_H__
28#define __BRIDGED_SUPPORT_H__
29
30#include "handle.h"
31
32#if defined(__cplusplus)
33extern "C" {
34#endif
35
36PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle);
37
38#if defined (__cplusplus)
39}
40#endif
41
42#endif
43
diff --git a/drivers/gpu/pvr/buffer_manager.c b/drivers/gpu/pvr/buffer_manager.c
new file mode 100644
index 00000000000..cde168391c8
--- /dev/null
+++ b/drivers/gpu/pvr/buffer_manager.c
@@ -0,0 +1,2040 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28
29#include "sysconfig.h"
30#include "hash.h"
31#include "ra.h"
32#include "pdump_km.h"
33#include "lists.h"
34
35static IMG_BOOL
36ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
37static IMG_VOID
38BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
39static IMG_BOOL
40BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
41 IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
42 IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase);
43
44static IMG_BOOL
45DevMemoryAlloc (BM_CONTEXT *pBMContext,
46 BM_MAPPING *pMapping,
47 IMG_SIZE_T *pActualSize,
48 IMG_UINT32 uFlags,
49 IMG_UINT32 dev_vaddr_alignment,
50 IMG_DEV_VIRTADDR *pDevVAddr);
51static IMG_VOID
52DevMemoryFree (BM_MAPPING *pMapping);
53
54static IMG_BOOL
55AllocMemory (BM_CONTEXT *pBMContext,
56 BM_HEAP *psBMHeap,
57 IMG_DEV_VIRTADDR *psDevVAddr,
58 IMG_SIZE_T uSize,
59 IMG_UINT32 uFlags,
60 IMG_UINT32 uDevVAddrAlignment,
61 BM_BUF *pBuf)
62{
63 BM_MAPPING *pMapping;
64 IMG_UINTPTR_T uOffset;
65 RA_ARENA *pArena = IMG_NULL;
66
67 PVR_DPF ((PVR_DBG_MESSAGE,
68 "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
69 uSize, uFlags, uDevVAddrAlignment));
70
71
72
73
74 if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
75 {
76 if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
77 {
78
79 PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
80 return IMG_FALSE;
81 }
82
83
84
85
86 if(psBMHeap->ui32Attribs
87 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
88 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
89 {
90
91 pArena = psBMHeap->pImportArena;
92 PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
93 }
94 else
95 {
96 PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
97 return IMG_FALSE;
98 }
99
100
101 if (!RA_Alloc(pArena,
102 uSize,
103 IMG_NULL,
104 (IMG_VOID*) &pMapping,
105 uFlags,
106 uDevVAddrAlignment,
107 0,
108 (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
109 {
110 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize));
111 return IMG_FALSE;
112 }
113
114 uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
115 if(pMapping->CpuVAddr)
116 {
117 pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
118 }
119 else
120 {
121 pBuf->CpuVAddr = IMG_NULL;
122 }
123
124 if(uSize == pMapping->uSize)
125 {
126 pBuf->hOSMemHandle = pMapping->hOSMemHandle;
127 }
128 else
129 {
130 if(OSGetSubMemHandle(pMapping->hOSMemHandle,
131 uOffset,
132 uSize,
133 psBMHeap->ui32Attribs,
134 &pBuf->hOSMemHandle)!=PVRSRV_OK)
135 {
136 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
137 return IMG_FALSE;
138 }
139 }
140
141
142 pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
143
144 if(uFlags & PVRSRV_MEM_ZERO)
145 {
146 if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
147 {
148 return IMG_FALSE;
149 }
150 }
151 }
152 else
153 {
154 if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
155 {
156
157 PVR_ASSERT(psDevVAddr != IMG_NULL);
158
159 if (psDevVAddr == IMG_NULL)
160 {
161 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
162 return IMG_FALSE;
163 }
164
165
166 pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
167 uSize,
168 IMG_NULL,
169 PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
170 uDevVAddrAlignment,
171 psDevVAddr);
172
173
174 pBuf->DevVAddr = *psDevVAddr;
175 }
176 else
177 {
178
179
180
181 pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
182 uSize,
183 IMG_NULL,
184 0,
185 uDevVAddrAlignment,
186 &pBuf->DevVAddr);
187 }
188
189
190 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
191 sizeof (struct _BM_MAPPING_),
192 (IMG_PVOID *)&pMapping, IMG_NULL,
193 "Buffer Manager Mapping") != PVRSRV_OK)
194 {
195 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
196 return IMG_FALSE;
197 }
198
199
200 pBuf->CpuVAddr = IMG_NULL;
201 pBuf->hOSMemHandle = 0;
202 pBuf->CpuPAddr.uiAddr = 0;
203
204
205 pMapping->CpuVAddr = IMG_NULL;
206 pMapping->CpuPAddr.uiAddr = 0;
207 pMapping->DevVAddr = pBuf->DevVAddr;
208 pMapping->psSysAddr = IMG_NULL;
209 pMapping->uSize = uSize;
210 pMapping->hOSMemHandle = 0;
211 }
212
213
214 pMapping->pArena = pArena;
215
216
217 pMapping->pBMHeap = psBMHeap;
218 pBuf->pMapping = pMapping;
219
220
221 PVR_DPF ((PVR_DBG_MESSAGE,
222 "AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
223 (IMG_UINTPTR_T)pMapping,
224 pMapping->DevVAddr.uiAddr,
225 (IMG_UINTPTR_T)pMapping->CpuVAddr,
226 pMapping->CpuPAddr.uiAddr,
227 pMapping->uSize));
228
229 PVR_DPF ((PVR_DBG_MESSAGE,
230 "AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
231 (IMG_UINTPTR_T)pBuf,
232 pBuf->DevVAddr.uiAddr,
233 (IMG_UINTPTR_T)pBuf->CpuVAddr,
234 pBuf->CpuPAddr.uiAddr,
235 uSize));
236
237
238 PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
239
240 return IMG_TRUE;
241}
242
243
244static IMG_BOOL
245WrapMemory (BM_HEAP *psBMHeap,
246 IMG_SIZE_T uSize,
247 IMG_SIZE_T ui32BaseOffset,
248 IMG_BOOL bPhysContig,
249 IMG_SYS_PHYADDR *psAddr,
250 IMG_VOID *pvCPUVAddr,
251 IMG_UINT32 uFlags,
252 BM_BUF *pBuf)
253{
254 IMG_DEV_VIRTADDR DevVAddr = {0};
255 BM_MAPPING *pMapping;
256 IMG_BOOL bResult;
257 IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
258
259 PVR_DPF ((PVR_DBG_MESSAGE,
260 "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
261 (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
262
263 PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
264
265 PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
266
267 uSize += ui32BaseOffset;
268 uSize = HOST_PAGEALIGN (uSize);
269
270
271 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
272 sizeof(*pMapping),
273 (IMG_PVOID *)&pMapping, IMG_NULL,
274 "Mocked-up mapping") != PVRSRV_OK)
275 {
276 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
277 return IMG_FALSE;
278 }
279
280 OSMemSet(pMapping, 0, sizeof (*pMapping));
281
282 pMapping->uSize = uSize;
283 pMapping->pBMHeap = psBMHeap;
284
285 if(pvCPUVAddr)
286 {
287 pMapping->CpuVAddr = pvCPUVAddr;
288
289 if (bPhysContig)
290 {
291 pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
292 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
293
294 if(OSRegisterMem(pMapping->CpuPAddr,
295 pMapping->CpuVAddr,
296 pMapping->uSize,
297 uFlags,
298 &pMapping->hOSMemHandle) != PVRSRV_OK)
299 {
300 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed",
301 pMapping->CpuPAddr.uiAddr, pMapping->uSize));
302 goto fail_cleanup;
303 }
304 }
305 else
306 {
307 pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
308 pMapping->psSysAddr = psAddr;
309
310 if(OSRegisterDiscontigMem(pMapping->psSysAddr,
311 pMapping->CpuVAddr,
312 pMapping->uSize,
313 uFlags,
314 &pMapping->hOSMemHandle) != PVRSRV_OK)
315 {
316 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=%d) failed",
317 pMapping->uSize));
318 goto fail_cleanup;
319 }
320 }
321 }
322 else
323 {
324 if (bPhysContig)
325 {
326 pMapping->eCpuMemoryOrigin = hm_wrapped;
327 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
328
329 if(OSReservePhys(pMapping->CpuPAddr,
330 pMapping->uSize,
331 uFlags,
332 &pMapping->CpuVAddr,
333 &pMapping->hOSMemHandle) != PVRSRV_OK)
334 {
335 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
336 pMapping->CpuPAddr.uiAddr, pMapping->uSize));
337 goto fail_cleanup;
338 }
339 }
340 else
341 {
342 pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
343 pMapping->psSysAddr = psAddr;
344
345 if(OSReserveDiscontigPhys(pMapping->psSysAddr,
346 pMapping->uSize,
347 uFlags,
348 &pMapping->CpuVAddr,
349 &pMapping->hOSMemHandle) != PVRSRV_OK)
350 {
351 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
352 pMapping->uSize));
353 goto fail_cleanup;
354 }
355 }
356 }
357
358
359 bResult = DevMemoryAlloc(psBMHeap->pBMContext,
360 pMapping,
361 IMG_NULL,
362 uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
363 IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
364 &DevVAddr);
365 if (!bResult)
366 {
367 PVR_DPF((PVR_DBG_ERROR,
368 "WrapMemory: DevMemoryAlloc(0x%x) failed",
369 pMapping->uSize));
370 goto fail_cleanup;
371 }
372
373
374 pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
375 if(!ui32BaseOffset)
376 {
377 pBuf->hOSMemHandle = pMapping->hOSMemHandle;
378 }
379 else
380 {
381 if(OSGetSubMemHandle(pMapping->hOSMemHandle,
382 ui32BaseOffset,
383 (pMapping->uSize-ui32BaseOffset),
384 uFlags,
385 &pBuf->hOSMemHandle)!=PVRSRV_OK)
386 {
387 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
388 goto fail_cleanup;
389 }
390 }
391 if(pMapping->CpuVAddr)
392 {
393 pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
394 }
395 pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
396
397 if(uFlags & PVRSRV_MEM_ZERO)
398 {
399 if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
400 {
401 return IMG_FALSE;
402 }
403 }
404
405 PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
406 PVR_DPF ((PVR_DBG_MESSAGE,
407 "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
408 pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
409 PVR_DPF ((PVR_DBG_MESSAGE,
410 "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
411 pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize));
412
413 pBuf->pMapping = pMapping;
414 return IMG_TRUE;
415
416fail_cleanup:
417 if(ui32BaseOffset && pBuf->hOSMemHandle)
418 {
419 OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
420 }
421
422 if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
423 {
424 switch(pMapping->eCpuMemoryOrigin)
425 {
426 case hm_wrapped:
427 OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
428 break;
429 case hm_wrapped_virtaddr:
430 OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
431 break;
432 case hm_wrapped_scatter:
433 OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
434 break;
435 case hm_wrapped_scatter_virtaddr:
436 OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
437 break;
438 default:
439 break;
440 }
441
442 }
443
444 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
445
446
447 return IMG_FALSE;
448}
449
450
451static IMG_BOOL
452ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
453{
454 IMG_VOID *pvCpuVAddr;
455
456 if(pBuf->CpuVAddr)
457 {
458 OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
459 }
460 else if(pMapping->eCpuMemoryOrigin == hm_contiguous
461 || pMapping->eCpuMemoryOrigin == hm_wrapped)
462 {
463 pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
464 ui32Bytes,
465 PVRSRV_HAP_KERNEL_ONLY
466 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
467 IMG_NULL);
468 if(!pvCpuVAddr)
469 {
470 PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
471 return IMG_FALSE;
472 }
473 OSMemSet(pvCpuVAddr, 0, ui32Bytes);
474 OSUnMapPhysToLin(pvCpuVAddr,
475 ui32Bytes,
476 PVRSRV_HAP_KERNEL_ONLY
477 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
478 IMG_NULL);
479 }
480 else
481 {
482 IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
483 IMG_SIZE_T ui32CurrentOffset = 0;
484 IMG_CPU_PHYADDR CpuPAddr;
485
486
487 PVR_ASSERT(pBuf->hOSMemHandle);
488
489 while(ui32BytesRemaining > 0)
490 {
491 IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
492 CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
493
494 if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
495 {
496 ui32BlockBytes =
497 MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
498 }
499
500 pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
501 ui32BlockBytes,
502 PVRSRV_HAP_KERNEL_ONLY
503 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
504 IMG_NULL);
505 if(!pvCpuVAddr)
506 {
507 PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
508 return IMG_FALSE;
509 }
510 OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
511 OSUnMapPhysToLin(pvCpuVAddr,
512 ui32BlockBytes,
513 PVRSRV_HAP_KERNEL_ONLY
514 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
515 IMG_NULL);
516
517 ui32BytesRemaining -= ui32BlockBytes;
518 ui32CurrentOffset += ui32BlockBytes;
519 }
520 }
521
522 return IMG_TRUE;
523}
524
525static IMG_VOID
526FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
527{
528 BM_MAPPING *pMapping;
529
530 PVR_DPF ((PVR_DBG_MESSAGE,
531 "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
532 (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
533 (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
534
535
536 pMapping = pBuf->pMapping;
537
538 if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
539 {
540
541 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
542 {
543
544 if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
545 {
546
547 PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
548 }
549 else
550 {
551
552 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
553 pBuf->pMapping = IMG_NULL;
554 }
555 }
556 }
557 else
558 {
559
560 if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
561 {
562
563 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
564 {
565
566 OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
567 }
568 }
569 if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
570 {
571
572
573 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
574 {
575
576
577
578 PVR_ASSERT(pBuf->ui32ExportCount == 0)
579 RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
580 }
581 }
582 else
583 {
584 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
585 {
586 switch (pMapping->eCpuMemoryOrigin)
587 {
588 case hm_wrapped:
589 OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
590 break;
591 case hm_wrapped_virtaddr:
592 OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
593 break;
594 case hm_wrapped_scatter:
595 OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
596 break;
597 case hm_wrapped_scatter_virtaddr:
598 OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
599 break;
600 default:
601 break;
602 }
603 }
604 if (bFromAllocator)
605 DevMemoryFree (pMapping);
606
607 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
608 {
609
610 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
611 pBuf->pMapping = IMG_NULL;
612 }
613 }
614 }
615
616
617 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
618 {
619 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
620
621 }
622}
623
624static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
625{
626 if(psBMHeap->ui32Attribs
627 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
628 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
629 {
630 if (psBMHeap->pImportArena)
631 {
632 IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
633 if (!bTestDelete)
634 {
635 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
636 return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
637 }
638 }
639 }
640 return PVRSRV_OK;
641}
642
643
644PVRSRV_ERROR
645BM_DestroyContext(IMG_HANDLE hBMContext,
646 IMG_BOOL *pbDestroyed)
647{
648 PVRSRV_ERROR eError;
649 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
650
651 PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
652
653 if (pbDestroyed != IMG_NULL)
654 {
655 *pbDestroyed = IMG_FALSE;
656 }
657
658
659
660 if (pBMContext == IMG_NULL)
661 {
662 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
663 return PVRSRV_ERROR_INVALID_PARAMS;
664 }
665
666 pBMContext->ui32RefCount--;
667
668 if (pBMContext->ui32RefCount > 0)
669 {
670
671 return PVRSRV_OK;
672 }
673
674
675
676
677 eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
678 if(eError != PVRSRV_OK)
679 {
680 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
681#if 0
682
683
684
685
686 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Cleaning up with ResManFreeSpecial"));
687 if(ResManFreeSpecial() != PVRSRV_OK)
688 {
689 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeSpecial failed %d",eError));
690 }
691
692#endif
693 return eError;
694 }
695 else
696 {
697
698 eError = ResManFreeResByPtr(pBMContext->hResItem);
699 if(eError != PVRSRV_OK)
700 {
701 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
702 return eError;
703 }
704
705
706 if (pbDestroyed != IMG_NULL)
707 {
708 *pbDestroyed = IMG_TRUE;
709 }
710 }
711
712 return PVRSRV_OK;
713}
714
715
716static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
717{
718 PVRSRV_DEVICE_NODE *psDeviceNode;
719 psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
720
721
722 if(psBMHeap->ui32Attribs
723 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
724 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
725 {
726 if (psBMHeap->pImportArena)
727 {
728 RA_Delete (psBMHeap->pImportArena);
729 }
730 }
731 else
732 {
733 PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
734 return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE;
735 }
736
737
738 psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
739
740
741 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
742
743
744 return PVRSRV_OK;
745}
746
747
748static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam,
749 IMG_UINT32 ui32Param)
750{
751 BM_CONTEXT *pBMContext = pvParam;
752 PVRSRV_DEVICE_NODE *psDeviceNode;
753 PVRSRV_ERROR eError;
754 PVR_UNREFERENCED_PARAMETER(ui32Param);
755
756
757
758 psDeviceNode = pBMContext->psDeviceNode;
759
760
761
762 eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
763 &BM_DestroyContextCallBack_AnyVaCb,
764 psDeviceNode);
765 if (eError != PVRSRV_OK)
766 {
767 return eError;
768 }
769
770
771 if (pBMContext->psMMUContext)
772 {
773 psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
774 }
775
776
777
778 if (pBMContext->pBufferHash)
779 {
780 HASH_Delete(pBMContext->pBufferHash);
781 }
782
783 if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
784 {
785
786 psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
787 }
788 else
789 {
790
791 List_BM_CONTEXT_Remove(pBMContext);
792 }
793
794 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
795
796
797 return PVRSRV_OK;
798}
799
800
801static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
802{
803 PRESMAN_CONTEXT hResManContext;
804 hResManContext = va_arg(va, PRESMAN_CONTEXT);
805 if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
806 {
807
808 pBMContext->ui32RefCount++;
809 return pBMContext;
810 }
811 return IMG_NULL;
812}
813
814static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
815{
816 PVRSRV_DEVICE_NODE *psDeviceNode;
817 BM_CONTEXT *pBMContext;
818 psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
819 pBMContext = va_arg(va, BM_CONTEXT*);
820 switch(psBMHeap->sDevArena.DevMemHeapType)
821 {
822 case DEVICE_MEMORY_HEAP_SHARED:
823 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
824 {
825
826 psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
827 break;
828 }
829 }
830}
831
832IMG_HANDLE
833BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
834 IMG_DEV_PHYADDR *psPDDevPAddr,
835 PVRSRV_PER_PROCESS_DATA *psPerProc,
836 IMG_BOOL *pbCreated)
837{
838 BM_CONTEXT *pBMContext;
839 DEVICE_MEMORY_INFO *psDevMemoryInfo;
840 IMG_BOOL bKernelContext;
841 PRESMAN_CONTEXT hResManContext;
842
843 PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
844
845 if (psPerProc == IMG_NULL)
846 {
847 bKernelContext = IMG_TRUE;
848 hResManContext = psDeviceNode->hResManContext;
849 }
850 else
851 {
852 bKernelContext = IMG_FALSE;
853 hResManContext = psPerProc->hResManContext;
854 }
855
856 if (pbCreated != IMG_NULL)
857 {
858 *pbCreated = IMG_FALSE;
859 }
860
861
862 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
863
864 if (bKernelContext == IMG_FALSE)
865 {
866 IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
867 &BM_CreateContext_IncRefCount_AnyVaCb,
868 hResManContext);
869 if (res)
870 {
871 return res;
872 }
873 }
874
875
876 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
877 sizeof (struct _BM_CONTEXT_),
878 (IMG_PVOID *)&pBMContext, IMG_NULL,
879 "Buffer Manager Context") != PVRSRV_OK)
880 {
881 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
882 return IMG_NULL;
883 }
884 OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
885
886
887 pBMContext->psDeviceNode = psDeviceNode;
888
889
890
891 pBMContext->pBufferHash = HASH_Create(32);
892 if (pBMContext->pBufferHash==IMG_NULL)
893 {
894 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
895 goto cleanup;
896 }
897
898 if(psDeviceNode->pfnMMUInitialise(psDeviceNode,
899 &pBMContext->psMMUContext,
900 psPDDevPAddr) != PVRSRV_OK)
901 {
902 PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
903 goto cleanup;
904 }
905
906 if(bKernelContext)
907 {
908
909 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
910 psDevMemoryInfo->pBMKernelContext = pBMContext;
911 }
912 else
913 {
914
915
916
917
918
919 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
920
921 if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
922 {
923 PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
924 goto cleanup;
925 }
926
927 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
928
929
930
931
932
933 pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
934
935
936
937
938 List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
939 &BM_CreateContext_InsertHeap_ForEachVaCb,
940 psDeviceNode,
941 pBMContext);
942
943
944 List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
945 }
946
947
948 pBMContext->ui32RefCount++;
949
950
951 pBMContext->hResItem = ResManRegisterRes(hResManContext,
952 RESMAN_TYPE_DEVICEMEM_CONTEXT,
953 pBMContext,
954 0,
955 &BM_DestroyContextCallBack);
956 if (pBMContext->hResItem == IMG_NULL)
957 {
958 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
959 goto cleanup;
960 }
961
962 if (pbCreated != IMG_NULL)
963 {
964 *pbCreated = IMG_TRUE;
965 }
966 return (IMG_HANDLE)pBMContext;
967
968cleanup:
969 (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0);
970
971 return IMG_NULL;
972}
973
974
975static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
976{
977 DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
978 psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
979 if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID)
980 {
981
982 return psBMHeap;
983 }
984 else
985 {
986 return IMG_NULL;
987 }
988}
989
990IMG_HANDLE
991BM_CreateHeap (IMG_HANDLE hBMContext,
992 DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
993{
994 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
995 PVRSRV_DEVICE_NODE *psDeviceNode;
996 BM_HEAP *psBMHeap;
997
998 PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
999
1000 if(!pBMContext)
1001 {
1002 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
1003 return IMG_NULL;
1004 }
1005
1006 psDeviceNode = pBMContext->psDeviceNode;
1007
1008
1009
1010
1011
1012
1013 if(pBMContext->ui32RefCount > 0)
1014 {
1015 psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
1016 &BM_CreateHeap_AnyVaCb,
1017 psDevMemHeapInfo);
1018
1019 if (psBMHeap)
1020 {
1021 return psBMHeap;
1022 }
1023 }
1024
1025
1026 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1027 sizeof (BM_HEAP),
1028 (IMG_PVOID *)&psBMHeap, IMG_NULL,
1029 "Buffer Manager Heap") != PVRSRV_OK)
1030 {
1031 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
1032 return IMG_NULL;
1033 }
1034
1035 OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
1036
1037 psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
1038 psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
1039 psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
1040 psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
1041 psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
1042 psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
1043 psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
1044 psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
1045
1046
1047 psBMHeap->pBMContext = pBMContext;
1048
1049 psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
1050 &psBMHeap->sDevArena,
1051 &psBMHeap->pVMArena,
1052 &psBMHeap->psMMUAttrib);
1053 if (!psBMHeap->pMMUHeap)
1054 {
1055 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
1056 goto ErrorExit;
1057 }
1058
1059
1060 psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
1061 0, 0, IMG_NULL,
1062 MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize),
1063 &BM_ImportMemory,
1064 &BM_FreeMemory,
1065 IMG_NULL,
1066 psBMHeap);
1067 if(psBMHeap->pImportArena == IMG_NULL)
1068 {
1069 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
1070 goto ErrorExit;
1071 }
1072
1073 if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1074 {
1075
1076
1077
1078
1079 psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
1080 if(psBMHeap->pLocalDevMemArena == IMG_NULL)
1081 {
1082 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
1083 goto ErrorExit;
1084 }
1085 }
1086
1087
1088 List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
1089
1090 return (IMG_HANDLE)psBMHeap;
1091
1092
1093ErrorExit:
1094
1095
1096 if (psBMHeap->pMMUHeap != IMG_NULL)
1097 {
1098 psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
1099 psDeviceNode->pfnMMUFinalise (pBMContext->psMMUContext);
1100 }
1101
1102
1103 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
1104
1105
1106 return IMG_NULL;
1107}
1108
1109IMG_VOID
1110BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
1111{
1112 BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
1113 PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
1114
1115 PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
1116
1117 if(psBMHeap)
1118 {
1119
1120 if(psBMHeap->ui32Attribs
1121 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
1122 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
1123 {
1124 if (psBMHeap->pImportArena)
1125 {
1126 RA_Delete (psBMHeap->pImportArena);
1127 }
1128 }
1129 else
1130 {
1131 PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
1132 return;
1133 }
1134
1135
1136 psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
1137
1138
1139 List_BM_HEAP_Remove(psBMHeap);
1140
1141 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
1142
1143 }
1144 else
1145 {
1146 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
1147 }
1148}
1149
1150
1151IMG_BOOL
1152BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
1153{
1154
1155 PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
1156 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1157
1158
1159 return IMG_TRUE;
1160}
1161
1162IMG_BOOL
1163BM_Alloc ( IMG_HANDLE hDevMemHeap,
1164 IMG_DEV_VIRTADDR *psDevVAddr,
1165 IMG_SIZE_T uSize,
1166 IMG_UINT32 *pui32Flags,
1167 IMG_UINT32 uDevVAddrAlignment,
1168 BM_HANDLE *phBuf)
1169{
1170 BM_BUF *pBuf;
1171 BM_CONTEXT *pBMContext;
1172 BM_HEAP *psBMHeap;
1173 SYS_DATA *psSysData;
1174 IMG_UINT32 uFlags;
1175
1176 if (pui32Flags == IMG_NULL)
1177 {
1178 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
1179 PVR_DBG_BREAK;
1180 return IMG_FALSE;
1181 }
1182
1183 uFlags = *pui32Flags;
1184
1185 PVR_DPF ((PVR_DBG_MESSAGE,
1186 "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
1187 uSize, uFlags, uDevVAddrAlignment));
1188
1189 SysAcquireData(&psSysData);
1190
1191 psBMHeap = (BM_HEAP*)hDevMemHeap;
1192 pBMContext = psBMHeap->pBMContext;
1193
1194 if(uDevVAddrAlignment == 0)
1195 {
1196 uDevVAddrAlignment = 1;
1197 }
1198
1199
1200 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1201 sizeof (BM_BUF),
1202 (IMG_PVOID *)&pBuf, IMG_NULL,
1203 "Buffer Manager buffer") != PVRSRV_OK)
1204 {
1205 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
1206 return IMG_FALSE;
1207 }
1208 OSMemSet(pBuf, 0, sizeof (BM_BUF));
1209
1210
1211 if (AllocMemory(pBMContext,
1212 psBMHeap,
1213 psDevVAddr,
1214 uSize,
1215 uFlags,
1216 uDevVAddrAlignment,
1217 pBuf) != IMG_TRUE)
1218 {
1219 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
1220
1221 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
1222 return IMG_FALSE;
1223 }
1224
1225 PVR_DPF ((PVR_DBG_MESSAGE,
1226 "BM_Alloc (uSize=0x%x, uFlags=0x%x)",
1227 uSize, uFlags));
1228
1229
1230 pBuf->ui32RefCount = 1;
1231 *phBuf = (BM_HANDLE)pBuf;
1232 *pui32Flags = uFlags | psBMHeap->ui32Attribs;
1233
1234
1235 if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
1236 {
1237 *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
1238 *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
1239 }
1240
1241 return IMG_TRUE;
1242}
1243
1244
1245
1246#if defined(PVR_LMA)
1247static IMG_BOOL
1248ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
1249{
1250 IMG_UINT32 i;
1251
1252 for (i = 0; i < ui32PageCount; i++)
1253 {
1254 IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
1255 IMG_SYS_PHYADDR sEndSysPAddr;
1256
1257 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
1258 {
1259 return IMG_FALSE;
1260 }
1261
1262 sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
1263
1264 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
1265 {
1266 return IMG_FALSE;
1267 }
1268 }
1269
1270 return IMG_TRUE;
1271}
1272
1273static IMG_BOOL
1274ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
1275{
1276 IMG_SYS_PHYADDR sEndSysPAddr;
1277
1278 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
1279 {
1280 return IMG_FALSE;
1281 }
1282
1283 sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
1284
1285 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
1286 {
1287 return IMG_FALSE;
1288 }
1289
1290 return IMG_TRUE;
1291}
1292
1293#define WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
1294
1295#define WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
1296
1297#endif
1298
1299
1300IMG_BOOL
1301BM_Wrap ( IMG_HANDLE hDevMemHeap,
1302 IMG_SIZE_T ui32Size,
1303 IMG_SIZE_T ui32Offset,
1304 IMG_BOOL bPhysContig,
1305 IMG_SYS_PHYADDR *psSysAddr,
1306 IMG_VOID *pvCPUVAddr,
1307 IMG_UINT32 *pui32Flags,
1308 BM_HANDLE *phBuf)
1309{
1310 BM_BUF *pBuf;
1311 BM_CONTEXT *psBMContext;
1312 BM_HEAP *psBMHeap;
1313 SYS_DATA *psSysData;
1314 IMG_SYS_PHYADDR sHashAddress;
1315 IMG_UINT32 uFlags;
1316
1317 psBMHeap = (BM_HEAP*)hDevMemHeap;
1318 psBMContext = psBMHeap->pBMContext;
1319
1320 uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);
1321
1322 if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
1323 {
1324 uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
1325 uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
1326 }
1327
1328 PVR_DPF ((PVR_DBG_MESSAGE,
1329 "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
1330 ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
1331
1332 SysAcquireData(&psSysData);
1333
1334#if defined(PVR_LMA)
1335 if (bPhysContig)
1336 {
1337 if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
1338 {
1339 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
1340 return IMG_FALSE;
1341 }
1342 }
1343 else
1344 {
1345 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
1346
1347 if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
1348 {
1349 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
1350 return IMG_FALSE;
1351 }
1352 }
1353#endif
1354
1355 sHashAddress = psSysAddr[0];
1356
1357
1358 sHashAddress.uiAddr += ui32Offset;
1359
1360
1361 pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
1362
1363 if(pBuf)
1364 {
1365 IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
1366
1367
1368 if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
1369 pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
1370 {
1371 PVR_DPF((PVR_DBG_MESSAGE,
1372 "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
1373 ui32Size, ui32Offset, sHashAddress.uiAddr));
1374
1375 pBuf->ui32RefCount++;
1376 *phBuf = (BM_HANDLE)pBuf;
1377 if(pui32Flags)
1378 *pui32Flags = uFlags;
1379
1380 return IMG_TRUE;
1381 }
1382 }
1383
1384
1385 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1386 sizeof (BM_BUF),
1387 (IMG_PVOID *)&pBuf, IMG_NULL,
1388 "Buffer Manager buffer") != PVRSRV_OK)
1389 {
1390 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
1391 return IMG_FALSE;
1392 }
1393 OSMemSet(pBuf, 0, sizeof (BM_BUF));
1394
1395
1396 if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
1397 {
1398 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
1399 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
1400
1401 return IMG_FALSE;
1402 }
1403
1404
1405 if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
1406 {
1407
1408 PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
1409
1410 if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
1411 {
1412 FreeBuf (pBuf, uFlags, IMG_TRUE);
1413 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
1414 return IMG_FALSE;
1415 }
1416 }
1417
1418 PVR_DPF ((PVR_DBG_MESSAGE,
1419 "BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
1420 ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
1421
1422
1423 pBuf->ui32RefCount = 1;
1424 *phBuf = (BM_HANDLE)pBuf;
1425 if(pui32Flags)
1426 {
1427
1428 *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
1429 }
1430
1431 return IMG_TRUE;
1432}
1433
1434IMG_VOID
1435BM_Export (BM_HANDLE hBuf)
1436{
1437 BM_BUF *pBuf = (BM_BUF *)hBuf;
1438
1439 pBuf->ui32ExportCount++;
1440}
1441
1442IMG_VOID
1443BM_FreeExport(BM_HANDLE hBuf,
1444 IMG_UINT32 ui32Flags)
1445{
1446 BM_BUF *pBuf = (BM_BUF *)hBuf;
1447
1448 pBuf->ui32ExportCount--;
1449 FreeBuf (pBuf, ui32Flags, IMG_FALSE);
1450}
1451
1452IMG_VOID
1453BM_Free (BM_HANDLE hBuf,
1454 IMG_UINT32 ui32Flags)
1455{
1456 BM_BUF *pBuf = (BM_BUF *)hBuf;
1457 SYS_DATA *psSysData;
1458 IMG_SYS_PHYADDR sHashAddr;
1459
1460 PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%x)", (IMG_UINTPTR_T)hBuf));
1461 PVR_ASSERT (pBuf!=IMG_NULL);
1462
1463 if (pBuf == IMG_NULL)
1464 {
1465 PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
1466 return;
1467 }
1468
1469 SysAcquireData(&psSysData);
1470
1471 pBuf->ui32RefCount--;
1472
1473 if(pBuf->ui32RefCount == 0)
1474 {
1475 if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
1476 {
1477 sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
1478
1479 HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr);
1480 }
1481 FreeBuf (pBuf, ui32Flags, IMG_TRUE);
1482 }
1483}
1484
1485
1486IMG_CPU_VIRTADDR
1487BM_HandleToCpuVaddr (BM_HANDLE hBuf)
1488{
1489 BM_BUF *pBuf = (BM_BUF *)hBuf;
1490
1491 PVR_ASSERT (pBuf != IMG_NULL);
1492 if (pBuf == IMG_NULL)
1493 {
1494 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
1495 return IMG_NULL;
1496 }
1497
1498 PVR_DPF ((PVR_DBG_MESSAGE,
1499 "BM_HandleToCpuVaddr(h=0x%x)=0x%x",
1500 (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
1501 return pBuf->CpuVAddr;
1502}
1503
1504
1505IMG_DEV_VIRTADDR
1506BM_HandleToDevVaddr (BM_HANDLE hBuf)
1507{
1508 BM_BUF *pBuf = (BM_BUF *)hBuf;
1509
1510 PVR_ASSERT (pBuf != IMG_NULL);
1511 if (pBuf == IMG_NULL)
1512 {
1513 IMG_DEV_VIRTADDR DevVAddr = {0};
1514 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
1515 return DevVAddr;
1516 }
1517
1518 PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
1519 return pBuf->DevVAddr;
1520}
1521
1522
1523IMG_SYS_PHYADDR
1524BM_HandleToSysPaddr (BM_HANDLE hBuf)
1525{
1526 BM_BUF *pBuf = (BM_BUF *)hBuf;
1527
1528 PVR_ASSERT (pBuf != IMG_NULL);
1529
1530 if (pBuf == IMG_NULL)
1531 {
1532 IMG_SYS_PHYADDR PhysAddr = {0};
1533 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
1534 return PhysAddr;
1535 }
1536
1537 PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
1538 return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
1539}
1540
1541IMG_HANDLE
1542BM_HandleToOSMemHandle(BM_HANDLE hBuf)
1543{
1544 BM_BUF *pBuf = (BM_BUF *)hBuf;
1545
1546 PVR_ASSERT (pBuf != IMG_NULL);
1547
1548 if (pBuf == IMG_NULL)
1549 {
1550 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
1551 return IMG_NULL;
1552 }
1553
1554 PVR_DPF ((PVR_DBG_MESSAGE,
1555 "BM_HandleToOSMemHandle(h=0x%x)=0x%x",
1556 (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
1557 return pBuf->hOSMemHandle;
1558}
1559
1560static IMG_BOOL
1561DevMemoryAlloc (BM_CONTEXT *pBMContext,
1562 BM_MAPPING *pMapping,
1563 IMG_SIZE_T *pActualSize,
1564 IMG_UINT32 uFlags,
1565 IMG_UINT32 dev_vaddr_alignment,
1566 IMG_DEV_VIRTADDR *pDevVAddr)
1567{
1568 PVRSRV_DEVICE_NODE *psDeviceNode;
1569#ifdef PDUMP
1570 IMG_UINT32 ui32PDumpSize = pMapping->uSize;
1571#endif
1572
1573 psDeviceNode = pBMContext->psDeviceNode;
1574
1575 if(uFlags & PVRSRV_MEM_INTERLEAVED)
1576 {
1577
1578 pMapping->uSize *= 2;
1579 }
1580
1581#ifdef PDUMP
1582 if(uFlags & PVRSRV_MEM_DUMMY)
1583 {
1584
1585 ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
1586 }
1587#endif
1588
1589
1590 if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
1591 pMapping->uSize,
1592 pActualSize,
1593 0,
1594 dev_vaddr_alignment,
1595 &(pMapping->DevVAddr)))
1596 {
1597 PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
1598 return IMG_FALSE;
1599 }
1600
1601#ifdef SUPPORT_SGX_MMU_BYPASS
1602 EnableHostAccess(pBMContext->psMMUContext);
1603#endif
1604
1605
1606
1607 PDUMPMALLOCPAGES(&psDeviceNode->sDevId, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, (IMG_HANDLE)pMapping);
1608
1609 switch (pMapping->eCpuMemoryOrigin)
1610 {
1611 case hm_wrapped:
1612 case hm_wrapped_virtaddr:
1613 case hm_contiguous:
1614 {
1615 psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap,
1616 pMapping->DevVAddr,
1617 SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
1618 pMapping->uSize,
1619 uFlags,
1620 (IMG_HANDLE)pMapping);
1621
1622 *pDevVAddr = pMapping->DevVAddr;
1623 break;
1624 }
1625 case hm_env:
1626 {
1627 psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap,
1628 pMapping->DevVAddr,
1629 pMapping->uSize,
1630 pMapping->CpuVAddr,
1631 pMapping->hOSMemHandle,
1632 pDevVAddr,
1633 uFlags,
1634 (IMG_HANDLE)pMapping);
1635 break;
1636 }
1637 case hm_wrapped_scatter:
1638 case hm_wrapped_scatter_virtaddr:
1639 {
1640 psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
1641 pMapping->DevVAddr,
1642 pMapping->psSysAddr,
1643 pMapping->uSize,
1644 uFlags,
1645 (IMG_HANDLE)pMapping);
1646
1647 *pDevVAddr = pMapping->DevVAddr;
1648 break;
1649 }
1650 default:
1651 PVR_DPF((PVR_DBG_ERROR,
1652 "Illegal value %d for pMapping->eCpuMemoryOrigin",
1653 pMapping->eCpuMemoryOrigin));
1654 return IMG_FALSE;
1655 }
1656
1657#ifdef SUPPORT_SGX_MMU_BYPASS
1658 DisableHostAccess(pBMContext->psMMUContext);
1659#endif
1660
1661 return IMG_TRUE;
1662}
1663
1664static IMG_VOID
1665DevMemoryFree (BM_MAPPING *pMapping)
1666{
1667 PVRSRV_DEVICE_NODE *psDeviceNode;
1668#ifdef PDUMP
1669 IMG_UINT32 ui32PSize;
1670#endif
1671
1672#ifdef PDUMP
1673
1674 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1675 {
1676
1677 ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
1678 }
1679 else
1680 {
1681 ui32PSize = pMapping->uSize;
1682 }
1683
1684 PDUMPFREEPAGES(pMapping->pBMHeap,
1685 pMapping->DevVAddr,
1686 ui32PSize,
1687 pMapping->pBMHeap->sDevArena.ui32DataPageSize,
1688 (IMG_HANDLE)pMapping,
1689 (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE);
1690#endif
1691
1692 psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
1693
1694 psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize));
1695}
1696
1697static IMG_BOOL
1698BM_ImportMemory (IMG_VOID *pH,
1699 IMG_SIZE_T uRequestSize,
1700 IMG_SIZE_T *pActualSize,
1701 BM_MAPPING **ppsMapping,
1702 IMG_UINT32 uFlags,
1703 IMG_UINTPTR_T *pBase)
1704{
1705 BM_MAPPING *pMapping;
1706 BM_HEAP *pBMHeap = pH;
1707 BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
1708 IMG_BOOL bResult;
1709 IMG_SIZE_T uSize;
1710 IMG_SIZE_T uPSize;
1711 IMG_UINT32 uDevVAddrAlignment = 0;
1712
1713 PVR_DPF ((PVR_DBG_MESSAGE,
1714 "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
1715 (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
1716
1717 PVR_ASSERT (ppsMapping != IMG_NULL);
1718 PVR_ASSERT (pBMContext != IMG_NULL);
1719
1720 if (ppsMapping == IMG_NULL)
1721 {
1722 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
1723 goto fail_exit;
1724 }
1725
1726 uSize = HOST_PAGEALIGN (uRequestSize);
1727 PVR_ASSERT (uSize >= uRequestSize);
1728
1729 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1730 sizeof (BM_MAPPING),
1731 (IMG_PVOID *)&pMapping, IMG_NULL,
1732 "Buffer Manager Mapping") != PVRSRV_OK)
1733 {
1734 PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
1735 goto fail_exit;
1736 }
1737
1738 pMapping->hOSMemHandle = 0;
1739 pMapping->CpuVAddr = 0;
1740 pMapping->DevVAddr.uiAddr = 0;
1741 pMapping->CpuPAddr.uiAddr = 0;
1742 pMapping->uSize = uSize;
1743 pMapping->pBMHeap = pBMHeap;
1744 pMapping->ui32Flags = uFlags;
1745
1746
1747 if (pActualSize)
1748 {
1749 *pActualSize = uSize;
1750 }
1751
1752
1753 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1754 {
1755 uPSize = pBMHeap->sDevArena.ui32DataPageSize;
1756 }
1757 else
1758 {
1759 uPSize = pMapping->uSize;
1760 }
1761
1762
1763
1764 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1765 {
1766 IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
1767
1768
1769 if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
1770 {
1771 ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
1772 ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
1773 }
1774
1775
1776 if (OSAllocPages(ui32Attribs,
1777 uPSize,
1778 pBMHeap->sDevArena.ui32DataPageSize,
1779 (IMG_VOID **)&pMapping->CpuVAddr,
1780 &pMapping->hOSMemHandle) != PVRSRV_OK)
1781 {
1782 PVR_DPF((PVR_DBG_ERROR,
1783 "BM_ImportMemory: OSAllocPages(0x%x) failed",
1784 uPSize));
1785 goto fail_mapping_alloc;
1786 }
1787
1788
1789 pMapping->eCpuMemoryOrigin = hm_env;
1790 }
1791 else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1792 {
1793 IMG_SYS_PHYADDR sSysPAddr;
1794 IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
1795
1796
1797 PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
1798
1799
1800 if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
1801 {
1802 ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
1803 ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
1804 }
1805
1806 if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
1807 uPSize,
1808 IMG_NULL,
1809 IMG_NULL,
1810 0,
1811 pBMHeap->sDevArena.ui32DataPageSize,
1812 0,
1813 (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
1814 {
1815 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
1816 goto fail_mapping_alloc;
1817 }
1818
1819
1820 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
1821 if(OSReservePhys(pMapping->CpuPAddr,
1822 uPSize,
1823 ui32Attribs,
1824 &pMapping->CpuVAddr,
1825 &pMapping->hOSMemHandle) != PVRSRV_OK)
1826 {
1827 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
1828 goto fail_dev_mem_alloc;
1829 }
1830
1831
1832 pMapping->eCpuMemoryOrigin = hm_contiguous;
1833 }
1834 else
1835 {
1836 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
1837 goto fail_mapping_alloc;
1838 }
1839
1840
1841 bResult = DevMemoryAlloc (pBMContext,
1842 pMapping,
1843 IMG_NULL,
1844 uFlags,
1845 uDevVAddrAlignment,
1846 &pMapping->DevVAddr);
1847 if (!bResult)
1848 {
1849 PVR_DPF((PVR_DBG_ERROR,
1850 "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
1851 pMapping->uSize));
1852 goto fail_dev_mem_alloc;
1853 }
1854
1855
1856
1857 PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
1858
1859 *pBase = pMapping->DevVAddr.uiAddr;
1860 *ppsMapping = pMapping;
1861
1862 PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
1863 return IMG_TRUE;
1864
1865fail_dev_mem_alloc:
1866 if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
1867 {
1868
1869 if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
1870 {
1871 pMapping->uSize /= 2;
1872 }
1873
1874 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1875 {
1876 uPSize = pBMHeap->sDevArena.ui32DataPageSize;
1877 }
1878 else
1879 {
1880 uPSize = pMapping->uSize;
1881 }
1882
1883 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1884 {
1885 OSFreePages(pBMHeap->ui32Attribs,
1886 uPSize,
1887 (IMG_VOID *)pMapping->CpuVAddr,
1888 pMapping->hOSMemHandle);
1889 }
1890 else
1891 {
1892 IMG_SYS_PHYADDR sSysPAddr;
1893
1894 if(pMapping->CpuVAddr)
1895 {
1896 OSUnReservePhys(pMapping->CpuVAddr,
1897 uPSize,
1898 pBMHeap->ui32Attribs,
1899 pMapping->hOSMemHandle);
1900 }
1901 sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
1902 RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1903 }
1904 }
1905fail_mapping_alloc:
1906 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
1907
1908fail_exit:
1909 return IMG_FALSE;
1910}
1911
1912
1913static IMG_VOID
1914BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
1915{
1916 BM_HEAP *pBMHeap = h;
1917 IMG_SIZE_T uPSize;
1918
1919 PVR_UNREFERENCED_PARAMETER (_base);
1920
1921 PVR_DPF ((PVR_DBG_MESSAGE,
1922 "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)",
1923 (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
1924
1925 PVR_ASSERT (psMapping != IMG_NULL);
1926
1927 if (psMapping == IMG_NULL)
1928 {
1929 PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
1930 return;
1931 }
1932
1933 DevMemoryFree (psMapping);
1934
1935
1936 if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
1937 {
1938 psMapping->uSize /= 2;
1939 }
1940
1941 if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1942 {
1943 uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
1944 }
1945 else
1946 {
1947 uPSize = psMapping->uSize;
1948 }
1949
1950 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1951 {
1952 OSFreePages(pBMHeap->ui32Attribs,
1953 uPSize,
1954 (IMG_VOID *) psMapping->CpuVAddr,
1955 psMapping->hOSMemHandle);
1956 }
1957 else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1958 {
1959 IMG_SYS_PHYADDR sSysPAddr;
1960
1961 OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
1962
1963 sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
1964
1965 RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1966 }
1967 else
1968 {
1969 PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"));
1970 }
1971
1972 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
1973
1974
1975 PVR_DPF((PVR_DBG_MESSAGE,
1976 "..BM_FreeMemory (h=0x%x, base=0x%x)",
1977 (IMG_UINTPTR_T)h, _base));
1978}
1979
1980IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1981 IMG_DEV_VIRTADDR sDevVPageAddr,
1982 IMG_DEV_PHYADDR *psDevPAddr)
1983{
1984 PVRSRV_DEVICE_NODE *psDeviceNode;
1985
1986 PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
1987
1988 PVR_ASSERT (psMemInfo && psDevPAddr)
1989
1990
1991 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1992
1993 psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
1994
1995 *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
1996 sDevVPageAddr);
1997}
1998
1999
2000MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
2001{
2002 BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
2003
2004 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
2005
2006 return pBMHeap->pBMContext->psMMUContext;
2007}
2008
2009MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
2010{
2011 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
2012
2013 PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
2014
2015 return pBMContext->psMMUContext;
2016}
2017
2018IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
2019{
2020 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
2021
2022 return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
2023}
2024
2025
2026PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
2027{
2028 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
2029
2030 return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
2031}
2032
2033
2034IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
2035{
2036 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
2037
2038 return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
2039}
2040
diff --git a/drivers/gpu/pvr/buffer_manager.h b/drivers/gpu/pvr/buffer_manager.h
new file mode 100644
index 00000000000..1467cd3939f
--- /dev/null
+++ b/drivers/gpu/pvr/buffer_manager.h
@@ -0,0 +1,210 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _BUFFER_MANAGER_H_
28#define _BUFFER_MANAGER_H_
29
30#include "img_types.h"
31#include "ra.h"
32#include "perproc.h"
33
34#if defined(__cplusplus)
35extern "C"{
36#endif
37
38typedef struct _BM_HEAP_ BM_HEAP;
39
40struct _BM_MAPPING_
41{
42 enum
43 {
44 hm_wrapped = 1,
45 hm_wrapped_scatter,
46 hm_wrapped_virtaddr,
47 hm_wrapped_scatter_virtaddr,
48 hm_env,
49 hm_contiguous
50 } eCpuMemoryOrigin;
51
52 BM_HEAP *pBMHeap;
53 RA_ARENA *pArena;
54
55 IMG_CPU_VIRTADDR CpuVAddr;
56 IMG_CPU_PHYADDR CpuPAddr;
57 IMG_DEV_VIRTADDR DevVAddr;
58 IMG_SYS_PHYADDR *psSysAddr;
59 IMG_SIZE_T uSize;
60 IMG_HANDLE hOSMemHandle;
61 IMG_UINT32 ui32Flags;
62};
63
64typedef struct _BM_BUF_
65{
66 IMG_CPU_VIRTADDR *CpuVAddr;
67 IMG_VOID *hOSMemHandle;
68 IMG_CPU_PHYADDR CpuPAddr;
69 IMG_DEV_VIRTADDR DevVAddr;
70
71 BM_MAPPING *pMapping;
72 IMG_UINT32 ui32RefCount;
73 IMG_UINT32 ui32ExportCount;
74} BM_BUF;
75
76struct _BM_HEAP_
77{
78 IMG_UINT32 ui32Attribs;
79 BM_CONTEXT *pBMContext;
80 RA_ARENA *pImportArena;
81 RA_ARENA *pLocalDevMemArena;
82 RA_ARENA *pVMArena;
83 DEV_ARENA_DESCRIPTOR sDevArena;
84 MMU_HEAP *pMMUHeap;
85 PDUMP_MMU_ATTRIB *psMMUAttrib;
86
87 struct _BM_HEAP_ *psNext;
88 struct _BM_HEAP_ **ppsThis;
89};
90
91struct _BM_CONTEXT_
92{
93 MMU_CONTEXT *psMMUContext;
94
95
96 BM_HEAP *psBMHeap;
97
98
99 BM_HEAP *psBMSharedHeap;
100
101 PVRSRV_DEVICE_NODE *psDeviceNode;
102
103
104 HASH_TABLE *pBufferHash;
105
106
107 IMG_HANDLE hResItem;
108
109 IMG_UINT32 ui32RefCount;
110
111
112
113 struct _BM_CONTEXT_ *psNext;
114 struct _BM_CONTEXT_ **ppsThis;
115};
116
117
118
119typedef IMG_VOID *BM_HANDLE;
120
121#define BP_POOL_MASK 0x7
122
123#define BP_CONTIGUOUS (1 << 3)
124#define BP_PARAMBUFFER (1 << 4)
125
126#define BM_MAX_DEVMEM_ARENAS 2
127
128IMG_HANDLE
129BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
130 IMG_DEV_PHYADDR *psPDDevPAddr,
131 PVRSRV_PER_PROCESS_DATA *psPerProc,
132 IMG_BOOL *pbCreated);
133
134
135PVRSRV_ERROR
136BM_DestroyContext (IMG_HANDLE hBMContext,
137 IMG_BOOL *pbCreated);
138
139
140IMG_HANDLE
141BM_CreateHeap (IMG_HANDLE hBMContext,
142 DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo);
143
144IMG_VOID
145BM_DestroyHeap (IMG_HANDLE hDevMemHeap);
146
147
148IMG_BOOL
149BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode);
150
151IMG_BOOL
152BM_Alloc (IMG_HANDLE hDevMemHeap,
153 IMG_DEV_VIRTADDR *psDevVAddr,
154 IMG_SIZE_T uSize,
155 IMG_UINT32 *pui32Flags,
156 IMG_UINT32 uDevVAddrAlignment,
157 BM_HANDLE *phBuf);
158
159IMG_BOOL
160BM_Wrap ( IMG_HANDLE hDevMemHeap,
161 IMG_SIZE_T ui32Size,
162 IMG_SIZE_T ui32Offset,
163 IMG_BOOL bPhysContig,
164 IMG_SYS_PHYADDR *psSysAddr,
165 IMG_VOID *pvCPUVAddr,
166 IMG_UINT32 *pui32Flags,
167 BM_HANDLE *phBuf);
168
169IMG_VOID
170BM_Free (BM_HANDLE hBuf,
171 IMG_UINT32 ui32Flags);
172
173
174IMG_CPU_VIRTADDR
175BM_HandleToCpuVaddr (BM_HANDLE hBuf);
176
177IMG_DEV_VIRTADDR
178BM_HandleToDevVaddr (BM_HANDLE hBuf);
179
180IMG_SYS_PHYADDR
181BM_HandleToSysPaddr (BM_HANDLE hBuf);
182
183IMG_HANDLE
184BM_HandleToOSMemHandle (BM_HANDLE hBuf);
185
186IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
187 IMG_DEV_VIRTADDR sDevVPageAddr,
188 IMG_DEV_PHYADDR *psDevPAddr);
189
190MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap);
191
192MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext);
193
194IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap);
195
196PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext);
197
198
199IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
200
201IMG_VOID BM_Export(BM_HANDLE hBuf);
202
203IMG_VOID BM_FreeExport(BM_HANDLE hBuf, IMG_UINT32 ui32Flags);
204
205#if defined(__cplusplus)
206}
207#endif
208
209#endif
210
diff --git a/drivers/gpu/pvr/device.h b/drivers/gpu/pvr/device.h
new file mode 100644
index 00000000000..2488aa9de36
--- /dev/null
+++ b/drivers/gpu/pvr/device.h
@@ -0,0 +1,316 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __DEVICE_H__
28#define __DEVICE_H__
29
30#if defined(__cplusplus)
31extern "C" {
32#endif
33
34#include "ra.h"
35#include "resman.h"
36
37typedef struct _BM_CONTEXT_ BM_CONTEXT;
38
39typedef struct _MMU_HEAP_ MMU_HEAP;
40typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
41
42#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0))
43#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1))
44#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2))
45#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3))
46
47typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE;
48#define DEVICE_MEMORY_HEAP_PERCONTEXT 0
49#define DEVICE_MEMORY_HEAP_KERNEL 1
50#define DEVICE_MEMORY_HEAP_SHARED 2
51#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED 3
52
53#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY 1
54#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV 2
55
56typedef struct _DEVICE_MEMORY_HEAP_INFO_
57{
58
59 IMG_UINT32 ui32HeapID;
60
61
62 IMG_CHAR *pszName;
63
64
65 IMG_CHAR *pszBSName;
66
67
68 IMG_DEV_VIRTADDR sDevVAddrBase;
69
70
71 IMG_UINT32 ui32HeapSize;
72
73
74 IMG_UINT32 ui32Attribs;
75
76
77 DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
78
79
80 IMG_HANDLE hDevMemHeap;
81
82
83 RA_ARENA *psLocalDevMemArena;
84
85
86 IMG_UINT32 ui32DataPageSize;
87
88 IMG_UINT32 ui32XTileStride;
89
90} DEVICE_MEMORY_HEAP_INFO;
91
92typedef struct _DEVICE_MEMORY_INFO_
93{
94
95 IMG_UINT32 ui32AddressSpaceSizeLog2;
96
97
98
99
100 IMG_UINT32 ui32Flags;
101
102
103 IMG_UINT32 ui32HeapCount;
104
105
106 IMG_UINT32 ui32SyncHeapID;
107
108
109 IMG_UINT32 ui32MappingHeapID;
110
111
112 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
113
114
115 BM_CONTEXT *pBMKernelContext;
116
117
118 BM_CONTEXT *pBMContext;
119
120} DEVICE_MEMORY_INFO;
121
122
123typedef struct DEV_ARENA_DESCRIPTOR_TAG
124{
125 IMG_UINT32 ui32HeapID;
126
127 IMG_CHAR *pszName;
128
129 IMG_DEV_VIRTADDR BaseDevVAddr;
130
131 IMG_UINT32 ui32Size;
132
133 DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
134
135
136 IMG_UINT32 ui32DataPageSize;
137
138 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo;
139
140} DEV_ARENA_DESCRIPTOR;
141
142
143typedef struct _PDUMP_MMU_ATTRIB_
144{
145 PVRSRV_DEVICE_IDENTIFIER sDevId;
146
147 IMG_CHAR *pszPDRegRegion;
148
149
150 IMG_UINT32 ui32DataPageMask;
151
152
153 IMG_UINT32 ui32PTEValid;
154 IMG_UINT32 ui32PTSize;
155 IMG_UINT32 ui32PTEAlignShift;
156
157
158 IMG_UINT32 ui32PDEMask;
159 IMG_UINT32 ui32PDEAlignShift;
160
161} PDUMP_MMU_ATTRIB;
162
163typedef struct _SYS_DATA_TAG_ *PSYS_DATA;
164
165typedef struct _PVRSRV_DEVICE_NODE_
166{
167 PVRSRV_DEVICE_IDENTIFIER sDevId;
168 IMG_UINT32 ui32RefCount;
169
170
171
172
173 PVRSRV_ERROR (*pfnInitDevice) (IMG_VOID*);
174
175 PVRSRV_ERROR (*pfnDeInitDevice) (IMG_VOID*);
176
177
178 PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
179
180
181 PVRSRV_ERROR (*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*);
182 IMG_VOID (*pfnMMUFinalise)(MMU_CONTEXT*);
183 IMG_VOID (*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*);
184 MMU_HEAP* (*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**,PDUMP_MMU_ATTRIB **ppsMMUAttrib);
185 IMG_VOID (*pfnMMUDelete)(MMU_HEAP*);
186 IMG_BOOL (*pfnMMUAlloc)(MMU_HEAP*pMMU,
187 IMG_SIZE_T uSize,
188 IMG_SIZE_T *pActualSize,
189 IMG_UINT32 uFlags,
190 IMG_UINT32 uDevVAddrAlignment,
191 IMG_DEV_VIRTADDR *pDevVAddr);
192 IMG_VOID (*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32);
193 IMG_VOID (*pfnMMUEnable)(MMU_HEAP*);
194 IMG_VOID (*pfnMMUDisable)(MMU_HEAP*);
195 IMG_VOID (*pfnMMUMapPages)(MMU_HEAP *pMMU,
196 IMG_DEV_VIRTADDR devVAddr,
197 IMG_SYS_PHYADDR SysPAddr,
198 IMG_SIZE_T uSize,
199 IMG_UINT32 ui32MemFlags,
200 IMG_HANDLE hUniqueTag);
201 IMG_VOID (*pfnMMUMapShadow)(MMU_HEAP *pMMU,
202 IMG_DEV_VIRTADDR MapBaseDevVAddr,
203 IMG_SIZE_T uSize,
204 IMG_CPU_VIRTADDR CpuVAddr,
205 IMG_HANDLE hOSMemHandle,
206 IMG_DEV_VIRTADDR *pDevVAddr,
207 IMG_UINT32 ui32MemFlags,
208 IMG_HANDLE hUniqueTag);
209 IMG_VOID (*pfnMMUUnmapPages)(MMU_HEAP *pMMU,
210 IMG_DEV_VIRTADDR dev_vaddr,
211 IMG_UINT32 ui32PageCount,
212 IMG_HANDLE hUniqueTag);
213
214 IMG_VOID (*pfnMMUMapScatter)(MMU_HEAP *pMMU,
215 IMG_DEV_VIRTADDR DevVAddr,
216 IMG_SYS_PHYADDR *psSysAddr,
217 IMG_SIZE_T uSize,
218 IMG_UINT32 ui32MemFlags,
219 IMG_HANDLE hUniqueTag);
220
221 IMG_DEV_PHYADDR (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
222 IMG_DEV_PHYADDR (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext);
223
224
225 PVRSRV_ERROR (*pfnAllocMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
226 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
227 IMG_UINT32 ui32TilingStride,
228 IMG_UINT32 *pui32RangeIndex);
229 PVRSRV_ERROR (*pfnFreeMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
230 IMG_UINT32 ui32RangeIndex);
231
232
233 IMG_BOOL (*pfnDeviceISR)(IMG_VOID*);
234
235 IMG_VOID *pvISRData;
236
237 IMG_UINT32 ui32SOCInterruptBit;
238
239 IMG_VOID (*pfnDeviceMISR)(IMG_VOID*);
240
241
242 IMG_VOID (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
243
244 IMG_BOOL bReProcessDeviceCommandComplete;
245
246
247 DEVICE_MEMORY_INFO sDevMemoryInfo;
248
249
250 IMG_VOID *pvDevice;
251 IMG_UINT32 ui32pvDeviceSize;
252
253
254 PRESMAN_CONTEXT hResManContext;
255
256
257 PSYS_DATA psSysData;
258
259
260 RA_ARENA *psLocalDevMemArena;
261
262 IMG_UINT32 ui32Flags;
263
264 struct _PVRSRV_DEVICE_NODE_ *psNext;
265 struct _PVRSRV_DEVICE_NODE_ **ppsThis;
266
267#if defined(PDUMP)
268
269 PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
270
271 IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
272#endif
273} PVRSRV_DEVICE_NODE;
274
275PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
276 PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
277 IMG_UINT32 ui32SOCInterruptBit,
278 IMG_UINT32 *pui32DeviceIndex );
279
280PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex);
281PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful);
282
283PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
284
285PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex);
286
287#if !defined(USE_CODE)
288
289IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr,
290 IMG_UINT32 ui32Value,
291 IMG_UINT32 ui32Mask,
292 IMG_UINT32 ui32Waitus,
293 IMG_UINT32 ui32Tries);
294
295#endif
296
297
298#if defined (USING_ISR_INTERRUPTS)
299PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value,
300 IMG_UINT32 ui32Mask,
301 IMG_UINT32 ui32Waitus,
302 IMG_UINT32 ui32Tries);
303#endif
304
305PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData);
306IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData);
307IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode);
308IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData);
309IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData);
310
311#if defined(__cplusplus)
312}
313#endif
314
315#endif
316
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c
new file mode 100644
index 00000000000..869253b2ecb
--- /dev/null
+++ b/drivers/gpu/pvr/deviceclass.c
@@ -0,0 +1,2012 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "buffer_manager.h"
29#include "kernelbuffer.h"
30#include "kerneldisplay.h"
31#include "pvr_bridge_km.h"
32#include "pdump_km.h"
33#include "deviceid.h"
34
35#include "lists.h"
36
37PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
38PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
39
40#if defined(SUPPORT_MISR_IN_THREAD)
41void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
42#endif
43
44#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
45IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
46 IMG_BOOL bScheduleMISR);
47#endif
48typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
49
50typedef struct PVRSRV_DC_BUFFER_TAG
51{
52
53 PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
54
55 struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
56 struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
57} PVRSRV_DC_BUFFER;
58
59typedef struct PVRSRV_DC_SWAPCHAIN_TAG
60{
61 IMG_HANDLE hExtSwapChain;
62 IMG_UINT32 ui32SwapChainID;
63 IMG_UINT32 ui32RefCount;
64 IMG_UINT32 ui32Flags;
65 PVRSRV_QUEUE_INFO *psQueue;
66 PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
67 IMG_UINT32 ui32BufferCount;
68 PVRSRV_DC_BUFFER *psLastFlipBuffer;
69 IMG_UINT32 ui32MinSwapInterval;
70 IMG_UINT32 ui32MaxSwapInterval;
71 struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
72 struct PVRSRV_DC_SWAPCHAIN_TAG *psNext;
73} PVRSRV_DC_SWAPCHAIN;
74
75
76typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
77{
78 struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
79 IMG_HANDLE hResItem;
80} PVRSRV_DC_SWAPCHAIN_REF;
81
82
83typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG
84{
85 IMG_UINT32 ui32RefCount;
86 IMG_UINT32 ui32DeviceID;
87 IMG_HANDLE hExtDevice;
88 PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable;
89 IMG_HANDLE hDevMemContext;
90 PVRSRV_DC_BUFFER sSystemBuffer;
91 struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared;
92} PVRSRV_DISPLAYCLASS_INFO;
93
94
95typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
96{
97 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
98 PRESMAN_ITEM hResItem;
99} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
100
101
102typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
103
104typedef struct PVRSRV_BC_BUFFER_TAG
105{
106
107 PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
108
109 struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
110} PVRSRV_BC_BUFFER;
111
112
113typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
114{
115 IMG_UINT32 ui32RefCount;
116 IMG_UINT32 ui32DeviceID;
117 IMG_HANDLE hExtDevice;
118 PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable;
119 IMG_HANDLE hDevMemContext;
120
121 IMG_UINT32 ui32BufferCount;
122 PVRSRV_BC_BUFFER *psBuffer;
123
124} PVRSRV_BUFFERCLASS_INFO;
125
126
127typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
128{
129 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
130 IMG_HANDLE hResItem;
131} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
132
133
134static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
135{
136 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
137
138 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
139
140 return psDCPerContextInfo->psDCInfo;
141}
142
143
144static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
145{
146 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
147
148 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
149
150 return psBCPerContextInfo->psBCInfo;
151}
152
153static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
154{
155 IMG_UINT *pui32DevCount;
156 IMG_UINT32 **ppui32DevID;
157 PVRSRV_DEVICE_CLASS peDeviceClass;
158
159 pui32DevCount = va_arg(va, IMG_UINT*);
160 ppui32DevID = va_arg(va, IMG_UINT32**);
161 peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
162
163 if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
164 && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
165 {
166 (*pui32DevCount)++;
167 if(*ppui32DevID)
168 {
169 *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
170 }
171 }
172}
173
174
175IMG_EXPORT
176PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass,
177 IMG_UINT32 *pui32DevCount,
178 IMG_UINT32 *pui32DevID )
179{
180
181 IMG_UINT ui32DevCount = 0;
182 SYS_DATA *psSysData;
183
184 SysAcquireData(&psSysData);
185
186
187 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
188 &PVRSRVEnumerateDCKM_ForEachVaCb,
189 &ui32DevCount,
190 &pui32DevID,
191 DeviceClass);
192
193 if(pui32DevCount)
194 {
195 *pui32DevCount = ui32DevCount;
196 }
197 else if(pui32DevID == IMG_NULL)
198 {
199 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters"));
200 return (PVRSRV_ERROR_INVALID_PARAMS);
201 }
202
203 return PVRSRV_OK;
204}
205
206
207static
208PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
209 IMG_UINT32 *pui32DeviceID)
210{
211 PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL;
212 PVRSRV_DEVICE_NODE *psDeviceNode;
213 SYS_DATA *psSysData;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 SysAcquireData(&psSysData);
231
232
233
234
235
236 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
237 sizeof(*psDCInfo),
238 (IMG_VOID **)&psDCInfo, IMG_NULL,
239 "Display Class Info") != PVRSRV_OK)
240 {
241 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
242 return PVRSRV_ERROR_OUT_OF_MEMORY;
243 }
244 OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
245
246
247 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
248 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
249 (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
250 "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
251 {
252 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
253 goto ErrorExit;
254 }
255 OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
256
257
258 *psDCInfo->psFuncTable = *psFuncTable;
259
260
261 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
262 sizeof(PVRSRV_DEVICE_NODE),
263 (IMG_VOID **)&psDeviceNode, IMG_NULL,
264 "Device Node") != PVRSRV_OK)
265 {
266 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
267 goto ErrorExit;
268 }
269 OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
270
271 psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo;
272 psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
273 psDeviceNode->ui32RefCount = 1;
274 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
275 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
276 psDeviceNode->psSysData = psSysData;
277
278
279 if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
280 {
281 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
282 goto ErrorExit;
283 }
284 psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
285 if (pui32DeviceID)
286 {
287 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
288 }
289
290
291 SysRegisterExternalDevice(psDeviceNode);
292
293
294 List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
295
296 return PVRSRV_OK;
297
298ErrorExit:
299
300 if(psDCInfo->psFuncTable)
301 {
302 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
303 psDCInfo->psFuncTable = IMG_NULL;
304 }
305
306 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
307
308
309 return PVRSRV_ERROR_OUT_OF_MEMORY;
310}
311
312static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
313{
314 SYS_DATA *psSysData;
315 PVRSRV_DEVICE_NODE *psDeviceNode;
316 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
317
318 SysAcquireData(&psSysData);
319
320
321 psDeviceNode = (PVRSRV_DEVICE_NODE*)
322 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
323 &MatchDeviceKM_AnyVaCb,
324 ui32DevIndex,
325 IMG_FALSE,
326 PVRSRV_DEVICE_CLASS_DISPLAY);
327 if (!psDeviceNode)
328 {
329
330 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
331 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
332 }
333
334
335 psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
336
337
338
339
340 if(psDCInfo->ui32RefCount == 0)
341 {
342
343
344 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
345
346
347 SysRemoveExternalDevice(psDeviceNode);
348
349
350
351
352 PVR_ASSERT(psDCInfo->ui32RefCount == 0);
353 (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
354 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
355 psDCInfo->psFuncTable = IMG_NULL;
356 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
357
358 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
359
360 }
361 else
362 {
363 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
364 return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
365 }
366
367 return PVRSRV_OK;
368}
369
370
371static
372PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
373 IMG_UINT32 *pui32DeviceID)
374{
375 PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
376 PVRSRV_DEVICE_NODE *psDeviceNode;
377 SYS_DATA *psSysData;
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392 SysAcquireData(&psSysData);
393
394
395
396
397
398 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
399 sizeof(*psBCInfo),
400 (IMG_VOID **)&psBCInfo, IMG_NULL,
401 "Buffer Class Info") != PVRSRV_OK)
402 {
403 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
404 return PVRSRV_ERROR_OUT_OF_MEMORY;
405 }
406 OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
407
408
409 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
410 sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
411 (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
412 "Function table for SRVKM->BUFFER") != PVRSRV_OK)
413 {
414 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
415 goto ErrorExit;
416 }
417 OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
418
419
420 *psBCInfo->psFuncTable = *psFuncTable;
421
422
423 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
424 sizeof(PVRSRV_DEVICE_NODE),
425 (IMG_VOID **)&psDeviceNode, IMG_NULL,
426 "Device Node") != PVRSRV_OK)
427 {
428 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
429 goto ErrorExit;
430 }
431 OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
432
433 psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo;
434 psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
435 psDeviceNode->ui32RefCount = 1;
436 psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
437 psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
438 psDeviceNode->psSysData = psSysData;
439
440
441 if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
442 {
443 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
444 goto ErrorExit;
445 }
446 psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
447 if (pui32DeviceID)
448 {
449 *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
450 }
451
452
453 List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
454
455 return PVRSRV_OK;
456
457ErrorExit:
458
459 if(psBCInfo->psFuncTable)
460 {
461 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
462 psBCInfo->psFuncTable = IMG_NULL;
463 }
464
465 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
466
467
468 return PVRSRV_ERROR_OUT_OF_MEMORY;
469}
470
471
472static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
473{
474 SYS_DATA *psSysData;
475 PVRSRV_DEVICE_NODE *psDevNode;
476 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
477
478 SysAcquireData(&psSysData);
479
480
481 psDevNode = (PVRSRV_DEVICE_NODE*)
482 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
483 &MatchDeviceKM_AnyVaCb,
484 ui32DevIndex,
485 IMG_FALSE,
486 PVRSRV_DEVICE_CLASS_BUFFER);
487
488 if (!psDevNode)
489 {
490 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
491 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
492 }
493
494
495
496 psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
497
498
499
500
501 if(psBCInfo->ui32RefCount == 0)
502 {
503
504
505 List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
506
507
508
509
510 (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
511
512
513 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
514 psBCInfo->psFuncTable = IMG_NULL;
515 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
516
517 (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
518
519 }
520 else
521 {
522 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
523 return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
524 }
525
526 return PVRSRV_OK;
527}
528
529
530
531IMG_EXPORT
532PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM,
533 IMG_BOOL bResManCallback)
534{
535 PVRSRV_ERROR eError;
536 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
537
538 PVR_UNREFERENCED_PARAMETER(bResManCallback);
539
540 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
541
542
543 eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem);
544
545 return eError;
546}
547
548
549static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
550 IMG_UINT32 ui32Param)
551{
552 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
553 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
554
555 PVR_UNREFERENCED_PARAMETER(ui32Param);
556
557 psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
558 psDCInfo = psDCPerContextInfo->psDCInfo;
559
560 psDCInfo->ui32RefCount--;
561 if(psDCInfo->ui32RefCount == 0)
562 {
563
564 psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
565
566 if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
567 {
568 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
569 }
570
571 psDCInfo->hDevMemContext = IMG_NULL;
572 psDCInfo->hExtDevice = IMG_NULL;
573 }
574
575 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
576
577
578 return PVRSRV_OK;
579}
580
581
582IMG_EXPORT
583PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
584 IMG_UINT32 ui32DeviceID,
585 IMG_HANDLE hDevCookie,
586 IMG_HANDLE *phDeviceKM)
587{
588 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
589 PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
590 PVRSRV_DEVICE_NODE *psDeviceNode;
591 SYS_DATA *psSysData;
592 PVRSRV_ERROR eError;
593
594 if(!phDeviceKM || !hDevCookie)
595 {
596 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
597 return PVRSRV_ERROR_INVALID_PARAMS;
598 }
599
600 SysAcquireData(&psSysData);
601
602
603 psDeviceNode = (PVRSRV_DEVICE_NODE*)
604 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
605 &MatchDeviceKM_AnyVaCb,
606 ui32DeviceID,
607 IMG_FALSE,
608 PVRSRV_DEVICE_CLASS_DISPLAY);
609 if (!psDeviceNode)
610 {
611 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
612 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
613 }
614 psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
615
616
617
618
619 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
620 sizeof(*psDCPerContextInfo),
621 (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
622 "Display Class per Context Info") != PVRSRV_OK)
623 {
624 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
625 return PVRSRV_ERROR_OUT_OF_MEMORY;
626 }
627 OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
628
629 if(psDCInfo->ui32RefCount++ == 0)
630 {
631
632 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
633
634
635 psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
636
637
638 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
639 (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
640 &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
641 if(eError != PVRSRV_OK)
642 {
643 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
644 psDCInfo->ui32RefCount--;
645 return eError;
646 }
647
648
649 eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
650 &psDCInfo->hExtDevice,
651 (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
652 if(eError != PVRSRV_OK)
653 {
654 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
655 psDCInfo->ui32RefCount--;
656 PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
657 return eError;
658 }
659
660 psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
661 }
662
663 psDCPerContextInfo->psDCInfo = psDCInfo;
664 psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
665 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
666 psDCPerContextInfo,
667 0,
668 &CloseDCDeviceCallBack);
669
670
671 *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
672
673 return PVRSRV_OK;
674}
675
676
677IMG_EXPORT
678PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
679 IMG_UINT32 *pui32Count,
680 DISPLAY_FORMAT *psFormat)
681{
682 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
683
684 if(!hDeviceKM || !pui32Count || !psFormat)
685 {
686 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
687 return PVRSRV_ERROR_INVALID_PARAMS;
688 }
689
690 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
691
692
693 return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
694}
695
696
697
698IMG_EXPORT
699PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM,
700 DISPLAY_FORMAT *psFormat,
701 IMG_UINT32 *pui32Count,
702 DISPLAY_DIMS *psDim)
703{
704 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
705
706 if(!hDeviceKM || !pui32Count || !psFormat)
707 {
708 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
709 return PVRSRV_ERROR_INVALID_PARAMS;
710 }
711
712 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
713
714
715 return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
716}
717
718
719IMG_EXPORT
720PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
721 IMG_HANDLE *phBuffer)
722{
723 PVRSRV_ERROR eError;
724 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
725 IMG_HANDLE hExtBuffer;
726
727 if(!hDeviceKM || !phBuffer)
728 {
729 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
730 return PVRSRV_ERROR_INVALID_PARAMS;
731 }
732
733 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
734
735
736 eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer);
737 if(eError != PVRSRV_OK)
738 {
739 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
740 return eError;
741 }
742
743
744 psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
745 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
746 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
747 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
748
749 psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
750
751
752 *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
753
754 return PVRSRV_OK;
755}
756
757
758IMG_EXPORT
759PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM,
760 DISPLAY_INFO *psDisplayInfo)
761{
762 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
763 PVRSRV_ERROR eError;
764
765 if(!hDeviceKM || !psDisplayInfo)
766 {
767 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters"));
768 return PVRSRV_ERROR_INVALID_PARAMS;
769 }
770
771 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
772
773
774 eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo);
775 if (eError != PVRSRV_OK)
776 {
777 return eError;
778 }
779
780 if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
781 {
782 psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
783 }
784
785 return PVRSRV_OK;
786}
787
788
789IMG_EXPORT
790PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef)
791{
792 PVRSRV_ERROR eError;
793 PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
794
795 if(!hSwapChainRef)
796 {
797 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
798 return PVRSRV_ERROR_INVALID_PARAMS;
799 }
800
801 psSwapChainRef = hSwapChainRef;
802
803 eError = ResManFreeResByPtr(psSwapChainRef->hResItem);
804
805 return eError;
806}
807
808
809static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
810{
811 PVRSRV_ERROR eError;
812 PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
813 IMG_UINT32 i;
814
815
816
817 if( psDCInfo->psDCSwapChainShared )
818 {
819 if( psDCInfo->psDCSwapChainShared == psSwapChain )
820 {
821 psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
822 }
823 else
824 {
825 PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
826 psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
827 while( psCurrentSwapChain->psNext )
828 {
829 if( psCurrentSwapChain->psNext != psSwapChain )
830 {
831 psCurrentSwapChain = psCurrentSwapChain->psNext;
832 continue;
833 }
834 psCurrentSwapChain->psNext = psSwapChain->psNext;
835 break;
836 }
837 }
838 }
839
840
841 PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
842
843
844 eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
845 psSwapChain->hExtSwapChain);
846
847 if (eError != PVRSRV_OK)
848 {
849 PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
850 return eError;
851 }
852
853
854 for(i=0; i<psSwapChain->ui32BufferCount; i++)
855 {
856 if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
857 {
858 if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
859 {
860 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
861 }
862 }
863 }
864
865 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
866
867
868 return eError;
869}
870
871
872static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
873{
874 PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
875 PVRSRV_ERROR eError = PVRSRV_OK;
876
877 PVR_UNREFERENCED_PARAMETER(ui32Param);
878
879 if(--psSwapChainRef->psSwapChain->ui32RefCount == 0)
880 {
881 eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
882 }
883
884 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
885 return eError;
886}
887
888static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
889 IMG_UINT32 ui32SwapChainID)
890{
891 PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
892
893 for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
894 psCurrentSwapChain;
895 psCurrentSwapChain = psCurrentSwapChain->psNext)
896 {
897 if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
898 return psCurrentSwapChain;
899 }
900 return IMG_NULL;
901}
902
903static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
904 PVRSRV_DC_SWAPCHAIN *psSwapChain,
905 PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef)
906{
907 PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
908
909
910 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
911 sizeof(PVRSRV_DC_SWAPCHAIN_REF),
912 (IMG_VOID **)&psSwapChainRef, IMG_NULL,
913 "Display Class Swapchain Reference") != PVRSRV_OK)
914 {
915 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
916 return PVRSRV_ERROR_OUT_OF_MEMORY;
917 }
918 OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
919
920
921 psSwapChain->ui32RefCount++;
922
923
924 psSwapChainRef->psSwapChain = psSwapChain;
925 psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
926 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
927 psSwapChainRef,
928 0,
929 &DestroyDCSwapChainRefCallBack);
930 *ppsSwapChainRef = psSwapChainRef;
931
932 return PVRSRV_OK;
933}
934
935
936IMG_EXPORT
937PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
938 IMG_HANDLE hDeviceKM,
939 IMG_UINT32 ui32Flags,
940 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
941 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
942 IMG_UINT32 ui32BufferCount,
943 IMG_UINT32 ui32OEMFlags,
944 IMG_HANDLE *phSwapChainRef,
945 IMG_UINT32 *pui32SwapChainID)
946{
947 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
948 PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
949 PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
950 PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
951 PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
952 PVRSRV_ERROR eError;
953 IMG_UINT32 i;
954 DISPLAY_INFO sDisplayInfo;
955
956
957 if(!hDeviceKM
958 || !psDstSurfAttrib
959 || !psSrcSurfAttrib
960 || !phSwapChainRef
961 || !pui32SwapChainID)
962 {
963 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters"));
964 return PVRSRV_ERROR_INVALID_PARAMS;
965 }
966
967 if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
968 {
969 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers"));
970 return PVRSRV_ERROR_TOOMANYBUFFERS;
971 }
972
973 if (ui32BufferCount < 2)
974 {
975 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers"));
976 return PVRSRV_ERROR_TOO_FEW_BUFFERS;
977 }
978
979 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
980
981 if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
982 {
983
984 psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
985 if( psSwapChain )
986 {
987
988 eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
989 psSwapChain,
990 &psSwapChainRef);
991 if( eError != PVRSRV_OK )
992 {
993 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
994 return eError;
995 }
996
997 *phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
998 return PVRSRV_OK;
999 }
1000 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
1001 return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
1002 }
1003
1004
1005 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
1006 sizeof(PVRSRV_DC_SWAPCHAIN),
1007 (IMG_VOID **)&psSwapChain, IMG_NULL,
1008 "Display Class Swapchain") != PVRSRV_OK)
1009 {
1010 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
1011 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1012 goto ErrorExit;
1013 }
1014 OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
1015
1016
1017 eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
1018 if(eError != PVRSRV_OK)
1019 {
1020 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
1021 goto ErrorExit;
1022 }
1023
1024
1025 psSwapChain->psQueue = psQueue;
1026
1027
1028 for(i=0; i<ui32BufferCount; i++)
1029 {
1030 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
1031 psDCInfo->hDevMemContext,
1032 &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1033 if(eError != PVRSRV_OK)
1034 {
1035 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
1036 goto ErrorExit;
1037 }
1038
1039 psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
1040
1041
1042 psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
1043 psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
1044 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
1045
1046
1047 psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
1048 psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
1049
1050
1051 apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
1052 }
1053
1054 psSwapChain->ui32BufferCount = ui32BufferCount;
1055 psSwapChain->psDCInfo = psDCInfo;
1056
1057#if defined(PDUMP)
1058 PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)",
1059 *pui32SwapChainID,
1060 ui32BufferCount);
1061 PDUMPCOMMENT(" Src surface dimensions == %u x %u",
1062 psSrcSurfAttrib->sDims.ui32Width,
1063 psSrcSurfAttrib->sDims.ui32Height);
1064 PDUMPCOMMENT(" Dst surface dimensions == %u x %u",
1065 psDstSurfAttrib->sDims.ui32Width,
1066 psDstSurfAttrib->sDims.ui32Height);
1067#endif
1068
1069 eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
1070 if (eError != PVRSRV_OK)
1071 {
1072 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
1073 return eError;
1074 }
1075
1076 psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval;
1077 psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval;
1078
1079
1080 eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
1081 ui32Flags,
1082 psDstSurfAttrib,
1083 psSrcSurfAttrib,
1084 ui32BufferCount,
1085 apsSyncData,
1086 ui32OEMFlags,
1087 &psSwapChain->hExtSwapChain,
1088 &psSwapChain->ui32SwapChainID);
1089 if(eError != PVRSRV_OK)
1090 {
1091 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
1092 PDUMPCOMMENT("Swapchain allocation failed.");
1093 goto ErrorExit;
1094 }
1095
1096
1097 eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
1098 psSwapChain,
1099 &psSwapChainRef);
1100 if( eError != PVRSRV_OK )
1101 {
1102 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
1103 PDUMPCOMMENT("Swapchain allocation failed.");
1104 goto ErrorExit;
1105 }
1106
1107 psSwapChain->ui32RefCount = 1;
1108 psSwapChain->ui32Flags = ui32Flags;
1109
1110
1111 if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
1112 {
1113 if(! psDCInfo->psDCSwapChainShared )
1114 {
1115 psDCInfo->psDCSwapChainShared = psSwapChain;
1116 }
1117 else
1118 {
1119 PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
1120 psDCInfo->psDCSwapChainShared = psSwapChain;
1121 psSwapChain->psNext = psOldHead;
1122 }
1123 }
1124
1125
1126 *pui32SwapChainID = psSwapChain->ui32SwapChainID;
1127
1128
1129 *phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
1130
1131 return eError;
1132
1133ErrorExit:
1134
1135 for(i=0; i<ui32BufferCount; i++)
1136 {
1137 if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1138 {
1139 if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1140 {
1141 PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1142 }
1143 }
1144 }
1145
1146 if(psQueue)
1147 {
1148 PVRSRVDestroyCommandQueueKM(psQueue);
1149 }
1150
1151 if(psSwapChain)
1152 {
1153 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
1154
1155 }
1156
1157 return eError;
1158}
1159
1160
1161
1162
1163IMG_EXPORT
1164PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
1165 IMG_HANDLE hSwapChainRef,
1166 IMG_RECT *psRect)
1167{
1168 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1169 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1170
1171 if(!hDeviceKM || !hSwapChainRef)
1172 {
1173 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
1174 return PVRSRV_ERROR_INVALID_PARAMS;
1175 }
1176
1177 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1178 psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1179
1180 return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
1181 psSwapChain->hExtSwapChain,
1182 psRect);
1183}
1184
1185
1186IMG_EXPORT
1187PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
1188 IMG_HANDLE hSwapChainRef,
1189 IMG_RECT *psRect)
1190{
1191 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1192 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1193
1194 if(!hDeviceKM || !hSwapChainRef)
1195 {
1196 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
1197 return PVRSRV_ERROR_INVALID_PARAMS;
1198 }
1199
1200 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1201 psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1202
1203 return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
1204 psSwapChain->hExtSwapChain,
1205 psRect);
1206}
1207
1208
1209IMG_EXPORT
1210PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
1211 IMG_HANDLE hSwapChainRef,
1212 IMG_UINT32 ui32CKColour)
1213{
1214 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1215 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1216
1217 if(!hDeviceKM || !hSwapChainRef)
1218 {
1219 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
1220 return PVRSRV_ERROR_INVALID_PARAMS;
1221 }
1222
1223 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1224 psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1225
1226 return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
1227 psSwapChain->hExtSwapChain,
1228 ui32CKColour);
1229}
1230
1231
1232IMG_EXPORT
1233PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
1234 IMG_HANDLE hSwapChainRef,
1235 IMG_UINT32 ui32CKColour)
1236{
1237 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1238 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1239
1240 if(!hDeviceKM || !hSwapChainRef)
1241 {
1242 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
1243 return PVRSRV_ERROR_INVALID_PARAMS;
1244 }
1245
1246 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1247 psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1248
1249 return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
1250 psSwapChain->hExtSwapChain,
1251 ui32CKColour);
1252}
1253
1254
1255IMG_EXPORT
1256PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
1257 IMG_HANDLE hSwapChainRef,
1258 IMG_UINT32 *pui32BufferCount,
1259 IMG_HANDLE *phBuffer)
1260{
1261 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1262 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1263 IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
1264 PVRSRV_ERROR eError;
1265 IMG_UINT32 i;
1266
1267 if(!hDeviceKM || !hSwapChainRef || !phBuffer)
1268 {
1269 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
1270 return PVRSRV_ERROR_INVALID_PARAMS;
1271 }
1272
1273 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1274 psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1275
1276
1277 eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
1278 psSwapChain->hExtSwapChain,
1279 pui32BufferCount,
1280 ahExtBuffer);
1281
1282 PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1283
1284
1285
1286
1287 for(i=0; i<*pui32BufferCount; i++)
1288 {
1289 psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
1290 phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
1291 }
1292
1293 return eError;
1294}
1295
1296
1297IMG_EXPORT
1298PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
1299 IMG_HANDLE hBuffer,
1300 IMG_UINT32 ui32SwapInterval,
1301 IMG_HANDLE hPrivateTag,
1302 IMG_UINT32 ui32ClipRectCount,
1303 IMG_RECT *psClipRect)
1304{
1305 PVRSRV_ERROR eError;
1306 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1307 PVRSRV_DC_BUFFER *psBuffer;
1308 PVRSRV_QUEUE_INFO *psQueue;
1309 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1310 IMG_UINT32 i;
1311 IMG_BOOL bAddReferenceToLast = IMG_TRUE;
1312 IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
1313 IMG_UINT32 ui32NumSrcSyncs = 1;
1314 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1315 PVRSRV_COMMAND *psCommand;
1316
1317 if(!hDeviceKM || !hBuffer || !psClipRect)
1318 {
1319 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
1320 return PVRSRV_ERROR_INVALID_PARAMS;
1321 }
1322
1323#if defined(SUPPORT_LMA)
1324 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
1325 if(eError != PVRSRV_OK)
1326 {
1327 return eError;
1328 }
1329#endif
1330
1331 psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
1332 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1333
1334
1335 if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval ||
1336 ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval)
1337 {
1338 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u",
1339 ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval));
1340 return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
1341 }
1342
1343#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1344
1345 if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
1346 {
1347 psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
1348 psBuffer->psSwapChain->hExtSwapChain,
1349 psBuffer->sDeviceClassBuffer.hExtBuffer,
1350 hPrivateTag,
1351 &ui16SwapCommandID,
1352 &bAddReferenceToLast);
1353
1354 }
1355
1356#endif
1357
1358
1359 psQueue = psBuffer->psSwapChain->psQueue;
1360
1361
1362 apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1363
1364
1365
1366 if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer &&
1367 psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
1368 {
1369 apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1370
1371
1372
1373 ui32NumSrcSyncs++;
1374 }
1375
1376
1377 eError = PVRSRVInsertCommandKM (psQueue,
1378 &psCommand,
1379 psDCInfo->ui32DeviceID,
1380 ui16SwapCommandID,
1381 0,
1382 IMG_NULL,
1383 ui32NumSrcSyncs,
1384 apsSrcSync,
1385 sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount));
1386 if(eError != PVRSRV_OK)
1387 {
1388 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
1389 goto Exit;
1390 }
1391
1392
1393 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
1394
1395
1396 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1397
1398
1399 psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
1400
1401
1402 psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
1403
1404
1405 psFlipCmd->hPrivateTag = hPrivateTag;
1406
1407
1408 psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
1409
1410 psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND));
1411
1412 for(i=0; i<ui32ClipRectCount; i++)
1413 {
1414 psFlipCmd->psClipRect[i] = psClipRect[i];
1415 }
1416
1417
1418 psFlipCmd->ui32SwapInterval = ui32SwapInterval;
1419
1420
1421 eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
1422 if (eError != PVRSRV_OK)
1423 {
1424 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
1425 goto Exit;
1426 }
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
1438 {
1439 if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED)
1440 {
1441 goto ProcessedQueues;
1442 }
1443 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
1444 } END_LOOP_UNTIL_TIMEOUT();
1445
1446 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to process queues"));
1447
1448 eError = PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE;
1449 goto Exit;
1450
1451ProcessedQueues:
1452
1453 psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1454
1455Exit:
1456
1457 if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
1458 {
1459 eError = PVRSRV_ERROR_RETRY;
1460 }
1461
1462#if defined(SUPPORT_LMA)
1463 PVRSRVPowerUnlock(KERNEL_ID);
1464#endif
1465 return eError;
1466}
1467
1468
1469IMG_EXPORT
1470PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
1471 IMG_HANDLE hSwapChainRef)
1472{
1473 PVRSRV_ERROR eError;
1474 PVRSRV_QUEUE_INFO *psQueue;
1475 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1476 PVRSRV_DC_SWAPCHAIN *psSwapChain;
1477 PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
1478 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1479 IMG_UINT32 ui32NumSrcSyncs = 1;
1480 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1481 PVRSRV_COMMAND *psCommand;
1482 IMG_BOOL bAddReferenceToLast = IMG_TRUE;
1483 IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
1484
1485 if(!hDeviceKM || !hSwapChainRef)
1486 {
1487 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
1488 return PVRSRV_ERROR_INVALID_PARAMS;
1489 }
1490
1491#if defined(SUPPORT_LMA)
1492 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
1493 if(eError != PVRSRV_OK)
1494 {
1495 return eError;
1496 }
1497#endif
1498
1499 psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1500 psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
1501 psSwapChain = psSwapChainRef->psSwapChain;
1502
1503
1504 psQueue = psSwapChain->psQueue;
1505
1506#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1507
1508 if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
1509 {
1510 psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
1511 psSwapChain->hExtSwapChain,
1512 psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer,
1513 0,
1514 &ui16SwapCommandID,
1515 &bAddReferenceToLast);
1516
1517 }
1518
1519#endif
1520
1521
1522 apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
1523
1524
1525
1526 if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer)
1527 {
1528
1529 if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
1530 {
1531 apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1532
1533
1534
1535 ui32NumSrcSyncs++;
1536 }
1537 }
1538
1539
1540 eError = PVRSRVInsertCommandKM (psQueue,
1541 &psCommand,
1542 psDCInfo->ui32DeviceID,
1543 ui16SwapCommandID,
1544 0,
1545 IMG_NULL,
1546 ui32NumSrcSyncs,
1547 apsSrcSync,
1548 sizeof(DISPLAYCLASS_FLIP_COMMAND));
1549 if(eError != PVRSRV_OK)
1550 {
1551 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
1552 goto Exit;
1553 }
1554
1555
1556 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
1557
1558
1559 psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1560
1561
1562 psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
1563
1564
1565 psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
1566
1567
1568 psFlipCmd->hPrivateTag = IMG_NULL;
1569
1570
1571 psFlipCmd->ui32ClipRectCount = 0;
1572
1573 psFlipCmd->ui32SwapInterval = 1;
1574
1575
1576 eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
1577 if (eError != PVRSRV_OK)
1578 {
1579 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
1580 goto Exit;
1581 }
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
1592 {
1593 if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED)
1594 {
1595 goto ProcessedQueues;
1596 }
1597
1598 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
1599 } END_LOOP_UNTIL_TIMEOUT();
1600
1601 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues"));
1602 eError = PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE;
1603 goto Exit;
1604
1605ProcessedQueues:
1606
1607 psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1608
1609 eError = PVRSRV_OK;
1610
1611Exit:
1612
1613 if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
1614 {
1615 eError = PVRSRV_ERROR_RETRY;
1616 }
1617
1618#if defined(SUPPORT_LMA)
1619 PVRSRVPowerUnlock(KERNEL_ID);
1620#endif
1621 return eError;
1622}
1623
1624
1625static
1626PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler,
1627 IMG_VOID *pvISRHandlerData,
1628 IMG_UINT32 ui32ISRSourceMask,
1629 IMG_UINT32 ui32DeviceID)
1630{
1631 SYS_DATA *psSysData;
1632 PVRSRV_DEVICE_NODE *psDevNode;
1633
1634 PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
1635
1636 SysAcquireData(&psSysData);
1637
1638
1639 psDevNode = (PVRSRV_DEVICE_NODE*)
1640 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
1641 &MatchDeviceKM_AnyVaCb,
1642 ui32DeviceID,
1643 IMG_TRUE);
1644
1645 if (psDevNode == IMG_NULL)
1646 {
1647 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
1648 PVR_DBG_BREAK;
1649 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
1650 }
1651
1652
1653 psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
1654
1655
1656 psDevNode->pfnDeviceISR = pfnISRHandler;
1657
1658 return PVRSRV_OK;
1659}
1660
1661static
1662IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1663{
1664 PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1665 IMG_UINT32 ui32State;
1666 ui32State = va_arg(va, IMG_UINT32);
1667
1668 if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
1669 {
1670 psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
1671 if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice)
1672 {
1673 psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State);
1674 }
1675 }
1676}
1677
1678
1679IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
1680{
1681 SYS_DATA *psSysData;
1682
1683 SysAcquireData(&psSysData);
1684
1685 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1686 &PVRSRVSetDCState_ForEachVaCb,
1687 ui32State);
1688}
1689
1690
1691IMG_EXPORT
1692IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
1693{
1694 psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
1695 psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM;
1696 psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM;
1697 psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction;
1698 psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM;
1699 psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM;
1700#if defined(SUPPORT_MISR_IN_THREAD)
1701 psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR;
1702#else
1703 psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM;
1704#endif
1705 psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler;
1706 psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice;
1707#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1708 psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
1709#endif
1710
1711 return IMG_TRUE;
1712}
1713
1714
1715
1716IMG_EXPORT
1717PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM,
1718 IMG_BOOL bResManCallback)
1719{
1720 PVRSRV_ERROR eError;
1721 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1722
1723 PVR_UNREFERENCED_PARAMETER(bResManCallback);
1724
1725 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
1726
1727
1728 eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem);
1729
1730 return eError;
1731}
1732
1733
1734static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
1735 IMG_UINT32 ui32Param)
1736{
1737 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1738 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1739
1740 PVR_UNREFERENCED_PARAMETER(ui32Param);
1741
1742 psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
1743 psBCInfo = psBCPerContextInfo->psBCInfo;
1744
1745 psBCInfo->ui32RefCount--;
1746 if(psBCInfo->ui32RefCount == 0)
1747 {
1748 IMG_UINT32 i;
1749
1750
1751 psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice);
1752
1753
1754 for(i=0; i<psBCInfo->ui32BufferCount; i++)
1755 {
1756 if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1757 {
1758 if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1759 {
1760 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1761 }
1762 }
1763 }
1764
1765
1766 if(psBCInfo->psBuffer)
1767 {
1768 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
1769 psBCInfo->psBuffer = IMG_NULL;
1770 }
1771 }
1772
1773 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
1774
1775
1776 return PVRSRV_OK;
1777}
1778
1779
1780IMG_EXPORT
1781PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
1782 IMG_UINT32 ui32DeviceID,
1783 IMG_HANDLE hDevCookie,
1784 IMG_HANDLE *phDeviceKM)
1785{
1786 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1787 PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1788 PVRSRV_DEVICE_NODE *psDeviceNode;
1789 SYS_DATA *psSysData;
1790 IMG_UINT32 i;
1791 PVRSRV_ERROR eError;
1792
1793 if(!phDeviceKM || !hDevCookie)
1794 {
1795 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
1796 return PVRSRV_ERROR_INVALID_PARAMS;
1797 }
1798
1799 SysAcquireData(&psSysData);
1800
1801
1802 psDeviceNode = (PVRSRV_DEVICE_NODE*)
1803 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
1804 &MatchDeviceKM_AnyVaCb,
1805 ui32DeviceID,
1806 IMG_FALSE,
1807 PVRSRV_DEVICE_CLASS_BUFFER);
1808 if (!psDeviceNode)
1809 {
1810 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
1811 return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
1812 }
1813 psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
1814
1815
1816
1817
1818 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1819 sizeof(*psBCPerContextInfo),
1820 (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
1821 "Buffer Class per Context Info") != PVRSRV_OK)
1822 {
1823 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
1824 return PVRSRV_ERROR_OUT_OF_MEMORY;
1825 }
1826 OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
1827
1828 if(psBCInfo->ui32RefCount++ == 0)
1829 {
1830 BUFFER_INFO sBufferInfo;
1831
1832 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
1833
1834
1835 psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
1836
1837
1838 eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice);
1839 if(eError != PVRSRV_OK)
1840 {
1841 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
1842 return eError;
1843 }
1844
1845
1846 eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
1847 if(eError != PVRSRV_OK)
1848 {
1849 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
1850 return eError;
1851 }
1852
1853
1854 psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
1855
1856
1857
1858 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1859 sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
1860 (IMG_VOID **)&psBCInfo->psBuffer,
1861 IMG_NULL,
1862 "Array of Buffer Class Buffer");
1863 if(eError != PVRSRV_OK)
1864 {
1865 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
1866 return eError;
1867 }
1868 OSMemSet (psBCInfo->psBuffer,
1869 0,
1870 sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
1871
1872 for(i=0; i<psBCInfo->ui32BufferCount; i++)
1873 {
1874
1875 eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
1876 psBCInfo->hDevMemContext,
1877 &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1878 if(eError != PVRSRV_OK)
1879 {
1880 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
1881 goto ErrorExit;
1882 }
1883
1884 psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
1885
1886
1887
1888
1889 eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
1890 i,
1891 psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
1892 &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
1893 if(eError != PVRSRV_OK)
1894 {
1895 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
1896 goto ErrorExit;
1897 }
1898
1899
1900 psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
1901 psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
1902 psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
1903 }
1904 }
1905
1906 psBCPerContextInfo->psBCInfo = psBCInfo;
1907 psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
1908 RESMAN_TYPE_BUFFERCLASS_DEVICE,
1909 psBCPerContextInfo,
1910 0,
1911 &CloseBCDeviceCallBack);
1912
1913
1914 *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
1915
1916 return PVRSRV_OK;
1917
1918ErrorExit:
1919
1920
1921 for(i=0; i<psBCInfo->ui32BufferCount; i++)
1922 {
1923 if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1924 {
1925 if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1926 {
1927 PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1928 }
1929 }
1930 }
1931
1932
1933 if(psBCInfo->psBuffer)
1934 {
1935 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
1936 psBCInfo->psBuffer = IMG_NULL;
1937 }
1938
1939 return eError;
1940}
1941
1942
1943
1944
1945IMG_EXPORT
1946PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM,
1947 BUFFER_INFO *psBufferInfo)
1948{
1949 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1950 PVRSRV_ERROR eError;
1951
1952 if(!hDeviceKM || !psBufferInfo)
1953 {
1954 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters"));
1955 return PVRSRV_ERROR_INVALID_PARAMS;
1956 }
1957
1958 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1959
1960 eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo);
1961
1962 if(eError != PVRSRV_OK)
1963 {
1964 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info"));
1965 return eError;
1966 }
1967
1968 return PVRSRV_OK;
1969}
1970
1971
1972IMG_EXPORT
1973PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM,
1974 IMG_UINT32 ui32BufferIndex,
1975 IMG_HANDLE *phBuffer)
1976{
1977 PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1978
1979 if(!hDeviceKM || !phBuffer)
1980 {
1981 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters"));
1982 return PVRSRV_ERROR_INVALID_PARAMS;
1983 }
1984
1985 psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1986
1987 if(ui32BufferIndex < psBCInfo->ui32BufferCount)
1988 {
1989 *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex];
1990 }
1991 else
1992 {
1993 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount));
1994 return PVRSRV_ERROR_INVALID_PARAMS;
1995 }
1996
1997 return PVRSRV_OK;
1998}
1999
2000
2001IMG_EXPORT
2002IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
2003{
2004 psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
2005
2006 psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM;
2007 psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM;
2008 psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM;
2009
2010 return IMG_TRUE;
2011}
2012
diff --git a/drivers/gpu/pvr/deviceid.h b/drivers/gpu/pvr/deviceid.h
new file mode 100644
index 00000000000..b6fe92163ec
--- /dev/null
+++ b/drivers/gpu/pvr/deviceid.h
@@ -0,0 +1,36 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __DEVICEID_H__
28#define __DEVICEID_H__
29
30#include "services.h"
31#include "syscommon.h"
32
33PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
34PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
35
36#endif
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c
new file mode 100644
index 00000000000..f15ff9143eb
--- /dev/null
+++ b/drivers/gpu/pvr/devicemem.c
@@ -0,0 +1,1554 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "services_headers.h"
30#include "buffer_manager.h"
31#include "pdump_km.h"
32#include "pvr_bridge_km.h"
33
34static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
35 IMG_HANDLE hDevMemHeap,
36 IMG_UINT32 ui32Flags,
37 IMG_SIZE_T ui32Size,
38 IMG_SIZE_T ui32Alignment,
39 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
40
41typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
42{
43
44 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
45
46 PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo;
47} RESMAN_MAP_DEVICE_MEM_DATA;
48
49typedef struct _PVRSRV_DC_MAPINFO_
50{
51 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
52 PVRSRV_DEVICE_NODE *psDeviceNode;
53 IMG_UINT32 ui32RangeIndex;
54 IMG_UINT32 ui32TilingStride;
55} PVRSRV_DC_MAPINFO;
56
57
58IMG_EXPORT
59PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
60 PVRSRV_HEAP_INFO *psHeapInfo)
61{
62 PVRSRV_DEVICE_NODE *psDeviceNode;
63 IMG_UINT32 ui32HeapCount;
64 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
65 IMG_UINT32 i;
66
67 if (hDevCookie == IMG_NULL)
68 {
69 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"));
70 PVR_DBG_BREAK;
71 return PVRSRV_ERROR_INVALID_PARAMS;
72 }
73
74 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
75
76
77 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
78 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
79
80
81 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
82
83
84 for(i=0; i<ui32HeapCount; i++)
85 {
86
87 psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
88 psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
89 psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
90 psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
91 psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
92 }
93
94 for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
95 {
96 OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
97 psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
98 }
99
100 return PVRSRV_OK;
101}
102
103IMG_EXPORT
104PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
105 PVRSRV_PER_PROCESS_DATA *psPerProc,
106 IMG_HANDLE *phDevMemContext,
107 IMG_UINT32 *pui32ClientHeapCount,
108 PVRSRV_HEAP_INFO *psHeapInfo,
109 IMG_BOOL *pbCreated,
110 IMG_BOOL *pbShared)
111{
112 PVRSRV_DEVICE_NODE *psDeviceNode;
113 IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
114 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
115 IMG_HANDLE hDevMemContext;
116 IMG_HANDLE hDevMemHeap;
117 IMG_DEV_PHYADDR sPDDevPAddr;
118 IMG_UINT32 i;
119
120#if !defined(PVR_SECURE_HANDLES)
121 PVR_UNREFERENCED_PARAMETER(pbShared);
122#endif
123
124 if (hDevCookie == IMG_NULL)
125 {
126 PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"));
127 PVR_DBG_BREAK;
128 return PVRSRV_ERROR_INVALID_PARAMS;
129 }
130
131 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
132
133
134
135 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
136 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
137
138
139
140 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
141
142
143
144 hDevMemContext = BM_CreateContext(psDeviceNode,
145 &sPDDevPAddr,
146 psPerProc,
147 pbCreated);
148 if (hDevMemContext == IMG_NULL)
149 {
150 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"));
151 return PVRSRV_ERROR_OUT_OF_MEMORY;
152 }
153
154
155 for(i=0; i<ui32HeapCount; i++)
156 {
157 switch(psDeviceMemoryHeap[i].DevMemHeapType)
158 {
159 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
160 {
161
162 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
163 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
164 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
165 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
166 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
167#if defined(PVR_SECURE_HANDLES)
168 pbShared[ui32ClientHeapCount] = IMG_TRUE;
169#endif
170 ui32ClientHeapCount++;
171 break;
172 }
173 case DEVICE_MEMORY_HEAP_PERCONTEXT:
174 {
175 hDevMemHeap = BM_CreateHeap(hDevMemContext,
176 &psDeviceMemoryHeap[i]);
177
178
179 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
180 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
181 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
182 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
183 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
184#if defined(PVR_SECURE_HANDLES)
185 pbShared[ui32ClientHeapCount] = IMG_FALSE;
186#endif
187
188 ui32ClientHeapCount++;
189 break;
190 }
191 }
192 }
193
194
195 *pui32ClientHeapCount = ui32ClientHeapCount;
196 *phDevMemContext = hDevMemContext;
197
198 return PVRSRV_OK;
199}
200
201IMG_EXPORT
202PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
203 IMG_HANDLE hDevMemContext,
204 IMG_BOOL *pbDestroyed)
205{
206 PVR_UNREFERENCED_PARAMETER(hDevCookie);
207
208 return BM_DestroyContext(hDevMemContext, pbDestroyed);
209}
210
211
212
213
214IMG_EXPORT
215PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
216 IMG_HANDLE hDevMemContext,
217 IMG_UINT32 *pui32ClientHeapCount,
218 PVRSRV_HEAP_INFO *psHeapInfo,
219 IMG_BOOL *pbShared)
220{
221 PVRSRV_DEVICE_NODE *psDeviceNode;
222 IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
223 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
224 IMG_HANDLE hDevMemHeap;
225 IMG_UINT32 i;
226
227#if !defined(PVR_SECURE_HANDLES)
228 PVR_UNREFERENCED_PARAMETER(pbShared);
229#endif
230
231 if (hDevCookie == IMG_NULL)
232 {
233 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"));
234 PVR_DBG_BREAK;
235 return PVRSRV_ERROR_INVALID_PARAMS;
236 }
237
238 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
239
240
241
242 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
243 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
244
245
246
247 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
248
249
250 for(i=0; i<ui32HeapCount; i++)
251 {
252 switch(psDeviceMemoryHeap[i].DevMemHeapType)
253 {
254 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
255 {
256
257 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
258 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
259 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
260 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
261 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
262#if defined(PVR_SECURE_HANDLES)
263 pbShared[ui32ClientHeapCount] = IMG_TRUE;
264#endif
265 ui32ClientHeapCount++;
266 break;
267 }
268 case DEVICE_MEMORY_HEAP_PERCONTEXT:
269 {
270 hDevMemHeap = BM_CreateHeap(hDevMemContext,
271 &psDeviceMemoryHeap[i]);
272
273
274 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
275 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
276 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
277 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
278 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
279#if defined(PVR_SECURE_HANDLES)
280 pbShared[ui32ClientHeapCount] = IMG_FALSE;
281#endif
282
283 ui32ClientHeapCount++;
284 break;
285 }
286 }
287 }
288
289
290 *pui32ClientHeapCount = ui32ClientHeapCount;
291
292 return PVRSRV_OK;
293}
294
295
296static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
297 IMG_HANDLE hDevMemHeap,
298 IMG_UINT32 ui32Flags,
299 IMG_SIZE_T ui32Size,
300 IMG_SIZE_T ui32Alignment,
301 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
302{
303 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
304 BM_HANDLE hBuffer;
305
306 PVRSRV_MEMBLK *psMemBlock;
307 IMG_BOOL bBMError;
308
309 PVR_UNREFERENCED_PARAMETER(hDevCookie);
310
311 *ppsMemInfo = IMG_NULL;
312
313 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
314 sizeof(PVRSRV_KERNEL_MEM_INFO),
315 (IMG_VOID **)&psMemInfo, IMG_NULL,
316 "Kernel Memory Info") != PVRSRV_OK)
317 {
318 PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
319 return (PVRSRV_ERROR_OUT_OF_MEMORY);
320 }
321
322 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
323
324 psMemBlock = &(psMemInfo->sMemBlk);
325
326
327 psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
328
329 bBMError = BM_Alloc (hDevMemHeap,
330 IMG_NULL,
331 ui32Size,
332 &psMemInfo->ui32Flags,
333 IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
334 &hBuffer);
335
336 if (!bBMError)
337 {
338 PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
339 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
340
341 return PVRSRV_ERROR_OUT_OF_MEMORY;
342 }
343
344
345 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
346 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
347
348
349 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
350
351
352
353 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
354
355 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
356
357 psMemInfo->ui32AllocSize = ui32Size;
358
359
360 psMemInfo->pvSysBackupBuffer = IMG_NULL;
361
362
363 *ppsMemInfo = psMemInfo;
364
365
366 return (PVRSRV_OK);
367}
368
369static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_BOOL bFromAllocator)
370{
371 BM_HANDLE hBuffer;
372
373 if (!psMemInfo)
374 {
375 return PVRSRV_ERROR_INVALID_PARAMS;
376 }
377
378 hBuffer = psMemInfo->sMemBlk.hBuffer;
379
380
381 if (bFromAllocator)
382 BM_Free(hBuffer, psMemInfo->ui32Flags);
383 else
384 BM_FreeExport(hBuffer, psMemInfo->ui32Flags);
385
386
387 if ((psMemInfo->pvSysBackupBuffer) && bFromAllocator)
388 {
389
390 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
391 psMemInfo->pvSysBackupBuffer = IMG_NULL;
392 }
393
394 if (psMemInfo->ui32RefCount == 0)
395 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
396
397
398 return(PVRSRV_OK);
399}
400
401static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
402{
403 BM_HANDLE hBuffer;
404
405 if (!psMemInfo)
406 {
407 return PVRSRV_ERROR_INVALID_PARAMS;
408 }
409
410 hBuffer = psMemInfo->sMemBlk.hBuffer;
411
412
413 BM_Free(hBuffer, psMemInfo->ui32Flags);
414
415 if(psMemInfo->pvSysBackupBuffer)
416 {
417
418 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
419 psMemInfo->pvSysBackupBuffer = IMG_NULL;
420 }
421
422 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
423
424
425 return(PVRSRV_OK);
426}
427
428
429IMG_EXPORT
430PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
431 IMG_HANDLE hDevMemContext,
432 PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo)
433{
434 IMG_HANDLE hSyncDevMemHeap;
435 DEVICE_MEMORY_INFO *psDevMemoryInfo;
436 BM_CONTEXT *pBMContext;
437 PVRSRV_ERROR eError;
438 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
439 PVRSRV_SYNC_DATA *psSyncData;
440
441 eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
442 sizeof(PVRSRV_KERNEL_SYNC_INFO),
443 (IMG_VOID **)&psKernelSyncInfo, IMG_NULL,
444 "Kernel Synchronization Info");
445 if (eError != PVRSRV_OK)
446 {
447 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
448 return PVRSRV_ERROR_OUT_OF_MEMORY;
449 }
450
451 psKernelSyncInfo->ui32RefCount = 0;
452
453
454 pBMContext = (BM_CONTEXT*)hDevMemContext;
455 psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
456
457
458 hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
459
460
461
462
463 eError = AllocDeviceMem(hDevCookie,
464 hSyncDevMemHeap,
465 PVRSRV_MEM_CACHE_CONSISTENT,
466 sizeof(PVRSRV_SYNC_DATA),
467 sizeof(IMG_UINT32),
468 &psKernelSyncInfo->psSyncDataMemInfoKM);
469
470 if (eError != PVRSRV_OK)
471 {
472
473 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
474 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
475
476 return PVRSRV_ERROR_OUT_OF_MEMORY;
477 }
478
479
480 psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
481 psSyncData = psKernelSyncInfo->psSyncData;
482
483 psSyncData->ui32WriteOpsPending = 0;
484 psSyncData->ui32WriteOpsComplete = 0;
485 psSyncData->ui32ReadOpsPending = 0;
486 psSyncData->ui32ReadOpsComplete = 0;
487 psSyncData->ui32LastOpDumpVal = 0;
488 psSyncData->ui32LastReadOpDumpVal = 0;
489
490#if defined(PDUMP)
491 PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
492 psKernelSyncInfo->psSyncDataMemInfoKM,
493 0,
494 psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize,
495 PDUMP_FLAGS_CONTINUOUS,
496 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
497#endif
498
499 psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
500 psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
501
502
503 psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
504
505
506 *ppsKernelSyncInfo = psKernelSyncInfo;
507
508 return PVRSRV_OK;
509}
510
511
512IMG_EXPORT
513PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
514{
515 PVRSRV_ERROR eError;
516
517 if (psKernelSyncInfo->ui32RefCount != 0)
518 {
519 PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
520
521 return PVRSRV_ERROR_OUT_OF_MEMORY;
522 }
523
524 eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
525 (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
526
527
528 return eError;
529}
530
531static IMG_VOID freeWrapped(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
532{
533 IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
534
535
536 if(psMemInfo->sMemBlk.psIntSysPAddr)
537 {
538 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
539 psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
540 }
541
542 if(hOSWrapMem)
543 {
544 OSReleasePhysPageAddr(hOSWrapMem);
545 }
546}
547
548static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
549 IMG_UINT32 ui32Param,
550 IMG_BOOL bFromAllocator)
551{
552 PVRSRV_ERROR eError = PVRSRV_OK;
553
554 PVR_UNREFERENCED_PARAMETER(ui32Param);
555
556
557 psMemInfo->ui32RefCount--;
558
559
560 if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) && (bFromAllocator == IMG_TRUE))
561 {
562 IMG_HANDLE hMemInfo = IMG_NULL;
563
564
565 eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
566 &hMemInfo,
567 psMemInfo,
568 PVRSRV_HANDLE_TYPE_MEM_INFO);
569 if(eError != PVRSRV_OK)
570 {
571 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list"));
572 return eError;
573 }
574
575
576 eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
577 hMemInfo,
578 PVRSRV_HANDLE_TYPE_MEM_INFO);
579 if(eError != PVRSRV_OK)
580 {
581 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo"));
582 return eError;
583 }
584 }
585
586
587 if (psMemInfo->ui32RefCount == 0)
588 {
589 switch(psMemInfo->memType)
590 {
591
592 case PVRSRV_MEMTYPE_WRAPPED:
593 freeWrapped(psMemInfo);
594 case PVRSRV_MEMTYPE_DEVICE:
595 if (psMemInfo->psKernelSyncInfo)
596 {
597 psMemInfo->psKernelSyncInfo->ui32RefCount--;
598
599 if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
600 {
601 eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
602 }
603 }
604 case PVRSRV_MEMTYPE_DEVICECLASS:
605 break;
606 default:
607 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
608 eError = PVRSRV_ERROR_INVALID_MEMINFO;
609 }
610 }
611
612
613
614 eError = FreeDeviceMem2(psMemInfo, bFromAllocator);
615
616 return eError;
617}
618
619static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam,
620 IMG_UINT32 ui32Param)
621{
622 PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
623
624 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
625}
626
627
628IMG_EXPORT
629PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
630 PVRSRV_KERNEL_MEM_INFO *psMemInfo)
631{
632 PVRSRV_ERROR eError;
633
634 PVR_UNREFERENCED_PARAMETER(hDevCookie);
635
636 if (!psMemInfo)
637 {
638 return PVRSRV_ERROR_INVALID_PARAMS;
639 }
640
641 if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
642 {
643 eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
644 }
645 else
646 {
647
648 eError = FreeDeviceMemCallBack(psMemInfo, 0);
649 }
650
651 return eError;
652}
653
654
655IMG_EXPORT
656PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
657 PVRSRV_PER_PROCESS_DATA *psPerProc,
658 IMG_HANDLE hDevMemHeap,
659 IMG_UINT32 ui32Flags,
660 IMG_SIZE_T ui32Size,
661 IMG_SIZE_T ui32Alignment,
662 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
663{
664 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
665 PVRSRV_ERROR eError;
666 BM_HEAP *psBMHeap;
667 IMG_HANDLE hDevMemContext;
668
669 if (!hDevMemHeap ||
670 (ui32Size == 0))
671 {
672 return PVRSRV_ERROR_INVALID_PARAMS;
673 }
674
675
676 if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
677 {
678
679 if (((ui32Size % HOST_PAGESIZE()) != 0) ||
680 ((ui32Alignment % HOST_PAGESIZE()) != 0))
681 {
682 return PVRSRV_ERROR_INVALID_PARAMS;
683 }
684 }
685
686 eError = AllocDeviceMem(hDevCookie,
687 hDevMemHeap,
688 ui32Flags,
689 ui32Size,
690 ui32Alignment,
691 &psMemInfo);
692
693 if (eError != PVRSRV_OK)
694 {
695 return eError;
696 }
697
698 if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
699 {
700 psMemInfo->psKernelSyncInfo = IMG_NULL;
701 }
702 else
703 {
704
705
706
707 psBMHeap = (BM_HEAP*)hDevMemHeap;
708 hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
709 eError = PVRSRVAllocSyncInfoKM(hDevCookie,
710 hDevMemContext,
711 &psMemInfo->psKernelSyncInfo);
712 if(eError != PVRSRV_OK)
713 {
714 goto free_mainalloc;
715 }
716 psMemInfo->psKernelSyncInfo->ui32RefCount++;
717 }
718
719
720 *ppsMemInfo = psMemInfo;
721
722 if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
723 {
724 psMemInfo->sMemBlk.hResItem = IMG_NULL;
725 }
726 else
727 {
728
729 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
730 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
731 psMemInfo,
732 0,
733 &FreeDeviceMemCallBack);
734 if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
735 {
736
737 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
738 goto free_mainalloc;
739 }
740 }
741
742
743 psMemInfo->ui32RefCount++;
744
745 psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
746
747
748 return (PVRSRV_OK);
749
750free_mainalloc:
751 FreeDeviceMem(psMemInfo);
752
753 return eError;
754}
755
756
757IMG_EXPORT
758PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
759 PVRSRV_KERNEL_MEM_INFO *psMemInfo)
760{
761 PVRSRV_ERROR eError;
762 PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie;
763
764 PVR_UNREFERENCED_PARAMETER(hDevCookie);
765
766 if (!psMemInfo)
767 {
768 return PVRSRV_ERROR_INVALID_PARAMS;
769 }
770
771 eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext);
772
773 PVR_ASSERT(eError == PVRSRV_OK);
774
775 return eError;
776}
777
778
779IMG_EXPORT
780PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
781 IMG_SIZE_T *pui32Total,
782 IMG_SIZE_T *pui32Free,
783 IMG_SIZE_T *pui32LargestBlock)
784{
785
786
787 PVR_UNREFERENCED_PARAMETER(ui32Flags);
788 PVR_UNREFERENCED_PARAMETER(pui32Total);
789 PVR_UNREFERENCED_PARAMETER(pui32Free);
790 PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
791
792 return PVRSRV_OK;
793}
794
795
796
797
798IMG_EXPORT
799PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
800{
801 if (!psMemInfo)
802 {
803 return PVRSRV_ERROR_INVALID_PARAMS;
804 }
805
806 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
807}
808
809
810static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
811 IMG_UINT32 ui32Param)
812{
813 PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
814
815 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
816}
817
818
819IMG_EXPORT
820PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
821 PVRSRV_PER_PROCESS_DATA *psPerProc,
822 IMG_HANDLE hDevMemContext,
823 IMG_SIZE_T ui32ByteSize,
824 IMG_SIZE_T ui32PageOffset,
825 IMG_BOOL bPhysContig,
826 IMG_SYS_PHYADDR *psExtSysPAddr,
827 IMG_VOID *pvLinAddr,
828 IMG_UINT32 ui32Flags,
829 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
830{
831 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
832 DEVICE_MEMORY_INFO *psDevMemoryInfo;
833 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
834 IMG_HANDLE hDevMemHeap = IMG_NULL;
835 PVRSRV_DEVICE_NODE* psDeviceNode;
836 BM_HANDLE hBuffer;
837 PVRSRV_MEMBLK *psMemBlock;
838 IMG_BOOL bBMError;
839 BM_HEAP *psBMHeap;
840 PVRSRV_ERROR eError;
841 IMG_VOID *pvPageAlignedCPUVAddr;
842 IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL;
843 IMG_HANDLE hOSWrapMem = IMG_NULL;
844 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
845 IMG_UINT32 i;
846 IMG_SIZE_T ui32PageCount = 0;
847
848
849 psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
850 PVR_ASSERT(psDeviceNode != IMG_NULL);
851
852 if (psDeviceNode == IMG_NULL)
853 {
854 PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
855 return PVRSRV_ERROR_INVALID_PARAMS;
856 }
857
858 if(pvLinAddr)
859 {
860
861 ui32PageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
862
863
864 ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize;
865 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - ui32PageOffset);
866
867
868 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
869 ui32PageCount * sizeof(IMG_SYS_PHYADDR),
870 (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
871 "Array of Page Addresses") != PVRSRV_OK)
872 {
873 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
874 return PVRSRV_ERROR_OUT_OF_MEMORY;
875 }
876
877 eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
878 ui32PageCount * ui32HostPageSize,
879 psIntSysPAddr,
880 &hOSWrapMem);
881 if(eError != PVRSRV_OK)
882 {
883 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
884 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
885 goto ErrorExitPhase1;
886 }
887
888
889 psExtSysPAddr = psIntSysPAddr;
890
891
892
893 bPhysContig = IMG_FALSE;
894 }
895 else
896 {
897
898 }
899
900
901 psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
902 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
903 for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
904 {
905 if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
906 {
907 if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
908 {
909
910 hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
911 }
912 else
913 {
914 hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
915 }
916 break;
917 }
918 }
919
920 if(hDevMemHeap == IMG_NULL)
921 {
922 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
923 eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
924 goto ErrorExitPhase2;
925 }
926
927 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
928 sizeof(PVRSRV_KERNEL_MEM_INFO),
929 (IMG_VOID **)&psMemInfo, IMG_NULL,
930 "Kernel Memory Info") != PVRSRV_OK)
931 {
932 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
933 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
934 goto ErrorExitPhase2;
935 }
936
937 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
938 psMemInfo->ui32Flags = ui32Flags;
939
940 psMemBlock = &(psMemInfo->sMemBlk);
941
942 bBMError = BM_Wrap(hDevMemHeap,
943 ui32ByteSize,
944 ui32PageOffset,
945 bPhysContig,
946 psExtSysPAddr,
947 IMG_NULL,
948 &psMemInfo->ui32Flags,
949 &hBuffer);
950 if (!bBMError)
951 {
952 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
953 eError = PVRSRV_ERROR_BAD_MAPPING;
954 goto ErrorExitPhase3;
955 }
956
957
958 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
959 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
960 psMemBlock->hOSWrapMem = hOSWrapMem;
961 psMemBlock->psIntSysPAddr = psIntSysPAddr;
962
963
964 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
965
966
967 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
968 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
969 psMemInfo->ui32AllocSize = ui32ByteSize;
970
971
972
973 psMemInfo->pvSysBackupBuffer = IMG_NULL;
974
975
976
977
978 psBMHeap = (BM_HEAP*)hDevMemHeap;
979 hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
980 eError = PVRSRVAllocSyncInfoKM(hDevCookie,
981 hDevMemContext,
982 &psMemInfo->psKernelSyncInfo);
983 if(eError != PVRSRV_OK)
984 {
985 goto ErrorExitPhase4;
986 }
987
988 psMemInfo->psKernelSyncInfo->ui32RefCount++;
989
990
991 psMemInfo->ui32RefCount++;
992
993 psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
994
995
996 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
997 RESMAN_TYPE_DEVICEMEM_WRAP,
998 psMemInfo,
999 0,
1000 &UnwrapExtMemoryCallBack);
1001
1002
1003 *ppsMemInfo = psMemInfo;
1004
1005 return PVRSRV_OK;
1006
1007
1008
1009ErrorExitPhase4:
1010 if(psMemInfo)
1011 {
1012 FreeDeviceMem(psMemInfo);
1013
1014
1015
1016 psMemInfo = IMG_NULL;
1017 }
1018
1019ErrorExitPhase3:
1020 if(psMemInfo)
1021 {
1022 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1023
1024 }
1025
1026ErrorExitPhase2:
1027 if(psIntSysPAddr)
1028 {
1029 OSReleasePhysPageAddr(hOSWrapMem);
1030 }
1031
1032ErrorExitPhase1:
1033 if(psIntSysPAddr)
1034 {
1035 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
1036
1037 }
1038
1039 return eError;
1040}
1041
1042
1043IMG_EXPORT
1044PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
1045{
1046 if (!psMemInfo)
1047 {
1048 return PVRSRV_ERROR_INVALID_PARAMS;
1049 }
1050
1051 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
1052}
1053
1054
1055static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
1056 IMG_UINT32 ui32Param)
1057{
1058 PVRSRV_ERROR eError;
1059 RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam;
1060
1061 PVR_UNREFERENCED_PARAMETER(ui32Param);
1062
1063 if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
1064 {
1065 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
1066 psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
1067 }
1068
1069 psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--;
1070 if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
1071 {
1072 eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
1073 if(eError != PVRSRV_OK)
1074 {
1075 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
1076 return eError;
1077 }
1078 }
1079
1080 eError = FreeDeviceMem(psMapData->psMemInfo);
1081 if(eError != PVRSRV_OK)
1082 {
1083 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
1084 return eError;
1085 }
1086
1087
1088 eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, IMG_FALSE);
1089
1090 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
1091
1092
1093 return eError;
1094}
1095
1096
1097IMG_EXPORT
1098PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
1099 PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
1100 IMG_HANDLE hDstDevMemHeap,
1101 PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo)
1102{
1103 PVRSRV_ERROR eError;
1104 IMG_UINT32 i;
1105 IMG_SIZE_T ui32PageCount, ui32PageOffset;
1106 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
1107 IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
1108 IMG_DEV_PHYADDR sDevPAddr;
1109 BM_BUF *psBuf;
1110 IMG_DEV_VIRTADDR sDevVAddr;
1111 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
1112 BM_HANDLE hBuffer;
1113 PVRSRV_MEMBLK *psMemBlock;
1114 IMG_BOOL bBMError;
1115 PVRSRV_DEVICE_NODE *psDeviceNode;
1116 IMG_VOID *pvPageAlignedCPUVAddr;
1117 RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL;
1118
1119
1120 if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
1121 {
1122 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
1123 return PVRSRV_ERROR_INVALID_PARAMS;
1124 }
1125
1126
1127 *ppsDstMemInfo = IMG_NULL;
1128
1129 ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
1130 ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize;
1131 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - ui32PageOffset);
1132
1133
1134
1135
1136
1137 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1138 ui32PageCount*sizeof(IMG_SYS_PHYADDR),
1139 (IMG_VOID **)&psSysPAddr, IMG_NULL,
1140 "Array of Page Addresses") != PVRSRV_OK)
1141 {
1142 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
1143 return PVRSRV_ERROR_OUT_OF_MEMORY;
1144 }
1145
1146 psBuf = psSrcMemInfo->sMemBlk.hBuffer;
1147
1148
1149 psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
1150
1151
1152 sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(ui32PageOffset);
1153 for(i=0; i<ui32PageCount; i++)
1154 {
1155 BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
1156
1157
1158 psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
1159
1160
1161 sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
1162 }
1163
1164
1165 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1166 sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
1167 (IMG_VOID **)&psMapData, IMG_NULL,
1168 "Resource Manager Map Data") != PVRSRV_OK)
1169 {
1170 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
1171 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1172 goto ErrorExit;
1173 }
1174
1175
1176 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
1177 sizeof(PVRSRV_KERNEL_MEM_INFO),
1178 (IMG_VOID **)&psMemInfo, IMG_NULL,
1179 "Kernel Memory Info") != PVRSRV_OK)
1180 {
1181 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
1182 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1183 goto ErrorExit;
1184 }
1185
1186 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1187 psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
1188
1189 psMemBlock = &(psMemInfo->sMemBlk);
1190
1191 bBMError = BM_Wrap(hDstDevMemHeap,
1192 psSrcMemInfo->ui32AllocSize,
1193 ui32PageOffset,
1194 IMG_FALSE,
1195 psSysPAddr,
1196 pvPageAlignedCPUVAddr,
1197 &psMemInfo->ui32Flags,
1198 &hBuffer);
1199
1200 if (!bBMError)
1201 {
1202 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
1203 eError = PVRSRV_ERROR_BAD_MAPPING;
1204 goto ErrorExit;
1205 }
1206
1207
1208 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1209 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1210
1211
1212 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
1213
1214
1215 psMemBlock->psIntSysPAddr = psSysPAddr;
1216
1217
1218 psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
1219
1220
1221 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1222 psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
1223 psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
1224
1225
1226 psMemInfo->psKernelSyncInfo->ui32RefCount++;
1227
1228
1229
1230 psMemInfo->pvSysBackupBuffer = IMG_NULL;
1231
1232
1233 psMemInfo->ui32RefCount++;
1234
1235
1236 psSrcMemInfo->ui32RefCount++;
1237
1238
1239 BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
1240
1241 psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;
1242
1243
1244 psMapData->psMemInfo = psMemInfo;
1245 psMapData->psSrcMemInfo = psSrcMemInfo;
1246
1247
1248 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
1249 RESMAN_TYPE_DEVICEMEM_MAPPING,
1250 psMapData,
1251 0,
1252 &UnmapDeviceMemoryCallBack);
1253
1254 *ppsDstMemInfo = psMemInfo;
1255
1256 return PVRSRV_OK;
1257
1258
1259
1260ErrorExit:
1261
1262 if(psSysPAddr)
1263 {
1264
1265 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
1266
1267 }
1268
1269 if(psMemInfo)
1270 {
1271
1272 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1273
1274 }
1275
1276 if(psMapData)
1277 {
1278
1279 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
1280
1281 }
1282
1283 return eError;
1284}
1285
1286
1287IMG_EXPORT
1288PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
1289{
1290 if (!psMemInfo)
1291 {
1292 return PVRSRV_ERROR_INVALID_PARAMS;
1293 }
1294
1295 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
1296}
1297
1298
1299static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam,
1300 IMG_UINT32 ui32Param)
1301{
1302 PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam;
1303 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
1304
1305 PVR_UNREFERENCED_PARAMETER(ui32Param);
1306
1307 psMemInfo = psDCMapInfo->psMemInfo;
1308
1309#if defined(SUPPORT_MEMORY_TILING)
1310 if(psDCMapInfo->ui32TilingStride > 0)
1311 {
1312 PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode;
1313
1314 if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode,
1315 psDCMapInfo->ui32RangeIndex) != PVRSRV_OK)
1316 {
1317 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed"));
1318 }
1319 }
1320#endif
1321
1322 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL);
1323
1324 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
1325}
1326
1327
1328IMG_EXPORT
1329PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
1330 IMG_HANDLE hDevMemContext,
1331 IMG_HANDLE hDeviceClassBuffer,
1332 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
1333 IMG_HANDLE *phOSMapInfo)
1334{
1335 PVRSRV_ERROR eError;
1336 PVRSRV_DEVICE_NODE* psDeviceNode;
1337 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
1338 PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
1339 IMG_SYS_PHYADDR *psSysPAddr;
1340 IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
1341 IMG_BOOL bPhysContig;
1342 BM_CONTEXT *psBMContext;
1343 DEVICE_MEMORY_INFO *psDevMemoryInfo;
1344 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
1345 IMG_HANDLE hDevMemHeap = IMG_NULL;
1346 IMG_SIZE_T ui32ByteSize;
1347 IMG_SIZE_T ui32Offset;
1348 IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
1349 BM_HANDLE hBuffer;
1350 PVRSRV_MEMBLK *psMemBlock;
1351 IMG_BOOL bBMError;
1352 IMG_UINT32 i;
1353 PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;
1354
1355 if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
1356 {
1357 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
1358 return PVRSRV_ERROR_INVALID_PARAMS;
1359 }
1360
1361
1362 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1363 sizeof(PVRSRV_DC_MAPINFO),
1364 (IMG_VOID **)&psDCMapInfo, IMG_NULL,
1365 "PVRSRV_DC_MAPINFO") != PVRSRV_OK)
1366 {
1367 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
1368 return PVRSRV_ERROR_OUT_OF_MEMORY;
1369 }
1370 OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));
1371
1372 psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
1394 psDeviceClassBuffer->hExtBuffer,
1395 &psSysPAddr,
1396 &ui32ByteSize,
1397 &pvCPUVAddr,
1398 phOSMapInfo,
1399 &bPhysContig,
1400 &psDCMapInfo->ui32TilingStride);
1401 if(eError != PVRSRV_OK)
1402 {
1403 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
1404 goto ErrorExitPhase1;
1405 }
1406
1407
1408 psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
1409 psDeviceNode = psBMContext->psDeviceNode;
1410 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
1411 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
1412 for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
1413 {
1414 if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
1415 {
1416 if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
1417 {
1418
1419 hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
1420 }
1421 else
1422 {
1423 hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
1424 }
1425 break;
1426 }
1427 }
1428
1429 if(hDevMemHeap == IMG_NULL)
1430 {
1431 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
1432 eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
1433 goto ErrorExitPhase1;
1434 }
1435
1436
1437 ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
1438 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
1439
1440 eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
1441 sizeof(PVRSRV_KERNEL_MEM_INFO),
1442 (IMG_VOID **)&psMemInfo, IMG_NULL,
1443 "Kernel Memory Info");
1444 if(eError != PVRSRV_OK)
1445 {
1446 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
1447 goto ErrorExitPhase1;
1448 }
1449
1450 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1451
1452 psMemBlock = &(psMemInfo->sMemBlk);
1453
1454 bBMError = BM_Wrap(hDevMemHeap,
1455 ui32ByteSize,
1456 ui32Offset,
1457 bPhysContig,
1458 psSysPAddr,
1459 pvPageAlignedCPUVAddr,
1460 &psMemInfo->ui32Flags,
1461 &hBuffer);
1462
1463 if (!bBMError)
1464 {
1465 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
1466
1467 eError = PVRSRV_ERROR_BAD_MAPPING;
1468 goto ErrorExitPhase2;
1469 }
1470
1471
1472 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1473 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1474
1475
1476 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
1477
1478
1479
1480 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
1481
1482
1483 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1484 psMemInfo->ui32AllocSize = ui32ByteSize;
1485 psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
1486
1487
1488
1489 psMemInfo->pvSysBackupBuffer = IMG_NULL;
1490
1491
1492 psDCMapInfo->psMemInfo = psMemInfo;
1493
1494#if defined(SUPPORT_MEMORY_TILING)
1495 psDCMapInfo->psDeviceNode = psDeviceNode;
1496
1497 if(psDCMapInfo->ui32TilingStride > 0)
1498 {
1499
1500 eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
1501 psMemInfo,
1502 psDCMapInfo->ui32TilingStride,
1503 &psDCMapInfo->ui32RangeIndex);
1504 if (eError != PVRSRV_OK)
1505 {
1506 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
1507 goto ErrorExitPhase3;
1508 }
1509 }
1510#endif
1511
1512
1513 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
1514 RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
1515 psDCMapInfo,
1516 0,
1517 &UnmapDeviceClassMemoryCallBack);
1518
1519 psMemInfo->ui32RefCount++;
1520
1521 psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
1522
1523
1524 *ppsMemInfo = psMemInfo;
1525
1526 return PVRSRV_OK;
1527
1528#if defined(SUPPORT_MEMORY_TILING)
1529ErrorExitPhase3:
1530 if(psMemInfo)
1531 {
1532 FreeDeviceMem(psMemInfo);
1533
1534
1535
1536 psMemInfo = IMG_NULL;
1537 }
1538#endif
1539
1540ErrorExitPhase2:
1541 if(psMemInfo)
1542 {
1543 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1544 }
1545
1546ErrorExitPhase1:
1547 if(psDCMapInfo)
1548 {
1549 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
1550 }
1551
1552 return eError;
1553}
1554
diff --git a/drivers/gpu/pvr/display/omap_display.c b/drivers/gpu/pvr/display/omap_display.c
new file mode 100644
index 00000000000..1fb5f353870
--- /dev/null
+++ b/drivers/gpu/pvr/display/omap_display.c
@@ -0,0 +1,1078 @@
1/*
2 * drivers/gpu/pvr/display/omap_display.c
3 *
4 * Copyright (C) 2010 Texas Instruments
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/fb.h>
22
23#include <plat/vrfb.h>
24#include <plat/display.h>
25
26/* Workaround for DEBUG macro clash in framebuffer */
27#ifdef RELEASE
28#include <../drivers/video/omap2/omapfb/omapfb.h>
29#undef DEBUG
30#else
31#undef DEBUG
32#include <../drivers/video/omap2/omapfb/omapfb.h>
33#endif
34
35#define OMAP_DISP_DRV_NAME "omap_display"
36#define OMAP_DISP_FRAMEBUFFER_COUNT num_registered_fb
37
38#define OMAP_DISP_PAGE_MASK (PAGE_SIZE - 1)
39#define OMAP_DISP_PAGE_TRUNCATE (~OMAP_DISP_PAGE_MASK)
40#define OMAP_DISP_PAGE_ROUND_UP(x) \
41 (((x)+OMAP_DISP_PAGE_MASK) & OMAP_DISP_PAGE_TRUNCATE)
42
43#define OMAP_DISP_IRQ_TIMEOUT 500
44
45#ifdef DEBUG
46#define DBG_PRINT(format, ...) printk(KERN_DEBUG OMAP_DISP_DRV_NAME \
47 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
48#define WRN_PRINT(format, ...) printk(KERN_WARNING OMAP_DISP_DRV_NAME \
49 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
50#define ERR_PRINT(format, ...) printk(KERN_ERR OMAP_DISP_DRV_NAME \
51 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
52#else
53#define DBG_PRINT(format, ...)
54#define WRN_PRINT(format, ...)
55#define ERR_PRINT(format, ...)
56#endif
57
58#include "omap_display.h"
59
60/* List for the available displays */
61static struct omap_display_device *omap_display_list;
62static unsigned int omap_display_number;
63
64/* Forward declarations */
65static struct omap_display_buffer *create_main_buffer(
66 struct omap_display_device *display);
67static int display_destroy_buffer(struct omap_display_buffer *buffer);
68
69static int open_display(struct omap_display_device *display,
70 enum omap_display_feature features)
71{
72 int i;
73
74 DBG_PRINT("Opening display '%s'", display->name);
75
76 /* TODO: Support horizontal orientation */
77 if (features & ORIENTATION_HORIZONTAL) {
78 DBG_PRINT("Horizontal orientation is not supported yet , "
79 "falling back to vertical orientation");
80 features = ORIENTATION_VERTICAL;
81 }
82
83 display->features = features;
84 display->reference_count++;
85 for (i = 0; i < display->overlay_managers_count; i++)
86 omap_dss_get_device(display->overlay_managers[i]->device);
87
88 /* If the main buffer doesn't exist create it */
89 if (!display->main_buffer) {
90 DBG_PRINT("Main buffer doesn't exist for display '%s', create"
91 " one", display->name);
92 display->main_buffer = create_main_buffer(display);
93 if (!display->main_buffer) {
94 ERR_PRINT("Failed to create main buffer for '%s'",
95 display->name);
96 return 1;
97 }
98 }
99
100 return 0;
101}
102
103static int close_display(struct omap_display_device *display)
104{
105 int err;
106 int i;
107
108 /* TODO: Is it the same thing to close a virtual and single display? */
109 DBG_PRINT("Closing display '%s'", display->name);
110
111 display->reference_count--;
112 for (i = 0; i < display->overlay_managers_count; i++)
113 omap_dss_put_device(display->overlay_managers[i]->device);
114
115 if (display->flip_chain) {
116 err = display->destroy_flip_chain(display);
117 display->flip_chain = 0;
118 if (err)
119 WRN_PRINT("An error happened when destroying flip "
120 "chain for '%s'", display->name);
121 }
122
123 return 0;
124}
125
126static int get_max_buffers(struct omap_display_device *display)
127{
128 /* TODO: If TILER is wanted to be used how do you calculate this? */
129 int fb_idx;
130 switch (display->id) {
131 case OMAP_DISPID_PRIMARY:
132 fb_idx = 0;
133 break;
134 case OMAP_DISPID_SECONDARY:
135 fb_idx = 1;
136 break;
137 case OMAP_DISPID_TERTIARY:
138 fb_idx = 2;
139 break;
140 case OMAP_DISPID_VIRTUAL:
141 fb_idx = 0;
142 break;
143 case OMAP_DISPID_BADSTATE:
144 default:
145 ERR_PRINT("Unknown display id %i", display->id);
146 BUG();
147 }
148
149 /* Use the framebuffer memory */
150 if (fb_idx >= 0 && fb_idx < num_registered_fb) {
151 struct fb_info *framebuffer = registered_fb[fb_idx];
152 unsigned long buffer_size;
153
154 /* Single buffer size */
155 buffer_size = display->width * display->height *
156 display->bytes_per_pixel;
157 /* Page align the buffer size, round up to the page size */
158 buffer_size = OMAP_DISP_PAGE_ROUND_UP(buffer_size);
159
160 return (int) (framebuffer->fix.smem_len / buffer_size);
161 } else {
162 ERR_PRINT("Framebuffer %i doesn't exist for display '%s'",
163 fb_idx, display->name);
164 return 0;
165 }
166}
167
168static int create_flip_chain(struct omap_display_device *display,
169 unsigned int buffer_count)
170{
171 int fb_idx;
172
173 /* TODO: What about TILER buffers */
174 if (buffer_count <= 1) {
175 ERR_PRINT("Flip chains with %i buffers not supported",
176 buffer_count);
177 return 1;
178 } else if (buffer_count > display->buffers_available) {
179 ERR_PRINT("Requesting %i buffers when there is %i available"
180 " for '%s'", buffer_count, display->buffers_available,
181 display->name);
182 return 1;
183 } else if (display->flip_chain) {
184 ERR_PRINT("Flip chain already exists for '%s'", display->name);
185 return 1;
186 }
187
188 /* Create the flip chain with the framebuffer memory */
189 switch (display->id) {
190 case OMAP_DISPID_PRIMARY:
191 fb_idx = 0;
192 break;
193 case OMAP_DISPID_SECONDARY:
194 fb_idx = 1;
195 break;
196 case OMAP_DISPID_TERTIARY:
197 fb_idx = 2;
198 break;
199 case OMAP_DISPID_VIRTUAL:
200 fb_idx = 0;
201 break;
202 case OMAP_DISPID_BADSTATE:
203 default:
204 ERR_PRINT("Unknown display id %i", display->id);
205 BUG();
206 }
207
208 /* Use the framebuffer memory */
209 if (fb_idx >= 0 && fb_idx < num_registered_fb) {
210 struct fb_info *framebuffer = registered_fb[fb_idx];
211 unsigned long buffer_size;
212 struct omap_display_flip_chain *flip_chain;
213 int i;
214
215 if (!framebuffer || !framebuffer->fix.smem_start ||
216 !framebuffer->screen_base) {
217 ERR_PRINT("Framebuffer %i doesn't seem to be "
218 "initialized", fb_idx);
219 return 1;
220 }
221
222 /*
223 * Check if there is enough memory in the fb for the requested
224 * buffers
225 */
226 buffer_size = display->width * display->height *
227 display->bytes_per_pixel;
228 /* Page align the buffer size, round up to the page size */
229 buffer_size = OMAP_DISP_PAGE_ROUND_UP(buffer_size);
230
231 if (buffer_size * buffer_count > framebuffer->fix.smem_len) {
232 ERR_PRINT("Not enough memory to allocate %i buffers "
233 "(%lu bytes each), memory available %lu for "
234 "display '%s'", buffer_count, buffer_size,
235 (unsigned long)framebuffer->fix.smem_len,
236 display->name);
237 return 1;
238 }
239
240 flip_chain = kzalloc(sizeof(*flip_chain), GFP_KERNEL);
241
242 if (!flip_chain) {
243 ERR_PRINT("Out of memory");
244 return 1;
245 }
246
247 for (i = 0; i < buffer_count; i++) {
248 struct omap_display_buffer *buffer;
249
250 /*
251 * Reuse the main buffer as the first buffer in the
252 * flip chain
253 */
254 if (i == 0) {
255 buffer = display->main_buffer;
256 flip_chain->buffers[i] = buffer;
257 DBG_PRINT("Flip chain buffer %i has address "
258 "%lx for display '%s'", i,
259 buffer->physical_addr, display->name);
260 continue;
261 }
262
263 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
264
265 if (!buffer) {
266 /*
267 * FIXME: If one buffer allocation fails,
268 * deallocate flip chain and buffers
269 */
270 ERR_PRINT("Out of memory");
271 return 1;
272 }
273
274 buffer->physical_addr = framebuffer->fix.smem_start +
275 (buffer_size * i);
276 buffer->virtual_addr =
277 (unsigned long) framebuffer->screen_base +
278 (buffer_size * i);
279 buffer->size = buffer_size;
280 buffer->display = display;
281 flip_chain->buffers[i] = buffer;
282
283 DBG_PRINT("Flip chain buffer %i has address %lx for"
284 " display '%s'", i, buffer->physical_addr,
285 display->name);
286 }
287
288 display->flip_chain = flip_chain;
289 return 0;
290 } else {
291 ERR_PRINT("Framebuffer %i doesn't exist for display '%s'",
292 fb_idx, display->name);
293 return 1;
294 }
295
296 return 0;
297}
298
299static int destroy_flip_chain(struct omap_display_device *display)
300{
301 int i;
302 int err;
303
304 if (!display->flip_chain) {
305 DBG_PRINT("No flip chain to destroy for '%s'", display->name);
306 return 0;
307 }
308
309 for (i = 0; i < display->flip_chain->buffer_count; i++) {
310 struct omap_display_buffer *buffer =
311 display->flip_chain->buffers[i];
312 /* If buffer is main buffer don't touch it */
313 if (display->main_buffer == buffer)
314 continue;
315
316 err = display_destroy_buffer(buffer);
317 if (err) {
318 ERR_PRINT("Error destroying buffer in flip chain for"
319 " '%s'", display->name);
320 return 1;
321 }
322 }
323
324 DBG_PRINT("Destroying flip chain for '%s'", display->name);
325 kfree(display->flip_chain);
326 display->flip_chain = 0;
327
328 return 0;
329}
330
331static int rotate_display(struct omap_display_device *display,
332 unsigned int rotation)
333{
334 ERR_PRINT("Not supported yet");
335 return 1;
336}
337
338static int display_destroy_buffer(struct omap_display_buffer *buffer)
339{
340 kfree(buffer);
341 return 0;
342}
343
344static int present_buffer_virtual(struct omap_display_buffer *buffer)
345{
346 /*
347 * TODO: Support for ORIENTATION_VERTICAL is in place,
348 * ORIENTATION_HORIZONTAL is missing
349 */
350 struct omap_display_device *display_virtual = buffer->display;
351 struct omap_display_device *display_primary;
352 struct omap_display_device *display_secondary;
353 struct omap_display_buffer temp_buffer;
354 unsigned int buffer_offset;
355
356 if (display_virtual->id != OMAP_DISPID_VIRTUAL) {
357 ERR_PRINT("Not a virtual display");
358 BUG();
359 }
360
361 display_primary = omap_display_get(OMAP_DISPID_PRIMARY);
362 display_secondary = omap_display_get(OMAP_DISPID_SECONDARY);
363 /*
364 * Calculate offset without page alignment round up otherwise second
365 * display may see incorrect data
366 */
367 buffer_offset = display_primary->height * display_virtual->byte_stride;
368
369 /* The first buffer will be the base */
370 temp_buffer.physical_addr = buffer->physical_addr;
371 temp_buffer.virtual_addr = buffer->virtual_addr;
372 temp_buffer.size = buffer->size >> 1;
373
374 if (display_virtual->features & ORIENTATION_INVERT) {
375 /* Secondary display has the base */
376 temp_buffer.display = display_secondary;
377 display_secondary->present_buffer(&temp_buffer);
378 } else {
379 /* Primary display has the base */
380 temp_buffer.display = display_primary;
381 display_primary->present_buffer(&temp_buffer);
382 }
383
384 /* Remaining display will show the rest */
385 temp_buffer.physical_addr = buffer->physical_addr + buffer_offset;
386 temp_buffer.virtual_addr = buffer->virtual_addr + buffer_offset;
387
388 if (display_virtual->features & ORIENTATION_INVERT) {
389 temp_buffer.display = display_primary;
390 display_primary->present_buffer(&temp_buffer);
391 } else {
392 temp_buffer.display = display_secondary;
393 display_secondary->present_buffer(&temp_buffer);
394 }
395
396 return 0;
397}
398
399static int present_buffer(struct omap_display_buffer *buffer)
400{
401 struct omap_display_device *display = buffer->display;
402 int fb_idx;
403
404 switch (display->id) {
405 case OMAP_DISPID_PRIMARY:
406 fb_idx = 0;
407 break;
408 case OMAP_DISPID_SECONDARY:
409 fb_idx = 1;
410 break;
411 case OMAP_DISPID_TERTIARY:
412 fb_idx = 2;
413 break;
414 case OMAP_DISPID_VIRTUAL:
415 case OMAP_DISPID_BADSTATE:
416 default:
417 ERR_PRINT("Unable to handle display %i", display->id);
418 BUG();
419 }
420
421 if (fb_idx >= 0 && fb_idx < num_registered_fb) {
422 struct fb_info *framebuffer = registered_fb[fb_idx];
423 struct omapfb_info *ofbi = FB2OFB(framebuffer);
424 struct omapfb2_device *fbdev = ofbi->fbdev;
425 struct omap_overlay *overlay;
426 struct omap_overlay_info overlay_info;
427 int i;
428
429 omapfb_lock(fbdev);
430
431 /* Get the overlays attached to the framebuffer */
432 for (i = 0; i < ofbi->num_overlays ; i++) {
433 overlay = ofbi->overlays[i];
434 overlay->get_overlay_info(overlay, &overlay_info);
435
436 /* If the overlay is not enabled don't update it */
437 if (!overlay_info.enabled)
438 continue;
439
440 overlay_info.paddr = buffer->physical_addr;
441 overlay_info.vaddr = (void *) buffer->virtual_addr;
442 overlay->set_overlay_info(overlay, &overlay_info);
443
444 if (overlay->manager) {
445 overlay->manager->apply(overlay->manager);
446 if (overlay->manager->device &&
447 overlay->manager->device->update) {
448 overlay->manager->device->update(
449 overlay->manager->device,
450 0, 0,
451 overlay_info.width,
452 overlay_info.height);
453 }
454 }
455 }
456
457 omapfb_unlock(fbdev);
458 } else {
459 ERR_PRINT("Framebuffer %i doesn't exist for display '%s'",
460 fb_idx, display->name);
461 return 1;
462 }
463
464 return 0;
465}
466
467static u32 get_dss_irq(struct omap_dss_device *dss_device)
468{
469 u32 irq;
470
471 if (dss_device->type == OMAP_DISPLAY_TYPE_VENC)
472 irq = DISPC_IRQ_EVSYNC_ODD;
473 else if (dss_device->type == OMAP_DISPLAY_TYPE_HDMI)
474 irq = DISPC_IRQ_EVSYNC_EVEN;
475 else if (dss_device->type == OMAP_DISPLAY_TYPE_DSI)
476 if (!strcmp(dss_device->name, "lcd"))
477 irq = DISPC_IRQ_FRAMEDONE;
478 else
479 irq = DISPC_IRQ_FRAMEDONE2;
480 else
481 if (!strcmp(dss_device->name, "lcd"))
482 irq = DISPC_IRQ_VSYNC;
483 else
484 irq = DISPC_IRQ_VSYNC2;
485
486 return irq;
487}
488
489static int present_buffer_sync(struct omap_display_buffer *buffer)
490{
491 /* TODO: Cloning may tear with this implementation */
492 int err = 0;
493 struct omap_display_device *display = buffer->display;
494
495 err = display->sync(display);
496 err |= display->present_buffer(buffer);
497
498 return err;
499}
500
501static int present_buffer_sync_virtual(struct omap_display_buffer *buffer)
502{
503 void display_irq_wait_1(void *data, u32 mask)
504 {
505 struct omap_display_sync_item *sync_item =
506 (struct omap_display_sync_item *) data;
507
508 if (sync_item->invalidate)
509 return;
510
511 /* IRQ happened, present immediately */
512 sync_item->invalidate = 1;
513 sync_item->buffer->display->present_buffer(sync_item->buffer);
514 complete(sync_item->task);
515 }
516
517 void display_irq_wait_2(void *data, u32 mask)
518 {
519 struct omap_display_sync_item *sync_item =
520 (struct omap_display_sync_item *) data;
521
522 if (sync_item->invalidate)
523 return;
524
525 /* IRQ happened, present immediately */
526 sync_item->invalidate = 1;
527 sync_item->buffer->display->present_buffer(sync_item->buffer);
528 complete(sync_item->task);
529 }
530
531 /*
532 * TODO: Support for ORIENTATION_VERTICAL is in place,
533 * ORIENTATION_HORIZONTAL is missing. Some code can be reduced here,
534 * it will be simplified in the future.
535 */
536 struct omap_display_device *display_virtual = buffer->display;
537 struct omap_display_device *display_primary;
538 struct omap_display_device *display_secondary;
539 struct omap_display_buffer temp_buffer_top;
540 struct omap_display_buffer temp_buffer_bottom;
541 struct omap_display_sync_item sync_item_primary;
542 struct omap_display_sync_item sync_item_secondary;
543 DECLARE_COMPLETION_ONSTACK(completion_primary);
544 DECLARE_COMPLETION_ONSTACK(completion_secondary);
545 unsigned int buffer_offset;
546
547 if (display_virtual->id != OMAP_DISPID_VIRTUAL) {
548 ERR_PRINT("Not a virtual display");
549 BUG();
550 }
551
552 display_primary = omap_display_get(OMAP_DISPID_PRIMARY);
553 display_secondary = omap_display_get(OMAP_DISPID_SECONDARY);
554 /*
555 * Calculate offset without page alignment round up otherwise second
556 * display may see incorrect data
557 */
558 buffer_offset = display_primary->height * display_virtual->byte_stride;
559
560 /* The first buffer will be the top */
561 temp_buffer_top.physical_addr = buffer->physical_addr;
562 temp_buffer_top.virtual_addr = buffer->virtual_addr;
563 temp_buffer_top.size = buffer->size >> 1;
564 /* Then the bottom */
565 temp_buffer_bottom.physical_addr = buffer->physical_addr +
566 buffer_offset;
567 temp_buffer_bottom.virtual_addr = buffer->virtual_addr + buffer_offset;
568 temp_buffer_bottom.size = buffer->size >> 1;
569
570 if (display_virtual->features & ORIENTATION_INVERT) {
571 /* Secondary display has the base */
572 temp_buffer_top.display = display_secondary;
573 temp_buffer_bottom.display = display_primary;
574 sync_item_primary.buffer = &temp_buffer_bottom;
575 sync_item_secondary.buffer = &temp_buffer_top;
576
577 } else {
578 /* Primary display has the base */
579 temp_buffer_top.display = display_primary;
580 temp_buffer_bottom.display = display_secondary;
581 sync_item_primary.buffer = &temp_buffer_top;
582 sync_item_secondary.buffer = &temp_buffer_bottom;
583 }
584
585 sync_item_primary.task = &completion_primary;
586 sync_item_secondary.task = &completion_secondary;
587 sync_item_primary.invalidate = 0;
588 sync_item_secondary.invalidate = 0;
589
590 /* Register an ISR per display with its corresponding IRQ */
591 omap_dispc_register_isr(display_irq_wait_1, &sync_item_primary,
592 get_dss_irq(display_primary->overlay_managers[0]->device));
593
594 omap_dispc_register_isr(display_irq_wait_2, &sync_item_secondary,
595 get_dss_irq(display_secondary->overlay_managers[0]->device));
596
597 /* Wait until each display sync and present */
598 wait_for_completion_interruptible_timeout(&completion_primary,
599 OMAP_DISP_IRQ_TIMEOUT);
600 wait_for_completion_interruptible_timeout(&completion_secondary,
601 OMAP_DISP_IRQ_TIMEOUT);
602
603 /* Unregister ISRs */
604 omap_dispc_unregister_isr(display_irq_wait_1, &sync_item_primary,
605 get_dss_irq(display_primary->overlay_managers[0]->device));
606
607 omap_dispc_unregister_isr(display_irq_wait_2, &sync_item_secondary,
608 get_dss_irq(display_secondary->overlay_managers[0]->device));
609
610 return 0;
611}
612
613static int display_sync(struct omap_display_device *display)
614{
615 /* TODO: Synchronize properly with multiple managers */
616 struct omap_dss_device *dss_device =
617 display->overlay_managers[0]->device;
618 if (!dss_device || !dss_device->wait_vsync) {
619 ERR_PRINT("Unable to synchronize with '%s'", display->name);
620 return 1;
621 }
622 dss_device->wait_vsync(dss_device);
623 return 0;
624}
625
626static int display_sync_virtual(struct omap_display_device *display_virtual)
627{
628 void display_irq_wait(void *data, u32 mask)
629 {
630 complete((struct completion *)data);
631 }
632
633 /*
634 * Return as soon as one display generates an IRQ
635 */
636 struct omap_display_device *display_primary;
637 struct omap_display_device *display_secondary;
638 u32 irq_primary;
639 u32 irq_secondary;
640 u32 irq_mask;
641 DECLARE_COMPLETION_ONSTACK(completion);
642
643 if (display_virtual->id != OMAP_DISPID_VIRTUAL) {
644 ERR_PRINT("Not a virtual display");
645 BUG();
646 }
647
648 display_primary = omap_display_get(OMAP_DISPID_PRIMARY);
649 display_secondary = omap_display_get(OMAP_DISPID_SECONDARY);
650
651 irq_primary = get_dss_irq(
652 display_primary->overlay_managers[0]->device);
653
654 irq_secondary = get_dss_irq(
655 display_secondary->overlay_managers[0]->device);
656
657 irq_mask = irq_primary | irq_secondary;
658
659 /* Register an ISR with both IRQs and wait, then unregister */
660 omap_dispc_register_isr(display_irq_wait, &completion, irq_mask);
661
662 wait_for_completion_interruptible_timeout(&completion,
663 OMAP_DISP_IRQ_TIMEOUT);
664
665 omap_dispc_unregister_isr(display_irq_wait, &completion, irq_mask);
666
667 return 0;
668}
669
670static struct omap_display_buffer *create_main_buffer(
671 struct omap_display_device *display)
672{
673 int fb_idx;
674 switch (display->id) {
675 case OMAP_DISPID_PRIMARY:
676 fb_idx = 0;
677 break;
678 case OMAP_DISPID_SECONDARY:
679 fb_idx = 1;
680 break;
681 case OMAP_DISPID_TERTIARY:
682 fb_idx = 2;
683 break;
684 case OMAP_DISPID_VIRTUAL:
685 /* Use fb0 for virtual display */
686 fb_idx = 0;
687 break;
688 case OMAP_DISPID_BADSTATE:
689 default:
690 ERR_PRINT("Unknown display id %i", display->id);
691 BUG();
692 }
693
694 /* Use the framebuffer memory */
695 if (fb_idx >= 0 && fb_idx < num_registered_fb) {
696 struct fb_info *framebuffer = registered_fb[fb_idx];
697 unsigned long buffer_size;
698 struct omap_display_buffer *buffer;
699
700 if (!framebuffer || !framebuffer->fix.smem_start ||
701 !framebuffer->screen_base) {
702 ERR_PRINT("Framebuffer %i doesn't seem to be "
703 "initialized", fb_idx);
704 return NULL;
705 }
706
707 /*
708 * Check if there is enough memory in the fb for the
709 * main buffer
710 */
711 buffer_size = display->width * display->height *
712 display->bytes_per_pixel;
713 /* Page align the buffer size */
714 buffer_size = OMAP_DISP_PAGE_ROUND_UP(buffer_size);
715
716 if (buffer_size > framebuffer->fix.smem_len) {
717 ERR_PRINT("Main buffer needs %lu bytes while the "
718 "framebuffer %i has only %lu bytes for display"
719 " '%s'", buffer_size, fb_idx,
720 (unsigned long)framebuffer->fix.smem_len,
721 display->name);
722 return NULL;
723 }
724
725 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
726
727 if (!buffer) {
728 ERR_PRINT("Out of memory");
729 return NULL;
730 }
731
732 /* Use base addresses reported by the framebuffer */
733 buffer->physical_addr = framebuffer->fix.smem_start;
734 buffer->virtual_addr =
735 (unsigned long) framebuffer->screen_base;
736 buffer->size = buffer_size;
737 buffer->display = display;
738
739 DBG_PRINT("Created main buffer %lx for display '%s'",
740 buffer->physical_addr, display->name);
741
742 return buffer;
743 } else {
744 ERR_PRINT("Framebuffer %i doesn't exist for display '%s'",
745 fb_idx, display->name);
746 return NULL;
747 }
748}
749
750static int populate_display_info(struct omap_display_device *display,
751 struct omap_overlay_manager *overlay_manager)
752{
753 struct omap_dss_device *dss_device = overlay_manager->device;
754 u16 xres;
755 u16 yres;
756 int i;
757
758 if (!strcmp(dss_device->name, "lcd")) {
759 display->id = OMAP_DISPID_PRIMARY;
760 display->name = "primary";
761 } else if (!strcmp(dss_device->name, "2lcd")) {
762 display->id = OMAP_DISPID_SECONDARY;
763 display->name = "secondary";
764 } else if (!strcmp(dss_device->name, "hdmi")) {
765 display->id = OMAP_DISPID_TERTIARY;
766 display->name = "tertiary";
767 } else {
768 ERR_PRINT("Display id '%s' not supported", dss_device->name);
769 return 1;
770 }
771
772 dss_device->get_resolution(dss_device, &xres, &yres);
773 if (xres == 0 || yres == 0) {
774 ERR_PRINT("Unable to handle display '%s' with width %i "
775 "and height %i", dss_device->name, xres, yres);
776 return 1;
777 }
778
779 display->width = xres;
780 display->height = yres;
781
782 display->bits_per_pixel = dss_device->get_recommended_bpp(dss_device);
783 switch (display->bits_per_pixel) {
784 case 16:
785 /*
786 * TODO: Asume RGB_565, maybe need to double check in
787 * the DSS if this is true
788 */
789 display->pixel_format = RGB_565;
790 display->bytes_per_pixel = 2;
791 break;
792 case 24: /* 24 bits are encapsulated with 32 bits */
793 case 32:
794 /*
795 * TODO: Asume ARGB_8888, maybe need to double check in
796 * the DSS if this is true
797 */
798 display->pixel_format = ARGB_8888;
799 display->bytes_per_pixel = 4;
800 break;
801 default:
802 ERR_PRINT("Unable to handle %i bpp", display->bits_per_pixel);
803 return 1;
804 }
805
806 display->byte_stride = display->bytes_per_pixel * display->width;
807 display->rotation = OMAP_DSS_ROT_0; /* Asume rotation 0 degrees */
808 display->main_buffer = 0;
809 display->flip_chain = 0;
810
811 /* Add the manager to the list */
812 for (i = 0; i < OMAP_DISP_MAX_MANAGERS; i++)
813 display->overlay_managers[i] = 0;
814
815 display->overlay_managers[0] = overlay_manager;
816 display->overlay_managers_count = 1;
817
818 /* Assign function pointers for display operations */
819 display->open = open_display;
820 display->close = close_display;
821 display->create_flip_chain = create_flip_chain;
822 display->destroy_flip_chain = destroy_flip_chain;
823 display->rotate = rotate_display;
824 display->present_buffer = present_buffer;
825 display->sync = display_sync;
826 display->present_buffer_sync = present_buffer_sync;
827
828 display->main_buffer = create_main_buffer(display);
829 if (!display->main_buffer)
830 WRN_PRINT("Failed to create main buffer for '%s'",
831 display->name);
832
833 display->buffers_available = get_max_buffers(display);
834
835 /* Just print some display info */
836 DBG_PRINT("Found display '%s-%s' (%i,%i) %i bpp (%i bytes per pixel)"
837 " rotation %i", display->name, dss_device->name,
838 display->width, display->height, display->bits_per_pixel,
839 display->bytes_per_pixel, display->rotation);
840
841 return 0;
842}
843
844static int populate_virtual_display_info(struct omap_display_device *display)
845{
846 struct omap_display_device *display_primary ;
847 struct omap_display_device *display_secondary;
848 int i;
849
850 display->id = OMAP_DISPID_VIRTUAL;
851 display->name = "virtual";
852
853 display_primary = omap_display_get(OMAP_DISPID_PRIMARY);
854 display_secondary = omap_display_get(OMAP_DISPID_SECONDARY);
855
856 if (!display_primary) {
857 ERR_PRINT("Primary display doesn't exist");
858 return 1;
859 } else if (!display_secondary) {
860 ERR_PRINT("Secondary display doesn't exist");
861 return 1;
862 }
863
864 /* Combine primary and secondary display resolutions */
865 if (display_primary->width != display_secondary->width ||
866 display_primary->height != display_secondary->height) {
867 ERR_PRINT("Primary and seconday displays resolution are not"
868 " the same");
869 return 1;
870 }
871
872 /*
873 * TODO: Here it is hardcoded the resolution asumming a vertical
874 * virtual config, what about horizontal?
875 */
876 display->width = display_primary->width;
877 display->height = display_primary->height * 2;
878
879 if (display_primary->bits_per_pixel !=
880 display_secondary->bits_per_pixel) {
881 ERR_PRINT("Primary and seconday displays format are"
882 " not the same");
883 return 1;
884 }
885
886 display->bits_per_pixel = display_primary->bits_per_pixel;
887 switch (display->bits_per_pixel) {
888 case 16:
889 /*
890 * TODO: Asume RGB_565, maybe need to double check in
891 * the DSS if this is true
892 */
893 display->pixel_format = RGB_565;
894 display->bytes_per_pixel = 2;
895 break;
896 case 24: /* 24 bits are encapsulated with 32 bits */
897 case 32:
898 /*
899 * TODO: Asume ARGB_8888, maybe need to double check in
900 * the DSS if this is true
901 */
902 display->pixel_format = ARGB_8888;
903 display->bytes_per_pixel = 4;
904 break;
905 default:
906 ERR_PRINT("Unable to handle %i bpp",
907 display->bits_per_pixel);
908 return 1;
909 }
910
911 /* TODO: Asumming a vertical virtual config too for stride */
912 display->byte_stride = display->bytes_per_pixel * display->width;
913 display->rotation = OMAP_DSS_ROT_0; /* Asume rotation 0 degrees */
914 display->main_buffer = 0;
915 display->flip_chain = 0;
916
917 /* Add the primary and secondary overlay managers */
918 for (i = 0; i < OMAP_DISP_MAX_MANAGERS; i++)
919 display->overlay_managers[i] = 0;
920
921 display->overlay_managers[0] = display_primary->overlay_managers[0];
922 display->overlay_managers[1] = display_secondary->overlay_managers[0];
923 display->overlay_managers_count = 2;
924
925 /* Assign function pointers for display operations */
926 display->open = open_display;
927 display->close = close_display;
928 display->create_flip_chain = create_flip_chain;
929 display->destroy_flip_chain = destroy_flip_chain;
930 display->rotate = rotate_display;
931 display->present_buffer = present_buffer_virtual;
932 display->sync = display_sync_virtual;
933 display->present_buffer_sync = present_buffer_sync_virtual;
934
935 display->main_buffer = create_main_buffer(display);
936 if (!display->main_buffer)
937 WRN_PRINT("Failed to create main buffer for '%s'",
938 display->name);
939
940 display->buffers_available = get_max_buffers(display);
941
942 /* Just print some display info */
943 DBG_PRINT("Found display '%s' (%i,%i) %i bpp (%i bytes per pixel)"
944 " rotation %i", display->name, display->width, display->height,
945 display->bits_per_pixel, display->bytes_per_pixel,
946 display->rotation);
947
948 return 0;
949}
950
951static int create_display_list(void)
952{
953 int i;
954 unsigned int bytes_to_alloc;
955 struct omap_display_device *display;
956
957 /* Query number of possible displays available first */
958 omap_display_number = omap_dss_get_num_overlay_managers();
959 /* For virtual display */
960 omap_display_number++;
961
962 /* Allocate custom display list */
963 omap_display_list = kzalloc(
964 sizeof(*display) * omap_display_number, GFP_KERNEL);
965
966 if (!omap_display_list) {
967 ERR_PRINT("Out of memory");
968 return 1;
969 }
970
971 /* Populate each display info */
972 for (i = 0; i < omap_display_number - 1; i++) {
973 struct omap_overlay_manager *overlay_manager =
974 omap_dss_get_overlay_manager(i);
975 display = &omap_display_list[i];
976 if (!overlay_manager->device) {
977 WRN_PRINT("Display '%s' doesn't have a dss device "
978 "attached to it, ignoring",
979 overlay_manager->name);
980 display->id = OMAP_DISPID_BADSTATE;
981 continue;
982 }
983 if (populate_display_info(display, overlay_manager)) {
984 ERR_PRINT("Error populating display %i info with "
985 "manager '%s'", i,
986 overlay_manager->device->name);
987 display->id = OMAP_DISPID_BADSTATE;
988 continue;
989 }
990 }
991
992 /* Populate virtual display */
993 display = &omap_display_list[omap_display_number - 1];
994 if (populate_virtual_display_info(display)) {
995 ERR_PRINT("Error populating virtual display info");
996 display->id = OMAP_DISPID_BADSTATE;
997 }
998
999 return 0;
1000}
1001
1002struct omap_display_device *omap_display_get(enum omap_display_id id)
1003{
1004 int i;
1005 struct omap_display_device *display;
1006
1007 if (id == OMAP_DISPID_BADSTATE) {
1008 ERR_PRINT("Oops.. user must never request a bad display");
1009 BUG();
1010 }
1011
1012 for (i = 0; i < omap_display_number; i++) {
1013 display = &omap_display_list[i];
1014 if (display->id == id)
1015 return display;
1016 }
1017
1018 ERR_PRINT("Unknown display %i requested", id);
1019 return 0;
1020}
1021EXPORT_SYMBOL(omap_display_get);
1022
1023int omap_display_count(void)
1024{
1025 return omap_display_number;
1026}
1027EXPORT_SYMBOL(omap_display_count);
1028
1029int omap_display_init(void)
1030{
1031 /*
1032 * TODO: Is there a better way to check if list is already created?
1033 */
1034 if (!omap_display_list) {
1035 DBG_PRINT("Initializing driver");
1036 if (create_display_list()) {
1037 ERR_PRINT("Error loading driver");
1038 return 1;
1039 }
1040 }
1041 return 0;
1042}
1043EXPORT_SYMBOL(omap_display_init);
1044
1045int omap_display_deinit(void)
1046{
1047 int i;
1048 int err = 0;
1049 DBG_PRINT("Driver exiting");
1050
1051 for (i = 0; i < omap_display_number; i++) {
1052 struct omap_display_device *display = &omap_display_list[i];
1053
1054 if (!display)
1055 continue;
1056
1057 if (display->main_buffer) {
1058 err = display_destroy_buffer(display->main_buffer);
1059 display->main_buffer = 0;
1060 if (err)
1061 WRN_PRINT("An error happened when destroying "
1062 "main buffer for '%s'", display->name);
1063 }
1064
1065 err = display->close(display);
1066
1067 if (err)
1068 ERR_PRINT("Unable to close display '%s'",
1069 display->name);
1070 }
1071
1072 kfree(omap_display_list);
1073 omap_display_list = 0;
1074
1075 return err;
1076}
1077EXPORT_SYMBOL(omap_display_deinit);
1078
diff --git a/drivers/gpu/pvr/display/omap_display.h b/drivers/gpu/pvr/display/omap_display.h
new file mode 100644
index 00000000000..13916a9461f
--- /dev/null
+++ b/drivers/gpu/pvr/display/omap_display.h
@@ -0,0 +1,109 @@
1/*
2 * drivers/gpu/pvr/display/omap_display.h
3 *
4 * Copyright (C) 2010 Texas Instruments
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <plat/vrfb.h>
20#include <plat/display.h>
21#include <linux/completion.h>
22
23#ifndef __OMAP_DISPLAY_H_
24#define __OMAP_DISPLAY_H_
25
26/* Max overlay managers for virtual display */
27#define OMAP_DISP_MAX_MANAGERS 2
28/* 3 for triple buffering, 4 for virtual display */
29#define OMAP_DISP_MAX_FLIPCHAIN_BUFFERS 4
30#define OMAP_DISP_NUM_DISPLAYS 4 /* lcd, 2lcd, tv, virtual */
31
32struct omap_display_device;
33
34/* On OMAP 4 we can only manage 3 displays at the same time + virtual */
35enum omap_display_id {
36 OMAP_DISPID_PRIMARY = 1 << 0,
37 OMAP_DISPID_SECONDARY = 1 << 1,
38 OMAP_DISPID_TERTIARY = 1 << 2,
39 OMAP_DISPID_VIRTUAL = 1 << 15, /* Multiple displays */
40 OMAP_DISPID_BADSTATE = 1 << 30, /* Used to say a display is unusable*/
41};
42
43enum omap_display_pixel_format {
44 RGB_565 = 0,
45 ARGB_8888 = 1,
46};
47
48/* Primary display location for virtual display */
49enum omap_display_feature {
50 ORIENTATION_VERTICAL = 1 << 0,
51 ORIENTATION_HORIZONTAL = 1 << 1,
52 ORIENTATION_INVERT = 1 << 2,
53};
54
55struct omap_display_buffer {
56 unsigned long physical_addr;
57 unsigned long virtual_addr;
58 unsigned long size;
59 struct omap_display_device *display;
60};
61
62struct omap_display_flip_chain {
63 int buffer_count;
64 struct omap_display_buffer *buffers[OMAP_DISP_MAX_FLIPCHAIN_BUFFERS];
65 struct omap_display_device *display;
66};
67
68struct omap_display_sync_item {
69 struct omap_display_buffer *buffer;
70 struct completion *task;
71 int invalidate;
72};
73
74struct omap_display_device {
75 char *name;
76 enum omap_display_id id;
77 enum omap_display_pixel_format pixel_format;
78 enum omap_display_feature features;
79 unsigned int width;
80 unsigned int height;
81 unsigned int bits_per_pixel;
82 unsigned int bytes_per_pixel;
83 unsigned int byte_stride;
84 enum omap_dss_rotation_angle rotation;
85 unsigned int reference_count;
86 unsigned int buffers_available;
87 struct omap_display_buffer *main_buffer;
88 struct omap_display_flip_chain *flip_chain;
89 struct omap_overlay_manager *overlay_managers[OMAP_DISP_MAX_MANAGERS];
90 unsigned int overlay_managers_count;
91 int (*open)(struct omap_display_device *display,
92 enum omap_display_feature features);
93 int (*close) (struct omap_display_device *display);
94 int (*create_flip_chain) (struct omap_display_device *display,
95 unsigned int buffer_count);
96 int (*destroy_flip_chain) (struct omap_display_device *display);
97 int (*rotate) (struct omap_display_device *display,
98 enum omap_dss_rotation_angle rotation);
99 int (*present_buffer) (struct omap_display_buffer *buffer);
100 int (*sync) (struct omap_display_device *display);
101 int (*present_buffer_sync) (struct omap_display_buffer *buffer);
102};
103
104int omap_display_init(void);
105int omap_display_deinit(void);
106int omap_display_count(void);
107struct omap_display_device *omap_display_get(enum omap_display_id id);
108
109#endif
diff --git a/drivers/gpu/pvr/display/omap_sgx_displayclass.c b/drivers/gpu/pvr/display/omap_sgx_displayclass.c
new file mode 100644
index 00000000000..7b493f1d94e
--- /dev/null
+++ b/drivers/gpu/pvr/display/omap_sgx_displayclass.c
@@ -0,0 +1,1638 @@
1/*************************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 *************************************************************************/
26
27#include <linux/version.h>
28#include <linux/kernel.h>
29#include <linux/console.h>
30
31#include <linux/module.h>
32#include <linux/string.h>
33#include <linux/notifier.h>
34
35#if defined(LDM_PLATFORM)
36#include <linux/platform_device.h>
37#if defined(SGX_EARLYSUSPEND)
38#include <linux/earlysuspend.h>
39#endif
40#endif
41
42#include "img_defs.h"
43#include "servicesext.h"
44#include "kerneldisplay.h"
45#include "omap_sgx_displayclass.h"
46#include "omap_display.h"
47
48/* XXX: Expect 2 framebuffers for virtual display */
49#if (CONFIG_FB_OMAP2_NUM_FBS < 2)
50#error "Virtual display is supported only with 2 or more framebuffers, \
51CONFIG_FB_OMAP2_NUM_FBS must be equal or greater than 2 \
52see CONFIG_FB_OMAP2_NUM_FBS for details in the kernel config"
53#endif
54
55#define OMAP_DC_CMD_COUNT 1
56#define MAX_BUFFERS_FLIPPING 4
57
58/* Pointer Display->Services */
59static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = NULL;
60
61/* Pointer to the display devices */
62static struct OMAP_DISP_DEVINFO *pDisplayDevices = NULL;
63static int display_devices_count = 0;
64
65static void display_sync_handler(struct work_struct *work);
66static enum OMAP_ERROR get_pvr_dc_jtable (char *szFunctionName,
67 PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
68
69
70/*
71 * Swap to display buffer. This buffer refers to one inside the
72 * framebuffer memory.
73 * in: hDevice, hBuffer, ui32SwapInterval, hPrivateTag, ui32ClipRectCount,
74 * psClipRect
75 */
76static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
77 IMG_HANDLE hBuffer,
78 IMG_UINT32 ui32SwapInterval,
79 IMG_HANDLE hPrivateTag,
80 IMG_UINT32 ui32ClipRectCount,
81 IMG_RECT *psClipRect)
82{
83 /* Nothing to do */
84 return PVRSRV_OK;
85}
86
87/*
88 * Set display destination rectangle.
89 * in: hDevice, hSwapChain, psRect
90 */
91static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
92 IMG_HANDLE hSwapChain,
93 IMG_RECT *psRect)
94{
95 /* Nothing to do */
96 return PVRSRV_ERROR_NOT_SUPPORTED;
97}
98
99/*
100 * Set display source rectangle.
101 * in: hDevice, hSwapChain, psRect
102 */
103static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
104 IMG_HANDLE hSwapChain,
105 IMG_RECT *psRect)
106{
107 /* Nothing to do */
108 return PVRSRV_ERROR_NOT_SUPPORTED;
109}
110
111/*
112 * Set display destination colour key.
113 * in: hDevice, hSwapChain, ui32CKColour
114 */
115static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
116 IMG_HANDLE hSwapChain,
117 IMG_UINT32 ui32CKColour)
118{
119 /* Nothing to do */
120 return PVRSRV_ERROR_NOT_SUPPORTED;
121}
122
123/*
124 * Set display source colour key.
125 * in: hDevice, hSwapChain, ui32CKColour
126 */
127static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
128 IMG_HANDLE hSwapChain,
129 IMG_UINT32 ui32CKColour)
130{
131 /* Nothing to do */
132 return PVRSRV_ERROR_NOT_SUPPORTED;
133}
134
135/*
136 * Closes the display.
137 * in: hDevice
138 */
139static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
140{
141 struct OMAP_DISP_DEVINFO *psDevInfo =
142 (struct OMAP_DISP_DEVINFO*) hDevice;
143 struct omap_display_device *display = psDevInfo->display;
144
145 if(display->close(display))
146 WARNING_PRINTK("Unable to close properly display '%s'",
147 display->name);
148
149 return PVRSRV_OK;
150}
151
152/*
153 * Flushes the sync queue present in the specified swap chain.
154 * in: psSwapChain
155 */
156static void FlushInternalSyncQueue(struct OMAP_DISP_SWAPCHAIN *psSwapChain)
157{
158 struct OMAP_DISP_DEVINFO *psDevInfo =
159 (struct OMAP_DISP_DEVINFO*) psSwapChain->pvDevInfo;
160 struct OMAP_DISP_FLIP_ITEM *psFlipItem;
161 struct omap_display_device *display = psDevInfo->display;
162 unsigned long ulMaxIndex;
163 unsigned long i;
164
165 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
166 ulMaxIndex = psSwapChain->ulBufferCount - 1;
167
168 DEBUG_PRINTK("Flushing sync queue on display %lu",
169 psDevInfo->ulDeviceID);
170 for(i = 0; i < psSwapChain->ulBufferCount; i++)
171 {
172 if (psFlipItem->bValid == OMAP_FALSE)
173 continue;
174
175 DEBUG_PRINTK("Flushing swap buffer index %lu",
176 psSwapChain->ulRemoveIndex);
177
178 /* Flip the buffer if it hasn't been flipped */
179 if(psFlipItem->bFlipped == OMAP_FALSE)
180 {
181 display->present_buffer(psFlipItem->display_buffer);
182 }
183
184 /* If the command didn't complete, assume it did */
185 if(psFlipItem->bCmdCompleted == OMAP_FALSE)
186 {
187 DEBUG_PRINTK("Calling command complete for swap "
188 "buffer index %lu",
189 psSwapChain->ulRemoveIndex);
190 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
191 (IMG_HANDLE)psFlipItem->hCmdComplete,
192 IMG_TRUE);
193 }
194
195 psSwapChain->ulRemoveIndex++;
196 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
197 psSwapChain->ulRemoveIndex = 0;
198
199 /* Put the state of the buffer to be used again later */
200 psFlipItem->bFlipped = OMAP_FALSE;
201 psFlipItem->bCmdCompleted = OMAP_FALSE;
202 psFlipItem->bValid = OMAP_FALSE;
203 psFlipItem =
204 &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
205 }
206
207 psSwapChain->ulInsertIndex = 0;
208 psSwapChain->ulRemoveIndex = 0;
209}
210
211/*
212 * Sets the flush state of the specified display device
213 * at the swap chain level without blocking the call.
214 * in: psDevInfo, bFlushState
215 */
216static void SetFlushStateInternalNoLock(struct OMAP_DISP_DEVINFO* psDevInfo,
217 enum OMAP_BOOL bFlushState)
218{
219 struct OMAP_DISP_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
220
221 /* Nothing to do if there is no swap chain */
222 if (psSwapChain == NULL){
223 DEBUG_PRINTK("Swap chain is null, nothing to do for"
224 " display %lu", psDevInfo->ulDeviceID);
225 return;
226 }
227
228 if (bFlushState)
229 {
230 DEBUG_PRINTK("Desired flushState is true for display %lu",
231 psDevInfo->ulDeviceID);
232 if (psSwapChain->ulSetFlushStateRefCount == 0)
233 {
234 psSwapChain->bFlushCommands = OMAP_TRUE;
235 FlushInternalSyncQueue(psSwapChain);
236 }
237 psSwapChain->ulSetFlushStateRefCount++;
238 }
239 else
240 {
241 DEBUG_PRINTK("Desired flushState is false for display %lu",
242 psDevInfo->ulDeviceID);
243 if (psSwapChain->ulSetFlushStateRefCount != 0)
244 {
245 psSwapChain->ulSetFlushStateRefCount--;
246 if (psSwapChain->ulSetFlushStateRefCount == 0)
247 {
248 psSwapChain->bFlushCommands = OMAP_FALSE;
249 }
250 }
251 }
252}
253
254/*
255 * Sets the flush state of the specified display device
256 * at device level blocking the call if needed.
257 * in: psDevInfo, bFlushState
258 */
259static void SetFlushStateExternal(struct OMAP_DISP_DEVINFO* psDevInfo,
260 enum OMAP_BOOL bFlushState)
261{
262 DEBUG_PRINTK("Executing for display %lu",
263 psDevInfo->ulDeviceID);
264 mutex_lock(&psDevInfo->sSwapChainLockMutex);
265 if (psDevInfo->bFlushCommands != bFlushState)
266 {
267 psDevInfo->bFlushCommands = bFlushState;
268 SetFlushStateInternalNoLock(psDevInfo, bFlushState);
269 }
270 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
271}
272
273/*
274 * Opens the display.
275 * in: ui32DeviceID, phDevice
276 * out: psSystemBufferSyncData
277 */
278static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
279 IMG_HANDLE *phDevice,
280 PVRSRV_SYNC_DATA* psSystemBufferSyncData)
281{
282 struct OMAP_DISP_DEVINFO *psDevInfo;
283 struct omap_display_device *display;
284 int i;
285
286 psDevInfo = 0;
287 for(i = 0; i < display_devices_count; i++)
288 {
289 if(ui32DeviceID == (&pDisplayDevices[i])->ulDeviceID)
290 {
291 psDevInfo = &pDisplayDevices[i];
292 break;
293 }
294 }
295
296 if(!psDevInfo)
297 {
298 WARNING_PRINTK("Unable to identify display device with id %i",
299 (int)ui32DeviceID);
300 return OMAP_ERROR_INVALID_DEVICE;
301 }
302
303 psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
304 display = psDevInfo->display;
305
306 DEBUG_PRINTK("Opening display %lu '%s'",psDevInfo->ulDeviceID,
307 display->name);
308
309 /* TODO: Explain here why ORIENTATION_VERTICAL is used*/
310 if(display->open(display, ORIENTATION_VERTICAL | ORIENTATION_INVERT))
311 ERROR_PRINTK("Unable to open properly display '%s'",
312 psDevInfo->display->name);
313
314 display->present_buffer(display->main_buffer);
315
316 /* TODO: Turn on display here? */
317
318 *phDevice = (IMG_HANDLE)psDevInfo;
319
320 return PVRSRV_OK;
321}
322
323/*
324 * Gets the available formats for the display.
325 * in: hDevice
326 * out: pui32NumFormats, psFormat
327 */
328static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
329 IMG_UINT32 *pui32NumFormats,
330 DISPLAY_FORMAT *psFormat)
331{
332 struct OMAP_DISP_DEVINFO *psDevInfo;
333 if(!hDevice || !pui32NumFormats)
334 {
335 ERROR_PRINTK("Invalid parameters");
336 return PVRSRV_ERROR_INVALID_PARAMS;
337 }
338
339 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
340 *pui32NumFormats = 1;
341
342 if(psFormat)
343 psFormat[0] = psDevInfo->sDisplayFormat;
344 else
345 WARNING_PRINTK("Display format is null for"
346 " display %lu", psDevInfo->ulDeviceID);
347
348 return PVRSRV_OK;
349}
350
351/*
352 * Gets the available dimensions for the display.
353 * in: hDevice, psFormat
354 * out: pui32NumDims, psDim
355 */
356static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
357 DISPLAY_FORMAT *psFormat,
358 IMG_UINT32 *pui32NumDims,
359 DISPLAY_DIMS *psDim)
360{
361 struct OMAP_DISP_DEVINFO *psDevInfo;
362 if(!hDevice || !psFormat || !pui32NumDims)
363 {
364 ERROR_PRINTK("Invalid parameters");
365 return PVRSRV_ERROR_INVALID_PARAMS;
366 }
367
368 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
369 *pui32NumDims = 1;
370
371 if(psDim)
372 psDim[0] = psDevInfo->sDisplayDim;
373 else
374 WARNING_PRINTK("Display dimensions are null for"
375 " display %lu", psDevInfo->ulDeviceID);
376
377 return PVRSRV_OK;
378}
379
380/*
381 * Gets the display framebuffer physical address.
382 * in: hDevice
383 * out: phBuffer
384 */
385static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
386{
387 struct OMAP_DISP_DEVINFO *psDevInfo;
388
389 if(!hDevice || !phBuffer)
390 {
391 ERROR_PRINTK("Invalid parameters");
392 return PVRSRV_ERROR_INVALID_PARAMS;
393 }
394
395 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
396 *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
397
398 return PVRSRV_OK;
399}
400
401/*
402 * Gets the display general information.
403 * in: hDevice
404 * out: psDCInfo
405 */
406static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
407{
408 struct OMAP_DISP_DEVINFO *psDevInfo;
409
410 if(!hDevice || !psDCInfo)
411 {
412 ERROR_PRINTK("Invalid parameters");
413 return PVRSRV_ERROR_INVALID_PARAMS;
414 }
415
416 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
417 *psDCInfo = psDevInfo->sDisplayInfo;
418
419 return PVRSRV_OK;
420}
421
422/*
423 * Gets the display framebuffer virtual address.
424 * in: hDevice
425 * out: ppsSysAddr, pui32ByteSize, ppvCpuVAddr, phOSMapInfo, pbIsContiguous
426 */
427static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice,
428 IMG_HANDLE hBuffer,
429 IMG_SYS_PHYADDR **ppsSysAddr,
430 IMG_UINT32 *pui32ByteSize,
431 IMG_VOID **ppvCpuVAddr,
432 IMG_HANDLE *phOSMapInfo,
433 IMG_BOOL *pbIsContiguous,
434 IMG_UINT32 *pui32TilingStride)
435{
436 struct OMAP_DISP_DEVINFO *psDevInfo;
437 struct OMAP_DISP_BUFFER *psSystemBuffer;
438
439 if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize )
440 {
441 ERROR_PRINTK("Invalid parameters");
442 return PVRSRV_ERROR_INVALID_PARAMS;
443 }
444
445 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
446 psSystemBuffer = (struct OMAP_DISP_BUFFER *)hBuffer;
447 *ppsSysAddr = &psSystemBuffer->sSysAddr;
448 *pui32ByteSize = (IMG_UINT32)psDevInfo->sSystemBuffer.ulBufferSize;
449
450 if (ppvCpuVAddr)
451 *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
452
453 if (phOSMapInfo)
454 *phOSMapInfo = (IMG_HANDLE)0;
455
456 if (pbIsContiguous)
457 *pbIsContiguous = IMG_TRUE;
458
459 return PVRSRV_OK;
460}
461
462/*
463 * Creates a swap chain. Called when a 3D application begins.
464 * in: hDevice, ui32Flags, ui32BufferCount, psDstSurfAttrib, psSrcSurfAttrib
465 * ui32OEMFlags
466 * out: phSwapChain, ppsSyncData, pui32SwapChainID
467 */
468static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
469 IMG_UINT32 ui32Flags,
470 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
471 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
472 IMG_UINT32 ui32BufferCount,
473 PVRSRV_SYNC_DATA **ppsSyncData,
474 IMG_UINT32 ui32OEMFlags,
475 IMG_HANDLE *phSwapChain,
476 IMG_UINT32 *pui32SwapChainID)
477{
478 struct OMAP_DISP_DEVINFO *psDevInfo;
479 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
480 struct OMAP_DISP_BUFFER *psBuffer;
481 struct OMAP_DISP_FLIP_ITEM *psFlipItems;
482 IMG_UINT32 i;
483 PVRSRV_ERROR eError;
484 IMG_UINT32 ui32BuffersToSkip;
485 struct omap_display_device *display;
486 int err;
487
488 if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib ||
489 !ppsSyncData || !phSwapChain)
490 {
491 ERROR_PRINTK("Invalid parameters");
492 return PVRSRV_ERROR_INVALID_PARAMS;
493 }
494 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
495
496 if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
497 {
498 ERROR_PRINTK("Unable to operate with 0 MaxSwapChains for"
499 " display %lu", psDevInfo->ulDeviceID);
500 return PVRSRV_ERROR_NOT_SUPPORTED;
501 }
502
503 if(psDevInfo->psSwapChain != NULL)
504 {
505 ERROR_PRINTK("Swap chain already exists for"
506 " display %lu", psDevInfo->ulDeviceID);
507 return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
508 }
509
510 if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
511 {
512 ERROR_PRINTK("Too many buffers. Trying to use %u buffers while"
513 " there is only %u available for display %lu",
514 (unsigned int)ui32BufferCount,
515 (unsigned int)psDevInfo->
516 sDisplayInfo.ui32MaxSwapChainBuffers,
517 psDevInfo->ulDeviceID);
518 return PVRSRV_ERROR_TOOMANYBUFFERS;
519 }
520
521 ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers -
522 ui32BufferCount;
523
524 if((psDstSurfAttrib->pixelformat !=
525 psDevInfo->sDisplayFormat.pixelformat) ||
526 (psDstSurfAttrib->sDims.ui32ByteStride !=
527 psDevInfo->sDisplayDim.ui32ByteStride) ||
528 (psDstSurfAttrib->sDims.ui32Width !=
529 psDevInfo->sDisplayDim.ui32Width) ||
530 (psDstSurfAttrib->sDims.ui32Height !=
531 psDevInfo->sDisplayDim.ui32Height))
532 {
533 ERROR_PRINTK("Destination surface attributes differ from the"
534 " current framebuffer for display %lu",
535 psDevInfo->ulDeviceID);
536 return PVRSRV_ERROR_INVALID_PARAMS;
537 }
538
539 if((psDstSurfAttrib->pixelformat !=
540 psSrcSurfAttrib->pixelformat) ||
541 (psDstSurfAttrib->sDims.ui32ByteStride !=
542 psSrcSurfAttrib->sDims.ui32ByteStride) ||
543 (psDstSurfAttrib->sDims.ui32Width !=
544 psSrcSurfAttrib->sDims.ui32Width) ||
545 (psDstSurfAttrib->sDims.ui32Height !=
546 psSrcSurfAttrib->sDims.ui32Height))
547 {
548 ERROR_PRINTK("Destination surface attributes differ from the"
549 " target destination surface for display %lu",
550 psDevInfo->ulDeviceID);
551 return PVRSRV_ERROR_INVALID_PARAMS;
552 }
553
554 /* Create the flip chain in display side */
555 display = psDevInfo->display;
556 /* TODO: What about TILER buffers? */
557 /*
558 * Creating the flip chain with the maximum number of buffers
559 * we will decide which ones will be used later
560 */
561 err = display->create_flip_chain(
562 display, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers);
563 if(err)
564 {
565 ERROR_PRINTK("Unable to create the flip chain for '%s' display"
566 " id %lu", display->name, psDevInfo->ulDeviceID);
567 return PVRSRV_ERROR_INVALID_PARAMS;
568 }
569
570 /* Allocate memory needed for the swap chain */
571 psSwapChain = (struct OMAP_DISP_SWAPCHAIN*) kmalloc(
572 sizeof(struct OMAP_DISP_SWAPCHAIN), GFP_KERNEL);
573 if(!psSwapChain)
574 {
575 ERROR_PRINTK("Out of memory to allocate swap chain for"
576 " display %lu", psDevInfo->ulDeviceID);
577 return PVRSRV_ERROR_OUT_OF_MEMORY;
578 }
579
580 DEBUG_PRINTK("Creating swap chain for display %lu",
581 psDevInfo->ulDeviceID );
582
583 /* Allocate memory for the buffer abstraction structures */
584 psBuffer = (struct OMAP_DISP_BUFFER*) kmalloc(
585 sizeof(struct OMAP_DISP_BUFFER) * ui32BufferCount, GFP_KERNEL);
586 if(!psBuffer)
587 {
588 ERROR_PRINTK("Out of memory to allocate the buffer"
589 " abstraction structures for display %lu",
590 psDevInfo->ulDeviceID);
591 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
592 goto ErrorFreeSwapChain;
593 }
594
595 /* Allocate memory for the flip item abstraction structures */
596 psFlipItems = (struct OMAP_DISP_FLIP_ITEM *) kmalloc (
597 sizeof(struct OMAP_DISP_FLIP_ITEM) * ui32BufferCount,
598 GFP_KERNEL);
599 if (!psFlipItems)
600 {
601 ERROR_PRINTK("Out of memory to allocate the flip item"
602 " abstraction structures for display %lu",
603 psDevInfo->ulDeviceID);
604 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
605 goto ErrorFreeBuffers;
606 }
607
608 /* Assign to the swap chain structure the initial data */
609 psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
610 psSwapChain->psBuffer = psBuffer;
611 psSwapChain->psFlipItems = psFlipItems;
612 psSwapChain->ulInsertIndex = 0;
613 psSwapChain->ulRemoveIndex = 0;
614 psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
615 psSwapChain->pvDevInfo = (void*)psDevInfo;
616
617 /*
618 * Init the workqueue (single thread, freezable and real time)
619 * and its own work for this display
620 */
621 INIT_WORK(&psDevInfo->sync_display_work, display_sync_handler);
622 psDevInfo->sync_display_wq =
623 __create_workqueue("pvr_display_sync_wq", 1, 1, 1);
624
625 DEBUG_PRINTK("Swap chain will have %u buffers for display %lu",
626 (unsigned int)ui32BufferCount, psDevInfo->ulDeviceID);
627 /* Link the buffers available like a circular list */
628 for(i=0; i<ui32BufferCount-1; i++)
629 {
630 psBuffer[i].psNext = &psBuffer[i+1];
631 }
632 psBuffer[i].psNext = &psBuffer[0];
633
634 /* Initialize each buffer abstraction structure */
635 for(i=0; i<ui32BufferCount; i++)
636 {
637 /* Get the needed buffers from the display flip chain */
638 IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
639 struct omap_display_buffer * flip_buffer =
640 display->flip_chain->buffers[ui32SwapBuffer];
641 psBuffer[i].display_buffer = flip_buffer;
642 psBuffer[i].psSyncData = ppsSyncData[i];
643 psBuffer[i].sSysAddr.uiAddr = flip_buffer->physical_addr;
644 psBuffer[i].sCPUVAddr =
645 (IMG_CPU_VIRTADDR) flip_buffer->virtual_addr;
646 DEBUG_PRINTK("Display %lu buffer index %u has physical "
647 "address 0x%x",
648 psDevInfo->ulDeviceID,
649 (unsigned int)i,
650 (unsigned int)psBuffer[i].sSysAddr.uiAddr);
651 }
652
653 /* Initialize each flip item abstraction structure */
654 for(i=0; i<ui32BufferCount; i++)
655 {
656 psFlipItems[i].bValid = OMAP_FALSE;
657 psFlipItems[i].bFlipped = OMAP_FALSE;
658 psFlipItems[i].bCmdCompleted = OMAP_FALSE;
659 psFlipItems[i].display_buffer = 0;
660 }
661
662 mutex_lock(&psDevInfo->sSwapChainLockMutex);
663
664 psDevInfo->psSwapChain = psSwapChain;
665 psSwapChain->bFlushCommands = psDevInfo->bFlushCommands;
666 if (psSwapChain->bFlushCommands)
667 psSwapChain->ulSetFlushStateRefCount = 1;
668 else
669 psSwapChain->ulSetFlushStateRefCount = 0;
670
671 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
672
673 *phSwapChain = (IMG_HANDLE)psSwapChain;
674
675 return PVRSRV_OK;
676
677ErrorFreeBuffers:
678 kfree(psBuffer);
679ErrorFreeSwapChain:
680 kfree(psSwapChain);
681
682 return eError;
683}
684
685/*
686 * Destroy a swap chain. Called when a 3D application ends.
687 * in: hDevice, hSwapChain
688 */
689static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
690 IMG_HANDLE hSwapChain)
691{
692 struct OMAP_DISP_DEVINFO *psDevInfo;
693 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
694 struct omap_display_device *display;
695 int err;
696
697 if(!hDevice || !hSwapChain)
698 {
699 ERROR_PRINTK("Invalid parameters");
700 return PVRSRV_ERROR_INVALID_PARAMS;
701 }
702
703 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
704 psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
705 display = psDevInfo->display;
706
707 if (psSwapChain != psDevInfo->psSwapChain)
708 {
709 ERROR_PRINTK("Swap chain handler differs from the one "
710 "present in the display device pointer");
711 return PVRSRV_ERROR_INVALID_PARAMS;
712 }
713
714 DEBUG_PRINTK("Destroying swap chain for display %lu",
715 psDevInfo->ulDeviceID);
716
717 mutex_lock(&psDevInfo->sSwapChainLockMutex);
718
719 FlushInternalSyncQueue(psSwapChain);
720 psDevInfo->psSwapChain = NULL;
721
722 /*
723 * Present the buffer which is at the base of address of
724 * the framebuffer
725 */
726 display->present_buffer(display->main_buffer);
727
728 /* Destroy the flip chain in display side */
729 err = display->destroy_flip_chain(display);
730 if(err)
731 {
732 ERROR_PRINTK("Unable to destroy the flip chain for '%s' "
733 "display id %lu", display->name,
734 psDevInfo->ulDeviceID);
735 }
736
737 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
738
739 /* Destroy the workqueue */
740 flush_workqueue(psDevInfo->sync_display_wq);
741 destroy_workqueue(psDevInfo->sync_display_wq);
742
743 kfree(psSwapChain->psFlipItems);
744 kfree(psSwapChain->psBuffer);
745 kfree(psSwapChain);
746
747 return PVRSRV_OK;
748}
749
750
751/*
752 * Get display buffers. These are the buffers that can be allocated
753 * inside the framebuffer memory.
754 * in: hDevice, hSwapChain
755 * out: pui32BufferCount, phBuffer
756 */
757static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
758 IMG_HANDLE hSwapChain,
759 IMG_UINT32 *pui32BufferCount,
760 IMG_HANDLE *phBuffer)
761{
762 struct OMAP_DISP_DEVINFO *psDevInfo;
763 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
764 unsigned long i;
765
766 if(!hDevice || !hSwapChain || !pui32BufferCount || !phBuffer)
767 {
768 ERROR_PRINTK("Invalid parameters");
769 return PVRSRV_ERROR_INVALID_PARAMS;
770 }
771
772 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
773 psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
774 if (psSwapChain != psDevInfo->psSwapChain)
775 {
776 ERROR_PRINTK("Swap chain handler differs from the one "
777 "present in the display device %lu pointer",
778 psDevInfo->ulDeviceID);
779 return PVRSRV_ERROR_INVALID_PARAMS;
780 }
781 *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
782
783 for(i=0; i<psSwapChain->ulBufferCount; i++)
784 phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
785
786 return PVRSRV_OK;
787}
788
789/*
790 * Sets the display state.
791 * in: ui32State, hDevice
792 */
793static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
794{
795 struct OMAP_DISP_DEVINFO *psDevInfo =
796 (struct OMAP_DISP_DEVINFO*) hDevice;
797
798 switch (ui32State)
799 {
800 case DC_STATE_FLUSH_COMMANDS:
801 DEBUG_PRINTK("Setting state to flush commands for"
802 " display %lu", psDevInfo->ulDeviceID);
803 SetFlushStateExternal(psDevInfo, OMAP_TRUE);
804 break;
805 case DC_STATE_NO_FLUSH_COMMANDS:
806 DEBUG_PRINTK("Setting state to not flush commands for"
807 " display %lu", psDevInfo->ulDeviceID);
808 SetFlushStateExternal(psDevInfo, OMAP_FALSE);
809 break;
810 default:
811 WARNING_PRINTK("Unknown command state %u for display"
812 " %lu", (unsigned int)ui32State,
813 psDevInfo->ulDeviceID);
814 break;
815 }
816}
817
818/*
819 * Swap to display system buffer. This buffer refers to the one which
820 * is that fits in the framebuffer memory.
821 * in: hDevice, hSwapChain
822 */
823static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
824 IMG_HANDLE hSwapChain)
825{
826 struct OMAP_DISP_DEVINFO *psDevInfo;
827 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
828 struct omap_display_device *display;
829
830 if(!hDevice || !hSwapChain)
831 {
832 ERROR_PRINTK("Invalid parameters");
833 return PVRSRV_ERROR_INVALID_PARAMS;
834 }
835
836 psDevInfo = (struct OMAP_DISP_DEVINFO*)hDevice;
837 psSwapChain = (struct OMAP_DISP_SWAPCHAIN*)hSwapChain;
838 display = psDevInfo->display;
839
840 DEBUG_PRINTK("Executing for display %lu",
841 psDevInfo->ulDeviceID);
842
843 if (psSwapChain != psDevInfo->psSwapChain)
844 {
845 ERROR_PRINTK("Swap chain handler differs from the one "
846 "present in the display device %lu pointer",
847 psDevInfo->ulDeviceID);
848 return PVRSRV_ERROR_INVALID_PARAMS;
849 }
850
851 mutex_lock(&psDevInfo->sSwapChainLockMutex);
852
853 FlushInternalSyncQueue(psSwapChain);
854 display->present_buffer(display->main_buffer);
855
856 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
857
858 return PVRSRV_OK;
859}
860
861/*
862 * Handles the synchronization with the display
863 * in: work
864 */
865
866static void display_sync_handler(struct work_struct *work)
867{
868 /*
869 * TODO: Since present_buffer_sync waits and then present, this
870 * algorithm can be simplified further
871 */
872 struct OMAP_DISP_DEVINFO *psDevInfo = container_of(work,
873 struct OMAP_DISP_DEVINFO, sync_display_work);
874 struct omap_display_device *display = psDevInfo->display;
875 struct OMAP_DISP_FLIP_ITEM *psFlipItem;
876 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
877 unsigned long ulMaxIndex;
878
879 mutex_lock(&psDevInfo->sSwapChainLockMutex);
880
881 psSwapChain = psDevInfo->psSwapChain;
882 if (!psSwapChain || psSwapChain->bFlushCommands)
883 goto ExitUnlock;
884
885 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
886 ulMaxIndex = psSwapChain->ulBufferCount - 1;
887
888 /* Iterate through the flip items and flip them if necessary */
889 while(psFlipItem->bValid)
890 {
891 if(psFlipItem->bFlipped)
892 {
893 if(!psFlipItem->bCmdCompleted)
894 {
895 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
896 (IMG_HANDLE)psFlipItem->hCmdComplete,
897 IMG_TRUE);
898 psFlipItem->bCmdCompleted = OMAP_TRUE;
899 }
900
901 if(psFlipItem->ulSwapInterval == 0)
902 {
903 psSwapChain->ulRemoveIndex++;
904 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
905 psSwapChain->ulRemoveIndex = 0;
906 psFlipItem->bCmdCompleted = OMAP_FALSE;
907 psFlipItem->bFlipped = OMAP_FALSE;
908 psFlipItem->bValid = OMAP_FALSE;
909 }
910 else
911 {
912 /*
913 * Here the swap interval is not zero yet
914 * we need to schedule another work until
915 * it reaches zero
916 */
917 display->sync(display);
918 psFlipItem->ulSwapInterval--;
919 queue_work(psDevInfo->sync_display_wq,
920 &psDevInfo->sync_display_work);
921 goto ExitUnlock;
922 }
923 }
924 else
925 {
926 display->present_buffer_sync(
927 psFlipItem->display_buffer);
928 /*
929 * present_buffer_sync waits and then present, then
930 * swap interval decreases here too.
931 */
932 psFlipItem->ulSwapInterval--;
933 psFlipItem->bFlipped = OMAP_TRUE;
934 /*
935 * If the flip has been presented here then we need
936 * in the next sync execute the command complete,
937 * schedule another work
938 */
939 queue_work(psDevInfo->sync_display_wq,
940 &psDevInfo->sync_display_work);
941 goto ExitUnlock;
942 }
943 psFlipItem =
944 &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
945 }
946
947ExitUnlock:
948 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
949}
950
951/*
952 * Performs a flip. This function takes the necessary steps to present
953 * the buffer to be flipped in the display.
954 * in: hCmdCookie, ui32DataSize, pvData
955 */
956static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
957 IMG_UINT32 ui32DataSize,
958 IMG_VOID *pvData)
959{
960 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
961 struct OMAP_DISP_DEVINFO *psDevInfo;
962 struct OMAP_DISP_BUFFER *psBuffer;
963 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
964 struct omap_display_device *display;
965#if defined(SYS_USING_INTERRUPTS)
966 struct OMAP_DISP_FLIP_ITEM* psFlipItem;
967#endif
968
969 if(!hCmdCookie || !pvData)
970 {
971 WARNING_PRINTK("Ignoring call with NULL parameters");
972 return IMG_FALSE;
973 }
974
975 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
976
977 if (psFlipCmd == IMG_NULL ||
978 sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
979 {
980 WARNING_PRINTK("NULL command or command data size is wrong");
981 return IMG_FALSE;
982 }
983
984 psDevInfo = (struct OMAP_DISP_DEVINFO*)psFlipCmd->hExtDevice;
985 psBuffer = (struct OMAP_DISP_BUFFER*)psFlipCmd->hExtBuffer;
986 psSwapChain = (struct OMAP_DISP_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
987 display = psDevInfo->display;
988
989 mutex_lock(&psDevInfo->sSwapChainLockMutex);
990
991 if (psDevInfo->bDeviceSuspended)
992 {
993 /* If is suspended then assume the commands are completed */
994 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
995 hCmdCookie, IMG_TRUE);
996 goto ExitTrueUnlock;
997 }
998
999#if defined(SYS_USING_INTERRUPTS)
1000
1001 if( psFlipCmd->ui32SwapInterval == 0 ||
1002 psSwapChain->bFlushCommands == OMAP_TRUE)
1003 {
1004#endif
1005 display->present_buffer(psBuffer->display_buffer);
1006 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
1007 hCmdCookie, IMG_TRUE);
1008
1009#if defined(SYS_USING_INTERRUPTS)
1010 goto ExitTrueUnlock;
1011 }
1012
1013 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulInsertIndex];
1014
1015 if(psFlipItem->bValid == OMAP_FALSE)
1016 {
1017 unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1;
1018
1019 psFlipItem->bFlipped = OMAP_FALSE;
1020
1021 /*
1022 * The buffer is queued here, must be consumed by the workqueue
1023 */
1024 psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie;
1025 psFlipItem->ulSwapInterval =
1026 (unsigned long)psFlipCmd->ui32SwapInterval;
1027 psFlipItem->sSysAddr = &psBuffer->sSysAddr;
1028 psFlipItem->bValid = OMAP_TRUE;
1029 psFlipItem->display_buffer = psBuffer->display_buffer;
1030
1031 psSwapChain->ulInsertIndex++;
1032 if(psSwapChain->ulInsertIndex > ulMaxIndex)
1033 psSwapChain->ulInsertIndex = 0;
1034
1035 /* Give work to the workqueue to sync with the display */
1036 queue_work(psDevInfo->sync_display_wq,
1037 &psDevInfo->sync_display_work);
1038
1039 goto ExitTrueUnlock;
1040 }
1041
1042 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1043 return IMG_FALSE;
1044#endif
1045
1046ExitTrueUnlock:
1047 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1048 return IMG_TRUE;
1049}
1050
1051#if defined(LDM_PLATFORM)
1052
1053/*
1054 * Function called when the driver must suspend
1055 */
1056static void DriverSuspend(void)
1057{
1058 struct OMAP_DISP_DEVINFO *psDevInfo;
1059 int i;
1060
1061 if(!pDisplayDevices)
1062 return;
1063
1064 for(i = 0; i < display_devices_count; i++)
1065 {
1066 psDevInfo = &pDisplayDevices[i];
1067
1068 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1069
1070 if (psDevInfo->bDeviceSuspended)
1071 {
1072 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1073 continue;
1074 }
1075
1076 psDevInfo->bDeviceSuspended = OMAP_TRUE;
1077 SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE);
1078
1079 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1080 }
1081}
1082
1083/*
1084 * Function called when the driver must resume
1085 */
1086static void DriverResume(void)
1087{
1088 struct OMAP_DISP_DEVINFO *psDevInfo;
1089 int i;
1090
1091 if(!pDisplayDevices)
1092 return;
1093
1094 for(i = 0; i < display_devices_count; i++)
1095 {
1096 psDevInfo = &pDisplayDevices[i];
1097
1098 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1099
1100 if (!psDevInfo->bDeviceSuspended)
1101 {
1102 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1103 continue;
1104 }
1105
1106 SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE);
1107 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1108
1109 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1110 }
1111}
1112#endif /* defined(LDM_PLATFORM) */
1113
1114/*
1115 * Frees the kernel framebuffer
1116 * in: psDevInfo
1117 */
1118static void deinit_display_device(struct OMAP_DISP_DEVINFO *psDevInfo)
1119{
1120 /* TODO: Are we sure there is nothing to do here? */
1121}
1122
1123/*
1124 * Deinitialization routine for the 3rd party display driver
1125 */
1126static enum OMAP_ERROR destroy_display_devices(void)
1127{
1128 struct OMAP_DISP_DEVINFO *psDevInfo;
1129 PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable;
1130 int i;
1131
1132 DEBUG_PRINTK("Deinitializing 3rd party display driver");
1133
1134 if(!pDisplayDevices)
1135 return OMAP_OK;
1136
1137 for(i = 0; i < display_devices_count; i++)
1138 {
1139 psDevInfo = &pDisplayDevices[i];
1140 if(!psDevInfo->display)
1141 continue;
1142
1143 /* Remove the ProcessFlip command callback */
1144 psJTable = &psDevInfo->sPVRJTable;
1145
1146 if(!psJTable)
1147 continue;
1148
1149 if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(
1150 psDevInfo->ulDeviceID,
1151 OMAP_DC_CMD_COUNT) != PVRSRV_OK)
1152 {
1153 ERROR_PRINTK("Unable to remove callback for "
1154 "ProcessFlip command for display %lu",
1155 psDevInfo->ulDeviceID);
1156 return OMAP_ERROR_GENERIC;
1157 }
1158
1159 /* Remove the display device from services */
1160 if (psJTable->pfnPVRSRVRemoveDCDevice(
1161 psDevInfo->ulDeviceID) != PVRSRV_OK)
1162 {
1163 ERROR_PRINTK("Unable to remove the display %lu "
1164 "from services", psDevInfo->ulDeviceID);
1165 return OMAP_ERROR_GENERIC;
1166 }
1167
1168 deinit_display_device(psDevInfo);
1169 }
1170
1171 kfree(pDisplayDevices);
1172
1173 return OMAP_OK;
1174}
1175
1176/*
1177 * Extracts the framebuffer data from the kernel driver
1178 * in: psDevInfo
1179 */
1180static enum OMAP_ERROR init_display_device(struct OMAP_DISP_DEVINFO *psDevInfo,
1181 struct omap_display_device *display)
1182{
1183 int buffers_available = display->buffers_available;
1184
1185 /* Extract the needed data from the display struct */
1186 DEBUG_PRINTK("Display '%s' id %i information:", display->name,
1187 display->id);
1188 DEBUG_PRINTK("*Width, height: %u,%u", display->width,
1189 display->height);
1190 DEBUG_PRINTK("*Rotation: %u", display->rotation);
1191 DEBUG_PRINTK("*Stride: %u bytes", display->byte_stride);
1192 DEBUG_PRINTK("*Buffers available: %u", buffers_available);
1193 DEBUG_PRINTK("*Bytes per pixel: %u (%u bpp)",
1194 display->bytes_per_pixel, display->bits_per_pixel);
1195
1196 if(display->bits_per_pixel == 16)
1197 {
1198 if(display->pixel_format == RGB_565)
1199 {
1200 DEBUG_PRINTK("*Format: RGB565");
1201 psDevInfo->sDisplayFormat.pixelformat =
1202 PVRSRV_PIXEL_FORMAT_RGB565;
1203 }
1204 else
1205 WARNING_PRINTK("*Format: Unknown framebuffer"
1206 "format");
1207 }
1208 else if(display->bits_per_pixel == 24 ||
1209 display->bits_per_pixel == 32)
1210 {
1211 if(display->pixel_format == ARGB_8888)
1212 {
1213 DEBUG_PRINTK("*Format: ARGB8888");
1214 psDevInfo->sDisplayFormat.pixelformat =
1215 PVRSRV_PIXEL_FORMAT_ARGB8888;
1216
1217 }
1218 else
1219 WARNING_PRINTK("*Format: Unknown framebuffer"
1220 "format");
1221 }
1222 else
1223 WARNING_PRINTK("*Format: Unknown framebuffer format");
1224
1225 if(display->main_buffer)
1226 {
1227 DEBUG_PRINTK("*Bytes per buffer: %lu",
1228 display->main_buffer->size);
1229 DEBUG_PRINTK("*Main buffer physical address: 0x%lx",
1230 display->main_buffer->physical_addr);
1231 DEBUG_PRINTK("*Main buffer virtual address: 0x%lx",
1232 display->main_buffer->virtual_addr);
1233 DEBUG_PRINTK("*Main buffer size: %lu bytes",
1234 display->main_buffer->size);
1235 }
1236 else
1237 {
1238 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 0;
1239 ERROR_PRINTK("*No main buffer found for display '%s'",
1240 display->name);
1241 return OMAP_ERROR_INIT_FAILURE;
1242 }
1243
1244 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = buffers_available;
1245 mutex_init(&psDevInfo->sSwapChainLockMutex);
1246 psDevInfo->psSwapChain = 0;
1247 psDevInfo->bFlushCommands = OMAP_FALSE;
1248 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1249
1250 if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 1)
1251 {
1252 if(MAX_BUFFERS_FLIPPING == 1)
1253 {
1254 DEBUG_PRINTK("Flipping support is possible"
1255 " but you decided not to use it");
1256 }
1257
1258 DEBUG_PRINTK("*Flipping support");
1259 if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers >
1260 MAX_BUFFERS_FLIPPING)
1261 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers =
1262 MAX_BUFFERS_FLIPPING;
1263 }
1264 else
1265 {
1266 DEBUG_PRINTK("*Flipping not supported");
1267 }
1268
1269 if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0)
1270 {
1271 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0;
1272 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0;
1273 }
1274 else
1275 {
1276 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
1277 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
1278 }
1279 psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
1280
1281 /* Get the display and framebuffer needed info */
1282 strncpy(psDevInfo->sDisplayInfo.szDisplayName,
1283 DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
1284
1285 psDevInfo->sDisplayDim.ui32Width = display->width;
1286 psDevInfo->sDisplayDim.ui32Height = display->height;
1287 psDevInfo->sDisplayDim.ui32ByteStride = display->byte_stride;
1288 psDevInfo->sSystemBuffer.sSysAddr.uiAddr =
1289 display->main_buffer->physical_addr;
1290 psDevInfo->sSystemBuffer.sCPUVAddr =
1291 (IMG_CPU_VIRTADDR) display->main_buffer->virtual_addr;
1292 psDevInfo->sSystemBuffer.ulBufferSize = display->main_buffer->size;
1293 psDevInfo->display = display;
1294
1295 return OMAP_OK;
1296}
1297
1298/*
1299 * Initialization routine for the 3rd party display driver
1300 */
1301static enum OMAP_ERROR create_display_devices(void)
1302{
1303 PFN_CMD_PROC pfnCmdProcList[OMAP_DC_CMD_COUNT];
1304 IMG_UINT32 aui32SyncCountList[OMAP_DC_CMD_COUNT][2];
1305 int i;
1306 unsigned int bytes_to_alloc;
1307
1308 DEBUG_PRINTK("Initializing 3rd party display driver");
1309
1310 /* Ask for the number of displays available */
1311 omap_display_init();
1312 /* TODO: allow more displays */
1313 display_devices_count = 1; // omap_display_count();
1314
1315 DEBUG_PRINTK("Found %i displays", display_devices_count);
1316
1317 /*
1318 * Obtain the function pointer for the jump table from kernel
1319 * services to fill it with the function pointers that we want
1320 */
1321 if(get_pvr_dc_jtable ("PVRGetDisplayClassJTable",
1322 &pfnGetPVRJTable) != OMAP_OK)
1323 {
1324 ERROR_PRINTK("Unable to get the function to get the"
1325 " jump table display->services");
1326 return OMAP_ERROR_INIT_FAILURE;
1327 }
1328
1329 /*
1330 * Allocate the display device structures, one per display available
1331 */
1332 bytes_to_alloc =
1333 sizeof(struct OMAP_DISP_DEVINFO) * display_devices_count;
1334 pDisplayDevices = (struct OMAP_DISP_DEVINFO *) kmalloc(
1335 bytes_to_alloc, GFP_KERNEL);
1336 if(!pDisplayDevices)
1337 {
1338 pDisplayDevices = NULL;
1339 ERROR_PRINTK("Out of memory");
1340 return OMAP_ERROR_OUT_OF_MEMORY;
1341 }
1342 memset(pDisplayDevices, 0, bytes_to_alloc);
1343
1344 /*
1345 * Initialize each display device
1346 */
1347 for(i = 0; i < display_devices_count; i++)
1348 {
1349 struct omap_display_device *display;
1350 struct OMAP_DISP_DEVINFO * psDevInfo;
1351 enum omap_display_id id;
1352
1353 psDevInfo = &pDisplayDevices[i];
1354 psDevInfo->display = 0;
1355
1356 id = OMAP_DISPID_VIRTUAL;
1357
1358 /*
1359 * TODO: Modify this to allow primary, secondary,
1360 * not only virtual
1361 */
1362#if 0
1363 switch(i)
1364 {
1365 case 0:
1366 id = OMAP_DISPID_PRIMARY;
1367 break;
1368 case 1:
1369 id = OMAP_DISPID_SECONDARY;
1370 break;
1371 case 2:
1372 id = OMAP_DISPID_TERTIARY;
1373 break;
1374 case 3:
1375 id = OMAP_DISPID_VIRTUAL;
1376 break;
1377 default:
1378 ERROR_PRINTK("Invalid display type %i", i);
1379 BUG();
1380 }
1381
1382#endif
1383
1384 display = omap_display_get(id);
1385 if(!display)
1386 continue;
1387
1388 if(init_display_device(psDevInfo, display) != OMAP_OK)
1389 {
1390 ERROR_PRINTK("Unable to initialize display '%s' type"
1391 " %u", display->name, display->id);
1392 continue;
1393#if 0
1394 kfree(pDisplayDevices);
1395 pDisplayDevices = NULL;
1396 return OMAP_ERROR_INIT_FAILURE;
1397#endif
1398 }
1399
1400 /*
1401 * Populate each display device structure
1402 */
1403 if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
1404 {
1405 ERROR_PRINTK("Unable to get the jump table"
1406 " display->services for display '%s'",
1407 display->name);
1408 return OMAP_ERROR_INIT_FAILURE;
1409 }
1410
1411 /* Populate the function table that services will use */
1412 psDevInfo->sDCJTable.ui32TableSize =
1413 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
1414 psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
1415 psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
1416 psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
1417 psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
1418 psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
1419 psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
1420 psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
1421 psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
1422 psDevInfo->sDCJTable.pfnDestroyDCSwapChain =
1423 DestroyDCSwapChain;
1424 psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
1425 psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
1426 psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
1427 psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
1428 psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
1429 psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
1430 psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
1431 psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
1432
1433 /* Register the display device */
1434 if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice(
1435 &psDevInfo->sDCJTable,
1436 (IMG_UINT32*) &psDevInfo->ulDeviceID) != PVRSRV_OK)
1437 {
1438 ERROR_PRINTK("Unable to register the jump table"
1439 " services->display");
1440 return OMAP_ERROR_DEVICE_REGISTER_FAILED;
1441 }
1442
1443 DEBUG_PRINTK("Display '%s' registered with the GPU with"
1444 " id %lu", display->name, psDevInfo->ulDeviceID);
1445
1446 /*
1447 * Register the ProcessFlip function to notify when a frame is
1448 * ready to be flipped
1449 */
1450 pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
1451 aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
1452 aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
1453 if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(
1454 psDevInfo->ulDeviceID, &pfnCmdProcList[0],
1455 aui32SyncCountList, OMAP_DC_CMD_COUNT) != PVRSRV_OK)
1456 {
1457 ERROR_PRINTK("Unable to register callback for "
1458 "ProcessFlip command");
1459 return OMAP_ERROR_CANT_REGISTER_CALLBACK;
1460 }
1461
1462 }
1463 return OMAP_OK;
1464}
1465
1466/*
1467 * Here we get the function pointer to get jump table from
1468 * services using an external function.
1469 * in: szFunctionName
1470 * out: ppfnFuncTable
1471 */
1472static enum OMAP_ERROR get_pvr_dc_jtable (char *szFunctionName,
1473 PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
1474{
1475 if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
1476 {
1477 ERROR_PRINTK("Unable to get function pointer for %s"
1478 " from services", szFunctionName);
1479 return OMAP_ERROR_INVALID_PARAMS;
1480 }
1481 *ppfnFuncTable = PVRGetDisplayClassJTable;
1482
1483 return OMAP_OK;
1484}
1485
1486#if defined(LDM_PLATFORM)
1487
1488static volatile enum OMAP_BOOL bDeviceSuspended;
1489
1490/*
1491 * Common suspend driver function
1492 * in: psSwapChain, aPhyAddr
1493 */
1494static void CommonSuspend(void)
1495{
1496 if (bDeviceSuspended)
1497 {
1498 DEBUG_PRINTK("Driver is already suspended");
1499 return;
1500 }
1501
1502 DriverSuspend();
1503 bDeviceSuspended = OMAP_TRUE;
1504}
1505
1506#if defined(SGX_EARLYSUSPEND)
1507
1508static struct early_suspend driver_early_suspend;
1509
1510/*
1511 * Android specific, driver is requested to be suspended
1512 * in: ea_event
1513 */
1514static void DriverSuspend_Entry(struct early_suspend *ea_event)
1515{
1516 DEBUG_PRINTK("Requested driver suspend");
1517 CommonSuspend();
1518}
1519
1520/*
1521 * Android specific, driver is requested to be suspended
1522 * in: ea_event
1523 */
1524static void DriverResume_Entry(struct early_suspend *ea_event)
1525{
1526 DEBUG_PRINTK("Requested driver resume");
1527 DriverResume();
1528 bDeviceSuspended = OMAP_FALSE;
1529}
1530
1531static struct platform_driver omap_sgx_dc_driver = {
1532 .driver = {
1533 .name = DRVNAME,
1534 }
1535};
1536
1537#else /* defined(SGX_EARLYSUSPEND) */
1538
1539/*
1540 * Function called when the driver is requested to be suspended
1541 * in: pDevice, state
1542 */
1543static int DriverSuspend_Entry(struct platform_device unref__ *pDevice,
1544 pm_message_t unref__ state)
1545{
1546 DEBUG_PRINTK("Requested driver suspend");
1547 CommonSuspend();
1548 return 0;
1549}
1550
1551/*
1552 * Function called when the driver is requested to resume
1553 * in: pDevice
1554 */
1555static int DriverResume_Entry(struct platform_device unref__ *pDevice)
1556{
1557 DEBUG_PRINTK("Requested driver resume");
1558 DriverResume();
1559 bDeviceSuspended = OMAP_FALSE;
1560 return 0;
1561}
1562
1563/*
1564 * Function called when the driver is requested to shutdown
1565 * in: pDevice
1566 */
1567static IMG_VOID DriverShutdown_Entry(
1568 struct platform_device unref__ *pDevice)
1569{
1570 DEBUG_PRINTK("Requested driver shutdown");
1571 CommonSuspend();
1572}
1573
1574static struct platform_driver omap_sgx_dc_driver = {
1575 .driver = {
1576 .name = DRVNAME,
1577 },
1578 .suspend = DriverSuspend_Entry,
1579 .resume = DriverResume_Entry,
1580 .shutdown = DriverShutdown_Entry,
1581};
1582
1583#endif /* defined(SGX_EARLYSUSPEND) */
1584
1585#endif /* defined(LDM_PLATFORM) */
1586
1587/*
1588 * Driver init function
1589 */
1590static int __init omap_sgx_dc_init(void)
1591{
1592 if(create_display_devices() != OMAP_OK)
1593 {
1594 WARNING_PRINTK("Driver init failed");
1595 return -ENODEV;
1596 }
1597
1598#if defined(LDM_PLATFORM)
1599 DEBUG_PRINTK("Registering platform driver");
1600 if (platform_driver_register(&omap_sgx_dc_driver))
1601 {
1602 WARNING_PRINTK("Unable to register platform driver");
1603 if(destroy_display_devices() != OMAP_OK)
1604 WARNING_PRINTK("Driver cleanup failed\n");
1605 return -ENODEV;
1606 }
1607
1608#if defined(SGX_EARLYSUSPEND)
1609 driver_early_suspend.suspend = DriverSuspend_Entry;
1610 driver_early_suspend.resume = DriverResume_Entry;
1611 driver_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1612 register_early_suspend(&driver_early_suspend);
1613 DEBUG_PRINTK("Registered early suspend support");
1614#endif
1615
1616#endif
1617 return 0;
1618}
1619
1620/*
1621 * Driver exit function
1622 */
1623static IMG_VOID __exit omap_sgx_dc_deinit(IMG_VOID)
1624{
1625#if defined(LDM_PLATFORM)
1626 DEBUG_PRINTK("Removing platform driver");
1627 platform_driver_unregister(&omap_sgx_dc_driver);
1628#if defined(SGX_EARLYSUSPEND)
1629 unregister_early_suspend(&driver_early_suspend);
1630#endif
1631#endif
1632 if(destroy_display_devices() != OMAP_OK)
1633 WARNING_PRINTK("Driver cleanup failed");
1634}
1635
1636MODULE_SUPPORTED_DEVICE(DEVNAME);
1637late_initcall(omap_sgx_dc_init);
1638module_exit(omap_sgx_dc_deinit);
diff --git a/drivers/gpu/pvr/display/omap_sgx_displayclass.h b/drivers/gpu/pvr/display/omap_sgx_displayclass.h
new file mode 100644
index 00000000000..e97c4addc5a
--- /dev/null
+++ b/drivers/gpu/pvr/display/omap_sgx_displayclass.h
@@ -0,0 +1,123 @@
1/*************************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 *************************************************************************/
26
27#ifndef __OMAP_SGX_DISPLAYCLASS_H__
28#define __OMAP_SGX_DISPLAYCLASS_H__
29
30extern IMG_BOOL PVRGetDisplayClassJTable(
31 PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
32
33typedef void * OMAP_HANDLE;
34
35enum OMAP_BOOL
36{
37 OMAP_FALSE = 0,
38 OMAP_TRUE = 1,
39};
40
41struct OMAP_DISP_BUFFER
42{
43 unsigned long ulBufferSize;
44 IMG_SYS_PHYADDR sSysAddr;
45 IMG_CPU_VIRTADDR sCPUVAddr;
46 PVRSRV_SYNC_DATA *psSyncData;
47 struct OMAP_DISP_BUFFER *psNext;
48 struct omap_display_buffer *display_buffer;
49};
50
51struct OMAP_DISP_FLIP_ITEM
52{
53 OMAP_HANDLE hCmdComplete;
54 unsigned long ulSwapInterval;
55 enum OMAP_BOOL bValid;
56 enum OMAP_BOOL bFlipped;
57 enum OMAP_BOOL bCmdCompleted;
58 IMG_SYS_PHYADDR *sSysAddr;
59 struct omap_display_buffer *display_buffer;
60};
61
62struct OMAP_DISP_SWAPCHAIN
63{
64 unsigned long ulBufferCount;
65 struct OMAP_DISP_BUFFER *psBuffer;
66 struct OMAP_DISP_FLIP_ITEM *psFlipItems;
67 unsigned long ulInsertIndex;
68 unsigned long ulRemoveIndex;
69 PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable;
70 enum OMAP_BOOL bFlushCommands;
71 unsigned long ulSetFlushStateRefCount;
72 enum OMAP_BOOL bBlanked;
73 spinlock_t *psSwapChainLock;
74 void *pvDevInfo;
75};
76
77struct OMAP_DISP_DEVINFO
78{
79 unsigned long ulDeviceID;
80 struct OMAP_DISP_BUFFER sSystemBuffer;
81 PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable;
82 PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable;
83 struct OMAP_DISP_SWAPCHAIN *psSwapChain;
84 enum OMAP_BOOL bFlushCommands;
85 enum OMAP_BOOL bDeviceSuspended;
86 struct mutex sSwapChainLockMutex;
87 IMG_DEV_VIRTADDR sDisplayDevVAddr;
88 DISPLAY_INFO sDisplayInfo;
89 DISPLAY_FORMAT sDisplayFormat;
90 DISPLAY_DIMS sDisplayDim;
91 struct workqueue_struct *sync_display_wq;
92 struct work_struct sync_display_work;
93 PVRSRV_PIXEL_FORMAT ePixelFormat;
94 struct omap_display_device *display;
95};
96
97enum OMAP_ERROR
98{
99 OMAP_OK = 0,
100 OMAP_ERROR_GENERIC = 1,
101 OMAP_ERROR_OUT_OF_MEMORY = 2,
102 OMAP_ERROR_TOO_FEW_BUFFERS = 3,
103 OMAP_ERROR_INVALID_PARAMS = 4,
104 OMAP_ERROR_INIT_FAILURE = 5,
105 OMAP_ERROR_CANT_REGISTER_CALLBACK = 6,
106 OMAP_ERROR_INVALID_DEVICE = 7,
107 OMAP_ERROR_DEVICE_REGISTER_FAILED = 8
108
109};
110
111#define DISPLAY_DEVICE_NAME "PowerVR OMAP Display Driver"
112#define DRVNAME "omap_sgx_displayclass"
113#define DEVNAME DRVNAME
114#define DRIVER_PREFIX DRVNAME
115
116#define DEBUG_PRINTK(format, ...) printk("DEBUG " DRIVER_PREFIX \
117 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
118#define WARNING_PRINTK(format, ...) printk("WARNING " DRIVER_PREFIX \
119 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
120#define ERROR_PRINTK(format, ...) printk("ERROR " DRIVER_PREFIX \
121 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
122
123#endif
diff --git a/drivers/gpu/pvr/env_data.h b/drivers/gpu/pvr/env_data.h
new file mode 100644
index 00000000000..3d41219b797
--- /dev/null
+++ b/drivers/gpu/pvr/env_data.h
@@ -0,0 +1,66 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _ENV_DATA_
28#define _ENV_DATA_
29
30#include <linux/interrupt.h>
31#include <linux/pci.h>
32
33#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
34#include <linux/workqueue.h>
35#endif
36
37#define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000
38#define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000
39
40typedef struct _PVR_PCI_DEV_TAG
41{
42 struct pci_dev *psPCIDev;
43 HOST_PCI_INIT_FLAGS ePCIFlags;
44 IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE];
45} PVR_PCI_DEV;
46
47typedef struct _ENV_DATA_TAG
48{
49 IMG_VOID *pvBridgeData;
50 struct pm_dev *psPowerDevice;
51 IMG_BOOL bLISRInstalled;
52 IMG_BOOL bMISRInstalled;
53 IMG_UINT32 ui32IRQ;
54 IMG_VOID *pvISRCookie;
55#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
56 struct workqueue_struct *psWorkQueue;
57#endif
58#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
59 struct work_struct sMISRWork;
60 IMG_VOID *pvMISRData;
61#else
62 struct tasklet_struct sMISRTasklet;
63#endif
64} ENV_DATA;
65
66#endif
diff --git a/drivers/gpu/pvr/env_perproc.h b/drivers/gpu/pvr/env_perproc.h
new file mode 100644
index 00000000000..67c8a539f00
--- /dev/null
+++ b/drivers/gpu/pvr/env_perproc.h
@@ -0,0 +1,56 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __ENV_PERPROC_H__
28#define __ENV_PERPROC_H__
29
30#include <linux/list.h>
31#include <linux/proc_fs.h>
32
33#include "services.h"
34#include "handle.h"
35
36typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_
37{
38 IMG_HANDLE hBlockAlloc;
39 struct proc_dir_entry *psProcDir;
40#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
41 struct list_head sDRMAuthListHead;
42#endif
43} PVRSRV_ENV_PER_PROCESS_DATA;
44
45IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
46
47PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
48
49IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
50
51PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
52
53IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID);
54
55#endif
56
diff --git a/drivers/gpu/pvr/event.c b/drivers/gpu/pvr/event.c
new file mode 100644
index 00000000000..e2ef0d177ca
--- /dev/null
+++ b/drivers/gpu/pvr/event.c
@@ -0,0 +1,274 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/version.h>
32#include <asm/io.h>
33#include <asm/page.h>
34#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
35#include <asm/system.h>
36#endif
37#include <linux/mm.h>
38#include <linux/slab.h>
39#include <linux/vmalloc.h>
40#include <linux/delay.h>
41#include <linux/pci.h>
42
43#include <linux/string.h>
44#include <linux/sched.h>
45#include <linux/interrupt.h>
46#include <asm/hardirq.h>
47#include <linux/timer.h>
48#include <linux/capability.h>
49#include <linux/sched.h>
50#include <asm/uaccess.h>
51
52#include "img_types.h"
53#include "services_headers.h"
54#include "mm.h"
55#include "pvrmmap.h"
56#include "mmap.h"
57#include "env_data.h"
58#include "proc.h"
59#include "mutex.h"
60#include "lock.h"
61#include "event.h"
62
63typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG
64{
65 rwlock_t sLock;
66 struct list_head sList;
67
68} PVRSRV_LINUX_EVENT_OBJECT_LIST;
69
70
71typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG
72{
73 atomic_t sTimeStamp;
74 IMG_UINT32 ui32TimeStampPrevious;
75#if defined(DEBUG)
76 IMG_UINT ui32Stats;
77#endif
78 wait_queue_head_t sWait;
79 struct list_head sList;
80 IMG_HANDLE hResItem;
81 PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList;
82} PVRSRV_LINUX_EVENT_OBJECT;
83
84PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
85{
86 PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList;
87
88 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST),
89 (IMG_VOID **)&psEvenObjectList, IMG_NULL,
90 "Linux Event Object List") != PVRSRV_OK)
91 {
92 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
93 return PVRSRV_ERROR_OUT_OF_MEMORY;
94 }
95
96 INIT_LIST_HEAD(&psEvenObjectList->sList);
97
98 rwlock_init(&psEvenObjectList->sLock);
99
100 *phEventObjectList = (IMG_HANDLE *) psEvenObjectList;
101
102 return PVRSRV_OK;
103}
104
105PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
106{
107
108 PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
109
110 if(psEvenObjectList)
111 {
112 if (!list_empty(&psEvenObjectList->sList))
113 {
114 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
115 return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
116 }
117 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEvenObjectList, IMG_NULL);
118
119 }
120 return PVRSRV_OK;
121}
122
123
124PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject)
125{
126 if(hOSEventObjectList)
127 {
128 if(hOSEventObject)
129 {
130 PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
131#if defined(DEBUG)
132 PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %u", psLinuxEventObject->ui32Stats));
133#endif
134 if(ResManFreeResByPtr(psLinuxEventObject->hResItem) != PVRSRV_OK)
135 {
136 return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
137 }
138
139 return PVRSRV_OK;
140 }
141 }
142 return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
143
144}
145
146static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
147{
148 PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam;
149 PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
150
151 PVR_UNREFERENCED_PARAMETER(ui32Param);
152
153 write_lock_bh(&psLinuxEventObjectList->sLock);
154 list_del(&psLinuxEventObject->sList);
155 write_unlock_bh(&psLinuxEventObjectList->sLock);
156
157#if defined(DEBUG)
158 PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %u", psLinuxEventObject->ui32Stats));
159#endif
160
161 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL);
162
163
164 return PVRSRV_OK;
165}
166PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject)
167 {
168 PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
169 PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
170 IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
171 PVRSRV_PER_PROCESS_DATA *psPerProc;
172
173 psPerProc = PVRSRVPerProcessData(ui32PID);
174 if (psPerProc == IMG_NULL)
175 {
176 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data"));
177 return PVRSRV_ERROR_OUT_OF_MEMORY;
178 }
179
180
181 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT),
182 (IMG_VOID **)&psLinuxEventObject, IMG_NULL,
183 "Linux Event Object") != PVRSRV_OK)
184 {
185 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));
186 return PVRSRV_ERROR_OUT_OF_MEMORY;
187 }
188
189 INIT_LIST_HEAD(&psLinuxEventObject->sList);
190
191 atomic_set(&psLinuxEventObject->sTimeStamp, 0);
192 psLinuxEventObject->ui32TimeStampPrevious = 0;
193
194#if defined(DEBUG)
195 psLinuxEventObject->ui32Stats = 0;
196#endif
197 init_waitqueue_head(&psLinuxEventObject->sWait);
198
199 psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;
200
201 psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext,
202 RESMAN_TYPE_EVENT_OBJECT,
203 psLinuxEventObject,
204 0,
205 &LinuxEventObjectDeleteCallback);
206
207 write_lock_bh(&psLinuxEventObjectList->sLock);
208 list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
209 write_unlock_bh(&psLinuxEventObjectList->sLock);
210
211 *phOSEventObject = psLinuxEventObject;
212
213 return PVRSRV_OK;
214}
215
216PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList)
217{
218 PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
219 PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
220 struct list_head *psListEntry, *psListEntryTemp, *psList;
221 psList = &psLinuxEventObjectList->sList;
222
223 list_for_each_safe(psListEntry, psListEntryTemp, psList)
224 {
225
226 psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);
227
228 atomic_inc(&psLinuxEventObject->sTimeStamp);
229 wake_up_interruptible(&psLinuxEventObject->sWait);
230 }
231
232 return PVRSRV_OK;
233
234}
235
236PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout)
237{
238 IMG_UINT32 ui32TimeStamp;
239 DEFINE_WAIT(sWait);
240
241 PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
242
243 IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
244
245 do
246 {
247 prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
248 ui32TimeStamp = (IMG_UINT32)atomic_read(&psLinuxEventObject->sTimeStamp);
249
250 if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp)
251 {
252 break;
253 }
254
255 LinuxUnLockMutex(&gPVRSRVLock);
256
257 ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
258
259 LinuxLockMutex(&gPVRSRVLock);
260#if defined(DEBUG)
261 psLinuxEventObject->ui32Stats++;
262#endif
263
264
265 } while (ui32TimeOutJiffies);
266
267 finish_wait(&psLinuxEventObject->sWait, &sWait);
268
269 psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp;
270
271 return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
272
273}
274
diff --git a/drivers/gpu/pvr/event.h b/drivers/gpu/pvr/event.h
new file mode 100644
index 00000000000..d07bc9711d9
--- /dev/null
+++ b/drivers/gpu/pvr/event.h
@@ -0,0 +1,32 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList);
28PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList);
29PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject);
30PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject);
31PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
32PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout);
diff --git a/drivers/gpu/pvr/handle.c b/drivers/gpu/pvr/handle.c
new file mode 100644
index 00000000000..5e34af5b280
--- /dev/null
+++ b/drivers/gpu/pvr/handle.c
@@ -0,0 +1,1723 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifdef PVR_SECURE_HANDLES
28#include <stddef.h>
29
30#include "services_headers.h"
31#include "handle.h"
32
33#ifdef DEBUG
34#define HANDLE_BLOCK_SHIFT 2
35#else
36#define HANDLE_BLOCK_SHIFT 8
37#endif
38
39#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT)
40#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT)
41
42#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1)
43#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1)
44#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK))
45
46#define HANDLE_HASH_TAB_INIT_SIZE 32
47
48#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
49
50#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((i) + 1))
51#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1)
52
53#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i)
54#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i)
55#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK)
56
57#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)]))
58#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i)
59
60#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount)
61
62#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i))
63
64#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h)))
65
66#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index)
67#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle))
68
69#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a))
70#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1)
71
72#define DEFAULT_MAX_HANDLE 0x7fffffffu
73#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE)
74
75#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
76
77#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount))
78
79#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f)))
80#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f)))
81#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0))
82
83#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f)
84
85#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f)
86#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f)
87#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f)
88
89#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
90
91#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
92
93#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
94
95#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
96
97#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
98
99#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE)
100
101#ifdef MIN
102#undef MIN
103#endif
104
105#define MIN(x, y) (((x) < (y)) ? (x) : (y))
106
107struct sHandleList
108{
109 IMG_UINT32 ui32Prev;
110 IMG_UINT32 ui32Next;
111 IMG_HANDLE hParent;
112};
113
114enum ePVRSRVInternalHandleFlag
115{
116 INTERNAL_HANDLE_FLAG_NONE = 0x00,
117 INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
118 INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
119};
120
121struct sHandle
122{
123
124 PVRSRV_HANDLE_TYPE eType;
125
126
127 IMG_VOID *pvData;
128
129
130 IMG_UINT32 ui32NextIndexPlusOne;
131
132
133 enum ePVRSRVInternalHandleFlag eInternalFlag;
134
135
136 PVRSRV_HANDLE_ALLOC_FLAG eFlag;
137
138
139 IMG_UINT32 ui32Index;
140
141
142 struct sHandleList sChildren;
143
144
145 struct sHandleList sSiblings;
146};
147
148struct sHandleIndex
149{
150
151 struct sHandle *psHandle;
152
153
154 IMG_HANDLE hBlockAlloc;
155
156
157 IMG_UINT32 ui32FreeHandBlockCount;
158};
159
160struct _PVRSRV_HANDLE_BASE_
161{
162
163 IMG_HANDLE hBaseBlockAlloc;
164
165
166 IMG_HANDLE hArrayBlockAlloc;
167
168
169 struct sHandleIndex *psHandleArray;
170
171
172 HASH_TABLE *psHashTab;
173
174
175 IMG_UINT32 ui32FreeHandCount;
176
177
178 IMG_UINT32 ui32FirstFreeIndex;
179
180
181 IMG_UINT32 ui32MaxIndexPlusOne;
182
183
184 IMG_UINT32 ui32TotalHandCount;
185
186
187 IMG_UINT32 ui32LastFreeIndexPlusOne;
188
189
190 IMG_UINT32 ui32HandBatchSize;
191
192
193 IMG_UINT32 ui32TotalHandCountPreBatch;
194
195
196 IMG_UINT32 ui32FirstBatchIndexPlusOne;
197
198
199 IMG_UINT32 ui32BatchHandAllocFailures;
200
201
202 IMG_BOOL bPurgingEnabled;
203};
204
205enum eHandKey {
206 HAND_KEY_DATA = 0,
207 HAND_KEY_TYPE,
208 HAND_KEY_PARENT,
209 HAND_KEY_LEN
210};
211
212PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
213
214typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
215
216#ifdef INLINE_IS_PRAGMA
217#pragma inline(HandleListInit)
218#endif
219static INLINE
220IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
221{
222 psList->ui32Next = ui32Index;
223 psList->ui32Prev = ui32Index;
224 psList->hParent = hParent;
225}
226
227#ifdef INLINE_IS_PRAGMA
228#pragma inline(InitParentList)
229#endif
230static INLINE
231IMG_VOID InitParentList(struct sHandle *psHandle)
232{
233 IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle);
234
235 HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent));
236}
237
238#ifdef INLINE_IS_PRAGMA
239#pragma inline(InitChildEntry)
240#endif
241static INLINE
242IMG_VOID InitChildEntry(struct sHandle *psHandle)
243{
244 HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL);
245}
246
247#ifdef INLINE_IS_PRAGMA
248#pragma inline(HandleListIsEmpty)
249#endif
250static INLINE
251IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList)
252{
253 IMG_BOOL bIsEmpty;
254
255 bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index);
256
257#ifdef DEBUG
258 {
259 IMG_BOOL bIsEmpty2;
260
261 bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index);
262 PVR_ASSERT(bIsEmpty == bIsEmpty2);
263 }
264#endif
265
266 return bIsEmpty;
267}
268
269#ifdef DEBUG
270#ifdef INLINE_IS_PRAGMA
271#pragma inline(NoChildren)
272#endif
273static INLINE
274IMG_BOOL NoChildren(struct sHandle *psHandle)
275{
276 PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle));
277
278 return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren);
279}
280
281#ifdef INLINE_IS_PRAGMA
282#pragma inline(NoParent)
283#endif
284static INLINE
285IMG_BOOL NoParent(struct sHandle *psHandle)
286{
287 if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings))
288 {
289 PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL);
290
291 return IMG_TRUE;
292 }
293 else
294 {
295 PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL);
296 }
297 return IMG_FALSE;
298}
299#endif
300#ifdef INLINE_IS_PRAGMA
301#pragma inline(ParentHandle)
302#endif
303static INLINE
304IMG_HANDLE ParentHandle(struct sHandle *psHandle)
305{
306 return psHandle->sSiblings.hParent;
307}
308
309#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
310 ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
311
312#ifdef INLINE_IS_PRAGMA
313#pragma inline(HandleListInsertBefore)
314#endif
315static INLINE
316IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex)
317{
318
319 struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset);
320
321 PVR_ASSERT(psEntry->hParent == IMG_NULL);
322 PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next);
323 PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex));
324
325 psEntry->ui32Prev = psIns->ui32Prev;
326 psIns->ui32Prev = ui32EntryIndex;
327 psEntry->ui32Next = ui32InsIndex;
328 psPrevIns->ui32Next = ui32EntryIndex;
329
330 psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex);
331}
332
333#ifdef INLINE_IS_PRAGMA
334#pragma inline(AdoptChild)
335#endif
336static INLINE
337IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild)
338{
339 IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent);
340
341 PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent));
342
343 HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
344
345}
346
347#ifdef INLINE_IS_PRAGMA
348#pragma inline(HandleListRemove)
349#endif
350static INLINE
351IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset)
352{
353 if (!HandleListIsEmpty(ui32EntryIndex, psEntry))
354 {
355
356 struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
357 struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
358
359
360 PVR_ASSERT(psEntry->hParent != IMG_NULL);
361
362 psPrev->ui32Next = psEntry->ui32Next;
363 psNext->ui32Prev = psEntry->ui32Prev;
364
365 HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
366 }
367}
368
369#ifdef INLINE_IS_PRAGMA
370#pragma inline(UnlinkFromParent)
371#endif
372static INLINE
373IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
374{
375 HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
376}
377
378#ifdef INLINE_IS_PRAGMA
379#pragma inline(HandleListIterate)
380#endif
381static INLINE
382PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
383{
384 IMG_UINT32 ui32Index;
385 IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent);
386
387 PVR_ASSERT(psHead->hParent != IMG_NULL);
388
389
390 for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
391 {
392 struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
393
394 struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
395 PVRSRV_ERROR eError;
396
397 PVR_ASSERT(psEntry->hParent == psHead->hParent);
398
399 ui32Index = psEntry->ui32Next;
400
401 eError = (*pfnIterFunc)(psBase, psHandle);
402 if (eError != PVRSRV_OK)
403 {
404 return eError;
405 }
406 }
407
408 return PVRSRV_OK;
409}
410
411#ifdef INLINE_IS_PRAGMA
412#pragma inline(IterateOverChildren)
413#endif
414static INLINE
415PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
416{
417 return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc);
418}
419
420#ifdef INLINE_IS_PRAGMA
421#pragma inline(GetHandleStructure)
422#endif
423static INLINE
424PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
425{
426 IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle);
427 struct sHandle *psHandle;
428
429
430 if (!INDEX_IS_VALID(psBase, ui32Index))
431 {
432 PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
433 return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
434 }
435
436 psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
437 if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
438 {
439 PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
440 return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
441 }
442
443
444 if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
445 {
446 PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
447 return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
448 }
449
450
451 *ppsHandle = psHandle;
452
453 return PVRSRV_OK;
454}
455
456#ifdef INLINE_IS_PRAGMA
457#pragma inline(ParentIfPrivate)
458#endif
459static INLINE
460IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
461{
462 return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
463 ParentHandle(psHandle) : IMG_NULL;
464}
465
466#ifdef INLINE_IS_PRAGMA
467#pragma inline(InitKey)
468#endif
469static INLINE
470IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
471{
472 PVR_UNREFERENCED_PARAMETER(psBase);
473
474 aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData;
475 aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType;
476 aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent;
477}
478
479static
480PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount)
481{
482 struct sHandleIndex *psOldArray = psBase->psHandleArray;
483 IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc;
484 IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount;
485 struct sHandleIndex *psNewArray = IMG_NULL;
486 IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL;
487 PVRSRV_ERROR eError;
488 PVRSRV_ERROR eReturn = PVRSRV_OK;
489 IMG_UINT32 ui32Index;
490
491 if (ui32NewCount == ui32OldCount)
492 {
493 return PVRSRV_OK;
494 }
495
496 if (ui32NewCount != 0 && !psBase->bPurgingEnabled &&
497 ui32NewCount < ui32OldCount)
498 {
499 return PVRSRV_ERROR_INVALID_PARAMS;
500 }
501
502 if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) ||
503 ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0))
504 {
505 PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0);
506 PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0);
507
508 return PVRSRV_ERROR_INVALID_PARAMS;
509 }
510
511 if (ui32NewCount != 0)
512 {
513
514 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
515 HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
516 (IMG_VOID **)&psNewArray,
517 &hNewArrayBlockAlloc,
518 "Memory Area");
519 if (eError != PVRSRV_OK)
520 {
521 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError));
522 eReturn = eError;
523 goto error;
524 }
525
526 if (ui32OldCount != 0)
527 {
528 OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex));
529 }
530 }
531
532
533 for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE)
534 {
535 struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index);
536
537 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
538 sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
539 psIndex->psHandle,
540 psIndex->hBlockAlloc);
541 if (eError != PVRSRV_OK)
542 {
543 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
544 }
545 }
546
547
548 for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
549 {
550
551 struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
552
553 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
554 sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
555 (IMG_VOID **)&psIndex->psHandle,
556 &psIndex->hBlockAlloc,
557 "Memory Area");
558 if (eError != PVRSRV_OK)
559 {
560 psIndex->psHandle = IMG_NULL;
561 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError));
562 eReturn = eError;
563 }
564 else
565 {
566 IMG_UINT32 ui32SubIndex;
567
568 psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE;
569
570 for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++)
571 {
572 struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex;
573
574
575 psHandle->ui32Index = ui32SubIndex + ui32Index;
576 psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
577 psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
578 psHandle->ui32NextIndexPlusOne = 0;
579 }
580 }
581 }
582 if (eReturn != PVRSRV_OK)
583 {
584 goto error;
585 }
586
587#ifdef DEBUG_MAX_HANDLE_COUNT
588
589 if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT)
590 {
591 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT));
592 eReturn = PVRSRV_ERROR_OUT_OF_MEMORY;
593 goto error;
594 }
595#endif
596
597 if (psOldArray != IMG_NULL)
598 {
599
600 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
601 HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex),
602 psOldArray,
603 hOldArrayBlockAlloc);
604 if (eError != PVRSRV_OK)
605 {
606 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError));
607 }
608 }
609
610 psBase->psHandleArray = psNewArray;
611 psBase->hArrayBlockAlloc = hNewArrayBlockAlloc;
612 psBase->ui32TotalHandCount = ui32NewCount;
613
614 if (ui32NewCount > ui32OldCount)
615 {
616
617 PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount)
618
619
620 psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount);
621
622
623 if (psBase->ui32FirstFreeIndex == 0)
624 {
625 PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0)
626
627 psBase->ui32FirstFreeIndex = ui32OldCount;
628 }
629 else
630 {
631 if (!psBase->bPurgingEnabled)
632 {
633 PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
634 PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0)
635
636 INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1;
637 }
638 }
639
640 if (!psBase->bPurgingEnabled)
641 {
642 psBase->ui32LastFreeIndexPlusOne = ui32NewCount;
643 }
644 }
645 else
646 {
647 PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled)
648 PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount)
649 PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount)
650
651
652 psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount);
653
654 if (ui32NewCount == 0)
655 {
656 psBase->ui32FirstFreeIndex = 0;
657 psBase->ui32LastFreeIndexPlusOne = 0;
658 }
659 }
660
661 PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount);
662
663 return PVRSRV_OK;
664
665error:
666 PVR_ASSERT(eReturn != PVRSRV_OK);
667
668 if (psNewArray != IMG_NULL)
669 {
670
671 for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
672 {
673 struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
674 if (psIndex->psHandle != IMG_NULL)
675 {
676 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
677 sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
678 psIndex->psHandle,
679 psIndex->hBlockAlloc);
680 if (eError != PVRSRV_OK)
681 {
682 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
683 }
684 }
685 }
686
687
688 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
689 HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
690 psNewArray,
691 hNewArrayBlockAlloc);
692 if (eError != PVRSRV_OK)
693 {
694 PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError));
695 }
696 }
697
698 return eReturn;
699}
700
701static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
702{
703 return ReallocHandleArray(psBase, 0);
704}
705
706static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
707{
708 HAND_KEY aKey;
709 IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle);
710 PVRSRV_ERROR eError;
711
712
713 InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
714
715 if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
716 {
717 IMG_HANDLE hHandle;
718 hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
719
720 PVR_ASSERT(hHandle != IMG_NULL);
721 PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index));
722 PVR_UNREFERENCED_PARAMETER(hHandle);
723 }
724
725
726 UnlinkFromParent(psBase, psHandle);
727
728
729 eError = IterateOverChildren(psBase, psHandle, FreeHandle);
730 if (eError != PVRSRV_OK)
731 {
732 PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
733 return eError;
734 }
735
736
737 psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
738
739 if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
740 {
741
742 SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
743
744 return PVRSRV_OK;
745 }
746
747
748 if (!psBase->bPurgingEnabled)
749 {
750 if (psBase->ui32FreeHandCount == 0)
751 {
752 PVR_ASSERT(psBase->ui32FirstFreeIndex == 0);
753 PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
754
755 psBase->ui32FirstFreeIndex = ui32Index;
756 }
757 else
758 {
759
760 PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
761 PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
762 INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1;
763 }
764
765 PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0);
766
767
768 psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
769 }
770
771 psBase->ui32FreeHandCount++;
772 INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++;
773
774 PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE);
775
776#ifdef DEBUG
777 {
778 IMG_UINT32 ui32BlockedIndex;
779 IMG_UINT32 ui32FreeHandCount = 0;
780
781 for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
782 {
783 ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex);
784 }
785
786 PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount);
787 }
788#endif
789
790 return PVRSRV_OK;
791}
792
793static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase)
794{
795 IMG_UINT32 i;
796 PVRSRV_ERROR eError = PVRSRV_OK;
797
798 if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
799 {
800 return eError;
801 }
802
803 for (i = 0; i < psBase->ui32TotalHandCount; i++)
804 {
805 struct sHandle *psHandle;
806
807 psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i);
808
809 if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE)
810 {
811 eError = FreeHandle(psBase, psHandle);
812 if (eError != PVRSRV_OK)
813 {
814 PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError));
815 break;
816 }
817
818
819 if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
820 {
821 break;
822 }
823 }
824 }
825
826 return eError;
827}
828
829static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
830{
831 PVRSRV_ERROR eError;
832
833 if (HANDLES_BATCHED(psBase))
834 {
835 PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch"));
836 PVRSRVReleaseHandleBatch(psBase);
837 }
838
839
840 eError = FreeAllHandles(psBase);
841 if (eError != PVRSRV_OK)
842 {
843 PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
844 return eError;
845 }
846
847
848 eError = FreeHandleArray(psBase);
849 if (eError != PVRSRV_OK)
850 {
851 PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError));
852 return eError;
853 }
854
855 if (psBase->psHashTab != IMG_NULL)
856 {
857
858 HASH_Delete(psBase->psHashTab);
859 }
860
861 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
862 sizeof(*psBase),
863 psBase,
864 psBase->hBaseBlockAlloc);
865 if (eError != PVRSRV_OK)
866 {
867 PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError));
868 return eError;
869 }
870
871 return PVRSRV_OK;
872}
873
874#ifdef INLINE_IS_PRAGMA
875#pragma inline(FindHandle)
876#endif
877static INLINE
878IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
879{
880 HAND_KEY aKey;
881
882 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
883
884 InitKey(aKey, psBase, pvData, eType, hParent);
885
886 return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
887}
888
889static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
890{
891 PVRSRV_ERROR eError;
892 IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta);
893 IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
894;
895
896 PVR_ASSERT(ui32Delta != 0);
897
898
899 if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount)
900 {
901 ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne;
902
903 ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount;
904
905 if (ui32DeltaAdjusted < ui32Delta)
906 {
907 PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne));
908 return PVRSRV_ERROR_OUT_OF_MEMORY;
909 }
910 }
911
912 PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta);
913
914
915 eError = ReallocHandleArray(psBase, ui32NewTotalHandCount);
916 if (eError != PVRSRV_OK)
917 {
918 PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
919 return eError;
920 }
921
922 return PVRSRV_OK;
923}
924
925static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free)
926{
927 PVRSRV_ERROR eError;
928
929 if (ui32Free > psBase->ui32FreeHandCount)
930 {
931 IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount;
932 eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta);
933 if (eError != PVRSRV_OK)
934 {
935 PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError));
936
937 return eError;
938 }
939 }
940
941 return PVRSRV_OK;
942}
943
944static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
945{
946 IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE;
947 struct sHandle *psNewHandle = IMG_NULL;
948 IMG_HANDLE hHandle;
949 HAND_KEY aKey;
950 PVRSRV_ERROR eError;
951
952
953 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
954 PVR_ASSERT(psBase != IMG_NULL);
955 PVR_ASSERT(psBase->psHashTab != IMG_NULL);
956
957 if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
958 {
959
960 PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL);
961 }
962
963 if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase))
964 {
965 PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize));
966 }
967
968
969 eError = EnsureFreeHandles(psBase, 1);
970 if (eError != PVRSRV_OK)
971 {
972 PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError));
973 return eError;
974 }
975 PVR_ASSERT(psBase->ui32FreeHandCount != 0)
976
977 if (!psBase->bPurgingEnabled)
978 {
979
980 ui32NewIndex = psBase->ui32FirstFreeIndex;
981
982
983 psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
984 }
985 else
986 {
987 IMG_UINT32 ui32BlockedIndex;
988
989
990
991 PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0);
992
993 for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
994 {
995 struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex);
996
997 if (psIndex->ui32FreeHandBlockCount == 0)
998 {
999 continue;
1000 }
1001
1002 for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++)
1003 {
1004 psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
1005 if (HANDLE_STRUCT_IS_FREE(psNewHandle))
1006 {
1007 break;
1008 }
1009 }
1010 }
1011 psBase->ui32FirstFreeIndex = 0;
1012 PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount);
1013 }
1014 PVR_ASSERT(psNewHandle != IMG_NULL);
1015
1016
1017 hHandle = INDEX_TO_HANDLE(ui32NewIndex);
1018
1019
1020 if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
1021 {
1022
1023 InitKey(aKey, psBase, pvData, eType, hParent);
1024
1025
1026 if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
1027 {
1028 PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
1029
1030 return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
1031 }
1032 }
1033
1034 psBase->ui32FreeHandCount--;
1035
1036 PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE);
1037 PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0);
1038
1039 INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--;
1040
1041
1042 if (!psBase->bPurgingEnabled)
1043 {
1044
1045 if (psBase->ui32FreeHandCount == 0)
1046 {
1047 PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex);
1048 PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1));
1049
1050 psBase->ui32LastFreeIndexPlusOne = 0;
1051 psBase->ui32FirstFreeIndex = 0;
1052 }
1053 else
1054 {
1055
1056 psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
1057 ui32NewIndex + 1 :
1058 psNewHandle->ui32NextIndexPlusOne - 1;
1059 }
1060 }
1061
1062
1063 PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex);
1064
1065
1066 psNewHandle->eType = eType;
1067 psNewHandle->pvData = pvData;
1068 psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
1069 psNewHandle->eFlag = eFlag;
1070
1071 InitParentList(psNewHandle);
1072#if defined(DEBUG)
1073 PVR_ASSERT(NoChildren(psNewHandle));
1074#endif
1075
1076 InitChildEntry(psNewHandle);
1077#if defined(DEBUG)
1078 PVR_ASSERT(NoParent(psNewHandle));
1079#endif
1080
1081 if (HANDLES_BATCHED(psBase))
1082 {
1083
1084 psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
1085
1086 psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
1087
1088
1089 SET_BATCHED_HANDLE(psNewHandle);
1090 }
1091 else
1092 {
1093 psNewHandle->ui32NextIndexPlusOne = 0;
1094 }
1095
1096
1097 *phHandle = hHandle;
1098
1099 return PVRSRV_OK;
1100}
1101
1102PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
1103{
1104 IMG_HANDLE hHandle;
1105 PVRSRV_ERROR eError;
1106
1107 *phHandle = IMG_NULL;
1108
1109 if (HANDLES_BATCHED(psBase))
1110 {
1111
1112 psBase->ui32BatchHandAllocFailures++;
1113 }
1114
1115
1116 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1117
1118 if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
1119 {
1120
1121 hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
1122 if (hHandle != IMG_NULL)
1123 {
1124 struct sHandle *psHandle;
1125
1126 eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
1127 if (eError != PVRSRV_OK)
1128 {
1129 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed"));
1130 return eError;
1131 }
1132
1133
1134 if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
1135 {
1136 *phHandle = hHandle;
1137 eError = PVRSRV_OK;
1138 goto exit_ok;
1139 }
1140 return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
1141 }
1142 }
1143
1144 eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
1145
1146exit_ok:
1147 if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
1148 {
1149 psBase->ui32BatchHandAllocFailures--;
1150 }
1151
1152 return eError;
1153}
1154
1155PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
1156{
1157 struct sHandle *psPHand;
1158 struct sHandle *psCHand;
1159 PVRSRV_ERROR eError;
1160 IMG_HANDLE hParentKey;
1161 IMG_HANDLE hHandle;
1162
1163 *phHandle = IMG_NULL;
1164
1165 if (HANDLES_BATCHED(psBase))
1166 {
1167
1168 psBase->ui32BatchHandAllocFailures++;
1169 }
1170
1171
1172 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1173
1174 hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
1175 hParent : IMG_NULL;
1176
1177
1178 eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
1179 if (eError != PVRSRV_OK)
1180 {
1181 return eError;
1182 }
1183
1184 if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
1185 {
1186
1187 hHandle = FindHandle(psBase, pvData, eType, hParentKey);
1188 if (hHandle != IMG_NULL)
1189 {
1190 struct sHandle *psCHandle;
1191 PVRSRV_ERROR eErr;
1192
1193 eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType);
1194 if (eErr != PVRSRV_OK)
1195 {
1196 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
1197 return eErr;
1198 }
1199
1200 PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent);
1201
1202
1203 if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
1204 {
1205 *phHandle = hHandle;
1206 goto exit_ok;
1207 }
1208 return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
1209 }
1210 }
1211
1212 eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
1213 if (eError != PVRSRV_OK)
1214 {
1215 return eError;
1216 }
1217
1218
1219 psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent);
1220
1221 psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle);
1222
1223 AdoptChild(psBase, psPHand, psCHand);
1224
1225 *phHandle = hHandle;
1226
1227exit_ok:
1228 if (HANDLES_BATCHED(psBase))
1229 {
1230 psBase->ui32BatchHandAllocFailures--;
1231 }
1232
1233 return PVRSRV_OK;
1234}
1235
1236PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
1237{
1238 IMG_HANDLE hHandle;
1239
1240 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1241
1242
1243 hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
1244 if (hHandle == IMG_NULL)
1245 {
1246 return PVRSRV_ERROR_HANDLE_NOT_FOUND;
1247 }
1248
1249 *phHandle = hHandle;
1250
1251 return PVRSRV_OK;
1252}
1253
1254PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
1255{
1256 struct sHandle *psHandle;
1257 PVRSRV_ERROR eError;
1258
1259 eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE);
1260 if (eError != PVRSRV_OK)
1261 {
1262 PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError));
1263 return eError;
1264 }
1265
1266 *ppvData = psHandle->pvData;
1267 *peType = psHandle->eType;
1268
1269 return PVRSRV_OK;
1270}
1271
1272PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
1273{
1274 struct sHandle *psHandle;
1275 PVRSRV_ERROR eError;
1276
1277 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1278
1279 eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
1280 if (eError != PVRSRV_OK)
1281 {
1282 PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
1283 return eError;
1284 }
1285
1286 *ppvData = psHandle->pvData;
1287
1288 return PVRSRV_OK;
1289}
1290
1291PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
1292{
1293 struct sHandle *psPHand;
1294 struct sHandle *psCHand;
1295 PVRSRV_ERROR eError;
1296
1297 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1298
1299 eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
1300 if (eError != PVRSRV_OK)
1301 {
1302 PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
1303 return eError;
1304 }
1305
1306
1307 for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; )
1308 {
1309 eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE);
1310 if (eError != PVRSRV_OK)
1311 {
1312 PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
1313 return PVRSRV_ERROR_INVALID_SUBHANDLE;
1314 }
1315 }
1316
1317 *ppvData = psCHand->pvData;
1318
1319 return PVRSRV_OK;
1320}
1321
1322PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
1323{
1324 struct sHandle *psHandle;
1325 PVRSRV_ERROR eError;
1326
1327 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1328
1329 eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
1330 if (eError != PVRSRV_OK)
1331 {
1332 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError));
1333 return eError;
1334 }
1335
1336 *phParent = ParentHandle(psHandle);
1337
1338 return PVRSRV_OK;
1339}
1340
1341PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
1342{
1343 struct sHandle *psHandle;
1344 PVRSRV_ERROR eError;
1345
1346 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1347
1348 eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
1349 if (eError != PVRSRV_OK)
1350 {
1351 PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError));
1352 return eError;
1353 }
1354
1355 *ppvData = psHandle->pvData;
1356
1357 eError = FreeHandle(psBase, psHandle);
1358
1359 return eError;
1360}
1361
1362PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
1363{
1364 struct sHandle *psHandle;
1365 PVRSRV_ERROR eError;
1366
1367 PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
1368
1369 eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
1370 if (eError != PVRSRV_OK)
1371 {
1372 PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError));
1373 return eError;
1374 }
1375
1376 eError = FreeHandle(psBase, psHandle);
1377
1378 return eError;
1379}
1380
1381PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
1382{
1383 PVRSRV_ERROR eError;
1384
1385 if (HANDLES_BATCHED(psBase))
1386 {
1387 PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize));
1388 return PVRSRV_ERROR_HANDLE_BATCH_IN_USE;
1389 }
1390
1391 if (ui32BatchSize == 0)
1392 {
1393 PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize));
1394 return PVRSRV_ERROR_INVALID_PARAMS;
1395 }
1396
1397 eError = EnsureFreeHandles(psBase, ui32BatchSize);
1398 if (eError != PVRSRV_OK)
1399 {
1400 PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError));
1401 return eError;
1402 }
1403
1404 psBase->ui32HandBatchSize = ui32BatchSize;
1405
1406
1407 psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
1408
1409 PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0);
1410
1411 PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0);
1412
1413 PVR_ASSERT(HANDLES_BATCHED(psBase));
1414
1415 return PVRSRV_OK;
1416}
1417
1418static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit)
1419{
1420
1421 IMG_UINT32 ui32IndexPlusOne;
1422 IMG_BOOL bCommitBatch = bCommit;
1423
1424 if (!HANDLES_BATCHED(psBase))
1425 {
1426 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch"));
1427 return PVRSRV_ERROR_INVALID_PARAMS;
1428
1429 }
1430
1431 if (psBase->ui32BatchHandAllocFailures != 0)
1432 {
1433 if (bCommit)
1434 {
1435 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures."));
1436 }
1437 bCommitBatch = IMG_FALSE;
1438 }
1439
1440 PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit);
1441
1442 ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
1443 while(ui32IndexPlusOne != 0)
1444 {
1445 struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1);
1446 IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne;
1447 PVR_ASSERT(BATCHED_HANDLE(psHandle));
1448
1449 psHandle->ui32NextIndexPlusOne = 0;
1450
1451 if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
1452 {
1453 PVRSRV_ERROR eError;
1454
1455
1456 if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
1457 {
1458
1459 SET_UNBATCHED_HANDLE(psHandle);
1460 }
1461
1462 eError = FreeHandle(psBase, psHandle);
1463 if (eError != PVRSRV_OK)
1464 {
1465 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError));
1466 }
1467 PVR_ASSERT(eError == PVRSRV_OK);
1468 }
1469 else
1470 {
1471
1472 SET_UNBATCHED_HANDLE(psHandle);
1473 }
1474
1475 ui32IndexPlusOne = ui32NextIndexPlusOne;
1476 }
1477
1478#ifdef DEBUG
1479 if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount)
1480 {
1481 IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch;
1482
1483 PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch);
1484
1485 PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta));
1486
1487 }
1488#endif
1489
1490 psBase->ui32HandBatchSize = 0;
1491 psBase->ui32FirstBatchIndexPlusOne = 0;
1492 psBase->ui32TotalHandCountPreBatch = 0;
1493 psBase->ui32BatchHandAllocFailures = 0;
1494
1495 if (psBase->ui32BatchHandAllocFailures != 0 && bCommit)
1496 {
1497 PVR_ASSERT(!bCommitBatch);
1498
1499 return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE;
1500 }
1501
1502 return PVRSRV_OK;
1503}
1504
1505PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
1506{
1507 return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
1508}
1509
1510IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
1511{
1512 (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
1513}
1514
1515PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
1516{
1517 IMG_UINT32 ui32MaxHandleRounded;
1518
1519 if (HANDLES_BATCHED(psBase))
1520 {
1521 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
1522 return PVRSRV_ERROR_INVALID_PARAMS;
1523 }
1524
1525
1526 if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE)
1527 {
1528 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE));
1529
1530 return PVRSRV_ERROR_INVALID_PARAMS;
1531 }
1532
1533
1534 if (psBase->ui32TotalHandCount != 0)
1535 {
1536 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated"));
1537
1538 return PVRSRV_ERROR_INVALID_PARAMS;
1539 }
1540
1541 ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle);
1542
1543
1544 if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne)
1545 {
1546 psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded;
1547 }
1548
1549 PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0);
1550 PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE);
1551 PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0);
1552
1553 return PVRSRV_OK;
1554}
1555
1556IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
1557{
1558 return psBase->ui32MaxIndexPlusOne;
1559}
1560
1561PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
1562{
1563 if (psBase->bPurgingEnabled)
1564 {
1565 PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
1566 return PVRSRV_OK;
1567 }
1568
1569
1570 if (psBase->ui32TotalHandCount != 0)
1571 {
1572 PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated"));
1573 return PVRSRV_ERROR_INVALID_PARAMS;
1574 }
1575
1576 psBase->bPurgingEnabled = IMG_TRUE;
1577
1578 return PVRSRV_OK;
1579}
1580
1581PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
1582{
1583 IMG_UINT32 ui32BlockIndex;
1584 IMG_UINT32 ui32NewHandCount;
1585
1586 if (!psBase->bPurgingEnabled)
1587 {
1588 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base"));
1589 return PVRSRV_ERROR_NOT_SUPPORTED;
1590 }
1591
1592 if (HANDLES_BATCHED(psBase))
1593 {
1594 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode"));
1595 return PVRSRV_ERROR_INVALID_PARAMS;
1596 }
1597
1598 PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0);
1599
1600 for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--)
1601 {
1602 if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE)
1603 {
1604 break;
1605 }
1606 }
1607 ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex);
1608
1609
1610 if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
1611 {
1612 PVRSRV_ERROR eError;
1613
1614
1615
1616 eError = ReallocHandleArray(psBase, ui32NewHandCount);
1617 if (eError != PVRSRV_OK)
1618 {
1619 return eError;
1620 }
1621 }
1622
1623 return PVRSRV_OK;
1624}
1625
1626PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
1627{
1628 PVRSRV_HANDLE_BASE *psBase;
1629 IMG_HANDLE hBlockAlloc;
1630 PVRSRV_ERROR eError;
1631
1632 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1633 sizeof(*psBase),
1634 (IMG_PVOID *)&psBase,
1635 &hBlockAlloc,
1636 "Handle Base");
1637 if (eError != PVRSRV_OK)
1638 {
1639 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
1640 return eError;
1641 }
1642 OSMemSet(psBase, 0, sizeof(*psBase));
1643
1644
1645 psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default);
1646 if (psBase->psHashTab == IMG_NULL)
1647 {
1648 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n"));
1649 (IMG_VOID)PVRSRVFreeHandleBase(psBase);
1650 return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
1651 }
1652
1653 psBase->hBaseBlockAlloc = hBlockAlloc;
1654
1655 psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
1656
1657 *ppsBase = psBase;
1658
1659 return PVRSRV_OK;
1660}
1661
1662PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
1663{
1664 PVRSRV_ERROR eError;
1665
1666 PVR_ASSERT(psBase != gpsKernelHandleBase);
1667
1668 eError = FreeHandleBase(psBase);
1669 if (eError != PVRSRV_OK)
1670 {
1671 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError));
1672 }
1673
1674 return eError;
1675}
1676
1677PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
1678{
1679 PVRSRV_ERROR eError;
1680
1681 PVR_ASSERT(gpsKernelHandleBase == IMG_NULL);
1682
1683 eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
1684 if (eError != PVRSRV_OK)
1685 {
1686 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError));
1687 goto error;
1688 }
1689
1690 eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase);
1691 if (eError != PVRSRV_OK)
1692 {
1693 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError));
1694 goto error;
1695 }
1696
1697 return PVRSRV_OK;
1698error:
1699 (IMG_VOID) PVRSRVHandleDeInit();
1700 return eError;
1701}
1702
1703PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
1704{
1705 PVRSRV_ERROR eError = PVRSRV_OK;
1706
1707 if (gpsKernelHandleBase != IMG_NULL)
1708 {
1709 eError = FreeHandleBase(gpsKernelHandleBase);
1710 if (eError == PVRSRV_OK)
1711 {
1712 gpsKernelHandleBase = IMG_NULL;
1713 }
1714 else
1715 {
1716 PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError));
1717 }
1718 }
1719
1720 return eError;
1721}
1722#else
1723#endif
diff --git a/drivers/gpu/pvr/handle.h b/drivers/gpu/pvr/handle.h
new file mode 100644
index 00000000000..56de04aede0
--- /dev/null
+++ b/drivers/gpu/pvr/handle.h
@@ -0,0 +1,383 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __HANDLE_H__
28#define __HANDLE_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "img_types.h"
35#include "hash.h"
36#include "resman.h"
37
38typedef enum
39{
40 PVRSRV_HANDLE_TYPE_NONE = 0,
41 PVRSRV_HANDLE_TYPE_PERPROC_DATA,
42 PVRSRV_HANDLE_TYPE_DEV_NODE,
43 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
44 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
45 PVRSRV_HANDLE_TYPE_MEM_INFO,
46 PVRSRV_HANDLE_TYPE_SYNC_INFO,
47 PVRSRV_HANDLE_TYPE_DISP_INFO,
48 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
49 PVRSRV_HANDLE_TYPE_BUF_INFO,
50 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
51 PVRSRV_HANDLE_TYPE_BUF_BUFFER,
52 PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
53 PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
54 PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
55 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
56 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
58 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
59 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
60 PVRSRV_HANDLE_TYPE_MMAP_INFO,
61 PVRSRV_HANDLE_TYPE_SOC_TIMER,
62 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ
63} PVRSRV_HANDLE_TYPE;
64
65typedef enum
66{
67
68 PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0,
69
70 PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01,
71
72 PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02,
73
74 PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04
75} PVRSRV_HANDLE_ALLOC_FLAG;
76
77struct _PVRSRV_HANDLE_BASE_;
78typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE;
79
80#ifdef PVR_SECURE_HANDLES
81extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
82
83#define KERNEL_HANDLE_BASE (gpsKernelHandleBase)
84
85PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
86
87PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
88
89PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
90
91PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle);
92
93PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
94
95PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
96
97PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
98
99PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
100
101PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
102
103PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize);
104
105PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase);
106
107IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase);
108
109PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle);
110
111IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase);
112
113PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase);
114
115PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
116
117PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
118
119PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase);
120
121PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID);
122
123PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID);
124
125#else
126
127#define KERNEL_HANDLE_BASE IMG_NULL
128
129#ifdef INLINE_IS_PRAGMA
130#pragma inline(PVRSRVAllocHandle)
131#endif
132static INLINE
133PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
134{
135 PVR_UNREFERENCED_PARAMETER(eType);
136 PVR_UNREFERENCED_PARAMETER(eFlag);
137 PVR_UNREFERENCED_PARAMETER(psBase);
138
139 *phHandle = pvData;
140 return PVRSRV_OK;
141}
142
143#ifdef INLINE_IS_PRAGMA
144#pragma inline(PVRSRVAllocSubHandle)
145#endif
146static INLINE
147PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
148{
149 PVR_UNREFERENCED_PARAMETER(eType);
150 PVR_UNREFERENCED_PARAMETER(eFlag);
151 PVR_UNREFERENCED_PARAMETER(hParent);
152 PVR_UNREFERENCED_PARAMETER(psBase);
153
154 *phHandle = pvData;
155 return PVRSRV_OK;
156}
157
158#ifdef INLINE_IS_PRAGMA
159#pragma inline(PVRSRVFindHandle)
160#endif
161static INLINE
162PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
163{
164 PVR_UNREFERENCED_PARAMETER(eType);
165 PVR_UNREFERENCED_PARAMETER(psBase);
166
167 *phHandle = pvData;
168 return PVRSRV_OK;
169}
170
171#ifdef INLINE_IS_PRAGMA
172#pragma inline(PVRSRVLookupHandleAnyType)
173#endif
174static INLINE
175PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
176{
177 PVR_UNREFERENCED_PARAMETER(psBase);
178
179 *peType = PVRSRV_HANDLE_TYPE_NONE;
180
181 *ppvData = hHandle;
182 return PVRSRV_OK;
183}
184
185#ifdef INLINE_IS_PRAGMA
186#pragma inline(PVRSRVLookupHandle)
187#endif
188static INLINE
189PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
190{
191 PVR_UNREFERENCED_PARAMETER(psBase);
192 PVR_UNREFERENCED_PARAMETER(eType);
193
194 *ppvData = hHandle;
195 return PVRSRV_OK;
196}
197
198#ifdef INLINE_IS_PRAGMA
199#pragma inline(PVRSRVLookupSubHandle)
200#endif
201static INLINE
202PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
203{
204 PVR_UNREFERENCED_PARAMETER(psBase);
205 PVR_UNREFERENCED_PARAMETER(eType);
206 PVR_UNREFERENCED_PARAMETER(hAncestor);
207
208 *ppvData = hHandle;
209 return PVRSRV_OK;
210}
211
212#ifdef INLINE_IS_PRAGMA
213#pragma inline(PVRSRVGetParentHandle)
214#endif
215static INLINE
216PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
217{
218 PVR_UNREFERENCED_PARAMETER(psBase);
219 PVR_UNREFERENCED_PARAMETER(eType);
220 PVR_UNREFERENCED_PARAMETER(hHandle);
221
222 *phParent = IMG_NULL;
223
224 return PVRSRV_OK;
225}
226
227#ifdef INLINE_IS_PRAGMA
228#pragma inline(PVRSRVLookupAndReleaseHandle)
229#endif
230static INLINE
231PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
232{
233 PVR_UNREFERENCED_PARAMETER(eType);
234 PVR_UNREFERENCED_PARAMETER(psBase);
235
236 *ppvData = hHandle;
237 return PVRSRV_OK;
238}
239
240#ifdef INLINE_IS_PRAGMA
241#pragma inline(PVRSRVReleaseHandle)
242#endif
243static INLINE
244PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
245{
246 PVR_UNREFERENCED_PARAMETER(hHandle);
247 PVR_UNREFERENCED_PARAMETER(eType);
248 PVR_UNREFERENCED_PARAMETER(psBase);
249
250 return PVRSRV_OK;
251}
252
253#ifdef INLINE_IS_PRAGMA
254#pragma inline(PVRSRVNewHandleBatch)
255#endif
256static INLINE
257PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
258{
259 PVR_UNREFERENCED_PARAMETER(psBase);
260 PVR_UNREFERENCED_PARAMETER(ui32BatchSize);
261
262 return PVRSRV_OK;
263}
264
265#ifdef INLINE_IS_PRAGMA
266#pragma inline(PVRSRVCommitHandleBatch)
267#endif
268static INLINE
269PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
270{
271 PVR_UNREFERENCED_PARAMETER(psBase);
272
273 return PVRSRV_OK;
274}
275
276#ifdef INLINE_IS_PRAGMA
277#pragma inline(PVRSRVReleaseHandleBatch)
278#endif
279static INLINE
280IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
281{
282 PVR_UNREFERENCED_PARAMETER(psBase);
283}
284
285#ifdef INLINE_IS_PRAGMA
286#pragma inline(PVRSRVSetMaxHandle)
287#endif
288static INLINE
289PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
290{
291 PVR_UNREFERENCED_PARAMETER(psBase);
292 PVR_UNREFERENCED_PARAMETER(ui32MaxHandle);
293
294 return PVRSRV_ERROR_NOT_SUPPORTED;
295}
296
297#ifdef INLINE_IS_PRAGMA
298#pragma inline(PVRSRVGetMaxHandle)
299#endif
300static INLINE
301IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
302{
303 PVR_UNREFERENCED_PARAMETER(psBase);
304
305 return 0;
306}
307
308#ifdef INLINE_IS_PRAGMA
309#pragma inline(PVRSRVEnableHandlePurging)
310#endif
311static INLINE
312PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
313{
314 PVR_UNREFERENCED_PARAMETER(psBase);
315
316 return PVRSRV_OK;
317}
318
319#ifdef INLINE_IS_PRAGMA
320#pragma inline(PVRSRVPurgeHandles)
321#endif
322static INLINE
323PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
324{
325 PVR_UNREFERENCED_PARAMETER(psBase);
326
327 return PVRSRV_OK;
328}
329
330#ifdef INLINE_IS_PRAGMA
331#pragma inline(PVRSRVAllocHandleBase)
332#endif
333static INLINE
334PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
335{
336 *ppsBase = IMG_NULL;
337
338 return PVRSRV_OK;
339}
340
341#ifdef INLINE_IS_PRAGMA
342#pragma inline(PVRSRVFreeHandleBase)
343#endif
344static INLINE
345PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
346{
347 PVR_UNREFERENCED_PARAMETER(psBase);
348
349 return PVRSRV_OK;
350}
351
352#ifdef INLINE_IS_PRAGMA
353#pragma inline(PVRSRVHandleInit)
354#endif
355static INLINE
356PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
357{
358 return PVRSRV_OK;
359}
360
361#ifdef INLINE_IS_PRAGMA
362#pragma inline(PVRSRVHandleDeInit)
363#endif
364static INLINE
365PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
366{
367 return PVRSRV_OK;
368}
369
370#endif
371
372#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \
373 (IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag)
374
375#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \
376 (IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent)
377
378#if defined (__cplusplus)
379}
380#endif
381
382#endif
383
diff --git a/drivers/gpu/pvr/hash.c b/drivers/gpu/pvr/hash.c
new file mode 100644
index 00000000000..32b0779d456
--- /dev/null
+++ b/drivers/gpu/pvr/hash.c
@@ -0,0 +1,477 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "pvr_debug.h"
28#include "img_defs.h"
29#include "services.h"
30#include "servicesint.h"
31#include "hash.h"
32#include "osfunc.h"
33
34#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b))
35
36#define KEY_TO_INDEX(pHash, key, uSize) \
37 ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize))
38
39#define KEY_COMPARE(pHash, pKey1, pKey2) \
40 ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2)))
41
42struct _BUCKET_
43{
44
45 struct _BUCKET_ *pNext;
46
47
48 IMG_UINTPTR_T v;
49
50
51 IMG_UINTPTR_T k[];
52};
53typedef struct _BUCKET_ BUCKET;
54
55struct _HASH_TABLE_
56{
57
58 BUCKET **ppBucketTable;
59
60
61 IMG_UINT32 uSize;
62
63
64 IMG_UINT32 uCount;
65
66
67 IMG_UINT32 uMinimumSize;
68
69
70 IMG_UINT32 uKeySize;
71
72
73 HASH_FUNC *pfnHashFunc;
74
75
76 HASH_KEY_COMP *pfnKeyComp;
77};
78
79IMG_UINT32
80HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen)
81{
82 IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey;
83 IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T);
84 IMG_UINT32 ui;
85 IMG_UINT32 uHashKey = 0;
86
87 PVR_UNREFERENCED_PARAMETER(uHashTabLen);
88
89 PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
90
91 for (ui = 0; ui < uKeyLen; ui++)
92 {
93 IMG_UINT32 uHashPart = (IMG_UINT32)*p++;
94
95 uHashPart += (uHashPart << 12);
96 uHashPart ^= (uHashPart >> 22);
97 uHashPart += (uHashPart << 4);
98 uHashPart ^= (uHashPart >> 9);
99 uHashPart += (uHashPart << 10);
100 uHashPart ^= (uHashPart >> 2);
101 uHashPart += (uHashPart << 7);
102 uHashPart ^= (uHashPart >> 12);
103
104 uHashKey += uHashPart;
105 }
106
107 return uHashKey;
108}
109
110IMG_BOOL
111HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2)
112{
113 IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1;
114 IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2;
115 IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T);
116 IMG_UINT32 ui;
117
118 PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
119
120 for (ui = 0; ui < uKeyLen; ui++)
121 {
122 if (*p1++ != *p2++)
123 return IMG_FALSE;
124 }
125
126 return IMG_TRUE;
127}
128
129static PVRSRV_ERROR
130_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
131{
132 IMG_UINT32 uIndex;
133
134 PVR_ASSERT (pBucket != IMG_NULL);
135 PVR_ASSERT (ppBucketTable != IMG_NULL);
136 PVR_ASSERT (uSize != 0);
137
138 if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0))
139 {
140 PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter"));
141 return PVRSRV_ERROR_INVALID_PARAMS;
142 }
143
144 uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize);
145 pBucket->pNext = ppBucketTable[uIndex];
146 ppBucketTable[uIndex] = pBucket;
147
148 return PVRSRV_OK;
149}
150
151static PVRSRV_ERROR
152_Rehash (HASH_TABLE *pHash,
153 BUCKET **ppOldTable, IMG_UINT32 uOldSize,
154 BUCKET **ppNewTable, IMG_UINT32 uNewSize)
155{
156 IMG_UINT32 uIndex;
157 for (uIndex=0; uIndex< uOldSize; uIndex++)
158 {
159 BUCKET *pBucket;
160 pBucket = ppOldTable[uIndex];
161 while (pBucket != IMG_NULL)
162 {
163 PVRSRV_ERROR eError;
164 BUCKET *pNextBucket = pBucket->pNext;
165 eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize);
166 if (eError != PVRSRV_OK)
167 {
168 PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed"));
169 return eError;
170 }
171 pBucket = pNextBucket;
172 }
173 }
174 return PVRSRV_OK;
175}
176
177static IMG_BOOL
178_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize)
179{
180 if (uNewSize != pHash->uSize)
181 {
182 BUCKET **ppNewTable;
183 IMG_UINT32 uIndex;
184
185 PVR_DPF ((PVR_DBG_MESSAGE,
186 "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x",
187 pHash->uSize, uNewSize, pHash->uCount));
188
189 OSAllocMem(PVRSRV_PAGEABLE_SELECT,
190 sizeof (BUCKET *) * uNewSize,
191 (IMG_PVOID*)&ppNewTable, IMG_NULL,
192 "Hash Table Buckets");
193 if (ppNewTable == IMG_NULL)
194 return IMG_FALSE;
195
196 for (uIndex=0; uIndex<uNewSize; uIndex++)
197 ppNewTable[uIndex] = IMG_NULL;
198
199 if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK)
200 {
201 return IMG_FALSE;
202 }
203
204 OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
205
206 pHash->ppBucketTable = ppNewTable;
207 pHash->uSize = uNewSize;
208 }
209 return IMG_TRUE;
210}
211
212
213HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp)
214{
215 HASH_TABLE *pHash;
216 IMG_UINT32 uIndex;
217
218 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen));
219
220 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
221 sizeof(HASH_TABLE),
222 (IMG_VOID **)&pHash, IMG_NULL,
223 "Hash Table") != PVRSRV_OK)
224 {
225 return IMG_NULL;
226 }
227
228 pHash->uCount = 0;
229 pHash->uSize = uInitialLen;
230 pHash->uMinimumSize = uInitialLen;
231 pHash->uKeySize = uKeySize;
232 pHash->pfnHashFunc = pfnHashFunc;
233 pHash->pfnKeyComp = pfnKeyComp;
234
235 OSAllocMem(PVRSRV_PAGEABLE_SELECT,
236 sizeof (BUCKET *) * pHash->uSize,
237 (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL,
238 "Hash Table Buckets");
239
240 if (pHash->ppBucketTable == IMG_NULL)
241 {
242 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
243
244 return IMG_NULL;
245 }
246
247 for (uIndex=0; uIndex<pHash->uSize; uIndex++)
248 pHash->ppBucketTable[uIndex] = IMG_NULL;
249 return pHash;
250}
251
252HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
253{
254 return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
255 &HASH_Func_Default, &HASH_Key_Comp_Default);
256}
257
258IMG_VOID
259HASH_Delete (HASH_TABLE *pHash)
260{
261 if (pHash != IMG_NULL)
262 {
263 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete"));
264
265 PVR_ASSERT (pHash->uCount==0);
266 if(pHash->uCount != 0)
267 {
268 PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
269 PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
270 }
271 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
272 pHash->ppBucketTable = IMG_NULL;
273 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
274
275 }
276}
277
278IMG_BOOL
279HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v)
280{
281 BUCKET *pBucket;
282
283 PVR_DPF ((PVR_DBG_MESSAGE,
284 "HASH_Insert_Extended: Hash=0x%08x, pKey=0x%08x, v=0x%x",
285 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
286
287 PVR_ASSERT (pHash != IMG_NULL);
288
289 if (pHash == IMG_NULL)
290 {
291 PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter"));
292 return IMG_FALSE;
293 }
294
295 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
296 sizeof(BUCKET) + pHash->uKeySize,
297 (IMG_VOID **)&pBucket, IMG_NULL,
298 "Hash Table entry") != PVRSRV_OK)
299 {
300 return IMG_FALSE;
301 }
302
303 pBucket->v = v;
304
305 OSMemCopy(pBucket->k, pKey, pHash->uKeySize);
306 if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
307 {
308 return IMG_FALSE;
309 }
310
311 pHash->uCount++;
312
313
314 if (pHash->uCount << 1 > pHash->uSize)
315 {
316
317
318 _Resize (pHash, pHash->uSize << 1);
319 }
320
321
322 return IMG_TRUE;
323}
324
325IMG_BOOL
326HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
327{
328 PVR_DPF ((PVR_DBG_MESSAGE,
329 "HASH_Insert: Hash=0x%x, k=0x%x, v=0x%x",
330 (IMG_UINTPTR_T)pHash, k, v));
331
332 return HASH_Insert_Extended(pHash, &k, v);
333}
334
335IMG_UINTPTR_T
336HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
337{
338 BUCKET **ppBucket;
339 IMG_UINT32 uIndex;
340
341 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x",
342 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
343
344 PVR_ASSERT (pHash != IMG_NULL);
345
346 if (pHash == IMG_NULL)
347 {
348 PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table"));
349 return 0;
350 }
351
352 uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
353
354 for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
355 {
356
357 if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
358 {
359 BUCKET *pBucket = *ppBucket;
360 IMG_UINTPTR_T v = pBucket->v;
361 (*ppBucket) = pBucket->pNext;
362
363 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL);
364
365
366 pHash->uCount--;
367
368
369 if (pHash->uSize > (pHash->uCount << 2) &&
370 pHash->uSize > pHash->uMinimumSize)
371 {
372
373
374 _Resize (pHash,
375 PRIVATE_MAX (pHash->uSize >> 1,
376 pHash->uMinimumSize));
377 }
378
379 PVR_DPF ((PVR_DBG_MESSAGE,
380 "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x%x",
381 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
382 return v;
383 }
384 }
385 PVR_DPF ((PVR_DBG_MESSAGE,
386 "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
387 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
388 return 0;
389}
390
391IMG_UINTPTR_T
392HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
393{
394 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%x, k=0x%x",
395 (IMG_UINTPTR_T)pHash, k));
396
397 return HASH_Remove_Extended(pHash, &k);
398}
399
400IMG_UINTPTR_T
401HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
402{
403 BUCKET **ppBucket;
404 IMG_UINT32 uIndex;
405
406 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%x, pKey=0x%x",
407 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
408
409 PVR_ASSERT (pHash != IMG_NULL);
410
411 if (pHash == IMG_NULL)
412 {
413 PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table"));
414 return 0;
415 }
416
417 uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
418
419 for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
420 {
421
422 if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
423 {
424 BUCKET *pBucket = *ppBucket;
425 IMG_UINTPTR_T v = pBucket->v;
426
427 PVR_DPF ((PVR_DBG_MESSAGE,
428 "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x%x",
429 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
430 return v;
431 }
432 }
433 PVR_DPF ((PVR_DBG_MESSAGE,
434 "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
435 (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
436 return 0;
437}
438
439IMG_UINTPTR_T
440HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
441{
442 PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%x, k=0x%x",
443 (IMG_UINTPTR_T)pHash, k));
444 return HASH_Retrieve_Extended(pHash, &k);
445}
446
447#ifdef HASH_TRACE
448IMG_VOID
449HASH_Dump (HASH_TABLE *pHash)
450{
451 IMG_UINT32 uIndex;
452 IMG_UINT32 uMaxLength=0;
453 IMG_UINT32 uEmptyCount=0;
454
455 PVR_ASSERT (pHash != IMG_NULL);
456 for (uIndex=0; uIndex<pHash->uSize; uIndex++)
457 {
458 BUCKET *pBucket;
459 IMG_UINT32 uLength = 0;
460 if (pHash->ppBucketTable[uIndex] == IMG_NULL)
461 {
462 uEmptyCount++;
463 }
464 for (pBucket=pHash->ppBucketTable[uIndex];
465 pBucket != IMG_NULL;
466 pBucket = pBucket->pNext)
467 {
468 uLength++;
469 }
470 uMaxLength = PRIVATE_MAX (uMaxLength, uLength);
471 }
472
473 PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d",
474 pHash->uMinimumSize, pHash->uSize, pHash->uCount));
475 PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength));
476}
477#endif
diff --git a/drivers/gpu/pvr/hash.h b/drivers/gpu/pvr/hash.h
new file mode 100644
index 00000000000..d45f4a98dda
--- /dev/null
+++ b/drivers/gpu/pvr/hash.h
@@ -0,0 +1,73 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _HASH_H_
28#define _HASH_H_
29
30#include "img_types.h"
31#include "osfunc.h"
32
33#if defined (__cplusplus)
34extern "C" {
35#endif
36
37typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
38typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
39
40typedef struct _HASH_TABLE_ HASH_TABLE;
41
42IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
43
44IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
45
46HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
47
48HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
49
50IMG_VOID HASH_Delete (HASH_TABLE *pHash);
51
52IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
53
54IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
55
56IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
57
58IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
59
60IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
61
62IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
63
64#ifdef HASH_TRACE
65IMG_VOID HASH_Dump (HASH_TABLE *pHash);
66#endif
67
68#if defined (__cplusplus)
69}
70#endif
71
72#endif
73
diff --git a/drivers/gpu/pvr/img_defs.h b/drivers/gpu/pvr/img_defs.h
new file mode 100644
index 00000000000..3ba2d2fc688
--- /dev/null
+++ b/drivers/gpu/pvr/img_defs.h
@@ -0,0 +1,118 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__IMG_DEFS_H__)
28#define __IMG_DEFS_H__
29
30#include "img_types.h"
31
32typedef enum img_tag_TriStateSwitch
33{
34 IMG_ON = 0x00,
35 IMG_OFF,
36 IMG_IGNORE
37
38} img_TriStateSwitch, * img_pTriStateSwitch;
39
40#define IMG_SUCCESS 0
41
42#define IMG_NO_REG 1
43
44#if defined (NO_INLINE_FUNCS)
45 #define INLINE
46 #define FORCE_INLINE
47#else
48#if defined (__cplusplus)
49 #define INLINE inline
50 #define FORCE_INLINE inline
51#else
52#if !defined(INLINE)
53 #define INLINE __inline
54#endif
55 #define FORCE_INLINE static __inline
56#endif
57#endif
58
59
60#ifndef PVR_UNREFERENCED_PARAMETER
61#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param)
62#endif
63
64#ifdef __GNUC__
65#define unref__ __attribute__ ((unused))
66#else
67#define unref__
68#endif
69
70#ifndef _TCHAR_DEFINED
71#if defined(UNICODE)
72typedef unsigned short TCHAR, *PTCHAR, *PTSTR;
73#else
74typedef char TCHAR, *PTCHAR, *PTSTR;
75#endif
76#define _TCHAR_DEFINED
77#endif
78
79
80 #if defined(__linux__) || defined(__METAG)
81
82 #define IMG_CALLCONV
83 #define IMG_INTERNAL __attribute__((visibility("hidden")))
84 #define IMG_EXPORT __attribute__((visibility("default")))
85 #define IMG_IMPORT
86 #define IMG_RESTRICT __restrict__
87
88 #else
89 #error("define an OS")
90 #endif
91
92#ifndef IMG_ABORT
93 #define IMG_ABORT() abort()
94#endif
95
96#ifndef IMG_MALLOC
97 #define IMG_MALLOC(A) malloc (A)
98#endif
99
100#ifndef IMG_FREE
101 #define IMG_FREE(A) free (A)
102#endif
103
104#define IMG_CONST const
105
106#if defined(__GNUC__)
107#define IMG_FORMAT_PRINTF(x,y) __attribute__((format(printf,x,y)))
108#else
109#define IMG_FORMAT_PRINTF(x,y)
110#endif
111
112#if defined (_WIN64)
113#define IMG_UNDEF (~0ULL)
114#else
115#define IMG_UNDEF (~0UL)
116#endif
117
118#endif
diff --git a/drivers/gpu/pvr/img_types.h b/drivers/gpu/pvr/img_types.h
new file mode 100644
index 00000000000..31962aaedbb
--- /dev/null
+++ b/drivers/gpu/pvr/img_types.h
@@ -0,0 +1,138 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __IMG_TYPES_H__
28#define __IMG_TYPES_H__
29
30#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS)
31#define IMG_ADDRSPACE_CPUVADDR_BITS 32
32#endif
33
34#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS)
35#define IMG_ADDRSPACE_PHYSADDR_BITS 32
36#endif
37
38typedef unsigned int IMG_UINT, *IMG_PUINT;
39typedef signed int IMG_INT, *IMG_PINT;
40
41typedef unsigned char IMG_UINT8, *IMG_PUINT8;
42typedef unsigned char IMG_BYTE, *IMG_PBYTE;
43typedef signed char IMG_INT8, *IMG_PINT8;
44typedef char IMG_CHAR, *IMG_PCHAR;
45
46typedef unsigned short IMG_UINT16, *IMG_PUINT16;
47typedef signed short IMG_INT16, *IMG_PINT16;
48#if !defined(IMG_UINT32_IS_ULONG)
49typedef unsigned int IMG_UINT32, *IMG_PUINT32;
50typedef signed int IMG_INT32, *IMG_PINT32;
51#else
52typedef unsigned long IMG_UINT32, *IMG_PUINT32;
53typedef signed long IMG_INT32, *IMG_PINT32;
54#endif
55#if !defined(IMG_UINT32_MAX)
56 #define IMG_UINT32_MAX 0xFFFFFFFFUL
57#endif
58
59 #if (defined(LINUX) || defined(__METAG))
60#if !defined(USE_CODE)
61 typedef unsigned long long IMG_UINT64, *IMG_PUINT64;
62 typedef long long IMG_INT64, *IMG_PINT64;
63#endif
64 #else
65
66 #error("define an OS")
67
68 #endif
69
70#if !(defined(LINUX) && defined (__KERNEL__))
71typedef float IMG_FLOAT, *IMG_PFLOAT;
72typedef double IMG_DOUBLE, *IMG_PDOUBLE;
73#endif
74
75typedef enum tag_img_bool
76{
77 IMG_FALSE = 0,
78 IMG_TRUE = 1,
79 IMG_FORCE_ALIGN = 0x7FFFFFFF
80} IMG_BOOL, *IMG_PBOOL;
81
82typedef void IMG_VOID, *IMG_PVOID;
83
84typedef IMG_INT32 IMG_RESULT;
85
86#if defined(_WIN64)
87typedef unsigned __int64 IMG_UINTPTR_T;
88#else
89typedef unsigned int IMG_UINTPTR_T;
90#endif
91
92typedef IMG_PVOID IMG_HANDLE;
93
94typedef void** IMG_HVOID, * IMG_PHVOID;
95
96typedef IMG_UINT32 IMG_SIZE_T;
97
98#define IMG_NULL 0
99
100typedef IMG_UINT32 IMG_SID;
101
102
103typedef IMG_PVOID IMG_CPU_VIRTADDR;
104
105typedef struct _IMG_DEV_VIRTADDR
106{
107
108 IMG_UINT32 uiAddr;
109#define IMG_CAST_TO_DEVVADDR_UINT(var) (IMG_UINT32)(var)
110
111} IMG_DEV_VIRTADDR;
112
113typedef struct _IMG_CPU_PHYADDR
114{
115
116 IMG_UINTPTR_T uiAddr;
117} IMG_CPU_PHYADDR;
118
119typedef struct _IMG_DEV_PHYADDR
120{
121#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
122
123 IMG_UINTPTR_T uiAddr;
124#else
125 IMG_UINT32 uiAddr;
126 IMG_UINT32 uiHighAddr;
127#endif
128} IMG_DEV_PHYADDR;
129
130typedef struct _IMG_SYS_PHYADDR
131{
132
133 IMG_UINTPTR_T uiAddr;
134} IMG_SYS_PHYADDR;
135
136#include "img_defs.h"
137
138#endif
diff --git a/drivers/gpu/pvr/ioctldef.h b/drivers/gpu/pvr/ioctldef.h
new file mode 100644
index 00000000000..4b23ad437a7
--- /dev/null
+++ b/drivers/gpu/pvr/ioctldef.h
@@ -0,0 +1,98 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __IOCTLDEF_H__
28#define __IOCTLDEF_H__
29
30#define MAKEIOCTLINDEX(i) (((i) >> 2) & 0xFFF)
31
32#ifndef CTL_CODE
33
34#define DEVICE_TYPE ULONG
35
36#define FILE_DEVICE_BEEP 0x00000001
37#define FILE_DEVICE_CD_ROM 0x00000002
38#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
39#define FILE_DEVICE_CONTROLLER 0x00000004
40#define FILE_DEVICE_DATALINK 0x00000005
41#define FILE_DEVICE_DFS 0x00000006
42#define FILE_DEVICE_DISK 0x00000007
43#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
44#define FILE_DEVICE_FILE_SYSTEM 0x00000009
45#define FILE_DEVICE_INPORT_PORT 0x0000000a
46#define FILE_DEVICE_KEYBOARD 0x0000000b
47#define FILE_DEVICE_MAILSLOT 0x0000000c
48#define FILE_DEVICE_MIDI_IN 0x0000000d
49#define FILE_DEVICE_MIDI_OUT 0x0000000e
50#define FILE_DEVICE_MOUSE 0x0000000f
51#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
52#define FILE_DEVICE_NAMED_PIPE 0x00000011
53#define FILE_DEVICE_NETWORK 0x00000012
54#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
55#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
56#define FILE_DEVICE_NULL 0x00000015
57#define FILE_DEVICE_PARALLEL_PORT 0x00000016
58#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
59#define FILE_DEVICE_PRINTER 0x00000018
60#define FILE_DEVICE_SCANNER 0x00000019
61#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
62#define FILE_DEVICE_SERIAL_PORT 0x0000001b
63#define FILE_DEVICE_SCREEN 0x0000001c
64#define FILE_DEVICE_SOUND 0x0000001d
65#define FILE_DEVICE_STREAMS 0x0000001e
66#define FILE_DEVICE_TAPE 0x0000001f
67#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
68#define FILE_DEVICE_TRANSPORT 0x00000021
69#define FILE_DEVICE_UNKNOWN 0x00000022
70#define FILE_DEVICE_VIDEO 0x00000023
71#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
72#define FILE_DEVICE_WAVE_IN 0x00000025
73#define FILE_DEVICE_WAVE_OUT 0x00000026
74#define FILE_DEVICE_8042_PORT 0x00000027
75#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
76#define FILE_DEVICE_BATTERY 0x00000029
77#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
78#define FILE_DEVICE_MODEM 0x0000002b
79#define FILE_DEVICE_VDM 0x0000002c
80#define FILE_DEVICE_MASS_STORAGE 0x0000002d
81
82#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
83 ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
84)
85
86#define METHOD_BUFFERED 0
87#define METHOD_IN_DIRECT 1
88#define METHOD_OUT_DIRECT 2
89#define METHOD_NEITHER 3
90
91#define FILE_ANY_ACCESS 0
92#define FILE_READ_ACCESS ( 0x0001 )
93#define FILE_WRITE_ACCESS ( 0x0002 )
94
95#endif
96
97#endif
98
diff --git a/drivers/gpu/pvr/kernelbuffer.h b/drivers/gpu/pvr/kernelbuffer.h
new file mode 100644
index 00000000000..5243aaf4a92
--- /dev/null
+++ b/drivers/gpu/pvr/kernelbuffer.h
@@ -0,0 +1,72 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__KERNELBUFFER_H__)
28#define __KERNELBUFFER_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_UINT32, IMG_HANDLE*);
35typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_UINT32, IMG_HANDLE);
36typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*);
37typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*);
38
39typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG
40{
41 IMG_UINT32 ui32TableSize;
42 PFN_OPEN_BC_DEVICE pfnOpenBCDevice;
43 PFN_CLOSE_BC_DEVICE pfnCloseBCDevice;
44 PFN_GET_BC_INFO pfnGetBCInfo;
45 PFN_GET_BC_BUFFER pfnGetBCBuffer;
46 PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
47
48} PVRSRV_BC_SRV2BUFFER_KMJTABLE;
49
50
51typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*);
52typedef IMG_VOID (*PFN_BC_SCHEDULE_DEVICES)(IMG_VOID);
53typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32);
54
55typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG
56{
57 IMG_UINT32 ui32TableSize;
58 PFN_BC_REGISTER_BUFFER_DEV pfnPVRSRVRegisterBCDevice;
59 PFN_BC_SCHEDULE_DEVICES pfnPVRSRVScheduleDevices;
60 PFN_BC_REMOVE_BUFFER_DEV pfnPVRSRVRemoveBCDevice;
61
62} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE;
63
64typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE);
65
66IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
67
68#if defined (__cplusplus)
69}
70#endif
71
72#endif
diff --git a/drivers/gpu/pvr/kerneldisplay.h b/drivers/gpu/pvr/kerneldisplay.h
new file mode 100644
index 00000000000..b5c1c7a1ecd
--- /dev/null
+++ b/drivers/gpu/pvr/kerneldisplay.h
@@ -0,0 +1,165 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__KERNELDISPLAY_H__)
28#define __KERNELDISPLAY_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);
35typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);
36typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);
37typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,
38 DISPLAY_FORMAT*,
39 IMG_UINT32*,
40 DISPLAY_DIMS*);
41typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);
42typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);
43typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,
44 IMG_UINT32,
45 DISPLAY_SURF_ATTRIBUTES*,
46 DISPLAY_SURF_ATTRIBUTES*,
47 IMG_UINT32,
48 PVRSRV_SYNC_DATA**,
49 IMG_UINT32,
50 IMG_HANDLE*,
51 IMG_UINT32*);
52typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE,
53 IMG_HANDLE);
54typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
55typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
56typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
57typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
58typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,
59 IMG_HANDLE,
60 IMG_UINT32*,
61 IMG_HANDLE*);
62typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,
63 IMG_HANDLE,
64 IMG_UINT32,
65 IMG_HANDLE,
66 IMG_UINT32,
67 IMG_RECT*);
68typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE);
69typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*);
70typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);
71
72typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG
73{
74 IMG_UINT32 ui32TableSize;
75 PFN_OPEN_DC_DEVICE pfnOpenDCDevice;
76 PFN_CLOSE_DC_DEVICE pfnCloseDCDevice;
77 PFN_ENUM_DC_FORMATS pfnEnumDCFormats;
78 PFN_ENUM_DC_DIMS pfnEnumDCDims;
79 PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer;
80 PFN_GET_DC_INFO pfnGetDCInfo;
81 PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
82 PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain;
83 PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain;
84 PFN_SET_DC_DSTRECT pfnSetDCDstRect;
85 PFN_SET_DC_SRCRECT pfnSetDCSrcRect;
86 PFN_SET_DC_DSTCK pfnSetDCDstColourKey;
87 PFN_SET_DC_SRCCK pfnSetDCSrcColourKey;
88 PFN_GET_DC_BUFFERS pfnGetDCBuffers;
89 PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer;
90 PFN_SWAP_TO_DC_SYSTEM pfnSwapToDCSystem;
91 PFN_SET_DC_STATE pfnSetDCState;
92 PFN_QUERY_SWAP_COMMAND_ID pfnQuerySwapCommandID;
93
94} PVRSRV_DC_SRV2DISP_KMJTABLE;
95
96typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);
97
98typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);
99typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);
100typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);
101typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);
102typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);
103typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);
104typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);
105typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,
106 PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
107 IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
108
109typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
110{
111 IMG_UINT32 ui32TableSize;
112 PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice;
113 PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice;
114 PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction;
115 PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList;
116 PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList;
117 PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete;
118 PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler;
119 PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice;
120 PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket;
121} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
122
123
124typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG
125{
126
127 IMG_HANDLE hExtDevice;
128
129
130 IMG_HANDLE hExtSwapChain;
131
132
133 IMG_HANDLE hExtBuffer;
134
135
136 IMG_HANDLE hPrivateTag;
137
138
139 IMG_UINT32 ui32ClipRectCount;
140
141
142 IMG_RECT *psClipRect;
143
144
145 IMG_UINT32 ui32SwapInterval;
146
147} DISPLAYCLASS_FLIP_COMMAND;
148
149#define DC_FLIP_COMMAND 0
150
151#define DC_STATE_NO_FLUSH_COMMANDS 0
152#define DC_STATE_FLUSH_COMMANDS 1
153
154
155typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);
156
157IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
158
159
160#if defined (__cplusplus)
161}
162#endif
163
164#endif
165
diff --git a/drivers/gpu/pvr/linkage.h b/drivers/gpu/pvr/linkage.h
new file mode 100644
index 00000000000..1d0d5775246
--- /dev/null
+++ b/drivers/gpu/pvr/linkage.h
@@ -0,0 +1,52 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __LINKAGE_H__
28#define __LINKAGE_H__
29
30#if !defined(SUPPORT_DRI_DRM)
31IMG_INT32 PVRSRV_BridgeDispatchKM(struct file *file, IMG_UINT cmd, IMG_UINT32 arg);
32#endif
33
34IMG_VOID PVRDPFInit(IMG_VOID);
35PVRSRV_ERROR PVROSFuncInit(IMG_VOID);
36IMG_VOID PVROSFuncDeInit(IMG_VOID);
37
38#ifdef DEBUG
39
40IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
41void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el);
42
43#ifdef PVR_MANUAL_POWER_CONTROL
44IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
45
46void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el);
47
48#endif
49
50#endif
51
52#endif
diff --git a/drivers/gpu/pvr/lists.c b/drivers/gpu/pvr/lists.c
new file mode 100644
index 00000000000..58389bf4a16
--- /dev/null
+++ b/drivers/gpu/pvr/lists.c
@@ -0,0 +1,99 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "lists.h"
28#include "services_headers.h"
29
30IMPLEMENT_LIST_ANY_VA(BM_HEAP)
31IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
32IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
33IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP)
34IMPLEMENT_LIST_REMOVE(BM_HEAP)
35IMPLEMENT_LIST_INSERT(BM_HEAP)
36
37IMPLEMENT_LIST_ANY_VA(BM_CONTEXT)
38IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL)
39IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK)
40IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT)
41IMPLEMENT_LIST_REMOVE(BM_CONTEXT)
42IMPLEMENT_LIST_INSERT(BM_CONTEXT)
43
44IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
45IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
46IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
47IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
48IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
49IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
50IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
51
52IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
53IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
54IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
55IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
56
57
58IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
59{
60 IMG_UINT32 ui32DevIndex;
61 IMG_BOOL bIgnoreClass;
62 PVRSRV_DEVICE_CLASS eDevClass;
63
64 ui32DevIndex = va_arg(va, IMG_UINT32);
65 bIgnoreClass = va_arg(va, IMG_BOOL);
66 if (!bIgnoreClass)
67 {
68 eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
69 }
70 else
71 {
72
73
74 eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
75 }
76
77 if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
78 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
79 {
80 return psDeviceNode;
81 }
82 return IMG_NULL;
83}
84
85IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
86{
87 IMG_UINT32 ui32DeviceIndex;
88
89 ui32DeviceIndex = va_arg(va, IMG_UINT32);
90
91 if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
92 {
93 return psPowerDev;
94 }
95 else
96 {
97 return IMG_NULL;
98 }
99}
diff --git a/drivers/gpu/pvr/lists.h b/drivers/gpu/pvr/lists.h
new file mode 100644
index 00000000000..0d7478862e1
--- /dev/null
+++ b/drivers/gpu/pvr/lists.h
@@ -0,0 +1,244 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __LISTS_UTILS__
28#define __LISTS_UTILS__
29
30#include <stdarg.h>
31#include "img_types.h"
32
33#define DECLARE_LIST_FOR_EACH(TYPE) \
34IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
35
36#define IMPLEMENT_LIST_FOR_EACH(TYPE) \
37IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
38{\
39 while(psHead)\
40 {\
41 pfnCallBack(psHead);\
42 psHead = psHead->psNext;\
43 }\
44}
45
46
47#define DECLARE_LIST_FOR_EACH_VA(TYPE) \
48IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...)
49
50#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \
51IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \
52{\
53 va_list ap;\
54 while(psHead)\
55 {\
56 va_start(ap, pfnCallBack);\
57 pfnCallBack(psHead, ap);\
58 psHead = psHead->psNext;\
59 va_end(ap);\
60 }\
61}
62
63
64#define DECLARE_LIST_ANY(TYPE) \
65IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))
66
67#define IMPLEMENT_LIST_ANY(TYPE) \
68IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\
69{ \
70 IMG_VOID *pResult;\
71 TYPE *psNextNode;\
72 pResult = IMG_NULL;\
73 psNextNode = psHead;\
74 while(psHead && !pResult)\
75 {\
76 psNextNode = psNextNode->psNext;\
77 pResult = pfnCallBack(psHead);\
78 psHead = psNextNode;\
79 }\
80 return pResult;\
81}
82
83
84#define DECLARE_LIST_ANY_VA(TYPE) \
85IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)
86
87#define IMPLEMENT_LIST_ANY_VA(TYPE) \
88IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
89{\
90 va_list ap;\
91 TYPE *psNextNode;\
92 IMG_VOID* pResult = IMG_NULL;\
93 while(psHead && !pResult)\
94 {\
95 psNextNode = psHead->psNext;\
96 va_start(ap, pfnCallBack);\
97 pResult = pfnCallBack(psHead, ap);\
98 va_end(ap);\
99 psHead = psNextNode;\
100 }\
101 return pResult;\
102}
103
104#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
105RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))
106
107#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
108RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\
109{ \
110 RTYPE result;\
111 TYPE *psNextNode;\
112 result = CONTINUE;\
113 psNextNode = psHead;\
114 while(psHead && result == CONTINUE)\
115 {\
116 psNextNode = psNextNode->psNext;\
117 result = pfnCallBack(psHead);\
118 psHead = psNextNode;\
119 }\
120 return result;\
121}
122
123
124#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
125RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)
126
127#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
128RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
129{\
130 va_list ap;\
131 TYPE *psNextNode;\
132 RTYPE result = CONTINUE;\
133 while(psHead && result == CONTINUE)\
134 {\
135 psNextNode = psHead->psNext;\
136 va_start(ap, pfnCallBack);\
137 result = pfnCallBack(psHead, ap);\
138 va_end(ap);\
139 psHead = psNextNode;\
140 }\
141 return result;\
142}
143
144
145#define DECLARE_LIST_REMOVE(TYPE) \
146IMG_VOID List_##TYPE##_Remove(TYPE *psNode)
147
148#define IMPLEMENT_LIST_REMOVE(TYPE) \
149IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\
150{\
151 (*psNode->ppsThis)=psNode->psNext;\
152 if(psNode->psNext)\
153 {\
154 psNode->psNext->ppsThis = psNode->ppsThis;\
155 }\
156}
157
158#define DECLARE_LIST_INSERT(TYPE) \
159IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)
160
161#define IMPLEMENT_LIST_INSERT(TYPE) \
162IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\
163{\
164 psNewNode->ppsThis = ppsHead;\
165 psNewNode->psNext = *ppsHead;\
166 *ppsHead = psNewNode;\
167 if(psNewNode->psNext)\
168 {\
169 psNewNode->psNext->ppsThis = &(psNewNode->psNext);\
170 }\
171}
172
173#define DECLARE_LIST_REVERSE(TYPE) \
174IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)
175
176#define IMPLEMENT_LIST_REVERSE(TYPE) \
177IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)\
178{\
179 TYPE *psTmpNode1; \
180 TYPE *psTmpNode2; \
181 TYPE *psCurNode; \
182 psTmpNode1 = IMG_NULL; \
183 psCurNode = *ppsHead; \
184 while(psCurNode) { \
185 psTmpNode2 = psCurNode->psNext; \
186 psCurNode->psNext = psTmpNode1; \
187 psTmpNode1 = psCurNode; \
188 psCurNode = psTmpNode2; \
189 if(psCurNode) \
190 { \
191 psTmpNode1->ppsThis = &(psCurNode->psNext); \
192 } \
193 else \
194 { \
195 psTmpNode1->ppsThis = ppsHead; \
196 } \
197 } \
198 *ppsHead = psTmpNode1; \
199}
200
201#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL)
202
203#include "services_headers.h"
204
205DECLARE_LIST_ANY_VA(BM_HEAP);
206DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
207DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
208DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
209DECLARE_LIST_REMOVE(BM_HEAP);
210DECLARE_LIST_INSERT(BM_HEAP);
211
212DECLARE_LIST_ANY_VA(BM_CONTEXT);
213DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL);
214DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK);
215DECLARE_LIST_FOR_EACH(BM_CONTEXT);
216DECLARE_LIST_REMOVE(BM_CONTEXT);
217DECLARE_LIST_INSERT(BM_CONTEXT);
218
219DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
220DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
221DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
222DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
223DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
224DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
225DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
226
227DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
228DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
229DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
230DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
231
232#undef DECLARE_LIST_ANY_2
233#undef DECLARE_LIST_ANY_VA
234#undef DECLARE_LIST_ANY_VA_2
235#undef DECLARE_LIST_FOR_EACH
236#undef DECLARE_LIST_FOR_EACH_VA
237#undef DECLARE_LIST_INSERT
238#undef DECLARE_LIST_REMOVE
239
240IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
241IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
242
243#endif
244
diff --git a/drivers/gpu/pvr/lock.h b/drivers/gpu/pvr/lock.h
new file mode 100644
index 00000000000..e0bf5ee67d4
--- /dev/null
+++ b/drivers/gpu/pvr/lock.h
@@ -0,0 +1,32 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __LOCK_H__
28#define __LOCK_H__
29
30extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
31
32#endif
diff --git a/drivers/gpu/pvr/mem.c b/drivers/gpu/pvr/mem.c
new file mode 100644
index 00000000000..a2673d53c23
--- /dev/null
+++ b/drivers/gpu/pvr/mem.c
@@ -0,0 +1,151 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "pvr_bridge_km.h"
29
30
31static PVRSRV_ERROR
32FreeSharedSysMemCallBack(IMG_PVOID pvParam,
33 IMG_UINT32 ui32Param)
34{
35 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam;
36
37 PVR_UNREFERENCED_PARAMETER(ui32Param);
38
39 OSFreePages(psKernelMemInfo->ui32Flags,
40 psKernelMemInfo->ui32AllocSize,
41 psKernelMemInfo->pvLinAddrKM,
42 psKernelMemInfo->sMemBlk.hOSMemHandle);
43
44 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
45 sizeof(PVRSRV_KERNEL_MEM_INFO),
46 psKernelMemInfo,
47 IMG_NULL);
48
49
50 return PVRSRV_OK;
51}
52
53
54IMG_EXPORT PVRSRV_ERROR
55PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
56 IMG_UINT32 ui32Flags,
57 IMG_SIZE_T ui32Size,
58 PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
59{
60 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
61
62 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
63 sizeof(PVRSRV_KERNEL_MEM_INFO),
64 (IMG_VOID **)&psKernelMemInfo, IMG_NULL,
65 "Kernel Memory Info") != PVRSRV_OK)
66 {
67 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo"));
68 return PVRSRV_ERROR_OUT_OF_MEMORY;
69 }
70
71 OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));
72
73 ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
74 ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
75 psKernelMemInfo->ui32Flags = ui32Flags;
76 psKernelMemInfo->ui32AllocSize = ui32Size;
77
78 if(OSAllocPages(psKernelMemInfo->ui32Flags,
79 psKernelMemInfo->ui32AllocSize,
80 HOST_PAGESIZE(),
81 &psKernelMemInfo->pvLinAddrKM,
82 &psKernelMemInfo->sMemBlk.hOSMemHandle)
83 != PVRSRV_OK)
84 {
85 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block"));
86 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
87 sizeof(PVRSRV_KERNEL_MEM_INFO),
88 psKernelMemInfo,
89 0);
90 return PVRSRV_ERROR_OUT_OF_MEMORY;
91 }
92
93
94 psKernelMemInfo->sMemBlk.hResItem =
95 ResManRegisterRes(psPerProc->hResManContext,
96 RESMAN_TYPE_SHARED_MEM_INFO,
97 psKernelMemInfo,
98 0,
99 &FreeSharedSysMemCallBack);
100
101 *ppsKernelMemInfo = psKernelMemInfo;
102
103 return PVRSRV_OK;
104}
105
106
107IMG_EXPORT PVRSRV_ERROR
108PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
109{
110 PVRSRV_ERROR eError;
111
112 if(psKernelMemInfo->sMemBlk.hResItem)
113 {
114 eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem);
115 }
116 else
117 {
118 eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0);
119 }
120
121 return eError;
122}
123
124
125IMG_EXPORT PVRSRV_ERROR
126PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
127{
128 PVRSRV_ERROR eError = PVRSRV_OK;
129
130 if(!psKernelMemInfo)
131 {
132 return PVRSRV_ERROR_INVALID_PARAMS;
133 }
134
135 if(psKernelMemInfo->sMemBlk.hResItem)
136 {
137 eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL);
138
139 if (eError != PVRSRV_OK)
140 {
141 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed"));
142 PVR_DBG_BREAK;
143 return eError;
144 }
145
146 psKernelMemInfo->sMemBlk.hResItem = IMG_NULL;
147 }
148
149 return eError;
150}
151
diff --git a/drivers/gpu/pvr/mem_debug.c b/drivers/gpu/pvr/mem_debug.c
new file mode 100644
index 00000000000..cbe99120e21
--- /dev/null
+++ b/drivers/gpu/pvr/mem_debug.c
@@ -0,0 +1,250 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef MEM_DEBUG_C
28#define MEM_DEBUG_C
29
30#if defined(PVRSRV_DEBUG_OS_MEMORY)
31
32#include "img_types.h"
33#include "services_headers.h"
34
35#if defined (__cplusplus)
36extern "C"
37{
38#endif
39
40#define STOP_ON_ERROR 0
41
42
43
44
45
46
47
48
49
50 IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
51 {
52 IMG_UINT8 *pui8Addr;
53 for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
54 {
55 if (*pui8Addr != ui8Pattern)
56 {
57 return IMG_FALSE;
58 }
59 }
60 return IMG_TRUE;
61 }
62
63
64
65 IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
66 {
67 OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
68
69
70 if (pvCpuVAddr == IMG_NULL)
71 {
72 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer"
73 " - referenced %s:%d - allocated %s:%d",
74 pvCpuVAddr,
75 pszFileName, uLine,
76 psInfo->sFileName, psInfo->uLineNo));
77 while (STOP_ON_ERROR);
78 }
79
80
81 if (((IMG_UINT32)pvCpuVAddr&3) != 0)
82 {
83 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment"
84 " - referenced %s:%d - allocated %s:%d",
85 pvCpuVAddr,
86 pszFileName, uLine,
87 psInfo->sFileName, psInfo->uLineNo));
88 while (STOP_ON_ERROR);
89 }
90
91
92 if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
93 {
94 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten"
95 " - referenced %s:%d - allocated %s:%d",
96 pvCpuVAddr,
97 pszFileName, uLine,
98 psInfo->sFileName, psInfo->uLineNo));
99 while (STOP_ON_ERROR);
100 }
101
102
103 if (uSize != psInfo->uSize)
104 {
105 PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)"
106 " - referenced %s:%d - allocated %s:%d",
107 pvCpuVAddr, uSize, psInfo->uSize,
108 pszFileName, uLine,
109 psInfo->sFileName, psInfo->uLineNo));
110 while (STOP_ON_ERROR);
111 }
112
113
114 if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
115 {
116 PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)"
117 " - referenced %s:%d - allocated %s:%d",
118 pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
119 pszFileName, uLine,
120 psInfo->sFileName, psInfo->uLineNo));
121 while (STOP_ON_ERROR);
122 }
123 else
124 {
125
126 uSize = psInfo->uSize;
127 }
128
129
130 if (uSize)
131 {
132 if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
133 {
134 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten"
135 " - referenced from %s:%d - allocated from %s:%d",
136 pvCpuVAddr,
137 pszFileName, uLine,
138 psInfo->sFileName, psInfo->uLineNo));
139 }
140 }
141
142
143 if (psInfo->eValid != isAllocated)
144 {
145 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)"
146 " - referenced %s:%d - freed %s:%d",
147 pvCpuVAddr, psInfo->eValid == isFree,
148 pszFileName, uLine,
149 psInfo->sFileName, psInfo->uLineNo));
150 while (STOP_ON_ERROR);
151 }
152 }
153
154 IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
155 {
156 IMG_SIZE_T i = 0;
157
158 for (; i < 128; i++)
159 {
160 *pDest = *pSrc;
161 if (*pSrc == '\0') break;
162 pDest++;
163 pSrc++;
164 }
165 }
166
167 PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
168 IMG_UINT32 ui32Size,
169 IMG_PVOID *ppvCpuVAddr,
170 IMG_HANDLE *phBlockAlloc,
171 IMG_CHAR *pszFilename,
172 IMG_UINT32 ui32Line)
173 {
174 OSMEM_DEBUG_INFO *psInfo;
175
176 PVRSRV_ERROR eError;
177
178 eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
179 ui32Size + TEST_BUFFER_PADDING,
180 ppvCpuVAddr,
181 phBlockAlloc,
182 pszFilename,
183 ui32Line);
184
185 if (eError != PVRSRV_OK)
186 {
187 return eError;
188 }
189
190
191 OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
192 OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
193
194
195 psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
196
197 OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
198 debug_strcpy(psInfo->sFileName, pszFilename);
199 psInfo->uLineNo = ui32Line;
200 psInfo->eValid = isAllocated;
201 psInfo->uSize = ui32Size;
202 psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
203
204
205 *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
206
207#ifdef PVRSRV_LOG_MEMORY_ALLOCS
208
209 PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
210#endif
211
212 return PVRSRV_OK;
213 }
214
215 PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
216 IMG_UINT32 ui32Size,
217 IMG_PVOID pvCpuVAddr,
218 IMG_HANDLE hBlockAlloc,
219 IMG_CHAR *pszFilename,
220 IMG_UINT32 ui32Line)
221 {
222 OSMEM_DEBUG_INFO *psInfo;
223
224
225 OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
226
227
228 OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);
229
230
231 psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
232
233
234 psInfo->uSize = 0;
235 psInfo->uSizeParityCheck = 0;
236 psInfo->eValid = isFree;
237 psInfo->uLineNo = ui32Line;
238 debug_strcpy(psInfo->sFileName, pszFilename);
239
240 return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
241 }
242
243#if defined (__cplusplus)
244
245}
246#endif
247
248#endif
249
250#endif
diff --git a/drivers/gpu/pvr/metrics.c b/drivers/gpu/pvr/metrics.c
new file mode 100644
index 00000000000..ee5cabd4998
--- /dev/null
+++ b/drivers/gpu/pvr/metrics.c
@@ -0,0 +1,160 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "metrics.h"
29
30#if defined(SUPPORT_VGX)
31#include "vgxapi_km.h"
32#endif
33
34#if defined(SUPPORT_SGX)
35#include "sgxapi_km.h"
36#endif
37
38#if defined(DEBUG) || defined(TIMING)
39
40static volatile IMG_UINT32 *pui32TimerRegister = 0;
41
42#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total
43#define PVRSRV_TIMER_TOTAL_IN_MS(X) ((1000*asTimers[X].ui32Total)/ui32TicksPerMS)
44#define PVRSRV_TIMER_COUNT(X) asTimers[X].ui32Count
45
46
47Temporal_Data asTimers[PVRSRV_NUM_TIMERS];
48
49
50IMG_UINT32 PVRSRVTimeNow(IMG_VOID)
51{
52 if (!pui32TimerRegister)
53 {
54 static IMG_BOOL bFirstTime = IMG_TRUE;
55
56 if (bFirstTime)
57 {
58 PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up"));
59
60 bFirstTime = IMG_FALSE;
61 }
62
63 return 0;
64 }
65
66#if defined(__sh__)
67
68 return (0xffffffff-*pui32TimerRegister);
69
70#else
71
72 return 0;
73
74#endif
75}
76
77
78static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID)
79{
80 IMG_UINT32 ui32Time1, ui32Time2;
81
82 ui32Time1 = PVRSRVTimeNow();
83
84 OSWaitus(1000000);
85
86 ui32Time2 = PVRSRVTimeNow();
87
88 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1));
89
90 return (ui32Time2 - ui32Time1);
91}
92
93
94IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo)
95{
96 IMG_UINT32 ui32Loop;
97
98 PVR_UNREFERENCED_PARAMETER(pvDevInfo);
99
100 for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
101 {
102 asTimers[ui32Loop].ui32Total = 0;
103 asTimers[ui32Loop].ui32Count = 0;
104 }
105
106
107 #if defined(__sh__)
108
109
110
111
112
113 *TCR_2 = TIMER_DIVISOR;
114
115
116 *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff;
117
118
119 *TST_REG |= (IMG_UINT8)0x04;
120
121 pui32TimerRegister = (IMG_UINT32 *)TCNT_2;
122
123 #else
124
125 pui32TimerRegister = 0;
126
127 #endif
128
129}
130
131
132IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID)
133{
134 IMG_UINT32 ui32TicksPerMS, ui32Loop;
135
136 ui32TicksPerMS = PVRSRVGetCPUFreq();
137
138 if (!ui32TicksPerMS)
139 {
140 PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq"));
141 return;
142 }
143
144 for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
145 {
146 if (asTimers[ui32Loop].ui32Count & 0x80000000L)
147 {
148 PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop));
149 }
150 }
151#if 0
152
153 PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1)));
154 PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1)));
155 PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1)));
156#endif
157}
158
159#endif
160
diff --git a/drivers/gpu/pvr/metrics.h b/drivers/gpu/pvr/metrics.h
new file mode 100644
index 00000000000..2632f8dbe02
--- /dev/null
+++ b/drivers/gpu/pvr/metrics.h
@@ -0,0 +1,130 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _METRICS_
28#define _METRICS_
29
30
31#if defined (__cplusplus)
32extern "C" {
33#endif
34
35
36#if defined(DEBUG) || defined(TIMING)
37
38
39typedef struct
40{
41 IMG_UINT32 ui32Start;
42 IMG_UINT32 ui32Stop;
43 IMG_UINT32 ui32Total;
44 IMG_UINT32 ui32Count;
45} Temporal_Data;
46
47extern Temporal_Data asTimers[];
48
49extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID);
50extern IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo);
51extern IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID);
52
53
54#define PVRSRV_TIMER_DUMMY 0
55
56#define PVRSRV_TIMER_EXAMPLE_1 1
57#define PVRSRV_TIMER_EXAMPLE_2 2
58
59
60#define PVRSRV_NUM_TIMERS (PVRSRV_TIMER_EXAMPLE_2 + 1)
61
62#define PVRSRV_TIME_START(X) { \
63 asTimers[X].ui32Count += 1; \
64 asTimers[X].ui32Count |= 0x80000000L; \
65 asTimers[X].ui32Start = PVRSRVTimeNow(); \
66 asTimers[X].ui32Stop = 0; \
67 }
68
69#define PVRSRV_TIME_SUSPEND(X) { \
70 asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
71 }
72
73#define PVRSRV_TIME_RESUME(X) { \
74 asTimers[X].ui32Start = PVRSRVTimeNow(); \
75 }
76
77#define PVRSRV_TIME_STOP(X) { \
78 asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
79 asTimers[X].ui32Total += asTimers[X].ui32Stop; \
80 asTimers[X].ui32Count &= 0x7FFFFFFFL; \
81 }
82
83#define PVRSRV_TIME_RESET(X) { \
84 asTimers[X].ui32Start = 0; \
85 asTimers[X].ui32Stop = 0; \
86 asTimers[X].ui32Total = 0; \
87 asTimers[X].ui32Count = 0; \
88 }
89
90
91#if defined(__sh__)
92
93#define TST_REG ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM))
94
95#define TCOR_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+28))
96#define TCNT_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+32))
97#define TCR_2 ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36))
98
99#define TIMER_DIVISOR 4
100
101#endif
102
103
104
105
106
107#else
108
109
110
111#define PVRSRV_TIME_START(X)
112#define PVRSRV_TIME_SUSPEND(X)
113#define PVRSRV_TIME_RESUME(X)
114#define PVRSRV_TIME_STOP(X)
115#define PVRSRV_TIME_RESET(X)
116
117#define PVRSRVSetupMetricTimers(X)
118#define PVRSRVOutputMetricTotals()
119
120
121
122#endif
123
124#if defined(__cplusplus)
125}
126#endif
127
128
129#endif
130
diff --git a/drivers/gpu/pvr/mm.c b/drivers/gpu/pvr/mm.c
new file mode 100644
index 00000000000..ecaba8e1015
--- /dev/null
+++ b/drivers/gpu/pvr/mm.c
@@ -0,0 +1,2012 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/version.h>
32#include <linux/mm.h>
33#include <linux/vmalloc.h>
34#include <asm/io.h>
35#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
36#include <linux/wrapper.h>
37#endif
38#include <linux/slab.h>
39#include <linux/highmem.h>
40#include <linux/sched.h>
41
42#include "img_defs.h"
43#include "services.h"
44#include "servicesint.h"
45#include "syscommon.h"
46#include "mutils.h"
47#include "mm.h"
48#include "pvrmmap.h"
49#include "mmap.h"
50#include "osfunc.h"
51#include "pvr_debug.h"
52#include "proc.h"
53#include "mutex.h"
54#include "lock.h"
55
56#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
57 #include "lists.h"
58#endif
59
60#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
61typedef enum {
62 DEBUG_MEM_ALLOC_TYPE_KMALLOC,
63 DEBUG_MEM_ALLOC_TYPE_VMALLOC,
64 DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
65 DEBUG_MEM_ALLOC_TYPE_IOREMAP,
66 DEBUG_MEM_ALLOC_TYPE_IO,
67 DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
68 DEBUG_MEM_ALLOC_TYPE_COUNT
69}DEBUG_MEM_ALLOC_TYPE;
70
71typedef struct _DEBUG_MEM_ALLOC_REC
72{
73 DEBUG_MEM_ALLOC_TYPE eAllocType;
74 IMG_VOID *pvKey;
75 IMG_VOID *pvCpuVAddr;
76 IMG_UINT32 ulCpuPAddr;
77 IMG_VOID *pvPrivateData;
78 IMG_UINT32 ui32Bytes;
79 pid_t pid;
80 IMG_CHAR *pszFileName;
81 IMG_UINT32 ui32Line;
82
83 struct _DEBUG_MEM_ALLOC_REC *psNext;
84 struct _DEBUG_MEM_ALLOC_REC **ppsThis;
85}DEBUG_MEM_ALLOC_REC;
86
87static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
88static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
89static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC)
90static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC)
91static IMPLEMENT_LIST_REMOVE(DEBUG_MEM_ALLOC_REC)
92
93
94static DEBUG_MEM_ALLOC_REC *g_MemoryRecords;
95
96static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
97static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
98
99static IMG_UINT32 g_SysRAMWaterMark;
100static IMG_UINT32 g_SysRAMHighWaterMark;
101
102static IMG_UINT32 g_IOMemWaterMark;
103static IMG_UINT32 g_IOMemHighWaterMark;
104
105static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
106 IMG_VOID *pvKey,
107 IMG_VOID *pvCpuVAddr,
108 IMG_UINT32 ulCpuPAddr,
109 IMG_VOID *pvPrivateData,
110 IMG_UINT32 ui32Bytes,
111 IMG_CHAR *pszFileName,
112 IMG_UINT32 ui32Line);
113
114static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
115
116static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType);
117
118
119static struct proc_dir_entry *g_SeqFileMemoryRecords =0;
120static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
121static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
122static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off);
123
124#endif
125
126
127#if defined(DEBUG_LINUX_MEM_AREAS)
128typedef struct _DEBUG_LINUX_MEM_AREA_REC
129{
130 LinuxMemArea *psLinuxMemArea;
131 IMG_UINT32 ui32Flags;
132 pid_t pid;
133
134 struct _DEBUG_LINUX_MEM_AREA_REC *psNext;
135 struct _DEBUG_LINUX_MEM_AREA_REC **ppsThis;
136}DEBUG_LINUX_MEM_AREA_REC;
137
138
139static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC)
140static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC)
141static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC)
142static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC)
143
144
145
146
147static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords;
148static IMG_UINT32 g_LinuxMemAreaCount;
149static IMG_UINT32 g_LinuxMemAreaWaterMark;
150static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
151
152
153static struct proc_dir_entry *g_SeqFileMemArea=0;
154
155static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
156static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
157static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off);
158
159#endif
160
161#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
162static PVRSRV_LINUX_MUTEX g_sDebugMutex;
163#endif
164
165#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS))
166static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
167#endif
168
169static LinuxKMemCache *psLinuxMemAreaCache;
170
171
172#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
173static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
174static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
175#endif
176
177static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID);
178static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea);
179#if defined(DEBUG_LINUX_MEM_AREAS)
180static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags);
181static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea);
182static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea);
183#endif
184
185PVRSRV_ERROR
186LinuxMMInit(IMG_VOID)
187{
188#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
189 LinuxInitMutex(&g_sDebugMutex);
190#endif
191
192#if defined(DEBUG_LINUX_MEM_AREAS)
193 {
194 g_SeqFileMemArea = CreateProcReadEntrySeq(
195 "mem_areas",
196 NULL,
197 ProcSeqNextMemArea,
198 ProcSeqShowMemArea,
199 ProcSeqOff2ElementMemArea,
200 ProcSeqStartstopDebugMutex
201 );
202 if(!g_SeqFileMemArea)
203 {
204 return PVRSRV_ERROR_OUT_OF_MEMORY;
205 }
206 }
207#endif
208
209
210#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
211 {
212 g_SeqFileMemoryRecords =CreateProcReadEntrySeq(
213 "meminfo",
214 NULL,
215 ProcSeqNextMemoryRecords,
216 ProcSeqShowMemoryRecords,
217 ProcSeqOff2ElementMemoryRecords,
218 ProcSeqStartstopDebugMutex
219 );
220 if(!g_SeqFileMemoryRecords)
221 {
222 return PVRSRV_ERROR_OUT_OF_MEMORY;
223 }
224 }
225#endif
226
227 psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
228 if(!psLinuxMemAreaCache)
229 {
230 PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
231 return PVRSRV_ERROR_OUT_OF_MEMORY;
232 }
233
234 return PVRSRV_OK;
235}
236
237#if defined(DEBUG_LINUX_MEM_AREAS)
238static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
239{
240 LinuxMemArea *psLinuxMemArea;
241
242 psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
243 PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
244 __FUNCTION__,
245 psCurrentRecord->psLinuxMemArea,
246 LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
247 psCurrentRecord->psLinuxMemArea->ui32ByteSize));
248
249 LinuxMemAreaDeepFree(psLinuxMemArea);
250}
251#endif
252
253#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
254static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
255
256{
257
258 PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
259 "type=%s "
260 "CpuVAddr=%p "
261 "CpuPAddr=0x%08x, "
262 "allocated @ file=%s,line=%d",
263 __FUNCTION__,
264 DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
265 psCurrentRecord->pvCpuVAddr,
266 psCurrentRecord->ulCpuPAddr,
267 psCurrentRecord->pszFileName,
268 psCurrentRecord->ui32Line));
269 switch(psCurrentRecord->eAllocType)
270 {
271 case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
272 KFreeWrapper(psCurrentRecord->pvCpuVAddr);
273 break;
274 case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
275 IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
276 break;
277 case DEBUG_MEM_ALLOC_TYPE_IO:
278
279 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
280 break;
281 case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
282 VFreeWrapper(psCurrentRecord->pvCpuVAddr);
283 break;
284 case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
285
286 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
287 break;
288 case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
289 KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
290 break;
291 default:
292 PVR_ASSERT(0);
293 }
294}
295#endif
296
297
298IMG_VOID
299LinuxMMCleanup(IMG_VOID)
300{
301
302#if defined(DEBUG_LINUX_MEM_AREAS)
303 {
304 if(g_LinuxMemAreaCount)
305 {
306 PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
307 __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
308 }
309
310 List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords,
311 LinuxMMCleanup_MemAreas_ForEachCb);
312
313 RemoveProcEntrySeq( g_SeqFileMemArea );
314 }
315#endif
316
317
318#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
319 {
320
321
322 List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords,
323 LinuxMMCleanup_MemRecords_ForEachVa);
324
325 RemoveProcEntrySeq( g_SeqFileMemoryRecords );
326 }
327#endif
328
329 if(psLinuxMemAreaCache)
330 {
331 KMemCacheDestroyWrapper(psLinuxMemAreaCache);
332 psLinuxMemAreaCache=NULL;
333 }
334}
335
336
337IMG_VOID *
338_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
339{
340 IMG_VOID *pvRet;
341 pvRet = kmalloc(ui32ByteSize, GFP_KERNEL);
342#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
343 if(pvRet)
344 {
345 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
346 pvRet,
347 pvRet,
348 0,
349 NULL,
350 ui32ByteSize,
351 pszFileName,
352 ui32Line
353 );
354 }
355#else
356 PVR_UNREFERENCED_PARAMETER(pszFileName);
357 PVR_UNREFERENCED_PARAMETER(ui32Line);
358#endif
359 return pvRet;
360}
361
362
363IMG_VOID
364_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
365{
366#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
367 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMALLOC, pvCpuVAddr, pszFileName, ui32Line);
368#else
369 PVR_UNREFERENCED_PARAMETER(pszFileName);
370 PVR_UNREFERENCED_PARAMETER(ui32Line);
371#endif
372 kfree(pvCpuVAddr);
373}
374
375
376#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
377static IMG_VOID
378DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
379 IMG_VOID *pvKey,
380 IMG_VOID *pvCpuVAddr,
381 IMG_UINT32 ulCpuPAddr,
382 IMG_VOID *pvPrivateData,
383 IMG_UINT32 ui32Bytes,
384 IMG_CHAR *pszFileName,
385 IMG_UINT32 ui32Line)
386{
387 DEBUG_MEM_ALLOC_REC *psRecord;
388
389 LinuxLockMutex(&g_sDebugMutex);
390
391 psRecord = kmalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL);
392
393 psRecord->eAllocType = eAllocType;
394 psRecord->pvKey = pvKey;
395 psRecord->pvCpuVAddr = pvCpuVAddr;
396 psRecord->ulCpuPAddr = ulCpuPAddr;
397 psRecord->pvPrivateData = pvPrivateData;
398 psRecord->pid = current->pid;
399 psRecord->ui32Bytes = ui32Bytes;
400 psRecord->pszFileName = pszFileName;
401 psRecord->ui32Line = ui32Line;
402
403 List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord);
404
405 g_WaterMarkData[eAllocType] += ui32Bytes;
406 if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
407 {
408 g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType];
409 }
410
411 if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
412 || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
413 || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
414 || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
415 {
416 g_SysRAMWaterMark += ui32Bytes;
417 if(g_SysRAMWaterMark > g_SysRAMHighWaterMark)
418 {
419 g_SysRAMHighWaterMark = g_SysRAMWaterMark;
420 }
421 }
422 else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
423 || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
424 {
425 g_IOMemWaterMark += ui32Bytes;
426 if(g_IOMemWaterMark > g_IOMemHighWaterMark)
427 {
428 g_IOMemHighWaterMark = g_IOMemWaterMark;
429 }
430 }
431
432 LinuxUnLockMutex(&g_sDebugMutex);
433}
434
435
436static IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va)
437{
438 DEBUG_MEM_ALLOC_TYPE eAllocType;
439 IMG_VOID *pvKey;
440
441 eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
442 pvKey = va_arg(va, IMG_VOID*);
443
444 if(psCurrentRecord->eAllocType == eAllocType
445 && psCurrentRecord->pvKey == pvKey)
446 {
447 eAllocType = psCurrentRecord->eAllocType;
448 g_WaterMarkData[eAllocType] -= psCurrentRecord->ui32Bytes;
449
450 if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
451 || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
452 || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
453 || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
454 {
455 g_SysRAMWaterMark -= psCurrentRecord->ui32Bytes;
456 }
457 else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
458 || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
459 {
460 g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
461 }
462
463 List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord);
464 kfree(psCurrentRecord);
465
466 return IMG_TRUE;
467 }
468 else
469 {
470 return IMG_FALSE;
471 }
472}
473
474
475static IMG_VOID
476DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
477{
478 LinuxLockMutex(&g_sDebugMutex);
479
480
481 if(!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
482 DebugMemAllocRecordRemove_AnyVaCb,
483 eAllocType,
484 pvKey))
485 {
486 PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with pvKey=%p (called from %s, line %d\n",
487 __FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), pvKey,
488 pszFileName, ui32Line));
489 }
490
491 LinuxUnLockMutex(&g_sDebugMutex);
492}
493
494
495static IMG_CHAR *
496DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
497{
498 IMG_CHAR *apszDebugMemoryRecordTypes[] = {
499 "KMALLOC",
500 "VMALLOC",
501 "ALLOC_PAGES",
502 "IOREMAP",
503 "IO",
504 "KMEM_CACHE_ALLOC"
505 };
506 return apszDebugMemoryRecordTypes[eAllocType];
507}
508#endif
509
510
511
512IMG_VOID *
513_VMallocWrapper(IMG_UINT32 ui32Bytes,
514 IMG_UINT32 ui32AllocFlags,
515 IMG_CHAR *pszFileName,
516 IMG_UINT32 ui32Line)
517{
518 pgprot_t PGProtFlags;
519 IMG_VOID *pvRet;
520
521 switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
522 {
523 case PVRSRV_HAP_CACHED:
524 PGProtFlags = PAGE_KERNEL;
525 break;
526 case PVRSRV_HAP_WRITECOMBINE:
527 PGProtFlags = PGPROT_WC(PAGE_KERNEL);
528 break;
529 case PVRSRV_HAP_UNCACHED:
530 PGProtFlags = PGPROT_UC(PAGE_KERNEL);
531 break;
532 default:
533 PVR_DPF((PVR_DBG_ERROR,
534 "VMAllocWrapper: unknown mapping flags=0x%08x",
535 ui32AllocFlags));
536 dump_stack();
537 return NULL;
538 }
539
540
541 pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
542
543#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
544 if(pvRet)
545 {
546 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC,
547 pvRet,
548 pvRet,
549 0,
550 NULL,
551 PAGE_ALIGN(ui32Bytes),
552 pszFileName,
553 ui32Line
554 );
555 }
556#else
557 PVR_UNREFERENCED_PARAMETER(pszFileName);
558 PVR_UNREFERENCED_PARAMETER(ui32Line);
559#endif
560
561 return pvRet;
562}
563
564
565IMG_VOID
566_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
567{
568#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
569 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, pszFileName, ui32Line);
570#else
571 PVR_UNREFERENCED_PARAMETER(pszFileName);
572 PVR_UNREFERENCED_PARAMETER(ui32Line);
573#endif
574 vfree(pvCpuVAddr);
575}
576
577
578LinuxMemArea *
579NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
580{
581 LinuxMemArea *psLinuxMemArea;
582 IMG_VOID *pvCpuVAddr;
583
584 psLinuxMemArea = LinuxMemAreaStructAlloc();
585 if(!psLinuxMemArea)
586 {
587 goto failed;
588 }
589
590 pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
591 if(!pvCpuVAddr)
592 {
593 goto failed;
594 }
595
596#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
597
598 ReservePages(pvCpuVAddr, ui32Bytes);
599#endif
600
601 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
602 psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
603 psLinuxMemArea->ui32ByteSize = ui32Bytes;
604 psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
605 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
606
607#if defined(DEBUG_LINUX_MEM_AREAS)
608 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
609#endif
610
611
612 if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
613 OSInvalidateCPUCacheRangeKM(psLinuxMemArea, pvCpuVAddr, ui32Bytes);
614
615 return psLinuxMemArea;
616
617failed:
618 PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
619 if(psLinuxMemArea)
620 LinuxMemAreaStructFree(psLinuxMemArea);
621 return NULL;
622}
623
624
625IMG_VOID
626FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
627{
628 PVR_ASSERT(psLinuxMemArea);
629 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC);
630 PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
631
632#if defined(DEBUG_LINUX_MEM_AREAS)
633 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
634#endif
635
636#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
637 UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
638 psLinuxMemArea->ui32ByteSize);
639#endif
640
641 PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
642 __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
643 VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
644
645 LinuxMemAreaStructFree(psLinuxMemArea);
646}
647
648
649#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
650static IMG_VOID
651ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
652{
653 IMG_VOID *pvPage;
654 IMG_VOID *pvEnd = pvAddress + ui32Length;
655
656 for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE)
657 {
658#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
659 SetPageReserved(vmalloc_to_page(pvPage));
660#else
661 mem_map_reserve(vmalloc_to_page(pvPage));
662#endif
663 }
664}
665
666
667static IMG_VOID
668UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
669{
670 IMG_VOID *pvPage;
671 IMG_VOID *pvEnd = pvAddress + ui32Length;
672
673 for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE)
674 {
675#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
676 ClearPageReserved(vmalloc_to_page(pvPage));
677#else
678 mem_map_unreserve(vmalloc_to_page(pvPage));
679#endif
680 }
681}
682#endif
683
684
685IMG_VOID *
686_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
687 IMG_UINT32 ui32Bytes,
688 IMG_UINT32 ui32MappingFlags,
689 IMG_CHAR *pszFileName,
690 IMG_UINT32 ui32Line)
691{
692 IMG_VOID *pvIORemapCookie;
693
694 switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
695 {
696 case PVRSRV_HAP_CACHED:
697 pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes);
698 break;
699 case PVRSRV_HAP_WRITECOMBINE:
700 pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes);
701 break;
702 case PVRSRV_HAP_UNCACHED:
703 pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes);
704 break;
705 default:
706 PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags"));
707 return NULL;
708 }
709
710#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
711 if(pvIORemapCookie)
712 {
713 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
714 pvIORemapCookie,
715 pvIORemapCookie,
716 BasePAddr.uiAddr,
717 NULL,
718 ui32Bytes,
719 pszFileName,
720 ui32Line
721 );
722 }
723#else
724 PVR_UNREFERENCED_PARAMETER(pszFileName);
725 PVR_UNREFERENCED_PARAMETER(ui32Line);
726#endif
727
728 return pvIORemapCookie;
729}
730
731
732IMG_VOID
733_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
734{
735#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
736 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, pvIORemapCookie, pszFileName, ui32Line);
737#else
738 PVR_UNREFERENCED_PARAMETER(pszFileName);
739 PVR_UNREFERENCED_PARAMETER(ui32Line);
740#endif
741 iounmap(pvIORemapCookie);
742}
743
744
745LinuxMemArea *
746NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
747 IMG_UINT32 ui32Bytes,
748 IMG_UINT32 ui32AreaFlags)
749{
750 LinuxMemArea *psLinuxMemArea;
751 IMG_VOID *pvIORemapCookie;
752
753 psLinuxMemArea = LinuxMemAreaStructAlloc();
754 if(!psLinuxMemArea)
755 {
756 return NULL;
757 }
758
759 pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags);
760 if(!pvIORemapCookie)
761 {
762 LinuxMemAreaStructFree(psLinuxMemArea);
763 return NULL;
764 }
765
766 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP;
767 psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie;
768 psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr;
769 psLinuxMemArea->ui32ByteSize = ui32Bytes;
770 psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
771 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
772
773#if defined(DEBUG_LINUX_MEM_AREAS)
774 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
775#endif
776
777 return psLinuxMemArea;
778}
779
780
781IMG_VOID
782FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea)
783{
784 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP);
785
786#if defined(DEBUG_LINUX_MEM_AREAS)
787 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
788#endif
789
790 IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie);
791
792 LinuxMemAreaStructFree(psLinuxMemArea);
793}
794
795
796#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
797static IMG_BOOL
798TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig)
799{
800 IMG_UINT32 ui32;
801 IMG_UINT32 ui32AddrChk;
802 IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
803
804
805 for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
806 ui32 < ui32NumPages;
807 ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr)
808 {
809 if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk)))
810 {
811 break;
812 }
813 }
814 if (ui32 == ui32NumPages)
815 {
816 return IMG_FALSE;
817 }
818
819 if (!bPhysContig)
820 {
821 for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
822 ui32 < ui32NumPages;
823 ui32++, ui32AddrChk += PAGE_SIZE)
824 {
825 if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
826 {
827 return IMG_FALSE;
828 }
829 }
830 }
831
832 return IMG_TRUE;
833}
834#endif
835
836LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags)
837{
838 LinuxMemArea *psLinuxMemArea;
839
840 psLinuxMemArea = LinuxMemAreaStructAlloc();
841 if(!psLinuxMemArea)
842 {
843 return NULL;
844 }
845
846 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV;
847 psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr;
848 psLinuxMemArea->uData.sExternalKV.bPhysContig =
849#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
850 (bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, ui32Bytes, bPhysContig))
851 ? IMG_TRUE : IMG_FALSE;
852#else
853 bPhysContig;
854#endif
855 if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
856 {
857 psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr;
858 }
859 else
860 {
861 psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr;
862 }
863 psLinuxMemArea->ui32ByteSize = ui32Bytes;
864 psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
865 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
866
867#if defined(DEBUG_LINUX_MEM_AREAS)
868 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
869#endif
870
871 return psLinuxMemArea;
872}
873
874
875IMG_VOID
876FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea)
877{
878 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV);
879
880#if defined(DEBUG_LINUX_MEM_AREAS)
881 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
882#endif
883
884 LinuxMemAreaStructFree(psLinuxMemArea);
885}
886
887
888LinuxMemArea *
889NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
890 IMG_UINT32 ui32Bytes,
891 IMG_UINT32 ui32AreaFlags)
892{
893 LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc();
894 if(!psLinuxMemArea)
895 {
896 return NULL;
897 }
898
899
900 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO;
901 psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr;
902 psLinuxMemArea->ui32ByteSize = ui32Bytes;
903 psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
904 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
905
906#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
907 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO,
908 (IMG_VOID *)BasePAddr.uiAddr,
909 0,
910 BasePAddr.uiAddr,
911 NULL,
912 ui32Bytes,
913 "unknown",
914 0
915 );
916#endif
917
918#if defined(DEBUG_LINUX_MEM_AREAS)
919 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
920#endif
921
922 return psLinuxMemArea;
923}
924
925
926IMG_VOID
927FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea)
928{
929 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO);
930
931#if defined(DEBUG_LINUX_MEM_AREAS)
932 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
933#endif
934
935#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
936 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO,
937 (IMG_VOID *)psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, __FILE__, __LINE__);
938#endif
939
940
941
942 LinuxMemAreaStructFree(psLinuxMemArea);
943}
944
945
946LinuxMemArea *
947NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
948{
949 LinuxMemArea *psLinuxMemArea;
950 IMG_UINT32 ui32PageCount;
951 struct page **pvPageList;
952 IMG_HANDLE hBlockPageList;
953 IMG_INT32 i;
954 PVRSRV_ERROR eError;
955
956 psLinuxMemArea = LinuxMemAreaStructAlloc();
957 if(!psLinuxMemArea)
958 {
959 goto failed_area_alloc;
960 }
961
962 ui32PageCount = RANGE_TO_PAGES(ui32Bytes);
963 eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList,
964 "Array of pages");
965 if(eError != PVRSRV_OK)
966 {
967 goto failed_page_list_alloc;
968 }
969
970 for(i=0; i<(IMG_INT32)ui32PageCount; i++)
971 {
972 pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
973 if(!pvPageList[i])
974 {
975 goto failed_alloc_pages;
976 }
977#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
978
979#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
980 SetPageReserved(pvPageList[i]);
981#else
982 mem_map_reserve(pvPageList[i]);
983#endif
984#endif
985
986 }
987
988#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
989 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
990 pvPageList,
991 0,
992 0,
993 NULL,
994 PAGE_ALIGN(ui32Bytes),
995 "unknown",
996 0
997 );
998#endif
999
1000 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
1001 psLinuxMemArea->uData.sPageList.pvPageList = pvPageList;
1002 psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
1003 psLinuxMemArea->ui32ByteSize = ui32Bytes;
1004 psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
1005 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
1006
1007
1008 if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
1009 {
1010 psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
1011 }
1012
1013#if defined(DEBUG_LINUX_MEM_AREAS)
1014 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
1015#endif
1016
1017 return psLinuxMemArea;
1018
1019failed_alloc_pages:
1020 for(i--; i >= 0; i--)
1021 {
1022 __free_pages(pvPageList[i], 0);
1023 }
1024 (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
1025 psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
1026failed_page_list_alloc:
1027 LinuxMemAreaStructFree(psLinuxMemArea);
1028failed_area_alloc:
1029 PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
1030
1031 return NULL;
1032}
1033
1034
1035IMG_VOID
1036FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
1037{
1038 IMG_UINT32 ui32PageCount;
1039 struct page **pvPageList;
1040 IMG_HANDLE hBlockPageList;
1041 IMG_INT32 i;
1042
1043 PVR_ASSERT(psLinuxMemArea);
1044 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
1045
1046#if defined(DEBUG_LINUX_MEM_AREAS)
1047 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
1048#endif
1049
1050 ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
1051 pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
1052 hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
1053
1054#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1055 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__);
1056#endif
1057
1058 for(i=0;i<(IMG_INT32)ui32PageCount;i++)
1059 {
1060#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
1061#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
1062 ClearPageReserved(pvPageList[i]);
1063#else
1064 mem_map_reserve(pvPageList[i]);
1065#endif
1066#endif
1067 __free_pages(pvPageList[i], 0);
1068 }
1069
1070 (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
1071 psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
1072
1073 LinuxMemAreaStructFree(psLinuxMemArea);
1074}
1075
1076
1077struct page*
1078LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea,
1079 IMG_UINT32 ui32ByteOffset)
1080{
1081 IMG_UINT32 ui32PageIndex;
1082 IMG_CHAR *pui8Addr;
1083
1084 switch(psLinuxMemArea->eAreaType)
1085 {
1086 case LINUX_MEM_AREA_ALLOC_PAGES:
1087 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
1088 return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
1089
1090 case LINUX_MEM_AREA_VMALLOC:
1091 pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
1092 pui8Addr += ui32ByteOffset;
1093 return vmalloc_to_page(pui8Addr);
1094
1095 case LINUX_MEM_AREA_SUB_ALLOC:
1096
1097 return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
1098 psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
1099 + ui32ByteOffset);
1100 default:
1101 PVR_DPF((PVR_DBG_ERROR,
1102 "%s: Unsupported request for struct page from LinuxMemArea with type=%s",
1103 __FUNCTION__, LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType)));
1104 return NULL;
1105 }
1106}
1107
1108
1109LinuxKMemCache *
1110KMemCacheCreateWrapper(IMG_CHAR *pszName,
1111 size_t Size,
1112 size_t Align,
1113 IMG_UINT32 ui32Flags)
1114{
1115#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS)
1116 ui32Flags |= SLAB_POISON|SLAB_RED_ZONE;
1117#endif
1118 return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL
1119#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
1120 , NULL
1121#endif
1122 );
1123}
1124
1125
1126IMG_VOID
1127KMemCacheDestroyWrapper(LinuxKMemCache *psCache)
1128{
1129 kmem_cache_destroy(psCache);
1130}
1131
1132
1133IMG_VOID *
1134_KMemCacheAllocWrapper(LinuxKMemCache *psCache,
1135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1136 gfp_t Flags,
1137#else
1138 IMG_INT Flags,
1139#endif
1140 IMG_CHAR *pszFileName,
1141 IMG_UINT32 ui32Line)
1142{
1143 IMG_VOID *pvRet;
1144
1145 pvRet = kmem_cache_zalloc(psCache, Flags);
1146
1147#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1148 DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
1149 pvRet,
1150 pvRet,
1151 0,
1152 psCache,
1153 kmem_cache_size(psCache),
1154 pszFileName,
1155 ui32Line
1156 );
1157#else
1158 PVR_UNREFERENCED_PARAMETER(pszFileName);
1159 PVR_UNREFERENCED_PARAMETER(ui32Line);
1160#endif
1161
1162 return pvRet;
1163}
1164
1165
1166IMG_VOID
1167_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
1168{
1169#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1170 DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
1171#else
1172 PVR_UNREFERENCED_PARAMETER(pszFileName);
1173 PVR_UNREFERENCED_PARAMETER(ui32Line);
1174#endif
1175
1176 kmem_cache_free(psCache, pvObject);
1177}
1178
1179
1180const IMG_CHAR *
1181KMemCacheNameWrapper(LinuxKMemCache *psCache)
1182{
1183 PVR_UNREFERENCED_PARAMETER(psCache);
1184
1185
1186 return "";
1187}
1188
1189
1190LinuxMemArea *
1191NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
1192 IMG_UINT32 ui32ByteOffset,
1193 IMG_UINT32 ui32Bytes)
1194{
1195 LinuxMemArea *psLinuxMemArea;
1196
1197 PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize);
1198
1199 psLinuxMemArea = LinuxMemAreaStructAlloc();
1200 if(!psLinuxMemArea)
1201 {
1202 return NULL;
1203 }
1204
1205 psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC;
1206 psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea;
1207 psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset;
1208 psLinuxMemArea->ui32ByteSize = ui32Bytes;
1209 psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags;
1210 psLinuxMemArea->bNeedsCacheInvalidate = psParentLinuxMemArea->bNeedsCacheInvalidate;
1211 INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
1212
1213#if defined(DEBUG_LINUX_MEM_AREAS)
1214 {
1215 DEBUG_LINUX_MEM_AREA_REC *psParentRecord;
1216 psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea);
1217 DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags);
1218 }
1219#endif
1220
1221 return psLinuxMemArea;
1222}
1223
1224
1225static IMG_VOID
1226FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea)
1227{
1228 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
1229
1230#if defined(DEBUG_LINUX_MEM_AREAS)
1231 DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
1232#endif
1233
1234
1235
1236 LinuxMemAreaStructFree(psLinuxMemArea);
1237}
1238
1239
1240static LinuxMemArea *
1241LinuxMemAreaStructAlloc(IMG_VOID)
1242{
1243#if 0
1244 LinuxMemArea *psLinuxMemArea;
1245 psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL);
1246 printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
1247 dump_stack();
1248 return psLinuxMemArea;
1249#else
1250 return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL);
1251#endif
1252}
1253
1254
1255static IMG_VOID
1256LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
1257{
1258 KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea);
1259
1260
1261}
1262
1263
1264IMG_VOID
1265LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea)
1266{
1267 switch(psLinuxMemArea->eAreaType)
1268 {
1269 case LINUX_MEM_AREA_VMALLOC:
1270 FreeVMallocLinuxMemArea(psLinuxMemArea);
1271 break;
1272 case LINUX_MEM_AREA_ALLOC_PAGES:
1273 FreeAllocPagesLinuxMemArea(psLinuxMemArea);
1274 break;
1275 case LINUX_MEM_AREA_IOREMAP:
1276 FreeIORemapLinuxMemArea(psLinuxMemArea);
1277 break;
1278 case LINUX_MEM_AREA_EXTERNAL_KV:
1279 FreeExternalKVLinuxMemArea(psLinuxMemArea);
1280 break;
1281 case LINUX_MEM_AREA_IO:
1282 FreeIOLinuxMemArea(psLinuxMemArea);
1283 break;
1284 case LINUX_MEM_AREA_SUB_ALLOC:
1285 FreeSubLinuxMemArea(psLinuxMemArea);
1286 break;
1287 default:
1288 PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n",
1289 __FUNCTION__, psLinuxMemArea->eAreaType));
1290 break;
1291 }
1292}
1293
1294
1295#if defined(DEBUG_LINUX_MEM_AREAS)
1296static IMG_VOID
1297DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
1298{
1299 DEBUG_LINUX_MEM_AREA_REC *psNewRecord;
1300 const IMG_CHAR *pi8FlagsString;
1301
1302 LinuxLockMutex(&g_sDebugMutex);
1303
1304 if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
1305 {
1306 g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize;
1307 if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
1308 {
1309 g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark;
1310 }
1311 }
1312 g_LinuxMemAreaCount++;
1313
1314
1315 psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
1316 if(psNewRecord)
1317 {
1318
1319 psNewRecord->psLinuxMemArea = psLinuxMemArea;
1320 psNewRecord->ui32Flags = ui32Flags;
1321 psNewRecord->pid = current->pid;
1322
1323 List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord);
1324 }
1325 else
1326 {
1327 PVR_DPF((PVR_DBG_ERROR,
1328 "%s: failed to allocate linux memory area record.",
1329 __FUNCTION__));
1330 }
1331
1332
1333 pi8FlagsString = HAPFlagsToString(ui32Flags);
1334 if(strstr(pi8FlagsString, "UNKNOWN"))
1335 {
1336 PVR_DPF((PVR_DBG_ERROR,
1337 "%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p",
1338 __FUNCTION__,
1339 ui32Flags,
1340 psLinuxMemArea));
1341
1342 }
1343
1344 LinuxUnLockMutex(&g_sDebugMutex);
1345}
1346
1347
1348
1349static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord,
1350 va_list va)
1351{
1352 LinuxMemArea *psLinuxMemArea;
1353
1354 psLinuxMemArea = va_arg(va, LinuxMemArea*);
1355 if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
1356 {
1357 return psCurrentRecord;
1358 }
1359 else
1360 {
1361 return IMG_NULL;
1362 }
1363}
1364
1365
1366static DEBUG_LINUX_MEM_AREA_REC *
1367DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea)
1368{
1369 DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
1370
1371 LinuxLockMutex(&g_sDebugMutex);
1372 psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
1373 MatchLinuxMemArea_AnyVaCb,
1374 psLinuxMemArea);
1375
1376 LinuxUnLockMutex(&g_sDebugMutex);
1377
1378 return psCurrentRecord;
1379}
1380
1381
1382static IMG_VOID
1383DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
1384{
1385 DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
1386
1387 LinuxLockMutex(&g_sDebugMutex);
1388
1389 if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
1390 {
1391 g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
1392 }
1393 g_LinuxMemAreaCount--;
1394
1395
1396 psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
1397 MatchLinuxMemArea_AnyVaCb,
1398 psLinuxMemArea);
1399 if(psCurrentRecord)
1400 {
1401
1402 List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
1403 kfree(psCurrentRecord);
1404 }
1405 else
1406 {
1407 PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n",
1408 __FUNCTION__, psLinuxMemArea));
1409 }
1410
1411 LinuxUnLockMutex(&g_sDebugMutex);
1412}
1413#endif
1414
1415
1416IMG_VOID *
1417LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
1418{
1419 switch(psLinuxMemArea->eAreaType)
1420 {
1421 case LINUX_MEM_AREA_VMALLOC:
1422 return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
1423 case LINUX_MEM_AREA_IOREMAP:
1424 return psLinuxMemArea->uData.sIORemap.pvIORemapCookie;
1425 case LINUX_MEM_AREA_EXTERNAL_KV:
1426 return psLinuxMemArea->uData.sExternalKV.pvExternalKV;
1427 case LINUX_MEM_AREA_SUB_ALLOC:
1428 {
1429 IMG_CHAR *pAddr =
1430 LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
1431 if(!pAddr)
1432 {
1433 return NULL;
1434 }
1435 return pAddr + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
1436 }
1437 default:
1438 return NULL;
1439 }
1440}
1441
1442
1443IMG_CPU_PHYADDR
1444LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
1445{
1446 IMG_CPU_PHYADDR CpuPAddr;
1447
1448 CpuPAddr.uiAddr = 0;
1449
1450 switch(psLinuxMemArea->eAreaType)
1451 {
1452 case LINUX_MEM_AREA_IOREMAP:
1453 {
1454 CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr;
1455 CpuPAddr.uiAddr += ui32ByteOffset;
1456 break;
1457 }
1458 case LINUX_MEM_AREA_EXTERNAL_KV:
1459 {
1460 if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
1461 {
1462 CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr);
1463 CpuPAddr.uiAddr += ui32ByteOffset;
1464 }
1465 else
1466 {
1467 IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
1468 IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageIndex];
1469
1470 CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
1471 CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
1472 }
1473 break;
1474 }
1475 case LINUX_MEM_AREA_IO:
1476 {
1477 CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr;
1478 CpuPAddr.uiAddr += ui32ByteOffset;
1479 break;
1480 }
1481 case LINUX_MEM_AREA_VMALLOC:
1482 {
1483 IMG_CHAR *pCpuVAddr;
1484 pCpuVAddr =
1485 (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
1486 pCpuVAddr += ui32ByteOffset;
1487 CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr);
1488 break;
1489 }
1490 case LINUX_MEM_AREA_ALLOC_PAGES:
1491 {
1492 struct page *page;
1493 IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
1494 page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
1495 CpuPAddr.uiAddr = page_to_phys(page);
1496 CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
1497 break;
1498 }
1499 case LINUX_MEM_AREA_SUB_ALLOC:
1500 {
1501 CpuPAddr =
1502 OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
1503 psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
1504 + ui32ByteOffset);
1505 break;
1506 }
1507 default:
1508 {
1509 PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
1510 __FUNCTION__, psLinuxMemArea->eAreaType));
1511 PVR_ASSERT(CpuPAddr.uiAddr);
1512 break;
1513 }
1514 }
1515
1516 return CpuPAddr;
1517}
1518
1519
1520IMG_BOOL
1521LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
1522{
1523 switch(psLinuxMemArea->eAreaType)
1524 {
1525 case LINUX_MEM_AREA_IOREMAP:
1526 case LINUX_MEM_AREA_IO:
1527 return IMG_TRUE;
1528
1529 case LINUX_MEM_AREA_EXTERNAL_KV:
1530 return psLinuxMemArea->uData.sExternalKV.bPhysContig;
1531
1532 case LINUX_MEM_AREA_VMALLOC:
1533 case LINUX_MEM_AREA_ALLOC_PAGES:
1534 return IMG_FALSE;
1535
1536 case LINUX_MEM_AREA_SUB_ALLOC:
1537
1538 return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
1539
1540 default:
1541 PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
1542 __FUNCTION__, psLinuxMemArea->eAreaType));
1543 break;
1544 }
1545 return IMG_FALSE;
1546}
1547
1548
1549const IMG_CHAR *
1550LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
1551{
1552
1553 switch(eMemAreaType)
1554 {
1555 case LINUX_MEM_AREA_IOREMAP:
1556 return "LINUX_MEM_AREA_IOREMAP";
1557 case LINUX_MEM_AREA_EXTERNAL_KV:
1558 return "LINUX_MEM_AREA_EXTERNAL_KV";
1559 case LINUX_MEM_AREA_IO:
1560 return "LINUX_MEM_AREA_IO";
1561 case LINUX_MEM_AREA_VMALLOC:
1562 return "LINUX_MEM_AREA_VMALLOC";
1563 case LINUX_MEM_AREA_SUB_ALLOC:
1564 return "LINUX_MEM_AREA_SUB_ALLOC";
1565 case LINUX_MEM_AREA_ALLOC_PAGES:
1566 return "LINUX_MEM_AREA_ALLOC_PAGES";
1567 default:
1568 PVR_ASSERT(0);
1569 }
1570
1571 return "";
1572}
1573
1574
1575#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1576static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start)
1577{
1578 if(start)
1579 {
1580 LinuxLockMutex(&g_sDebugMutex);
1581 }
1582 else
1583 {
1584 LinuxUnLockMutex(&g_sDebugMutex);
1585 }
1586}
1587#endif
1588
1589#if defined(DEBUG_LINUX_MEM_AREAS)
1590
1591static IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va)
1592{
1593 off_t *pOff = va_arg(va, off_t*);
1594 if (--(*pOff))
1595 {
1596 return IMG_NULL;
1597 }
1598 else
1599 {
1600 return psNode;
1601 }
1602}
1603
1604
1605static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off)
1606{
1607 DEBUG_LINUX_MEM_AREA_REC *psRecord;
1608 psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
1609 List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
1610 DecOffMemAreaRec_AnyVaCb,
1611 &off);
1612 return (void*)psRecord;
1613}
1614
1615static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
1616{
1617 DEBUG_LINUX_MEM_AREA_REC *psRecord;
1618 if(!off)
1619 {
1620 return PVR_PROC_SEQ_START_TOKEN;
1621 }
1622
1623 psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
1624 List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
1625 DecOffMemAreaRec_AnyVaCb,
1626 &off);
1627 return (void*)psRecord;
1628}
1629
1630
1631static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
1632{
1633 DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el;
1634 if(el == PVR_PROC_SEQ_START_TOKEN)
1635 {
1636
1637#if !defined(DEBUG_LINUX_XML_PROC_FILES)
1638 seq_printf( sfile,
1639 "Number of Linux Memory Areas: %u\n"
1640 "At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n"
1641 "At the highest water mark these areas corresponded to %u bytes (excluding SUB areas)\n"
1642 "\nDetails for all Linux Memory Areas:\n"
1643 "%s %-24s %s %s %-8s %-5s %s\n",
1644 g_LinuxMemAreaCount,
1645 g_LinuxMemAreaWaterMark,
1646 g_LinuxMemAreaHighWaterMark,
1647 "psLinuxMemArea",
1648 "LinuxMemType",
1649 "CpuVAddr",
1650 "CpuPAddr",
1651 "Bytes",
1652 "Pid",
1653 "Flags"
1654 );
1655#else
1656 seq_printf( sfile,
1657 "<mem_areas_header>\n"
1658 "\t<count>%u</count>\n"
1659 "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n"
1660 "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%u\"/>\n"
1661 "</mem_areas_header>\n",
1662 g_LinuxMemAreaCount,
1663 g_LinuxMemAreaWaterMark,
1664 g_LinuxMemAreaHighWaterMark
1665 );
1666#endif
1667 return;
1668 }
1669
1670 seq_printf( sfile,
1671#if !defined(DEBUG_LINUX_XML_PROC_FILES)
1672 "%8p %-24s %8p %08x %-8d %-5u %08x=(%s)\n",
1673#else
1674 "<linux_mem_area>\n"
1675 "\t<pointer>%8p</pointer>\n"
1676 "\t<type>%s</type>\n"
1677 "\t<cpu_virtual>%8p</cpu_virtual>\n"
1678 "\t<cpu_physical>%08x</cpu_physical>\n"
1679 "\t<bytes>%ld</bytes>\n"
1680 "\t<pid>%u</pid>\n"
1681 "\t<flags>%08lx</flags>\n"
1682 "\t<flags_string>%s</flags_string>\n"
1683 "</linux_mem_area>\n",
1684#endif
1685 psRecord->psLinuxMemArea,
1686 LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType),
1687 LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea),
1688 LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr,
1689 psRecord->psLinuxMemArea->ui32ByteSize,
1690 psRecord->pid,
1691 psRecord->ui32Flags,
1692 HAPFlagsToString(psRecord->ui32Flags)
1693 );
1694
1695}
1696
1697#endif
1698
1699
1700#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1701
1702static IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va)
1703{
1704 off_t *pOff = va_arg(va, off_t*);
1705 if (--(*pOff))
1706 {
1707 return IMG_NULL;
1708 }
1709 else
1710 {
1711 return psNode;
1712 }
1713}
1714
1715
1716
1717static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off)
1718{
1719 DEBUG_MEM_ALLOC_REC *psRecord;
1720 psRecord = (DEBUG_MEM_ALLOC_REC*)
1721 List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
1722 DecOffMemAllocRec_AnyVaCb,
1723 &off);
1724#if defined(DEBUG_LINUX_XML_PROC_FILES)
1725 if(!psRecord)
1726 {
1727 seq_printf( sfile, "</meminfo>\n");
1728 }
1729#endif
1730
1731 return (void*)psRecord;
1732}
1733
1734static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
1735{
1736 DEBUG_MEM_ALLOC_REC *psRecord;
1737 if(!off)
1738 {
1739 return PVR_PROC_SEQ_START_TOKEN;
1740 }
1741
1742 psRecord = (DEBUG_MEM_ALLOC_REC*)
1743 List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
1744 DecOffMemAllocRec_AnyVaCb,
1745 &off);
1746
1747#if defined(DEBUG_LINUX_XML_PROC_FILES)
1748 if(!psRecord)
1749 {
1750 seq_printf( sfile, "</meminfo>\n");
1751 }
1752#endif
1753
1754 return (void*)psRecord;
1755}
1756
1757static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
1758{
1759 DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
1760 if(el == PVR_PROC_SEQ_START_TOKEN)
1761 {
1762#if !defined(DEBUG_LINUX_XML_PROC_FILES)
1763
1764 seq_printf( sfile, "%-60s: %d bytes\n",
1765 "Current Water Mark of bytes allocated via kmalloc",
1766 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
1767 seq_printf( sfile, "%-60s: %d bytes\n",
1768 "Highest Water Mark of bytes allocated via kmalloc",
1769 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
1770 seq_printf( sfile, "%-60s: %d bytes\n",
1771 "Current Water Mark of bytes allocated via vmalloc",
1772 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
1773 seq_printf( sfile, "%-60s: %d bytes\n",
1774 "Highest Water Mark of bytes allocated via vmalloc",
1775 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
1776 seq_printf( sfile, "%-60s: %d bytes\n",
1777 "Current Water Mark of bytes allocated via alloc_pages",
1778 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
1779 seq_printf( sfile, "%-60s: %d bytes\n",
1780 "Highest Water Mark of bytes allocated via alloc_pages",
1781 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
1782 seq_printf( sfile, "%-60s: %d bytes\n",
1783 "Current Water Mark of bytes allocated via ioremap",
1784 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
1785 seq_printf( sfile, "%-60s: %d bytes\n",
1786 "Highest Water Mark of bytes allocated via ioremap",
1787 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
1788 seq_printf( sfile, "%-60s: %d bytes\n",
1789 "Current Water Mark of bytes reserved for \"IO\" memory areas",
1790 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
1791 seq_printf( sfile, "%-60s: %d bytes\n",
1792 "Highest Water Mark of bytes allocated for \"IO\" memory areas",
1793 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
1794 seq_printf( sfile, "%-60s: %d bytes\n",
1795 "Current Water Mark of bytes allocated via kmem_cache_alloc",
1796 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
1797 seq_printf( sfile, "%-60s: %d bytes\n",
1798 "Highest Water Mark of bytes allocated via kmem_cache_alloc",
1799 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
1800 seq_printf( sfile, "\n");
1801
1802 seq_printf( sfile, "%-60s: %d bytes\n",
1803 "The Current Water Mark for memory allocated from system RAM",
1804 g_SysRAMWaterMark);
1805 seq_printf( sfile, "%-60s: %d bytes\n",
1806 "The Highest Water Mark for memory allocated from system RAM",
1807 g_SysRAMHighWaterMark);
1808 seq_printf( sfile, "%-60s: %d bytes\n",
1809 "The Current Water Mark for memory allocated from IO memory",
1810 g_IOMemWaterMark);
1811 seq_printf( sfile, "%-60s: %d bytes\n",
1812 "The Highest Water Mark for memory allocated from IO memory",
1813 g_IOMemHighWaterMark);
1814
1815 seq_printf( sfile, "\n");
1816
1817 seq_printf( sfile, "Details for all known allocations:\n"
1818 "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
1819 "Type",
1820 "CpuVAddr",
1821 "CpuPAddr",
1822 "Bytes",
1823 "PID",
1824 "PrivateData",
1825 "Filename:Line");
1826
1827#else
1828
1829
1830 seq_printf( sfile, "<meminfo>\n<meminfo_header>\n");
1831 seq_printf( sfile,
1832 "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n",
1833 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
1834 seq_printf( sfile,
1835 "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n",
1836 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
1837 seq_printf( sfile,
1838 "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n",
1839 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
1840 seq_printf( sfile,
1841 "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n",
1842 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
1843 seq_printf( sfile,
1844 "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n",
1845 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
1846 seq_printf( sfile,
1847 "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n",
1848 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
1849 seq_printf( sfile,
1850 "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n",
1851 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
1852 seq_printf( sfile,
1853 "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n",
1854 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
1855 seq_printf( sfile,
1856 "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n",
1857 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
1858 seq_printf( sfile,
1859 "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n",
1860 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
1861 seq_printf( sfile,
1862 "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n",
1863 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
1864 seq_printf( sfile,
1865 "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n",
1866 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
1867 seq_printf( sfile,"\n" );
1868
1869 seq_printf( sfile,
1870 "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n",
1871 g_SysRAMWaterMark);
1872 seq_printf( sfile,
1873 "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n",
1874 g_SysRAMHighWaterMark);
1875 seq_printf( sfile,
1876 "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n",
1877 g_IOMemWaterMark);
1878 seq_printf( sfile,
1879 "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n",
1880 g_IOMemHighWaterMark);
1881
1882 seq_printf( sfile, "</meminfo_header>\n");
1883
1884#endif
1885 return;
1886 }
1887
1888 if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
1889 {
1890 seq_printf( sfile,
1891#if !defined(DEBUG_LINUX_XML_PROC_FILES)
1892 "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
1893#else
1894 "<allocation>\n"
1895 "\t<type>%s</type>\n"
1896 "\t<cpu_virtual>%-8p</cpu_virtual>\n"
1897 "\t<cpu_physical>%08x</cpu_physical>\n"
1898 "\t<bytes>%d</bytes>\n"
1899 "\t<pid>%d</pid>\n"
1900 "\t<private>%s</private>\n"
1901 "\t<filename>%s</filename>\n"
1902 "\t<line>%d</line>\n"
1903 "</allocation>\n",
1904#endif
1905 DebugMemAllocRecordTypeToString(psRecord->eAllocType),
1906 psRecord->pvCpuVAddr,
1907 psRecord->ulCpuPAddr,
1908 psRecord->ui32Bytes,
1909 psRecord->pid,
1910 "NULL",
1911 psRecord->pszFileName,
1912 psRecord->ui32Line);
1913 }
1914 else
1915 {
1916 seq_printf( sfile,
1917#if !defined(DEBUG_LINUX_XML_PROC_FILES)
1918 "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
1919#else
1920 "<allocation>\n"
1921 "\t<type>%s</type>\n"
1922 "\t<cpu_virtual>%-8p</cpu_virtual>\n"
1923 "\t<cpu_physical>%08x</cpu_physical>\n"
1924 "\t<bytes>%d</bytes>\n"
1925 "\t<pid>%d</pid>\n"
1926 "\t<private>%s</private>\n"
1927 "\t<filename>%s</filename>\n"
1928 "\t<line>%d</line>\n"
1929 "</allocation>\n",
1930#endif
1931 DebugMemAllocRecordTypeToString(psRecord->eAllocType),
1932 psRecord->pvCpuVAddr,
1933 psRecord->ulCpuPAddr,
1934 psRecord->ui32Bytes,
1935 psRecord->pid,
1936 KMemCacheNameWrapper(psRecord->pvPrivateData),
1937 psRecord->pszFileName,
1938 psRecord->ui32Line);
1939 }
1940}
1941
1942#endif
1943
1944
1945#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS)
1946const IMG_CHAR *
1947HAPFlagsToString(IMG_UINT32 ui32Flags)
1948{
1949 static IMG_CHAR szFlags[50];
1950 IMG_INT32 i32Pos = 0;
1951 IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex;
1952 IMG_CHAR *apszCacheTypes[] = {
1953 "UNCACHED",
1954 "CACHED",
1955 "WRITECOMBINE",
1956 "UNKNOWN"
1957 };
1958 IMG_CHAR *apszMapType[] = {
1959 "KERNEL_ONLY",
1960 "SINGLE_PROCESS",
1961 "MULTI_PROCESS",
1962 "FROM_EXISTING_PROCESS",
1963 "NO_CPU_VIRTUAL",
1964 "UNKNOWN"
1965 };
1966
1967
1968 if(ui32Flags & PVRSRV_HAP_UNCACHED){
1969 ui32CacheTypeIndex=0;
1970 }else if(ui32Flags & PVRSRV_HAP_CACHED){
1971 ui32CacheTypeIndex=1;
1972 }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){
1973 ui32CacheTypeIndex=2;
1974 }else{
1975 ui32CacheTypeIndex=3;
1976 PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)",
1977 __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)));
1978 }
1979
1980
1981 if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){
1982 ui32MapTypeIndex = 0;
1983 }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){
1984 ui32MapTypeIndex = 1;
1985 }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){
1986 ui32MapTypeIndex = 2;
1987 }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){
1988 ui32MapTypeIndex = 3;
1989 }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){
1990 ui32MapTypeIndex = 4;
1991 }else{
1992 ui32MapTypeIndex = 5;
1993 PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)",
1994 __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)));
1995 }
1996
1997 i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]);
1998 if (i32Pos <= 0)
1999 {
2000 PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)",
2001 __FUNCTION__, ui32CacheTypeIndex, i32Pos));
2002 szFlags[0] = 0;
2003 }
2004 else
2005 {
2006 sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]);
2007 }
2008
2009 return szFlags;
2010}
2011#endif
2012
diff --git a/drivers/gpu/pvr/mm.h b/drivers/gpu/pvr/mm.h
new file mode 100644
index 00000000000..047b3ad540c
--- /dev/null
+++ b/drivers/gpu/pvr/mm.h
@@ -0,0 +1,333 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __IMG_LINUX_MM_H__
28#define __IMG_LINUX_MM_H__
29
30#ifndef AUTOCONF_INCLUDED
31 #include <linux/config.h>
32#endif
33
34#include <linux/version.h>
35#include <linux/slab.h>
36#include <linux/mm.h>
37#include <linux/list.h>
38
39#include <asm/io.h>
40
41#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT)
42#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT)
43
44#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
45
46#define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
47
48#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
49#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot)
50#else
51#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
52#endif
53
54#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
55#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot)
56#else
57#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
58#endif
59
60#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
61#define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page)
62#else
63#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
64#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot);
65#else
66#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot);
67#endif
68#endif
69
70static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr)
71{
72 return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr));
73
74}
75
76typedef enum {
77 LINUX_MEM_AREA_IOREMAP,
78 LINUX_MEM_AREA_EXTERNAL_KV,
79 LINUX_MEM_AREA_IO,
80 LINUX_MEM_AREA_VMALLOC,
81 LINUX_MEM_AREA_ALLOC_PAGES,
82 LINUX_MEM_AREA_SUB_ALLOC,
83 LINUX_MEM_AREA_TYPE_COUNT
84}LINUX_MEM_AREA_TYPE;
85
86typedef struct _LinuxMemArea LinuxMemArea;
87
88
89struct _LinuxMemArea {
90 LINUX_MEM_AREA_TYPE eAreaType;
91 union _uData
92 {
93 struct _sIORemap
94 {
95
96 IMG_CPU_PHYADDR CPUPhysAddr;
97 IMG_VOID *pvIORemapCookie;
98 }sIORemap;
99 struct _sExternalKV
100 {
101
102 IMG_BOOL bPhysContig;
103 union {
104
105 IMG_SYS_PHYADDR SysPhysAddr;
106 IMG_SYS_PHYADDR *pSysPhysAddr;
107 } uPhysAddr;
108 IMG_VOID *pvExternalKV;
109 }sExternalKV;
110 struct _sIO
111 {
112
113 IMG_CPU_PHYADDR CPUPhysAddr;
114 }sIO;
115 struct _sVmalloc
116 {
117
118 IMG_VOID *pvVmallocAddress;
119 }sVmalloc;
120 struct _sPageList
121 {
122
123 struct page **pvPageList;
124 IMG_HANDLE hBlockPageList;
125 }sPageList;
126 struct _sSubAlloc
127 {
128
129 LinuxMemArea *psParentLinuxMemArea;
130 IMG_UINT32 ui32ByteOffset;
131 }sSubAlloc;
132 }uData;
133
134 IMG_UINT32 ui32ByteSize;
135
136 IMG_UINT32 ui32AreaFlags;
137
138 IMG_BOOL bMMapRegistered;
139
140 IMG_BOOL bNeedsCacheInvalidate;
141
142
143 struct list_head sMMapItem;
144
145
146 struct list_head sMMapOffsetStructList;
147};
148
149#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
150typedef kmem_cache_t LinuxKMemCache;
151#else
152typedef struct kmem_cache LinuxKMemCache;
153#endif
154
155
156PVRSRV_ERROR LinuxMMInit(IMG_VOID);
157
158
159IMG_VOID LinuxMMCleanup(IMG_VOID);
160
161
162#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
163#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, __FILE__, __LINE__)
164#else
165#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, NULL, 0)
166#endif
167IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *szFileName, IMG_UINT32 ui32Line);
168
169
170#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
171#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
172#else
173#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0)
174#endif
175IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
176
177
178#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
179#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
180#else
181#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0)
182#endif
183IMG_VOID *_VMallocWrapper(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
184
185
186#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
187#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
188#else
189#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0)
190#endif
191IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
192
193
194LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
195
196
197IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea);
198
199
200#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
201#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
202 _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
203#else
204#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
205 _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
206#endif
207IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
208 IMG_UINT32 ui32Bytes,
209 IMG_UINT32 ui32MappingFlags,
210 IMG_CHAR *pszFileName,
211 IMG_UINT32 ui32Line);
212
213
214LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
215
216
217IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea);
218
219LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags);
220
221
222IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea);
223
224
225#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
226#define IOUnmapWrapper(pvIORemapCookie) \
227 _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
228#else
229#define IOUnmapWrapper(pvIORemapCookie) \
230 _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
231#endif
232IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
233
234
235struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
236
237
238LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags);
239
240
241IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache);
242
243
244#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
245#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__)
246#else
247#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0)
248#endif
249
250#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
251IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
252#else
253IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
254#endif
255
256#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
257#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__)
258#else
259#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0)
260#endif
261IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
262
263
264const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache);
265
266
267LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
268
269
270IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea);
271
272
273LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
274
275
276IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea);
277
278
279LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
280 IMG_UINT32 ui32ByteOffset,
281 IMG_UINT32 ui32Bytes);
282
283
284IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea);
285
286
287#if defined(LINUX_MEM_AREAS_DEBUG)
288IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea);
289#else
290#define LinuxMemAreaRegister(X)
291#endif
292
293
294IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea);
295
296
297IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
298
299
300#define LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr)
301
302IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea);
303
304static inline LinuxMemArea *
305LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea)
306{
307 if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
308 {
309 return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
310 }
311 else
312 {
313 return psLinuxMemArea;
314 }
315}
316
317
318static inline LINUX_MEM_AREA_TYPE
319LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea)
320{
321 return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
322}
323
324
325const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType);
326
327
328#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS)
329const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags);
330#endif
331
332#endif
333
diff --git a/drivers/gpu/pvr/mmap.c b/drivers/gpu/pvr/mmap.c
new file mode 100644
index 00000000000..66cef26e522
--- /dev/null
+++ b/drivers/gpu/pvr/mmap.c
@@ -0,0 +1,1132 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/version.h>
32#include <linux/mm.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
36#include <linux/wrapper.h>
37#endif
38#include <linux/slab.h>
39#include <asm/io.h>
40#include <asm/page.h>
41#include <asm/shmparam.h>
42#include <asm/pgtable.h>
43#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
44#include <linux/sched.h>
45#include <asm/current.h>
46#endif
47#if defined(SUPPORT_DRI_DRM)
48#include <drm/drmP.h>
49#endif
50
51#include "img_defs.h"
52#include "services.h"
53#include "servicesint.h"
54#include "pvrmmap.h"
55#include "mutils.h"
56#include "mmap.h"
57#include "mm.h"
58#include "pvr_debug.h"
59#include "osfunc.h"
60#include "proc.h"
61#include "mutex.h"
62#include "handle.h"
63#include "perproc.h"
64#include "env_perproc.h"
65#include "bridged_support.h"
66#if defined(SUPPORT_DRI_DRM)
67#include "pvr_drm.h"
68#endif
69
70#if !defined(PVR_SECURE_HANDLES)
71#error "The mmap code requires PVR_SECURE_HANDLES"
72#endif
73
74static PVRSRV_LINUX_MUTEX g_sMMapMutex;
75
76static LinuxKMemCache *g_psMemmapCache = NULL;
77static LIST_HEAD(g_sMMapAreaList);
78static LIST_HEAD(g_sMMapOffsetStructList);
79#if defined(DEBUG_LINUX_MMAP_AREAS)
80static IMG_UINT32 g_ui32RegisteredAreas = 0;
81static IMG_UINT32 g_ui32TotalByteSize = 0;
82#endif
83
84
85#if defined(DEBUG_LINUX_MMAP_AREAS)
86static struct proc_dir_entry *g_ProcMMap;
87#endif
88
89#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
90#define MMAP2_PGOFF_RESOLUTION (32-PAGE_SHIFT+12)
91#define RESERVED_PGOFF_BITS 1
92#define MAX_MMAP_HANDLE ((1UL<<(MMAP2_PGOFF_RESOLUTION-RESERVED_PGOFF_BITS))-1)
93
94#define FIRST_PHYSICAL_PFN 0
95#define LAST_PHYSICAL_PFN (FIRST_PHYSICAL_PFN + MAX_MMAP_HANDLE)
96#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1)
97#define LAST_SPECIAL_PFN (FIRST_SPECIAL_PFN + MAX_MMAP_HANDLE)
98
99#else
100
101#if PAGE_SHIFT != 12
102#error This build variant has not yet been made non-4KB page-size aware
103#endif
104
105#if defined(PVR_MMAP_OFFSET_BASE)
106#define FIRST_SPECIAL_PFN PVR_MMAP_OFFSET_BASE
107#else
108#define FIRST_SPECIAL_PFN 0x80000000UL
109#endif
110
111#if defined(PVR_NUM_MMAP_HANDLES)
112#define MAX_MMAP_HANDLE PVR_NUM_MMAP_HANDLES
113#else
114#define MAX_MMAP_HANDLE 0x7fffffffUL
115#endif
116
117#endif
118
119#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
120static inline IMG_BOOL
121PFNIsPhysical(IMG_UINT32 pfn)
122{
123
124 return ( (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE;
125}
126
127static inline IMG_BOOL
128PFNIsSpecial(IMG_UINT32 pfn)
129{
130
131 return ((pfn >= FIRST_SPECIAL_PFN) ) ? IMG_TRUE : IMG_FALSE;
132}
133#endif
134
135#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
136static inline IMG_HANDLE
137MMapOffsetToHandle(IMG_UINT32 pfn)
138{
139 if (PFNIsPhysical(pfn))
140 {
141 PVR_ASSERT(PFNIsPhysical(pfn));
142 return IMG_NULL;
143 }
144 return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN);
145}
146#endif
147
148static inline IMG_UINT32
149HandleToMMapOffset(IMG_HANDLE hHandle)
150{
151 IMG_UINT32 ulHandle = (IMG_UINT32)hHandle;
152
153#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
154 if (PFNIsSpecial(ulHandle))
155 {
156 PVR_ASSERT(PFNIsSpecial(ulHandle));
157 return 0;
158 }
159#endif
160 return ulHandle + FIRST_SPECIAL_PFN;
161}
162
163#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
164static inline IMG_BOOL
165LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea)
166{
167 return LinuxMemAreaPhysIsContig(psLinuxMemArea);
168}
169#endif
170
171#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
172static inline IMG_UINT32
173GetCurrentThreadID(IMG_VOID)
174{
175
176 return (IMG_UINT32)current->pid;
177}
178#endif
179
180static PKV_OFFSET_STRUCT
181CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
182{
183 PKV_OFFSET_STRUCT psOffsetStruct;
184#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
185 const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
186#endif
187
188#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
189 PVR_DPF((PVR_DBG_MESSAGE,
190 "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8x)",
191 __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
192#endif
193
194 PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
195
196 PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
197
198 psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL);
199 if(psOffsetStruct == IMG_NULL)
200 {
201 PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache"));
202 return IMG_NULL;
203 }
204
205 psOffsetStruct->ui32MMapOffset = ui32Offset;
206
207 psOffsetStruct->psLinuxMemArea = psLinuxMemArea;
208
209 psOffsetStruct->ui32RealByteSize = ui32RealByteSize;
210
211
212#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
213 psOffsetStruct->ui32TID = GetCurrentThreadID();
214#endif
215 psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM();
216
217#if defined(DEBUG_LINUX_MMAP_AREAS)
218
219 psOffsetStruct->pszName = pszName;
220#endif
221
222 list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList);
223
224 return psOffsetStruct;
225}
226
227
228static IMG_VOID
229DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct)
230{
231#ifdef DEBUG
232 IMG_CPU_PHYADDR CpuPAddr;
233 CpuPAddr = LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0);
234#endif
235
236 list_del(&psOffsetStruct->sAreaItem);
237
238 if (psOffsetStruct->bOnMMapList)
239 {
240 list_del(&psOffsetStruct->sMMapItem);
241 }
242
243#ifdef DEBUG
244 PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: "
245 "psLinuxMemArea=%p, CpuPAddr=0x%08X", __FUNCTION__,
246 psOffsetStruct->psLinuxMemArea,
247 CpuPAddr.uiAddr));
248#endif
249
250 KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct);
251}
252
253
254static inline IMG_VOID
255DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea,
256 IMG_UINT32 *pui32RealByteSize,
257 IMG_UINT32 *pui32ByteOffset)
258{
259 IMG_UINT32 ui32PageAlignmentOffset;
260 IMG_CPU_PHYADDR CpuPAddr;
261
262 CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0);
263 ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr);
264
265 *pui32ByteOffset = ui32PageAlignmentOffset;
266
267 *pui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset);
268}
269
270
271PVRSRV_ERROR
272PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
273 IMG_HANDLE hMHandle,
274 IMG_UINT32 *pui32MMapOffset,
275 IMG_UINT32 *pui32ByteOffset,
276 IMG_UINT32 *pui32RealByteSize,
277 IMG_UINT32 *pui32UserVAddr)
278{
279 LinuxMemArea *psLinuxMemArea;
280 PKV_OFFSET_STRUCT psOffsetStruct;
281 IMG_HANDLE hOSMemHandle;
282 PVRSRV_ERROR eError;
283
284 LinuxLockMutex(&g_sMMapMutex);
285
286 PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
287
288 eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
289 if (eError != PVRSRV_OK)
290 {
291 PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
292
293 goto exit_unlock;
294 }
295
296 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
297
298 DetermineUsersSizeAndByteOffset(psLinuxMemArea,
299 pui32RealByteSize,
300 pui32ByteOffset);
301
302
303 list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
304 {
305 if (psPerProc->ui32PID == psOffsetStruct->ui32PID)
306 {
307
308 PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize);
309
310 *pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
311 *pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
312 psOffsetStruct->ui32RefCount++;
313
314 eError = PVRSRV_OK;
315 goto exit_unlock;
316 }
317 }
318
319
320 *pui32UserVAddr = 0;
321
322#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
323 if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea))
324 {
325 *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0);
326 PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset));
327 }
328 else
329#endif
330 {
331 *pui32MMapOffset = HandleToMMapOffset(hMHandle);
332#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
333 PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset));
334#endif
335 }
336
337 psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize);
338 if (psOffsetStruct == IMG_NULL)
339 {
340 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
341 goto exit_unlock;
342 }
343
344
345 list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList);
346
347 psOffsetStruct->bOnMMapList = IMG_TRUE;
348
349 psOffsetStruct->ui32RefCount++;
350
351 eError = PVRSRV_OK;
352
353
354
355
356 *pui32MMapOffset = *pui32MMapOffset << (PAGE_SHIFT - 12);
357
358exit_unlock:
359 LinuxUnLockMutex(&g_sMMapMutex);
360
361 return eError;
362}
363
364
365PVRSRV_ERROR
366PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
367 IMG_HANDLE hMHandle,
368 IMG_BOOL *pbMUnmap,
369 IMG_UINT32 *pui32RealByteSize,
370 IMG_UINT32 *pui32UserVAddr)
371{
372 LinuxMemArea *psLinuxMemArea;
373 PKV_OFFSET_STRUCT psOffsetStruct;
374 IMG_HANDLE hOSMemHandle;
375 PVRSRV_ERROR eError;
376 IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
377
378 LinuxLockMutex(&g_sMMapMutex);
379
380 PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
381
382 eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
383 if (eError != PVRSRV_OK)
384 {
385 PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
386
387 goto exit_unlock;
388 }
389
390 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
391
392
393 list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
394 {
395 if (psOffsetStruct->ui32PID == ui32PID)
396 {
397 if (psOffsetStruct->ui32RefCount == 0)
398 {
399 PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area %p", __FUNCTION__, psOffsetStruct, psLinuxMemArea));
400 eError = PVRSRV_ERROR_STILL_MAPPED;
401 goto exit_unlock;
402 }
403
404 psOffsetStruct->ui32RefCount--;
405
406 *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
407
408 *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0;
409 *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0;
410
411 eError = PVRSRV_OK;
412 goto exit_unlock;
413 }
414 }
415
416
417 PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %p (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
418
419 eError = PVRSRV_ERROR_MAPPING_NOT_FOUND;
420
421exit_unlock:
422 LinuxUnLockMutex(&g_sMMapMutex);
423
424 return eError;
425}
426
427static inline PKV_OFFSET_STRUCT
428FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
429{
430 PKV_OFFSET_STRUCT psOffsetStruct;
431#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
432 IMG_UINT32 ui32TID = GetCurrentThreadID();
433#endif
434 IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
435
436 list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
437 {
438 if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID)
439 {
440#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
441
442 if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID)
443#endif
444 {
445 return psOffsetStruct;
446 }
447 }
448 }
449
450 return IMG_NULL;
451}
452
453
454static IMG_BOOL
455DoMapToUser(LinuxMemArea *psLinuxMemArea,
456 struct vm_area_struct* ps_vma,
457 IMG_UINT32 ui32ByteOffset)
458{
459 IMG_UINT32 ui32ByteSize;
460
461 if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
462 {
463 return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea),
464 ps_vma,
465 psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset);
466 }
467
468
469 ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
470 PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0);
471
472#if defined (__sparc__)
473
474#error "SPARC not supported"
475#endif
476
477#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
478 if (PFNIsPhysical(ps_vma->vm_pgoff))
479 {
480 IMG_INT result;
481
482 PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea));
483 PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff);
484
485 result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, ui32ByteSize, ps_vma->vm_page_prot);
486
487 if(result == 0)
488 {
489 return IMG_TRUE;
490 }
491
492 PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result));
493 }
494#endif
495
496 {
497
498 IMG_UINT32 ulVMAPos;
499 IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize;
500 IMG_UINT32 ui32PA;
501#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
502 IMG_BOOL bMixedMap = IMG_FALSE;
503#endif
504
505 for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
506 {
507 IMG_UINT32 pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
508
509 if (!pfn_valid(pfn))
510 {
511#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
512 PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%x", __FUNCTION__, pfn));
513 return IMG_FALSE;
514#else
515 bMixedMap = IMG_TRUE;
516#endif
517 }
518 }
519
520#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
521 if (bMixedMap)
522 {
523 ps_vma->vm_flags |= VM_MIXEDMAP;
524 }
525#endif
526
527 ulVMAPos = ps_vma->vm_start;
528 for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
529 {
530 IMG_UINT32 pfn;
531 IMG_INT result;
532
533 pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
534
535#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
536 if (bMixedMap)
537 {
538 result = vm_insert_mixed(ps_vma, ulVMAPos, pfn);
539 if(result != 0)
540 {
541 PVR_DPF((PVR_DBG_ERROR,"%s: Error - vm_insert_mixed failed (%d)", __FUNCTION__, result));
542 return IMG_FALSE;
543 }
544 }
545 else
546#endif
547 {
548 struct page *psPage;
549
550 PVR_ASSERT(pfn_valid(pfn));
551
552 psPage = pfn_to_page(pfn);
553
554 result = VM_INSERT_PAGE(ps_vma, ulVMAPos, psPage);
555 if(result != 0)
556 {
557 PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result));
558 return IMG_FALSE;
559 }
560 }
561 ulVMAPos += PAGE_SIZE;
562 }
563 }
564
565 return IMG_TRUE;
566}
567
568
569static IMG_VOID
570MMapVOpenNoLock(struct vm_area_struct* ps_vma)
571{
572 PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
573 PVR_ASSERT(psOffsetStruct != IMG_NULL)
574 psOffsetStruct->ui32Mapped++;
575 PVR_ASSERT(!psOffsetStruct->bOnMMapList);
576
577 if (psOffsetStruct->ui32Mapped > 1)
578 {
579 PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped));
580 PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0);
581 }
582
583#if defined(DEBUG_LINUX_MMAP_AREAS)
584
585 PVR_DPF((PVR_DBG_MESSAGE,
586 "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %d, ui32Mapped %d",
587 __FUNCTION__,
588 psOffsetStruct->psLinuxMemArea,
589 LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
590 psOffsetStruct->ui32MMapOffset,
591 psOffsetStruct->ui32Mapped));
592#endif
593
594#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
595 MOD_INC_USE_COUNT;
596#endif
597}
598
599
600static void
601MMapVOpen(struct vm_area_struct* ps_vma)
602{
603 LinuxLockMutex(&g_sMMapMutex);
604
605 MMapVOpenNoLock(ps_vma);
606
607 LinuxUnLockMutex(&g_sMMapMutex);
608}
609
610
611static IMG_VOID
612MMapVCloseNoLock(struct vm_area_struct* ps_vma)
613{
614 PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
615 PVR_ASSERT(psOffsetStruct != IMG_NULL)
616
617#if defined(DEBUG_LINUX_MMAP_AREAS)
618 PVR_DPF((PVR_DBG_MESSAGE,
619 "%s: psLinuxMemArea %p, CpuVAddr %p ui32MMapOffset %d, ui32Mapped %d",
620 __FUNCTION__,
621 psOffsetStruct->psLinuxMemArea,
622 LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
623 psOffsetStruct->ui32MMapOffset,
624 psOffsetStruct->ui32Mapped));
625#endif
626
627 PVR_ASSERT(!psOffsetStruct->bOnMMapList);
628 psOffsetStruct->ui32Mapped--;
629 if (psOffsetStruct->ui32Mapped == 0)
630 {
631 if (psOffsetStruct->ui32RefCount != 0)
632 {
633 PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct %p has non-zero reference count (ui32RefCount = %u). User mode address of start of mapping: 0x%x", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr));
634 }
635
636 DestroyOffsetStruct(psOffsetStruct);
637 }
638
639 ps_vma->vm_private_data = NULL;
640
641#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
642 MOD_DEC_USE_COUNT;
643#endif
644}
645
646static void
647MMapVClose(struct vm_area_struct* ps_vma)
648{
649 LinuxLockMutex(&g_sMMapMutex);
650
651 MMapVCloseNoLock(ps_vma);
652
653 LinuxUnLockMutex(&g_sMMapMutex);
654}
655
656
657static struct vm_operations_struct MMapIOOps =
658{
659 .open=MMapVOpen,
660 .close=MMapVClose
661};
662
663
664int
665PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
666{
667 IMG_UINT32 ui32ByteSize;
668 PKV_OFFSET_STRUCT psOffsetStruct;
669 int iRetVal = 0;
670
671 PVR_UNREFERENCED_PARAMETER(pFile);
672
673 LinuxLockMutex(&g_sMMapMutex);
674
675 ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
676
677 PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx,"
678 " and ui32ByteSize %d(0x%08x)",
679 __FUNCTION__,
680 ps_vma->vm_pgoff,
681 ui32ByteSize, ui32ByteSize));
682
683 psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize);
684 if (psOffsetStruct == IMG_NULL)
685 {
686#if defined(SUPPORT_DRI_DRM)
687 LinuxUnLockMutex(&g_sMMapMutex);
688
689#if !defined(SUPPORT_DRI_DRM_EXT)
690
691 return drm_mmap(pFile, ps_vma);
692#else
693
694 return -ENOENT;
695#endif
696#else
697 PVR_UNREFERENCED_PARAMETER(pFile);
698
699 PVR_DPF((PVR_DBG_ERROR,
700 "%s: Attempted to mmap unregistered area at vm_pgoff 0x%lx",
701 __FUNCTION__, ps_vma->vm_pgoff));
702 iRetVal = -EINVAL;
703#endif
704 goto unlock_and_return;
705 }
706 list_del(&psOffsetStruct->sMMapItem);
707 psOffsetStruct->bOnMMapList = IMG_FALSE;
708
709
710 if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
711 ((ps_vma->vm_flags & VM_SHARED) == 0))
712 {
713 PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__));
714 iRetVal = -EINVAL;
715 goto unlock_and_return;
716 }
717
718 PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n",
719 __FUNCTION__, psOffsetStruct->psLinuxMemArea));
720
721 ps_vma->vm_flags |= VM_RESERVED;
722 ps_vma->vm_flags |= VM_IO;
723
724
725 ps_vma->vm_flags |= VM_DONTEXPAND;
726
727
728 ps_vma->vm_flags |= VM_DONTCOPY;
729
730 ps_vma->vm_private_data = (void *)psOffsetStruct;
731
732 switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK)
733 {
734 case PVRSRV_HAP_CACHED:
735
736 break;
737 case PVRSRV_HAP_WRITECOMBINE:
738 ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot);
739 break;
740 case PVRSRV_HAP_UNCACHED:
741 ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot);
742 break;
743 default:
744 PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__));
745 iRetVal = -EINVAL;
746 goto unlock_and_return;
747 }
748
749
750 ps_vma->vm_ops = &MMapIOOps;
751
752 if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0))
753 {
754 iRetVal = -EAGAIN;
755 goto unlock_and_return;
756 }
757
758 PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0)
759
760 psOffsetStruct->ui32UserVAddr = ps_vma->vm_start;
761
762
763 if(psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate)
764 {
765 IMG_UINT32 ui32RealByteSize, ui32ByteOffset;
766 IMG_VOID *pvBase;
767
768 DetermineUsersSizeAndByteOffset(psOffsetStruct->psLinuxMemArea,
769 &ui32RealByteSize,
770 &ui32ByteOffset);
771
772 ui32RealByteSize = psOffsetStruct->psLinuxMemArea->ui32ByteSize;
773 pvBase = (IMG_VOID *)ps_vma->vm_start + ui32ByteOffset;
774
775 OSInvalidateCPUCacheRangeKM(psOffsetStruct->psLinuxMemArea,
776 pvBase, ui32RealByteSize);
777 psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate = IMG_FALSE;
778 }
779
780
781 MMapVOpenNoLock(ps_vma);
782
783 PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n",
784 __FUNCTION__, ps_vma->vm_pgoff));
785
786unlock_and_return:
787 if (iRetVal != 0 && psOffsetStruct != IMG_NULL)
788 {
789 DestroyOffsetStruct(psOffsetStruct);
790 }
791
792 LinuxUnLockMutex(&g_sMMapMutex);
793
794 return iRetVal;
795}
796
797
798#if defined(DEBUG_LINUX_MMAP_AREAS)
799
800static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start)
801{
802 if(start)
803 {
804 LinuxLockMutex(&g_sMMapMutex);
805 }
806 else
807 {
808 LinuxUnLockMutex(&g_sMMapMutex);
809 }
810}
811
812
813static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off)
814{
815 LinuxMemArea *psLinuxMemArea;
816 if(!off)
817 {
818 return PVR_PROC_SEQ_START_TOKEN;
819 }
820
821 list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
822 {
823 PKV_OFFSET_STRUCT psOffsetStruct;
824
825 list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
826 {
827 off--;
828 if (off == 0)
829 {
830 PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
831 return (void*)psOffsetStruct;
832 }
833 }
834 }
835 return (void*)0;
836}
837
838static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off)
839{
840 return ProcSeqOff2ElementMMapRegistrations(sfile,off);
841}
842
843
844static void ProcSeqShowMMapRegistrations(struct seq_file *sfile, void *el)
845{
846 KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el;
847 LinuxMemArea *psLinuxMemArea;
848 IMG_UINT32 ui32RealByteSize;
849 IMG_UINT32 ui32ByteOffset;
850
851 if(el == PVR_PROC_SEQ_START_TOKEN)
852 {
853 seq_printf( sfile,
854#if !defined(DEBUG_LINUX_XML_PROC_FILES)
855 "Allocations registered for mmap: %u\n"
856 "In total these areas correspond to %u bytes\n"
857 "psLinuxMemArea "
858 "UserVAddr "
859 "KernelVAddr "
860 "CpuPAddr "
861 "MMapOffset "
862 "ByteLength "
863 "LinuxMemType "
864 "Pid Name Flags\n",
865#else
866 "<mmap_header>\n"
867 "\t<count>%u</count>\n"
868 "\t<bytes>%u</bytes>\n"
869 "</mmap_header>\n",
870#endif
871 g_ui32RegisteredAreas,
872 g_ui32TotalByteSize
873 );
874 return;
875 }
876
877 psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
878
879 DetermineUsersSizeAndByteOffset(psLinuxMemArea,
880 &ui32RealByteSize,
881 &ui32ByteOffset);
882
883 seq_printf( sfile,
884#if !defined(DEBUG_LINUX_XML_PROC_FILES)
885 "%-8p %08x %-8p %08x %08x %-8d %-24s %-5u %-8s %08x(%s)\n",
886#else
887 "<mmap_record>\n"
888 "\t<pointer>%-8p</pointer>\n"
889 "\t<user_virtual>%-8x</user_virtual>\n"
890 "\t<kernel_virtual>%-8p</kernel_virtual>\n"
891 "\t<cpu_physical>%08x</cpu_physical>\n"
892 "\t<mmap_offset>%08x</mmap_offset>\n"
893 "\t<bytes>%-8d</bytes>\n"
894 "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
895 "\t<pid>%-5u</pid>\n"
896 "\t<name>%-8s</name>\n"
897 "\t<flags>%08x</flags>\n"
898 "\t<flags_string>%s</flags_string>\n"
899 "</mmap_record>\n",
900#endif
901 psLinuxMemArea,
902 psOffsetStruct->ui32UserVAddr + ui32ByteOffset,
903 LinuxMemAreaToCpuVAddr(psLinuxMemArea),
904 LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr,
905 psOffsetStruct->ui32MMapOffset,
906 psLinuxMemArea->ui32ByteSize,
907 LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType),
908 psOffsetStruct->ui32PID,
909 psOffsetStruct->pszName,
910 psLinuxMemArea->ui32AreaFlags,
911 HAPFlagsToString(psLinuxMemArea->ui32AreaFlags));
912}
913
914#endif
915
916
917PVRSRV_ERROR
918PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea)
919{
920 PVRSRV_ERROR eError;
921#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
922 const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
923#endif
924
925 LinuxLockMutex(&g_sMMapMutex);
926
927#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
928 PVR_DPF((PVR_DBG_MESSAGE,
929 "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8x)",
930 __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
931#endif
932
933 PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
934
935
936 if(psLinuxMemArea->bMMapRegistered)
937 {
938 PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered",
939 __FUNCTION__, psLinuxMemArea));
940 eError = PVRSRV_ERROR_INVALID_PARAMS;
941 goto exit_unlock;
942 }
943
944 list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList);
945
946 psLinuxMemArea->bMMapRegistered = IMG_TRUE;
947
948#if defined(DEBUG_LINUX_MMAP_AREAS)
949 g_ui32RegisteredAreas++;
950
951 if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
952 {
953 g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize;
954 }
955#endif
956
957 eError = PVRSRV_OK;
958
959exit_unlock:
960 LinuxUnLockMutex(&g_sMMapMutex);
961
962 return eError;
963}
964
965
966PVRSRV_ERROR
967PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
968{
969 PVRSRV_ERROR eError;
970 PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
971
972 LinuxLockMutex(&g_sMMapMutex);
973
974 PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
975
976 list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
977 {
978 if (psOffsetStruct->ui32Mapped != 0)
979 {
980 PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %u", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
981 eError = PVRSRV_ERROR_STILL_MAPPED;
982 goto exit_unlock;
983 }
984 else
985 {
986
987 PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped", __FUNCTION__, psOffsetStruct));
988 }
989
990 PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList);
991
992 DestroyOffsetStruct(psOffsetStruct);
993 }
994
995 list_del(&psLinuxMemArea->sMMapItem);
996
997 psLinuxMemArea->bMMapRegistered = IMG_FALSE;
998
999#if defined(DEBUG_LINUX_MMAP_AREAS)
1000 g_ui32RegisteredAreas--;
1001 if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
1002 {
1003 g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize;
1004 }
1005#endif
1006
1007 eError = PVRSRV_OK;
1008
1009exit_unlock:
1010 LinuxUnLockMutex(&g_sMMapMutex);
1011 return eError;
1012}
1013
1014
1015PVRSRV_ERROR
1016LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
1017{
1018 PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
1019
1020 return PVRSRV_OK;
1021}
1022
1023IMG_VOID
1024LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
1025{
1026 PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
1027 IMG_BOOL bWarn = IMG_FALSE;
1028 IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
1029
1030 PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
1031
1032 LinuxLockMutex(&g_sMMapMutex);
1033
1034 list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
1035 {
1036 if (psOffsetStruct->ui32PID == ui32PID)
1037 {
1038 if (!bWarn)
1039 {
1040 PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__));
1041 bWarn = IMG_TRUE;
1042 }
1043 PVR_ASSERT(psOffsetStruct->ui32Mapped == 0);
1044 PVR_ASSERT(psOffsetStruct->bOnMMapList);
1045
1046 DestroyOffsetStruct(psOffsetStruct);
1047 }
1048 }
1049
1050 LinuxUnLockMutex(&g_sMMapMutex);
1051}
1052
1053
1054PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
1055{
1056 PVRSRV_ERROR eError;
1057
1058 eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE);
1059 if (eError != PVRSRV_OK)
1060 {
1061 PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError));
1062 return eError;
1063 }
1064
1065 return eError;
1066}
1067
1068
1069IMG_VOID
1070PVRMMapInit(IMG_VOID)
1071{
1072 LinuxInitMutex(&g_sMMapMutex);
1073
1074 g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0);
1075 if (!g_psMemmapCache)
1076 {
1077 PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
1078 goto error;
1079 }
1080
1081#if defined(DEBUG_LINUX_MMAP_AREAS)
1082 g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL,
1083 ProcSeqNextMMapRegistrations,
1084 ProcSeqShowMMapRegistrations,
1085 ProcSeqOff2ElementMMapRegistrations,
1086 ProcSeqStartstopMMapRegistations
1087 );
1088#endif
1089 return;
1090
1091error:
1092 PVRMMapCleanup();
1093 return;
1094}
1095
1096
1097IMG_VOID
1098PVRMMapCleanup(IMG_VOID)
1099{
1100 PVRSRV_ERROR eError;
1101
1102 if (!list_empty(&g_sMMapAreaList))
1103 {
1104 LinuxMemArea *psLinuxMemArea, *psTmpMemArea;
1105
1106 PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__));
1107
1108 PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__));
1109 list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem)
1110 {
1111 eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
1112 if (eError != PVRSRV_OK)
1113 {
1114 PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError));
1115 }
1116 PVR_ASSERT(eError == PVRSRV_OK);
1117
1118 LinuxMemAreaDeepFree(psLinuxMemArea);
1119 }
1120 }
1121 PVR_ASSERT(list_empty((&g_sMMapAreaList)));
1122
1123#if defined(DEBUG_LINUX_MMAP_AREAS)
1124 RemoveProcEntrySeq(g_ProcMMap);
1125#endif
1126
1127 if(g_psMemmapCache)
1128 {
1129 KMemCacheDestroyWrapper(g_psMemmapCache);
1130 g_psMemmapCache = NULL;
1131 }
1132}
diff --git a/drivers/gpu/pvr/mmap.h b/drivers/gpu/pvr/mmap.h
new file mode 100644
index 00000000000..486154a241f
--- /dev/null
+++ b/drivers/gpu/pvr/mmap.h
@@ -0,0 +1,113 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__MMAP_H__)
28#define __MMAP_H__
29
30#include <linux/mm.h>
31#include <linux/list.h>
32
33#if defined(VM_MIXEDMAP)
34#define PVR_MAKE_ALL_PFNS_SPECIAL
35#endif
36
37#include "perproc.h"
38#include "mm.h"
39
40typedef struct KV_OFFSET_STRUCT_TAG
41{
42
43 IMG_UINT32 ui32Mapped;
44
45
46 IMG_UINT32 ui32MMapOffset;
47
48 IMG_UINT32 ui32RealByteSize;
49
50
51 LinuxMemArea *psLinuxMemArea;
52
53#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
54
55 IMG_UINT32 ui32TID;
56#endif
57
58
59 IMG_UINT32 ui32PID;
60
61
62 IMG_BOOL bOnMMapList;
63
64
65 IMG_UINT32 ui32RefCount;
66
67
68 IMG_UINT32 ui32UserVAddr;
69
70
71#if defined(DEBUG_LINUX_MMAP_AREAS)
72 const IMG_CHAR *pszName;
73#endif
74
75
76 struct list_head sMMapItem;
77
78
79 struct list_head sAreaItem;
80}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT;
81
82
83
84IMG_VOID PVRMMapInit(IMG_VOID);
85
86
87IMG_VOID PVRMMapCleanup(IMG_VOID);
88
89
90PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea);
91
92
93PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea);
94
95
96PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
97 IMG_HANDLE hMHandle,
98 IMG_UINT32 *pui32MMapOffset,
99 IMG_UINT32 *pui32ByteOffset,
100 IMG_UINT32 *pui32RealByteSize, IMG_UINT32 *pui32UserVAddr);
101
102PVRSRV_ERROR
103PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
104 IMG_HANDLE hMHandle,
105 IMG_BOOL *pbMUnmap,
106 IMG_UINT32 *pui32RealByteSize,
107 IMG_UINT32 *pui32UserVAddr);
108
109int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
110
111
112#endif
113
diff --git a/drivers/gpu/pvr/module.c b/drivers/gpu/pvr/module.c
new file mode 100644
index 00000000000..43a3a27adae
--- /dev/null
+++ b/drivers/gpu/pvr/module.c
@@ -0,0 +1,744 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#if !defined(SUPPORT_DRI_DRM)
32
33 #if defined(LDM_PLATFORM)
34 #define PVR_LDM_PLATFORM_MODULE
35 #define PVR_LDM_MODULE
36 #else
37 #if defined(LDM_PCI)
38 #define PVR_LDM_PCI_MODULE
39 #define PVR_LDM_MODULE
40 #endif
41 #endif
42#endif
43
44#include <linux/init.h>
45#include <linux/kernel.h>
46#include <linux/module.h>
47#include <linux/version.h>
48#include <linux/fs.h>
49#include <linux/proc_fs.h>
50
51#if defined(SUPPORT_DRI_DRM)
52#include <drm/drmP.h>
53#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
54#include "env_perproc.h"
55#endif
56#endif
57
58#if defined(PVR_LDM_PLATFORM_MODULE)
59#include <linux/platform_device.h>
60#endif
61
62#if defined(PVR_LDM_PCI_MODULE)
63#include <linux/pci.h>
64#endif
65
66#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
67#include <asm/uaccess.h>
68#endif
69
70#include "img_defs.h"
71#include "services.h"
72#include "kerneldisplay.h"
73#include "kernelbuffer.h"
74#include "syscommon.h"
75#include "pvrmmap.h"
76#include "mutils.h"
77#include "mm.h"
78#include "mmap.h"
79#include "mutex.h"
80#include "pvr_debug.h"
81#include "srvkm.h"
82#include "perproc.h"
83#include "handle.h"
84#include "pvr_bridge_km.h"
85#include "proc.h"
86#include "pvrmodule.h"
87#include "private_data.h"
88#include "lock.h"
89#include "linkage.h"
90
91#if defined(SUPPORT_DRI_DRM)
92#include "pvr_drm.h"
93#endif
94#define DRVNAME PVRSRV_MODNAME
95#define DEVNAME PVRSRV_MODNAME
96
97#if defined(SUPPORT_DRI_DRM)
98#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
99#else
100#define PRIVATE_DATA(pFile) ((pFile)->private_data)
101#endif
102
103MODULE_SUPPORTED_DEVICE(DEVNAME);
104
105#if defined(PVRSRV_NEED_PVR_DPF)
106#include <linux/moduleparam.h>
107extern IMG_UINT32 gPVRDebugLevel;
108module_param(gPVRDebugLevel, uint, 0644);
109MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
110#endif
111
112
113EXPORT_SYMBOL(PVRGetDisplayClassJTable);
114EXPORT_SYMBOL(PVRGetBufferClassJTable);
115
116#if defined(PVR_LDM_MODULE)
117static struct class *psPvrClass;
118#endif
119
120#if !defined(SUPPORT_DRI_DRM)
121static IMG_INT AssignedMajorNumber;
122
123static IMG_INT PVRSRVOpen(struct inode* pInode, struct file* pFile);
124static IMG_INT PVRSRVRelease(struct inode* pInode, struct file* pFile);
125
126static struct file_operations pvrsrv_fops =
127{
128 .owner=THIS_MODULE,
129
130 .unlocked_ioctl=(IMG_VOID*)PVRSRV_BridgeDispatchKM,
131 .open=PVRSRVOpen,
132 .release=PVRSRVRelease,
133 .mmap=PVRMMap,
134};
135#endif
136
137PVRSRV_LINUX_MUTEX gPVRSRVLock;
138
139IMG_UINT32 gui32ReleasePID;
140
141#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
142static IMG_UINT32 gPVRPowerLevel;
143#endif
144
145#if defined(PVR_LDM_MODULE)
146
147#if defined(PVR_LDM_PLATFORM_MODULE)
148#define LDM_DEV struct platform_device
149#define LDM_DRV struct platform_driver
150#endif
151
152#if defined(PVR_LDM_PCI_MODULE)
153#define LDM_DEV struct pci_dev
154#define LDM_DRV struct pci_driver
155#endif
156
157#if defined(PVR_LDM_PLATFORM_MODULE)
158static IMG_INT PVRSRVDriverRemove(LDM_DEV *device);
159static IMG_INT PVRSRVDriverProbe(LDM_DEV *device);
160#endif
161#if defined(PVR_LDM_PCI_MODULE)
162static IMG_VOID PVRSRVDriverRemove(LDM_DEV *device);
163static IMG_INT PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
164#endif
165static IMG_INT PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
166static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *device);
167static IMG_INT PVRSRVDriverResume(LDM_DEV *device);
168
169#if defined(PVR_LDM_PCI_MODULE)
170struct pci_device_id powervr_id_table[] __devinitdata = {
171 { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID) },
172 { 0 }
173};
174
175MODULE_DEVICE_TABLE(pci, powervr_id_table);
176#endif
177
178static LDM_DRV powervr_driver = {
179#if defined(PVR_LDM_PLATFORM_MODULE)
180 .driver = {
181 .name = DRVNAME,
182 },
183#endif
184#if defined(PVR_LDM_PCI_MODULE)
185 .name = DRVNAME,
186 .id_table = powervr_id_table,
187#endif
188 .probe = PVRSRVDriverProbe,
189#if defined(PVR_LDM_PLATFORM_MODULE)
190 .remove = PVRSRVDriverRemove,
191#endif
192#if defined(PVR_LDM_PCI_MODULE)
193 .remove = __devexit_p(PVRSRVDriverRemove),
194#endif
195 .suspend = PVRSRVDriverSuspend,
196 .resume = PVRSRVDriverResume,
197 .shutdown = PVRSRVDriverShutdown,
198};
199
200LDM_DEV *gpsPVRLDMDev;
201
202#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE)
203
204static IMG_VOID PVRSRVDeviceRelease(struct device *pDevice)
205{
206 PVR_UNREFERENCED_PARAMETER(pDevice);
207}
208
209static struct platform_device powervr_device = {
210 .name = DEVNAME,
211 .id = -1,
212 .dev = {
213 .release = PVRSRVDeviceRelease
214 }
215};
216
217#endif
218
219#if defined(PVR_LDM_PLATFORM_MODULE)
220static IMG_INT PVRSRVDriverProbe(LDM_DEV *pDevice)
221#endif
222#if defined(PVR_LDM_PCI_MODULE)
223static IMG_INT __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
224#endif
225{
226 SYS_DATA *psSysData;
227
228 PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
229
230#if 0
231
232 if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
233 {
234 return -EINVAL;
235 }
236#endif
237
238 psSysData = SysAcquireDataNoCheck();
239 if ( psSysData == IMG_NULL)
240 {
241 gpsPVRLDMDev = pDevice;
242
243 if (SysInitialise() != PVRSRV_OK)
244 {
245 return -ENODEV;
246 }
247 }
248
249 return 0;
250}
251
252
253#if defined (PVR_LDM_PLATFORM_MODULE)
254static IMG_INT PVRSRVDriverRemove(LDM_DEV *pDevice)
255#endif
256#if defined(PVR_LDM_PCI_MODULE)
257static IMG_VOID __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
258#endif
259{
260 SYS_DATA *psSysData;
261
262 PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
263
264 SysAcquireData(&psSysData);
265
266#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
267 if (gPVRPowerLevel != 0)
268 {
269 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
270 {
271 gPVRPowerLevel = 0;
272 }
273 }
274#endif
275 (IMG_VOID)SysDeinitialise(psSysData);
276
277 gpsPVRLDMDev = IMG_NULL;
278
279#if 0
280 if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
281 {
282 return -EINVAL;
283 }
284#endif
285
286#if defined (PVR_LDM_PLATFORM_MODULE)
287 return 0;
288#endif
289#if defined (PVR_LDM_PCI_MODULE)
290 return;
291#endif
292}
293
294
295static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *pDevice)
296{
297 PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
298
299 (IMG_VOID) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
300}
301
302#endif
303
304
305#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
306#if defined(SUPPORT_DRI_DRM)
307IMG_INT PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
308#else
309static IMG_INT PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
310#endif
311{
312#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
313 PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
314
315 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
316 {
317 return -EINVAL;
318 }
319#endif
320 return 0;
321}
322
323
324#if defined(SUPPORT_DRI_DRM)
325IMG_INT PVRSRVDriverResume(struct drm_device *pDevice)
326#else
327static IMG_INT PVRSRVDriverResume(LDM_DEV *pDevice)
328#endif
329{
330#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
331 PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
332
333 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
334 {
335 return -EINVAL;
336 }
337#endif
338 return 0;
339}
340#endif
341
342
343#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
344IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
345{
346 IMG_CHAR data_buffer[2];
347 IMG_UINT32 PVRPowerLevel;
348
349 if (count != sizeof(data_buffer))
350 {
351 return -EINVAL;
352 }
353 else
354 {
355 if (copy_from_user(data_buffer, buffer, count))
356 return -EINVAL;
357 if (data_buffer[count - 1] != '\n')
358 return -EINVAL;
359 PVRPowerLevel = data_buffer[0] - '0';
360 if (PVRPowerLevel != gPVRPowerLevel)
361 {
362 if (PVRPowerLevel != 0)
363 {
364 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
365 {
366 return -EINVAL;
367 }
368 }
369 else
370 {
371 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
372 {
373 return -EINVAL;
374 }
375 }
376
377 gPVRPowerLevel = PVRPowerLevel;
378 }
379 }
380 return (count);
381}
382
383void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
384{
385 seq_printf(sfile, "%lu\n", gPVRPowerLevel);
386}
387
388#endif
389
390#if defined(SUPPORT_DRI_DRM)
391IMG_INT PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
392#else
393static IMG_INT PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
394#endif
395{
396 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
397 IMG_HANDLE hBlockAlloc;
398 IMG_INT iRet = -ENOMEM;
399 PVRSRV_ERROR eError;
400 IMG_UINT32 ui32PID;
401#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
402 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
403#endif
404
405#if defined(SUPPORT_DRI_DRM)
406 PVR_UNREFERENCED_PARAMETER(dev);
407#else
408 PVR_UNREFERENCED_PARAMETER(pInode);
409#endif
410
411 LinuxLockMutex(&gPVRSRVLock);
412
413 ui32PID = OSGetCurrentProcessIDKM();
414
415 if (PVRSRVProcessConnect(ui32PID) != PVRSRV_OK)
416 goto err_unlock;
417
418#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
419 psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
420 if (psEnvPerProc == IMG_NULL)
421 {
422 PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
423 goto err_unlock;
424 }
425#endif
426
427 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
428 sizeof(PVRSRV_FILE_PRIVATE_DATA),
429 (IMG_PVOID *)&psPrivateData,
430 &hBlockAlloc,
431 "File Private Data");
432
433 if(eError != PVRSRV_OK)
434 goto err_unlock;
435
436#if defined(PVR_SECURE_FD_EXPORT)
437 psPrivateData->hKernelMemInfo = NULL;
438#endif
439#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
440 psPrivateData->psDRMFile = pFile;
441
442 list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
443#endif
444 psPrivateData->ui32OpenPID = ui32PID;
445 psPrivateData->hBlockAlloc = hBlockAlloc;
446 PRIVATE_DATA(pFile) = psPrivateData;
447 iRet = 0;
448err_unlock:
449 LinuxUnLockMutex(&gPVRSRVLock);
450 return iRet;
451}
452
453
454#if defined(SUPPORT_DRI_DRM)
455IMG_INT PVRSRVRelease(struct drm_device unref__ *dev, struct drm_file *pFile)
456#else
457static IMG_INT PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
458#endif
459{
460 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
461
462#if defined(SUPPORT_DRI_DRM)
463 PVR_UNREFERENCED_PARAMETER(dev);
464#else
465 PVR_UNREFERENCED_PARAMETER(pInode);
466#endif
467
468 LinuxLockMutex(&gPVRSRVLock);
469
470 psPrivateData = PRIVATE_DATA(pFile);
471
472#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
473 list_del(&psPrivateData->sDRMAuthListItem);
474#endif
475
476
477 gui32ReleasePID = psPrivateData->ui32OpenPID;
478 PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
479 gui32ReleasePID = 0;
480
481 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
482 sizeof(PVRSRV_FILE_PRIVATE_DATA),
483 psPrivateData, psPrivateData->hBlockAlloc);
484
485 PRIVATE_DATA(pFile) = NULL;
486
487 LinuxUnLockMutex(&gPVRSRVLock);
488 return 0;
489}
490
491
492#if defined(SUPPORT_DRI_DRM)
493IMG_INT PVRCore_Init(IMG_VOID)
494#else
495static IMG_INT __init PVRCore_Init(IMG_VOID)
496#endif
497{
498 IMG_INT error;
499#if !defined(PVR_LDM_MODULE)
500 PVRSRV_ERROR eError;
501#else
502 struct device *psDev;
503#endif
504
505#if !defined(SUPPORT_DRI_DRM)
506
507 PVRDPFInit();
508#endif
509 PVR_TRACE(("PVRCore_Init"));
510
511 LinuxInitMutex(&gPVRSRVLock);
512
513 if (CreateProcEntries ())
514 {
515 error = -ENOMEM;
516 return error;
517 }
518
519 if (PVROSFuncInit() != PVRSRV_OK)
520 {
521 error = -ENOMEM;
522 goto init_failed;
523 }
524
525 PVRLinuxMUtilsInit();
526
527 if(LinuxMMInit() != PVRSRV_OK)
528 {
529 error = -ENOMEM;
530 goto init_failed;
531 }
532
533 LinuxBridgeInit();
534
535 PVRMMapInit();
536
537#if defined(PVR_LDM_MODULE)
538
539#if defined(PVR_LDM_PLATFORM_MODULE)
540 if ((error = platform_driver_register(&powervr_driver)) != 0)
541 {
542 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
543
544 goto init_failed;
545 }
546
547#if defined(MODULE)
548 if ((error = platform_device_register(&powervr_device)) != 0)
549 {
550 platform_driver_unregister(&powervr_driver);
551
552 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
553
554 goto init_failed;
555 }
556#endif
557#endif
558
559#if defined(PVR_LDM_PCI_MODULE)
560 if ((error = pci_register_driver(&powervr_driver)) != 0)
561 {
562 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
563
564 goto init_failed;
565 }
566#endif
567
568#else
569
570 if ((eError = SysInitialise()) != PVRSRV_OK)
571 {
572 error = -ENODEV;
573#if defined(TCF_REV) && (TCF_REV == 110)
574 if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
575 {
576 printk("\nAtlas wrapper (FPGA image) version mismatch");
577 error = -ENODEV;
578 }
579#endif
580 goto init_failed;
581 }
582#endif
583
584#if !defined(SUPPORT_DRI_DRM)
585 AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
586
587 if (AssignedMajorNumber <= 0)
588 {
589 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
590
591 error = -EBUSY;
592 goto sys_deinit;
593 }
594
595 PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
596#endif
597
598#if defined(PVR_LDM_MODULE)
599
600 psPvrClass = class_create(THIS_MODULE, "pvr");
601
602 if (IS_ERR(psPvrClass))
603 {
604 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
605 error = -EBUSY;
606 goto unregister_device;
607 }
608
609 psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
610#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
611 NULL,
612#endif
613 DEVNAME);
614 if (IS_ERR(psDev))
615 {
616 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
617 error = -EBUSY;
618 goto destroy_class;
619 }
620#endif
621
622 return 0;
623
624#if defined(PVR_LDM_MODULE)
625destroy_class:
626 class_destroy(psPvrClass);
627unregister_device:
628 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME);
629#endif
630#if !defined(SUPPORT_DRI_DRM)
631sys_deinit:
632#endif
633#if defined(PVR_LDM_MODULE)
634#if defined(PVR_LDM_PCI_MODULE)
635 pci_unregister_driver(&powervr_driver);
636#endif
637
638#if defined (PVR_LDM_PLATFORM_MODULE)
639#if defined (MODULE)
640 platform_device_unregister(&powervr_device);
641#endif
642 platform_driver_unregister(&powervr_driver);
643#endif
644
645#else
646
647 {
648 SYS_DATA *psSysData;
649
650 psSysData = SysAcquireDataNoCheck();
651 if (psSysData != IMG_NULL)
652 {
653 (IMG_VOID)SysDeinitialise(psSysData);
654 }
655 }
656#endif
657init_failed:
658 PVRMMapCleanup();
659 LinuxMMCleanup();
660 LinuxBridgeDeInit();
661 PVROSFuncDeInit();
662 RemoveProcEntries();
663
664 return error;
665
666}
667
668
669#if defined(SUPPORT_DRI_DRM)
670IMG_VOID PVRCore_Cleanup(IMG_VOID)
671#else
672static IMG_VOID __exit PVRCore_Cleanup(IMG_VOID)
673#endif
674{
675 SYS_DATA *psSysData;
676
677 PVR_TRACE(("PVRCore_Cleanup"));
678
679 SysAcquireData(&psSysData);
680
681#if defined(PVR_LDM_MODULE)
682 device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
683 class_destroy(psPvrClass);
684#endif
685
686#if !defined(SUPPORT_DRI_DRM)
687#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
688 if (
689#endif
690 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME)
691#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
692 ;
693#else
694 )
695 {
696 PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
697 }
698#endif
699#endif
700
701#if defined(PVR_LDM_MODULE)
702
703#if defined(PVR_LDM_PCI_MODULE)
704 pci_unregister_driver(&powervr_driver);
705#endif
706
707#if defined (PVR_LDM_PLATFORM_MODULE)
708#if defined (MODULE)
709 platform_device_unregister(&powervr_device);
710#endif
711 platform_driver_unregister(&powervr_driver);
712#endif
713
714#else
715#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
716 if (gPVRPowerLevel != 0)
717 {
718 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
719 {
720 gPVRPowerLevel = 0;
721 }
722 }
723#endif
724
725 (IMG_VOID)SysDeinitialise(psSysData);
726#endif
727
728 PVRMMapCleanup();
729
730 LinuxMMCleanup();
731
732 LinuxBridgeDeInit();
733
734 PVROSFuncDeInit();
735
736 RemoveProcEntries();
737
738 PVR_TRACE(("PVRCore_Cleanup: unloading"));
739}
740
741#if !defined(SUPPORT_DRI_DRM)
742module_init(PVRCore_Init);
743module_exit(PVRCore_Cleanup);
744#endif
diff --git a/drivers/gpu/pvr/mutex.c b/drivers/gpu/pvr/mutex.c
new file mode 100644
index 00000000000..09963ad9f00
--- /dev/null
+++ b/drivers/gpu/pvr/mutex.c
@@ -0,0 +1,136 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <linux/version.h>
28#include <linux/errno.h>
29#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
30#include <linux/mutex.h>
31#else
32#include <asm/semaphore.h>
33#endif
34#include <linux/module.h>
35
36#include <img_defs.h>
37#include <services.h>
38
39#include "mutex.h"
40
41
42#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
43
44IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
45{
46 mutex_init(psPVRSRVMutex);
47}
48
49IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
50{
51 mutex_lock(psPVRSRVMutex);
52}
53
54PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
55{
56 if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR)
57 {
58 return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR;
59 }
60 else
61 {
62 return PVRSRV_OK;
63 }
64}
65
66IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
67{
68 return mutex_trylock(psPVRSRVMutex);
69}
70
71IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
72{
73 mutex_unlock(psPVRSRVMutex);
74}
75
76IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
77{
78 return (mutex_is_locked(psPVRSRVMutex)) ? IMG_TRUE : IMG_FALSE;
79}
80
81
82#else
83
84
85IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
86{
87 init_MUTEX(&psPVRSRVMutex->sSemaphore);
88 atomic_set(&psPVRSRVMutex->Count, 0);
89}
90
91IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
92{
93 down(&psPVRSRVMutex->sSemaphore);
94 atomic_dec(&psPVRSRVMutex->Count);
95}
96
97PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
98{
99 if(down_interruptible(&psPVRSRVMutex->sSemaphore) == -EINTR)
100 {
101
102 return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR;
103 }else{
104 atomic_dec(&psPVRSRVMutex->Count);
105 return PVRSRV_OK;
106 }
107}
108
109IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
110{
111 IMG_INT32 Status = down_trylock(&psPVRSRVMutex->sSemaphore);
112 if(Status == 0)
113 {
114 atomic_dec(&psPVRSRVMutex->Count);
115 }
116
117 return Status;
118}
119
120IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
121{
122 atomic_inc(&psPVRSRVMutex->Count);
123 up(&psPVRSRVMutex->sSemaphore);
124}
125
126IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
127{
128 IMG_INT32 iCount;
129
130 iCount = atomic_read(&psPVRSRVMutex->Count);
131
132 return (IMG_BOOL)iCount;
133}
134
135#endif
136
diff --git a/drivers/gpu/pvr/mutex.h b/drivers/gpu/pvr/mutex.h
new file mode 100644
index 00000000000..b24a5990f8f
--- /dev/null
+++ b/drivers/gpu/pvr/mutex.h
@@ -0,0 +1,70 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __INCLUDED_LINUX_MUTEX_H_
28#define __INCLUDED_LINUX_MUTEX_H_
29
30#include <linux/version.h>
31
32#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
33#include <linux/mutex.h>
34#else
35#include <asm/semaphore.h>
36#endif
37
38
39
40#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
41
42typedef struct mutex PVRSRV_LINUX_MUTEX;
43
44#else
45
46
47typedef struct {
48 struct semaphore sSemaphore;
49
50 atomic_t Count;
51}PVRSRV_LINUX_MUTEX;
52
53#endif
54
55
56extern IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
57
58extern IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
59
60extern PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
61
62extern IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
63
64extern IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
65
66extern IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
67
68
69#endif
70
diff --git a/drivers/gpu/pvr/mutils.c b/drivers/gpu/pvr/mutils.c
new file mode 100644
index 00000000000..83eab51bb1d
--- /dev/null
+++ b/drivers/gpu/pvr/mutils.c
@@ -0,0 +1,133 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28#include <linux/config.h>
29#endif
30#include <linux/version.h>
31
32#include <linux/spinlock.h>
33#include <linux/mm.h>
34#include <asm/page.h>
35#include <asm/pgtable.h>
36
37#include "img_defs.h"
38#include "pvr_debug.h"
39#include "mutils.h"
40
41#if defined(SUPPORT_LINUX_X86_PAT)
42#define PAT_LINUX_X86_WC 1
43
44#define PAT_X86_ENTRY_BITS 8
45
46#define PAT_X86_BIT_PWT 1U
47#define PAT_X86_BIT_PCD 2U
48#define PAT_X86_BIT_PAT 4U
49#define PAT_X86_BIT_MASK (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)
50
51static IMG_BOOL g_write_combining_available = IMG_FALSE;
52
53#define PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)
54
55static inline IMG_UINT
56pvr_pat_index(pgprotval_t prot_val)
57{
58 IMG_UINT ret = 0;
59 pgprotval_t val = prot_val & _PAGE_CACHE_MASK;
60
61 ret |= PROT_TO_PAT_INDEX(val, PAT);
62 ret |= PROT_TO_PAT_INDEX(val, PCD);
63 ret |= PROT_TO_PAT_INDEX(val, PWT);
64
65 return ret;
66}
67
68static inline IMG_UINT
69pvr_pat_entry(u64 pat, IMG_UINT index)
70{
71 return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;
72}
73
74static IMG_VOID
75PVRLinuxX86PATProbe(IMG_VOID)
76{
77
78 if (cpu_has_pat)
79 {
80 u64 pat;
81 IMG_UINT pat_index;
82 IMG_UINT pat_entry;
83
84 PVR_TRACE(("%s: PAT available", __FUNCTION__));
85
86 rdmsrl(MSR_IA32_CR_PAT, pat);
87 PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));
88 PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));
89
90 pat_index = pvr_pat_index(_PAGE_CACHE_WC);
91 PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));
92
93 pat_entry = pvr_pat_entry(pat, pat_index);
94 PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));
95
96#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
97 g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);
98#endif
99 }
100#if defined(DEBUG)
101#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
102 if (g_write_combining_available)
103 {
104 PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));
105 }
106 else
107 {
108 PVR_TRACE(("%s: Write combining not available", __FUNCTION__));
109 }
110#else
111 PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));
112#endif
113#endif
114}
115
116pgprot_t
117pvr_pgprot_writecombine(pgprot_t prot)
118{
119
120
121 return (g_write_combining_available) ?
122 __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);
123}
124#endif
125
126IMG_VOID
127PVRLinuxMUtilsInit(IMG_VOID)
128{
129#if defined(SUPPORT_LINUX_X86_PAT)
130 PVRLinuxX86PATProbe();
131#endif
132}
133
diff --git a/drivers/gpu/pvr/mutils.h b/drivers/gpu/pvr/mutils.h
new file mode 100644
index 00000000000..943c2bd80a3
--- /dev/null
+++ b/drivers/gpu/pvr/mutils.h
@@ -0,0 +1,101 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __IMG_LINUX_MUTILS_H__
28#define __IMG_LINUX_MUTILS_H__
29
30#ifndef AUTOCONF_INCLUDED
31#include <linux/config.h>
32#endif
33
34#include <linux/version.h>
35
36#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)))
37#if defined(SUPPORT_LINUX_X86_PAT)
38#undef SUPPORT_LINUX_X86_PAT
39#endif
40#endif
41
42#if defined(SUPPORT_LINUX_X86_PAT)
43 pgprot_t pvr_pgprot_writecombine(pgprot_t prot);
44 #define PGPROT_WC(pv) pvr_pgprot_writecombine(pv)
45#else
46 #if defined(__arm__) || defined(__sh__)
47 #define PGPROT_WC(pv) pgprot_writecombine(pv)
48 #else
49 #if defined(__i386__)
50 #define PGPROT_WC(pv) pgprot_noncached(pv)
51 #else
52 #define PGPROT_WC(pv) pgprot_noncached(pv)
53 #error Unsupported architecture!
54 #endif
55 #endif
56#endif
57
58#define PGPROT_UC(pv) pgprot_noncached(pv)
59
60#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
61 #define IOREMAP(pa, bytes) ioremap_cache(pa, bytes)
62#else
63 #if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
64 #define IOREMAP(pa, bytes) ioremap_cached(pa, bytes)
65 #else
66 #define IOREMAP(pa, bytes) ioremap(pa, bytes)
67 #endif
68#endif
69
70#if defined(SUPPORT_LINUX_X86_PAT)
71 #if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
72 #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
73 #else
74 #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
75 #endif
76#else
77 #if defined(__arm__)
78 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
79 #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
80 #else
81 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
82 #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
83 #else
84 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17))
85 #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, L_PTE_BUFFERABLE)
86 #else
87 #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1)
88 #endif
89 #endif
90 #endif
91 #else
92 #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
93 #endif
94#endif
95
96#define IOREMAP_UC(pa, bytes) ioremap_nocache(pa, bytes)
97
98IMG_VOID PVRLinuxMUtilsInit(IMG_VOID);
99
100#endif
101
diff --git a/drivers/gpu/pvr/ocpdefs.h b/drivers/gpu/pvr/ocpdefs.h
new file mode 100644
index 00000000000..43744e3448f
--- /dev/null
+++ b/drivers/gpu/pvr/ocpdefs.h
@@ -0,0 +1,271 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _OCPDEFS_H_
28#define _OCPDEFS_H_
29
30#define EUR_CR_OCP_REVISION 0xFE00
31#define EUR_CR_OCP_REVISION_REV_MASK 0xFFFFFFFFUL
32#define EUR_CR_OCP_REVISION_REV_SHIFT 0
33#define EUR_CR_OCP_REVISION_REV_SIGNED 0
34
35#define EUR_CR_OCP_HWINFO 0xFE04
36#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_MASK 0x00000003UL
37#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SHIFT 0
38#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SIGNED 0
39
40#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_MASK 0x00000004UL
41#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SHIFT 2
42#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SIGNED 0
43
44#define EUR_CR_OCP_SYSCONFIG 0xFE10
45#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_MASK 0x0000000CUL
46#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT 2
47#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SIGNED 0
48
49#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_MASK 0x00000030UL
50#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT 4
51#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SIGNED 0
52
53#define EUR_CR_OCP_IRQSTATUS_RAW_0 0xFE24
54#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_MASK 0x00000001UL
55#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SHIFT 0
56#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SIGNED 0
57
58#define EUR_CR_OCP_IRQSTATUS_RAW_1 0xFE28
59#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_MASK 0x00000001UL
60#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SHIFT 0
61#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SIGNED 0
62
63#define EUR_CR_OCP_IRQSTATUS_RAW_2 0xFE2C
64#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_MASK 0x00000001UL
65#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SHIFT 0
66#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SIGNED 0
67
68#define EUR_CR_OCP_IRQSTATUS_0 0xFE30
69#define EUR_CR_OCP_IRQSTATUS_0_INIT_MASK 0x00000001UL
70#define EUR_CR_OCP_IRQSTATUS_0_INIT_SHIFT 0
71#define EUR_CR_OCP_IRQSTATUS_0_INIT_SIGNED 0
72
73#define EUR_CR_OCP_IRQSTATUS_1 0xFE34
74#define EUR_CR_OCP_IRQSTATUS_1_TARGET_MASK 0x00000001UL
75#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SHIFT 0
76#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SIGNED 0
77
78#define EUR_CR_OCP_IRQSTATUS_2 0xFE38
79#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_MASK 0x00000001UL
80#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SHIFT 0
81#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SIGNED 0
82
83#define EUR_CR_OCP_IRQENABLE_SET_0 0xFE3C
84#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_MASK 0x00000001UL
85#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SHIFT 0
86#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SIGNED 0
87
88#define EUR_CR_OCP_IRQENABLE_SET_1 0xFE40
89#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_MASK 0x00000001UL
90#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SHIFT 0
91#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SIGNED 0
92
93#define EUR_CR_OCP_IRQENABLE_SET_2 0xFE44
94#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_MASK 0x00000001UL
95#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SHIFT 0
96#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SIGNED 0
97
98#define EUR_CR_OCP_IRQENABLE_CLR_0 0xFE48
99#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_MASK 0x00000001UL
100#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SHIFT 0
101#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SIGNED 0
102
103#define EUR_CR_OCP_IRQENABLE_CLR_1 0xFE4C
104#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_MASK 0x00000001UL
105#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SHIFT 0
106#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SIGNED 0
107
108#define EUR_CR_OCP_IRQENABLE_CLR_2 0xFE50
109#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_MASK 0x00000001UL
110#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SHIFT 0
111#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SIGNED 0
112
113#define EUR_CR_OCP_PAGE_CONFIG 0xFF00
114#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_MASK 0x00000001UL
115#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SHIFT 0
116#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SIGNED 0
117
118#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_MASK 0x00000004UL
119#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SHIFT 2
120#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SIGNED 0
121
122#define EUR_CR_OCP_PAGE_CONFIG_SIZE_MASK 0x00000018UL
123#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SHIFT 3
124#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SIGNED 0
125
126#define EUR_CR_OCP_INTERRUPT_EVENT 0xFF04
127#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_MASK 0x00000001UL
128#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SHIFT 0
129#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SIGNED 0
130
131#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_MASK 0x00000002UL
132#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SHIFT 1
133#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SIGNED 0
134
135#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_MASK 0x00000004UL
136#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SHIFT 2
137#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SIGNED 0
138
139#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_MASK 0x00000008UL
140#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SHIFT 3
141#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SIGNED 0
142
143#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_MASK 0x00000010UL
144#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SHIFT 4
145#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SIGNED 0
146
147#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_MASK 0x00000020UL
148#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SHIFT 5
149#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SIGNED 0
150
151#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_MASK 0x00000100UL
152#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SHIFT 8
153#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SIGNED 0
154
155#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_MASK 0x00000200UL
156#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SHIFT 9
157#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SIGNED 0
158
159#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_MASK 0x00000400UL
160#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SHIFT 10
161#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SIGNED 0
162
163#define EUR_CR_OCP_DEBUG_CONFIG 0xFF08
164#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_MASK 0x00000003UL
165#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SHIFT 0
166#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SIGNED 0
167
168#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_MASK 0x0000000CUL
169#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SHIFT 2
170#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SIGNED 0
171
172#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_MASK 0x00000010UL
173#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SHIFT 4
174#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SIGNED 0
175
176#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_MASK 0x00000020UL
177#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SHIFT 5
178#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SIGNED 0
179
180#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK 0x80000000UL
181#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SHIFT 31
182#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SIGNED 0
183
184#define EUR_CR_OCP_DEBUG_STATUS 0xFF0C
185#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_MASK 0x00000003UL
186#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SHIFT 0
187#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SIGNED 0
188
189#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_MASK 0x00000004UL
190#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SHIFT 2
191#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SIGNED 0
192
193#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_MASK 0x00000008UL
194#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SHIFT 3
195#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SIGNED 0
196
197#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_MASK 0x00000030UL
198#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SHIFT 4
199#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SIGNED 0
200
201#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_MASK 0x000000C0UL
202#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SHIFT 6
203#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SIGNED 0
204
205#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_MASK 0x00000300UL
206#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SHIFT 8
207#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SIGNED 0
208
209#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_MASK 0x00000400UL
210#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SHIFT 10
211#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SIGNED 0
212
213#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_MASK 0x00000800UL
214#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SHIFT 11
215#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SIGNED 0
216
217#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_MASK 0x00001000UL
218#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SHIFT 12
219#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SIGNED 0
220
221#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_MASK 0x00006000UL
222#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SHIFT 13
223#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SIGNED 0
224
225#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_MASK 0x00008000UL
226#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SHIFT 15
227#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SIGNED 0
228
229#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_MASK 0x00010000UL
230#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SHIFT 16
231#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SIGNED 0
232
233#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_MASK 0x00020000UL
234#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SHIFT 17
235#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SIGNED 0
236
237#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_MASK 0x001C0000UL
238#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SHIFT 18
239#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SIGNED 0
240
241#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_MASK 0x03E00000UL
242#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SHIFT 21
243#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SIGNED 0
244
245#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_MASK 0x04000000UL
246#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SHIFT 26
247#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SIGNED 0
248
249#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_MASK 0x08000000UL
250#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SHIFT 27
251#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SIGNED 0
252
253#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_MASK 0x10000000UL
254#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SHIFT 28
255#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SIGNED 0
256
257#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_MASK 0x20000000UL
258#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SHIFT 29
259#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SIGNED 0
260
261#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_MASK 0x40000000UL
262#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SHIFT 30
263#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SIGNED 0
264
265#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_MASK 0x80000000UL
266#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SHIFT 31
267#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SIGNED 0
268
269
270#endif
271
diff --git a/drivers/gpu/pvr/omap3/oemfuncs.h b/drivers/gpu/pvr/omap3/oemfuncs.h
new file mode 100644
index 00000000000..d28356463cf
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/oemfuncs.h
@@ -0,0 +1,56 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__OEMFUNCS_H__)
28#define __OEMFUNCS_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl,
35 IMG_BYTE *pInBuf,
36 IMG_UINT32 InBufLen,
37 IMG_BYTE *pOutBuf,
38 IMG_UINT32 OutBufLen,
39 IMG_UINT32 *pdwBytesTransferred);
40typedef struct PVRSRV_DC_OEM_JTABLE_TAG
41{
42 PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch;
43 IMG_PVOID pvDummy1;
44 IMG_PVOID pvDummy2;
45 IMG_PVOID pvDummy3;
46
47} PVRSRV_DC_OEM_JTABLE;
48
49#define OEM_GET_EXT_FUNCS (1<<1)
50
51#if defined(__cplusplus)
52}
53#endif
54
55#endif
56
diff --git a/drivers/gpu/pvr/omap3/sysconfig.c b/drivers/gpu/pvr/omap3/sysconfig.c
new file mode 100644
index 00000000000..00520992b93
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/sysconfig.c
@@ -0,0 +1,970 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "kerneldisplay.h"
29#include "oemfuncs.h"
30#include "sgxinfo.h"
31#include "sgxinfokm.h"
32#include "syslocal.h"
33#include "sysconfig.h"
34
35#include "ocpdefs.h"
36
37#if !defined(NO_HARDWARE) && \
38 defined(SYS_USING_INTERRUPTS) && \
39 defined(SGX530) && (SGX_CORE_REV == 125)
40#define SGX_OCP_REGS_ENABLED
41#endif
42
43SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
44SYS_DATA gsSysData;
45
46static SYS_SPECIFIC_DATA gsSysSpecificData;
47SYS_SPECIFIC_DATA *gpsSysSpecificData;
48
49static IMG_UINT32 gui32SGXDeviceID;
50static SGX_DEVICE_MAP gsSGXDeviceMap;
51static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
52
53#define DEVICE_SGX_INTERRUPT (1 << 0)
54
55#if defined(NO_HARDWARE)
56static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;
57#endif
58
59IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
60 IMG_BYTE *pInBuf,
61 IMG_UINT32 InBufLen,
62 IMG_BYTE *pOutBuf,
63 IMG_UINT32 OutBufLen,
64 IMG_UINT32 *pdwBytesTransferred);
65
66#if defined(DEBUG) && defined(DUMP_OMAP34xx_CLOCKS) && defined(__linux__)
67
68#pragma GCC diagnostic ignored "-Wstrict-prototypes"
69#include <mach/clock.h>
70
71#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
72#include <../mach-omap2/clock_34xx.h>
73#define ONCHIP_CLKS onchip_clks
74#else
75#include <../mach-omap2/clock34xx.h>
76#define ONCHIP_CLKS onchip_34xx_clks
77#endif
78
79static void omap3_clk_recalc(struct clk *clk) {}
80static void omap3_followparent_recalc(struct clk *clk) {}
81static void omap3_propagate_rate(struct clk *clk) {}
82static void omap3_table_recalc(struct clk *clk) {}
83static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate) { return 0; }
84static int omap3_select_table_rate(struct clk *clk, unsigned long rate) { return 0; }
85
86#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
87static void omap3_dpll_recalc(struct clk *clk, unsigned long parent_rate,
88 u8 rate_storage) {}
89static void omap3_clkoutx2_recalc(struct clk *clk, unsigned long parent_rate,
90 u8 rate_storage) {}
91static void omap3_dpll_allow_idle(struct clk *clk) {}
92static void omap3_dpll_deny_idle(struct clk *clk) {}
93static u32 omap3_dpll_autoidle_read(struct clk *clk) { return 0; }
94static int omap3_noncore_dpll_enable(struct clk *clk) { return 0; }
95static void omap3_noncore_dpll_disable(struct clk *clk) {}
96static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) { return 0; }
97static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) { return 0; }
98void followparent_recalc(struct clk *clk, unsigned long new_parent_rate,
99 u8 rate_storage) {}
100long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) { return 0; }
101void omap2_clksel_recalc(struct clk *clk, unsigned long new_parent_rate,
102 u8 rate_storage) {}
103long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) { return 0; }
104int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { return 0; }
105void omap2_fixed_divisor_recalc(struct clk *clk, unsigned long new_parent_rate,
106 u8 rate_storage) {}
107void omap2_init_clksel_parent(struct clk *clk) {}
108#endif
109
110static void dump_omap34xx_clocks(void)
111{
112 struct clk **c;
113#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
114 struct vdd_prcm_config *t1 = vdd1_rate_table;
115 struct vdd_prcm_config *t2 = vdd2_rate_table;
116
117 t1 = t1;
118 t2 = t2;
119#else
120
121 omap3_dpll_allow_idle(0);
122 omap3_dpll_deny_idle(0);
123 omap3_dpll_autoidle_read(0);
124 omap3_clk_recalc(0);
125 omap3_followparent_recalc(0);
126 omap3_propagate_rate(0);
127 omap3_table_recalc(0);
128 omap3_round_to_table_rate(0, 0);
129 omap3_select_table_rate(0, 0);
130#endif
131
132 for(c = ONCHIP_CLKS; c < ONCHIP_CLKS + ARRAY_SIZE(ONCHIP_CLKS); c++)
133 {
134 struct clk *cp = *c, *copy;
135 unsigned long rate;
136 copy = clk_get(NULL, cp->name);
137 if(!copy)
138 continue;
139 rate = clk_get_rate(copy);
140 if (rate < 1000000)
141 {
142 PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu KHz (%lu Hz)", __func__, cp->name, rate/1000, rate));
143 }
144 else
145 {
146 PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu MHz (%lu Hz)", __func__, cp->name, rate/1000000, rate));
147 }
148 }
149}
150
151#else
152
153static INLINE void dump_omap34xx_clocks(void) {}
154
155#endif
156
157#if defined(SGX_OCP_REGS_ENABLED)
158
159#define SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE (SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE + EUR_CR_OCP_REVISION)
160#define SYS_OMAP3430_OCP_REGS_SIZE 0x110
161
162static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
163
164static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
165{
166 PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
167
168 if(eError == PVRSRV_OK)
169 {
170 OSWriteHWReg(gpvOCPRegsLinAddr,
171 EUR_CR_OCP_DEBUG_CONFIG - EUR_CR_OCP_REVISION,
172 EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
173 }
174
175 return eError;
176}
177
178#else
179
180static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
181{
182 return EnableSGXClocks(psSysData);
183}
184
185#endif
186
187static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
188{
189 PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
190
191#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
192 if(eError == PVRSRV_OK)
193 {
194
195 EnableSGXClocksWrap(psSysData);
196 }
197#endif
198
199 return eError;
200}
201
202static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
203{
204#if defined(NO_HARDWARE)
205 PVRSRV_ERROR eError;
206 IMG_CPU_PHYADDR sCpuPAddr;
207#endif
208
209 PVR_UNREFERENCED_PARAMETER(psSysData);
210
211
212 gsSGXDeviceMap.ui32Flags = 0x0;
213
214#if defined(NO_HARDWARE)
215
216
217 eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE,
218 &gsSGXRegsCPUVAddr,
219 &sCpuPAddr);
220 if(eError != PVRSRV_OK)
221 {
222 return eError;
223 }
224 gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
225 gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
226 gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
227#if defined(__linux__)
228
229 gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
230#else
231
232 gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;
233#endif
234
235 OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE);
236
237
238
239
240 gsSGXDeviceMap.ui32IRQ = 0;
241
242#else
243
244 gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;
245 gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
246 gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
247
248 gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;
249
250#endif
251
252#if defined(PDUMP)
253 {
254 static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
255 gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
256 }
257#endif
258
259
260 return PVRSRV_OK;
261}
262
263
264IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)
265{
266 static IMG_CHAR aszVersionString[100];
267 SYS_DATA *psSysData;
268 IMG_UINT32 ui32SGXRevision;
269 IMG_INT32 i32Count;
270#if !defined(NO_HARDWARE)
271 IMG_VOID *pvRegsLinAddr;
272
273 pvRegsLinAddr = OSMapPhysToLin(sRegRegion,
274 SYS_OMAP3430_SGX_REGS_SIZE,
275 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
276 IMG_NULL);
277 if(!pvRegsLinAddr)
278 {
279 return IMG_NULL;
280 }
281
282 ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),
283 EUR_CR_CORE_REVISION);
284#else
285 ui32SGXRevision = 0;
286#endif
287
288 SysAcquireData(&psSysData);
289
290 i32Count = OSSNPrintf(aszVersionString, 100,
291 "SGX revision = %u.%u.%u",
292 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
293 >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
294 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
295 >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
296 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
297 >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
298 );
299
300#if !defined(NO_HARDWARE)
301 OSUnMapPhysToLin(pvRegsLinAddr,
302 SYS_OMAP3430_SGX_REGS_SIZE,
303 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
304 IMG_NULL);
305#endif
306
307 if(i32Count == -1)
308 {
309 return IMG_NULL;
310 }
311
312 return aszVersionString;
313}
314
315
316PVRSRV_ERROR SysInitialise(IMG_VOID)
317{
318 IMG_UINT32 i;
319 PVRSRV_ERROR eError;
320 PVRSRV_DEVICE_NODE *psDeviceNode;
321 IMG_CPU_PHYADDR TimerRegPhysBase;
322#if !defined(SGX_DYNAMIC_TIMING_INFO)
323 SGX_TIMING_INFORMATION* psTimingInfo;
324#endif
325 gpsSysData = &gsSysData;
326 OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
327
328 gpsSysSpecificData = &gsSysSpecificData;
329 OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));
330
331 gpsSysData->pvSysSpecificData = gpsSysSpecificData;
332
333 eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
334 if (eError != PVRSRV_OK)
335 {
336 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
337 (IMG_VOID)SysDeinitialise(gpsSysData);
338 gpsSysData = IMG_NULL;
339 return eError;
340 }
341 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);
342
343 gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
344
345
346 for(i=0; i<SYS_DEVICE_COUNT; i++)
347 {
348 gpsSysData->sDeviceID[i].uiID = i;
349 gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
350 }
351
352 gpsSysData->psDeviceNodeList = IMG_NULL;
353 gpsSysData->psQueueList = IMG_NULL;
354
355 eError = SysInitialiseCommon(gpsSysData);
356 if (eError != PVRSRV_OK)
357 {
358 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));
359 (IMG_VOID)SysDeinitialise(gpsSysData);
360 gpsSysData = IMG_NULL;
361 return eError;
362 }
363
364 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
365 gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
366 gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
367 OSReservePhys(TimerRegPhysBase,
368 4,
369 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
370 (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
371 &gpsSysData->hSOCTimerRegisterOSMemHandle);
372
373#if !defined(SGX_DYNAMIC_TIMING_INFO)
374
375 psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
376 psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
377 psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
378#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
379 psTimingInfo->bEnableActivePM = IMG_TRUE;
380#else
381 psTimingInfo->bEnableActivePM = IMG_FALSE;
382#endif
383 psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
384 psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
385#endif
386
387
388
389 gpsSysSpecificData->ui32SrcClockDiv = 3;
390
391
392
393
394
395 eError = SysLocateDevices(gpsSysData);
396 if (eError != PVRSRV_OK)
397 {
398 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
399 (IMG_VOID)SysDeinitialise(gpsSysData);
400 gpsSysData = IMG_NULL;
401 return eError;
402 }
403 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
404
405#if defined(SGX_OCP_REGS_ENABLED)
406 {
407 IMG_SYS_PHYADDR sOCPRegsSysPBase;
408 IMG_CPU_PHYADDR sOCPRegsCpuPBase;
409
410 sOCPRegsSysPBase.uiAddr = SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE;
411 sOCPRegsCpuPBase = SysSysPAddrToCpuPAddr(sOCPRegsSysPBase);
412
413 gpvOCPRegsLinAddr = OSMapPhysToLin(sOCPRegsCpuPBase,
414 SYS_OMAP3430_OCP_REGS_SIZE,
415 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
416 IMG_NULL);
417
418 if (gpvOCPRegsLinAddr == IMG_NULL)
419 {
420 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to map OCP registers"));
421 return PVRSRV_ERROR_BAD_MAPPING;
422 }
423 }
424#endif
425
426
427
428
429 eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
430 DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
431 if (eError != PVRSRV_OK)
432 {
433 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
434 (IMG_VOID)SysDeinitialise(gpsSysData);
435 gpsSysData = IMG_NULL;
436 return eError;
437 }
438 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);
439
440
441
442
443
444 psDeviceNode = gpsSysData->psDeviceNodeList;
445 while(psDeviceNode)
446 {
447
448 switch(psDeviceNode->sDevId.eDeviceType)
449 {
450 case PVRSRV_DEVICE_TYPE_SGX:
451 {
452 DEVICE_MEMORY_INFO *psDevMemoryInfo;
453 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
454
455
456
457
458 psDeviceNode->psLocalDevMemArena = IMG_NULL;
459
460
461 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
462 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
463
464
465 for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
466 {
467 psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
468 }
469
470 gpsSGXDevNode = psDeviceNode;
471 gsSysSpecificData.psSGXDevNode = psDeviceNode;
472
473 break;
474 }
475 default:
476 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));
477 return PVRSRV_ERROR_INIT_FAILURE;
478 }
479
480
481 psDeviceNode = psDeviceNode->psNext;
482 }
483
484 eError = EnableSystemClocksWrap(gpsSysData);
485 if (eError != PVRSRV_OK)
486 {
487 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError));
488 (IMG_VOID)SysDeinitialise(gpsSysData);
489 gpsSysData = IMG_NULL;
490 return eError;
491 }
492 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
493#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
494 eError = EnableSGXClocksWrap(gpsSysData);
495 if (eError != PVRSRV_OK)
496 {
497 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
498 (IMG_VOID)SysDeinitialise(gpsSysData);
499 gpsSysData = IMG_NULL;
500 return eError;
501 }
502#endif
503
504 dump_omap34xx_clocks();
505
506 eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);
507 if (eError != PVRSRV_OK)
508 {
509 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
510 (IMG_VOID)SysDeinitialise(gpsSysData);
511 gpsSysData = IMG_NULL;
512 return eError;
513 }
514 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV);
515
516#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
517
518 DisableSGXClocks(gpsSysData);
519#endif
520
521 return PVRSRV_OK;
522}
523
524
525PVRSRV_ERROR SysFinalise(IMG_VOID)
526{
527 PVRSRV_ERROR eError = PVRSRV_OK;
528
529#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
530 eError = EnableSGXClocksWrap(gpsSysData);
531 if (eError != PVRSRV_OK)
532 {
533 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
534 (IMG_VOID)SysDeinitialise(gpsSysData);
535 gpsSysData = IMG_NULL;
536 return eError;
537 }
538#endif
539
540#if defined(SYS_USING_INTERRUPTS)
541
542 eError = OSInstallMISR(gpsSysData);
543 if (eError != PVRSRV_OK)
544 {
545 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR"));
546 (IMG_VOID)SysDeinitialise(gpsSysData);
547 gpsSysData = IMG_NULL;
548 return eError;
549 }
550 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR);
551
552
553 eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);
554 if (eError != PVRSRV_OK)
555 {
556 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR"));
557 (IMG_VOID)SysDeinitialise(gpsSysData);
558 gpsSysData = IMG_NULL;
559 return eError;
560 }
561 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
562#endif
563
564
565 gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);
566 if (!gpsSysData->pszVersionString)
567 {
568 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));
569 }
570 else
571 {
572 PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
573 }
574
575#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
576
577 DisableSGXClocks(gpsSysData);
578#endif
579
580 gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;
581
582 return eError;
583}
584
585
586PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
587{
588 PVRSRV_ERROR eError;
589
590#if defined(SYS_USING_INTERRUPTS)
591 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
592 {
593 eError = OSUninstallDeviceLISR(psSysData);
594 if (eError != PVRSRV_OK)
595 {
596 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed"));
597 return eError;
598 }
599 }
600
601 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR))
602 {
603 eError = OSUninstallMISR(psSysData);
604 if (eError != PVRSRV_OK)
605 {
606 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));
607 return eError;
608 }
609 }
610#else
611 PVR_UNREFERENCED_PARAMETER(psSysData);
612#endif
613
614 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV))
615 {
616#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
617 PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));
618
619 eError = EnableSGXClocksWrap(gpsSysData);
620 if (eError != PVRSRV_OK)
621 {
622 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed"));
623 return eError;
624 }
625#endif
626
627
628 eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID);
629 if (eError != PVRSRV_OK)
630 {
631 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));
632 return eError;
633 }
634 }
635
636#if defined(SGX_OCP_REGS_ENABLED)
637 OSUnMapPhysToLin(gpvOCPRegsLinAddr,
638 SYS_OMAP3430_OCP_REGS_SIZE,
639 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
640 IMG_NULL);
641#endif
642
643
644
645 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))
646 {
647 DisableSystemClocks(gpsSysData);
648 }
649
650 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA))
651 {
652 eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);
653 if (eError != PVRSRV_OK)
654 {
655 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));
656 return eError;
657 }
658 }
659
660 if(gpsSysData->pvSOCTimerRegisterKM)
661 {
662 OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
663 4,
664 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
665 gpsSysData->hSOCTimerRegisterOSMemHandle);
666 }
667
668 SysDeinitialiseCommon(gpsSysData);
669
670#if defined(NO_HARDWARE)
671 if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))
672 {
673
674 OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);
675 }
676#endif
677
678
679 gpsSysSpecificData->ui32SysSpecificData = 0;
680 gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;
681
682 gpsSysData = IMG_NULL;
683
684 return PVRSRV_OK;
685}
686
687
688PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
689 IMG_VOID **ppvDeviceMap)
690{
691
692 switch(eDeviceType)
693 {
694 case PVRSRV_DEVICE_TYPE_SGX:
695 {
696
697 *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
698
699 break;
700 }
701 default:
702 {
703 PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
704 }
705 }
706 return PVRSRV_OK;
707}
708
709
710IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
711 IMG_CPU_PHYADDR CpuPAddr)
712{
713 IMG_DEV_PHYADDR DevPAddr;
714
715 PVR_UNREFERENCED_PARAMETER(eDeviceType);
716
717
718 DevPAddr.uiAddr = CpuPAddr.uiAddr;
719
720 return DevPAddr;
721}
722
723IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
724{
725 IMG_CPU_PHYADDR cpu_paddr;
726
727
728 cpu_paddr.uiAddr = sys_paddr.uiAddr;
729 return cpu_paddr;
730}
731
732IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
733{
734 IMG_SYS_PHYADDR sys_paddr;
735
736
737 sys_paddr.uiAddr = cpu_paddr.uiAddr;
738 return sys_paddr;
739}
740
741
742IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
743{
744 IMG_DEV_PHYADDR DevPAddr;
745
746 PVR_UNREFERENCED_PARAMETER(eDeviceType);
747
748
749 DevPAddr.uiAddr = SysPAddr.uiAddr;
750
751 return DevPAddr;
752}
753
754
755IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
756{
757 IMG_SYS_PHYADDR SysPAddr;
758
759 PVR_UNREFERENCED_PARAMETER(eDeviceType);
760
761
762 SysPAddr.uiAddr = DevPAddr.uiAddr;
763
764 return SysPAddr;
765}
766
767
768IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
769{
770 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
771}
772
773
774IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
775{
776 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
777}
778
779
780IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
781 PVRSRV_DEVICE_NODE *psDeviceNode)
782{
783 PVR_UNREFERENCED_PARAMETER(psSysData);
784#if defined(NO_HARDWARE)
785
786 return 0xFFFFFFFF;
787#else
788
789 return psDeviceNode->ui32SOCInterruptBit;
790#endif
791}
792
793
794IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
795{
796 PVR_UNREFERENCED_PARAMETER(psSysData);
797 PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
798
799
800 OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM,
801 EUR_CR_EVENT_HOST_CLEAR);
802}
803
804
805PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
806{
807 PVRSRV_ERROR eError = PVRSRV_OK;
808
809 if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3)
810 {
811 PVR_TRACE(("SysSystemPrePowerState: Entering state D3"));
812
813#if defined(SYS_USING_INTERRUPTS)
814 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
815 {
816#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
817 IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);
818#endif
819 eError = OSUninstallDeviceLISR(gpsSysData);
820#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
821 if (bWrapped)
822 {
823 UnwrapSystemPowerChange(&gsSysSpecificData);
824 }
825#endif
826 if (eError != PVRSRV_OK)
827 {
828 PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError));
829 return eError;
830 }
831 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
832 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
833 }
834#endif
835
836 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))
837 {
838 DisableSystemClocks(gpsSysData);
839
840 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
841 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
842 }
843 }
844
845 return eError;
846}
847
848
849PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
850{
851 PVRSRV_ERROR eError = PVRSRV_OK;
852
853 if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0)
854 {
855 PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));
856
857 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS))
858 {
859 eError = EnableSystemClocksWrap(gpsSysData);
860 if (eError != PVRSRV_OK)
861 {
862 PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError));
863 return eError;
864 }
865 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
866 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
867 }
868
869#if defined(SYS_USING_INTERRUPTS)
870 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR))
871 {
872#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
873 IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);
874#endif
875
876 eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);
877#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
878 if (bWrapped)
879 {
880 UnwrapSystemPowerChange(&gsSysSpecificData);
881 }
882#endif
883 if (eError != PVRSRV_OK)
884 {
885 PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError));
886 return eError;
887 }
888 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
889 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
890 }
891#endif
892 }
893 return eError;
894}
895
896
897PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
898 PVRSRV_DEV_POWER_STATE eNewPowerState,
899 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
900{
901 PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
902
903 if (ui32DeviceIndex != gui32SGXDeviceID)
904 {
905 return PVRSRV_OK;
906 }
907
908#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
909 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
910 {
911 PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));
912 DisableSGXClocks(gpsSysData);
913 }
914#else
915 PVR_UNREFERENCED_PARAMETER(eNewPowerState );
916#endif
917 return PVRSRV_OK;
918}
919
920
921PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
922 PVRSRV_DEV_POWER_STATE eNewPowerState,
923 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
924{
925 PVRSRV_ERROR eError = PVRSRV_OK;
926
927 PVR_UNREFERENCED_PARAMETER(eNewPowerState);
928
929 if (ui32DeviceIndex != gui32SGXDeviceID)
930 {
931 return eError;
932 }
933
934#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
935 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
936 {
937 PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));
938 eError = EnableSGXClocksWrap(gpsSysData);
939 }
940#else
941 PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
942#endif
943
944 return eError;
945}
946
947
948PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID,
949 IMG_VOID *pvIn,
950 IMG_UINT32 ulInSize,
951 IMG_VOID *pvOut,
952 IMG_UINT32 ulOutSize)
953{
954 PVR_UNREFERENCED_PARAMETER(ui32ID);
955 PVR_UNREFERENCED_PARAMETER(pvIn);
956 PVR_UNREFERENCED_PARAMETER(ulInSize);
957 PVR_UNREFERENCED_PARAMETER(pvOut);
958 PVR_UNREFERENCED_PARAMETER(ulOutSize);
959
960 if ((ui32ID == OEM_GET_EXT_FUNCS) &&
961 (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))
962 {
963
964 PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut;
965 psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;
966 return PVRSRV_OK;
967 }
968
969 return PVRSRV_ERROR_INVALID_PARAMS;
970}
diff --git a/drivers/gpu/pvr/omap3/sysconfig.h b/drivers/gpu/pvr/omap3/sysconfig.h
new file mode 100644
index 00000000000..dd8a07d988d
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/sysconfig.h
@@ -0,0 +1,59 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SOCCONFIG_H__)
28#define __SOCCONFIG_H__
29
30#include "syscommon.h"
31
32#define VS_PRODUCT_NAME "OMAP3"
33
34#if defined(SGX530) && (SGX_CORE_REV == 125)
35#define SYS_SGX_CLOCK_SPEED 200000000
36#else
37#define SYS_SGX_CLOCK_SPEED 110666666
38#endif
39
40#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100)
41#define SYS_SGX_PDS_TIMER_FREQ (1000)
42
43#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS)
44#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (1)
45#endif
46
47
48#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE 0x50000000
49
50#define SYS_OMAP3430_SGX_REGS_SIZE 0x4000
51
52#define SYS_OMAP3430_SGX_IRQ 21
53
54#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024
55#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028
56#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040
57
58
59#endif
diff --git a/drivers/gpu/pvr/omap3/sysinfo.h b/drivers/gpu/pvr/omap3/sysinfo.h
new file mode 100644
index 00000000000..07718276b8d
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/sysinfo.h
@@ -0,0 +1,40 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SYSINFO_H__)
28#define __SYSINFO_H__
29
30#if defined(PVR_LINUX_USING_WORKQUEUES)
31#define MAX_HW_TIME_US (1000000)
32#else
33#define MAX_HW_TIME_US (500000)
34#endif
35
36#define WAIT_TRY_COUNT (10000)
37
38#define SYS_DEVICE_COUNT 3
39
40#endif
diff --git a/drivers/gpu/pvr/omap3/syslocal.h b/drivers/gpu/pvr/omap3/syslocal.h
new file mode 100644
index 00000000000..351ed695275
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/syslocal.h
@@ -0,0 +1,135 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SYSLOCAL_H__)
28#define __SYSLOCAL_H__
29
30#if defined(__linux__)
31
32#include <linux/version.h>
33#include <linux/clk.h>
34#if defined(PVR_LINUX_USING_WORKQUEUES)
35#include <linux/mutex.h>
36#else
37#include <linux/spinlock.h>
38#endif
39#include <asm/atomic.h>
40
41#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
42#include <linux/semaphore.h>
43#include <linux/resource.h>
44#else
45#include <asm/semaphore.h>
46#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
47#include <asm/arch/resource.h>
48#endif
49#endif
50
51#endif
52
53#if defined (__cplusplus)
54extern "C" {
55#endif
56
57
58
59IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion);
60
61IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);
62PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);
63
64IMG_VOID DisableSGXClocks(SYS_DATA *psSysData);
65PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);
66
67#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001
68#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002
69#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004
70#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008
71#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010
72#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020
73#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040
74#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080
75#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100
76
77#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200
78#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400
79
80#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))
81
82#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))
83
84#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)
85
86typedef struct _SYS_SPECIFIC_DATA_TAG_
87{
88 IMG_UINT32 ui32SysSpecificData;
89 PVRSRV_DEVICE_NODE *psSGXDevNode;
90 IMG_BOOL bSGXInitComplete;
91#if !defined(__linux__)
92 IMG_BOOL bSGXClocksEnabled;
93#endif
94 IMG_UINT32 ui32SrcClockDiv;
95#if defined(__linux__)
96 IMG_BOOL bSysClocksOneTimeInit;
97 atomic_t sSGXClocksEnabled;
98#if defined(PVR_LINUX_USING_WORKQUEUES)
99 struct mutex sPowerLock;
100#else
101 IMG_BOOL bConstraintNotificationsEnabled;
102 spinlock_t sPowerLock;
103 atomic_t sPowerLockCPU;
104 spinlock_t sNotifyLock;
105 atomic_t sNotifyLockCPU;
106 IMG_BOOL bCallVDD2PostFunc;
107#endif
108 struct clk *psCORE_CK;
109 struct clk *psSGX_FCK;
110 struct clk *psSGX_ICK;
111 struct clk *psMPU_CK;
112#if defined(DEBUG) || defined(TIMING)
113 struct clk *psGPT11_FCK;
114 struct clk *psGPT11_ICK;
115#endif
116#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
117 struct constraint_handle *pVdd2Handle;
118#endif
119#endif
120} SYS_SPECIFIC_DATA;
121
122extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
123
124#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
125IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
126IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
127#endif
128
129#if defined(__cplusplus)
130}
131#endif
132
133#endif
134
135
diff --git a/drivers/gpu/pvr/omap3/sysutils.c b/drivers/gpu/pvr/omap3/sysutils.c
new file mode 100644
index 00000000000..d2c4231315c
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/sysutils.c
@@ -0,0 +1,33 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(__linux__)
28#if defined(PVR_LINUX_USING_WORKQUEUES)
29#include "sysutils_linux_wqueue_compat.c"
30#else
31#include "sysutils_linux.c"
32#endif
33#endif
diff --git a/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c b/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c
new file mode 100644
index 00000000000..93c5b7c5b3a
--- /dev/null
+++ b/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c
@@ -0,0 +1,489 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <linux/version.h>
28#include <linux/clk.h>
29#include <linux/err.h>
30#include <linux/hardirq.h>
31#include <linux/mutex.h>
32#include <linux/platform_device.h>
33#include <plat/omap-pm.h>
34
35#include "sgxdefs.h"
36#include "services_headers.h"
37#include "sysinfo.h"
38#include "sgxapi_km.h"
39#include "sysconfig.h"
40#include "sgxinfokm.h"
41#include "syslocal.h"
42
43#if !defined(PVR_LINUX_USING_WORKQUEUES)
44#error "PVR_LINUX_USING_WORKQUEUES must be defined"
45#endif
46
47#define ONE_MHZ 1000000
48#define HZ_TO_MHZ(m) ((m) / ONE_MHZ)
49
50#if defined(SUPPORT_OMAP3430_SGXFCLK_96M)
51#define SGX_PARENT_CLOCK "cm_96m_fck"
52#else
53#define SGX_PARENT_CLOCK "core_ck"
54#endif
55
56extern struct platform_device *gpsPVRLDMDev;
57
58static PVRSRV_ERROR ForceMaxSGXClocks(SYS_SPECIFIC_DATA *psSysSpecData)
59{
60 PVR_UNREFERENCED_PARAMETER(psSysSpecData);
61
62 /* Pin the memory bus bw to the highest value according to CORE_REV */
63#if defined(SGX530) && (SGX_CORE_REV == 125)
64 omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 800000);
65#else
66 omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 664000);
67#endif
68 return PVRSRV_OK;
69}
70
71static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData)
72{
73 if (!in_interrupt())
74 {
75 BUG_ON(in_atomic());
76 mutex_lock(&psSysSpecData->sPowerLock);
77
78 }
79}
80
81static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData)
82{
83 if (!in_interrupt())
84 {
85 BUG_ON(in_atomic());
86 mutex_unlock(&psSysSpecData->sPowerLock);
87 }
88}
89
90PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData)
91{
92 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
93
94 PowerLockWrap(psSysSpecData);
95
96 return PVRSRV_OK;
97}
98
99IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData)
100{
101 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
102
103 PowerLockUnwrap(psSysSpecData);
104}
105
106IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
107{
108 return IMG_TRUE;
109}
110
111IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
112{
113}
114
115static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2)
116{
117 if (rate1 >= rate2)
118 {
119 return val * (rate1 / rate2);
120 }
121
122 return val / (rate2 / rate1);
123}
124
125static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)
126{
127 return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED);
128}
129
130static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)
131{
132 return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate);
133}
134
135IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)
136{
137 IMG_UINT32 rate;
138
139#if defined(NO_HARDWARE)
140 rate = SYS_SGX_CLOCK_SPEED;
141#else
142 PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);
143
144 rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);
145 PVR_ASSERT(rate != 0);
146#endif
147 psTimingInfo->ui32CoreClockSpeed = rate;
148 psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);
149 psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate);
150#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
151 psTimingInfo->bEnableActivePM = IMG_TRUE;
152#else
153 psTimingInfo->bEnableActivePM = IMG_FALSE;
154#endif
155 psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
156}
157
158PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
159{
160#if !defined(NO_HARDWARE)
161 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
162 long lNewRate;
163 long lRate;
164 IMG_INT res;
165
166 if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)
167 {
168 return PVRSRV_OK;
169 }
170
171 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));
172
173#if defined(DEBUG)
174 {
175 IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK);
176 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate)));
177 }
178#endif
179
180 res = clk_enable(psSysSpecData->psSGX_FCK);
181 if (res < 0)
182 {
183 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));
184 return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
185 }
186
187 res = clk_enable(psSysSpecData->psSGX_ICK);
188 if (res < 0)
189 {
190 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res));
191
192 clk_disable(psSysSpecData->psSGX_FCK);
193 return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
194 }
195
196 lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);
197 if (lNewRate <= 0)
198 {
199 PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));
200 return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE;
201 }
202
203 lRate = clk_get_rate(psSysSpecData->psSGX_FCK);
204 if (lRate != lNewRate)
205 {
206 res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);
207 if (res < 0)
208 {
209 PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res));
210 }
211 }
212
213#if defined(DEBUG)
214 {
215 IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);
216 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));
217 }
218#endif
219
220 ForceMaxSGXClocks(psSysSpecData);
221
222 atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
223
224#else /* !defined(NO_HARDWARE) */
225 PVR_UNREFERENCED_PARAMETER(psSysData);
226#endif /* !defined(NO_HARDWARE) */
227 return PVRSRV_OK;
228}
229
230
231IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
232{
233#if !defined(NO_HARDWARE)
234 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
235
236 if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)
237 {
238 return;
239 }
240
241 PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
242
243 if (psSysSpecData->psSGX_ICK)
244 {
245 clk_disable(psSysSpecData->psSGX_ICK);
246 }
247
248 if (psSysSpecData->psSGX_FCK)
249 {
250 clk_disable(psSysSpecData->psSGX_FCK);
251 }
252
253 omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 0);
254
255 atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
256
257#else
258 PVR_UNREFERENCED_PARAMETER(psSysData);
259#endif
260}
261
262PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
263{
264 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
265 struct clk *psCLK;
266 IMG_INT res;
267 PVRSRV_ERROR eError;
268
269#if defined(DEBUG) || defined(TIMING)
270 IMG_INT rate;
271 struct clk *sys_ck;
272 IMG_CPU_PHYADDR TimerRegPhysBase;
273 IMG_HANDLE hTimerEnable;
274 IMG_UINT32 *pui32TimerEnable;
275
276#endif
277
278 PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));
279
280 if (!psSysSpecData->bSysClocksOneTimeInit)
281 {
282 mutex_init(&psSysSpecData->sPowerLock);
283
284 atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
285
286 psCLK = clk_get(NULL, SGX_PARENT_CLOCK);
287 if (IS_ERR(psCLK))
288 {
289 PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));
290 goto ExitError;
291 }
292 psSysSpecData->psCORE_CK = psCLK;
293
294 psCLK = clk_get(NULL, "sgx_fck");
295 if (IS_ERR(psCLK))
296 {
297 PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));
298 goto ExitError;
299 }
300 psSysSpecData->psSGX_FCK = psCLK;
301
302 psCLK = clk_get(NULL, "sgx_ick");
303 if (IS_ERR(psCLK))
304 {
305 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));
306 goto ExitError;
307 }
308 psSysSpecData->psSGX_ICK = psCLK;
309
310#if defined(DEBUG)
311 psCLK = clk_get(NULL, "mpu_ck");
312 if (IS_ERR(psCLK))
313 {
314 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock"));
315 goto ExitError;
316 }
317 psSysSpecData->psMPU_CK = psCLK;
318#endif
319 res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK);
320 if (res < 0)
321 {
322 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));
323 goto ExitError;
324 }
325
326 psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
327 }
328
329#if defined(DEBUG) || defined(TIMING)
330
331 psCLK = clk_get(NULL, "gpt11_fck");
332 if (IS_ERR(psCLK))
333 {
334 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
335 goto ExitUnRegisterConstraintNotifications;
336 }
337 psSysSpecData->psGPT11_FCK = psCLK;
338
339 psCLK = clk_get(NULL, "gpt11_ick");
340 if (IS_ERR(psCLK))
341 {
342 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
343 goto ExitUnRegisterConstraintNotifications;
344 }
345 psSysSpecData->psGPT11_ICK = psCLK;
346
347 sys_ck = clk_get(NULL, "sys_ck");
348 if (IS_ERR(sys_ck))
349 {
350 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));
351 goto ExitUnRegisterConstraintNotifications;
352 }
353
354 if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)
355 {
356 PVR_TRACE(("Setting GPTIMER11 parent to System Clock"));
357 res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);
358 if (res < 0)
359 {
360 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));
361 goto ExitUnRegisterConstraintNotifications;
362 }
363 }
364
365 rate = clk_get_rate(psSysSpecData->psGPT11_FCK);
366 PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));
367
368 res = clk_enable(psSysSpecData->psGPT11_FCK);
369 if (res < 0)
370 {
371 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
372 goto ExitUnRegisterConstraintNotifications;
373 }
374
375 res = clk_enable(psSysSpecData->psGPT11_ICK);
376 if (res < 0)
377 {
378 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
379 goto ExitDisableGPT11FCK;
380 }
381
382
383 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;
384 pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
385 4,
386 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
387 &hTimerEnable);
388
389 if (pui32TimerEnable == IMG_NULL)
390 {
391 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
392 goto ExitDisableGPT11ICK;
393 }
394
395 rate = *pui32TimerEnable;
396 if(!(rate & 4))
397 {
398 PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));
399
400
401 *pui32TimerEnable = rate | 4;
402 }
403
404 OSUnMapPhysToLin(pui32TimerEnable,
405 4,
406 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
407 hTimerEnable);
408
409
410 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
411 pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
412 4,
413 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
414 &hTimerEnable);
415
416 if (pui32TimerEnable == IMG_NULL)
417 {
418 PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
419 goto ExitDisableGPT11ICK;
420 }
421
422
423 *pui32TimerEnable = 3;
424
425 OSUnMapPhysToLin(pui32TimerEnable,
426 4,
427 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
428 hTimerEnable);
429
430#endif
431
432 eError = PVRSRV_OK;
433 goto Exit;
434
435#if defined(DEBUG) || defined(TIMING)
436ExitDisableGPT11ICK:
437 clk_disable(psSysSpecData->psGPT11_ICK);
438ExitDisableGPT11FCK:
439 clk_disable(psSysSpecData->psGPT11_FCK);
440ExitUnRegisterConstraintNotifications:
441#endif
442ExitError:
443 eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE;
444Exit:
445 return eError;
446}
447
448IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
449{
450#if defined(DEBUG) || defined(TIMING)
451 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
452 IMG_CPU_PHYADDR TimerRegPhysBase;
453 IMG_HANDLE hTimerDisable;
454 IMG_UINT32 *pui32TimerDisable;
455#endif
456
457 PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));
458
459
460 DisableSGXClocks(psSysData);
461
462#if defined(DEBUG) || defined(TIMING)
463
464 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
465 pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
466 4,
467 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
468 &hTimerDisable);
469
470 if (pui32TimerDisable == IMG_NULL)
471 {
472 PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
473 }
474 else
475 {
476 *pui32TimerDisable = 0;
477
478 OSUnMapPhysToLin(pui32TimerDisable,
479 4,
480 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
481 hTimerDisable);
482 }
483
484 clk_disable(psSysSpecData->psGPT11_ICK);
485
486 clk_disable(psSysSpecData->psGPT11_FCK);
487
488#endif
489}
diff --git a/drivers/gpu/pvr/omap4/oemfuncs.h b/drivers/gpu/pvr/omap4/oemfuncs.h
new file mode 100644
index 00000000000..d28356463cf
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/oemfuncs.h
@@ -0,0 +1,56 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__OEMFUNCS_H__)
28#define __OEMFUNCS_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl,
35 IMG_BYTE *pInBuf,
36 IMG_UINT32 InBufLen,
37 IMG_BYTE *pOutBuf,
38 IMG_UINT32 OutBufLen,
39 IMG_UINT32 *pdwBytesTransferred);
40typedef struct PVRSRV_DC_OEM_JTABLE_TAG
41{
42 PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch;
43 IMG_PVOID pvDummy1;
44 IMG_PVOID pvDummy2;
45 IMG_PVOID pvDummy3;
46
47} PVRSRV_DC_OEM_JTABLE;
48
49#define OEM_GET_EXT_FUNCS (1<<1)
50
51#if defined(__cplusplus)
52}
53#endif
54
55#endif
56
diff --git a/drivers/gpu/pvr/omap4/sysconfig.c b/drivers/gpu/pvr/omap4/sysconfig.c
new file mode 100644
index 00000000000..3b4955445b7
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/sysconfig.c
@@ -0,0 +1,978 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "kerneldisplay.h"
29#include "oemfuncs.h"
30#include "sgxinfo.h"
31#include "sgxinfokm.h"
32#include "syslocal.h"
33#include "sysconfig.h"
34
35#include "ocpdefs.h"
36
37#if !defined(NO_HARDWARE) && \
38 defined(SYS_USING_INTERRUPTS) && \
39 defined(SGX540)
40#define SGX_OCP_REGS_ENABLED
41#endif
42
43SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
44SYS_DATA gsSysData;
45
46static SYS_SPECIFIC_DATA gsSysSpecificData;
47SYS_SPECIFIC_DATA *gpsSysSpecificData;
48
49static IMG_UINT32 gui32SGXDeviceID;
50static SGX_DEVICE_MAP gsSGXDeviceMap;
51static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
52
53#define DEVICE_SGX_INTERRUPT (1 << 0)
54
55#if defined(NO_HARDWARE)
56static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;
57#endif
58
59IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
60 IMG_BYTE *pInBuf,
61 IMG_UINT32 InBufLen,
62 IMG_BYTE *pOutBuf,
63 IMG_UINT32 OutBufLen,
64 IMG_UINT32 *pdwBytesTransferred);
65
66#if defined(DEBUG) && defined(DUMP_OMAP34xx_CLOCKS) && defined(__linux__)
67
68#pragma GCC diagnostic ignored "-Wstrict-prototypes"
69#include <mach/clock.h>
70
71#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
72#include <../mach-omap2/clock_34xx.h>
73#define ONCHIP_CLKS onchip_clks
74#else
75#include <../mach-omap2/clock34xx.h>
76#define ONCHIP_CLKS onchip_34xx_clks
77#endif
78
79static void omap3_clk_recalc(struct clk *clk) {}
80static void omap3_followparent_recalc(struct clk *clk) {}
81static void omap3_propagate_rate(struct clk *clk) {}
82static void omap3_table_recalc(struct clk *clk) {}
83static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate) { return 0; }
84static int omap3_select_table_rate(struct clk *clk, unsigned long rate) { return 0; }
85
86#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
87static void omap3_dpll_recalc(struct clk *clk, unsigned long parent_rate,
88 u8 rate_storage) {}
89static void omap3_clkoutx2_recalc(struct clk *clk, unsigned long parent_rate,
90 u8 rate_storage) {}
91static void omap3_dpll_allow_idle(struct clk *clk) {}
92static void omap3_dpll_deny_idle(struct clk *clk) {}
93static u32 omap3_dpll_autoidle_read(struct clk *clk) { return 0; }
94static int omap3_noncore_dpll_enable(struct clk *clk) { return 0; }
95static void omap3_noncore_dpll_disable(struct clk *clk) {}
96static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) { return 0; }
97static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) { return 0; }
98void followparent_recalc(struct clk *clk, unsigned long new_parent_rate,
99 u8 rate_storage) {}
100long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) { return 0; }
101void omap2_clksel_recalc(struct clk *clk, unsigned long new_parent_rate,
102 u8 rate_storage) {}
103long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) { return 0; }
104int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { return 0; }
105void omap2_fixed_divisor_recalc(struct clk *clk, unsigned long new_parent_rate,
106 u8 rate_storage) {}
107void omap2_init_clksel_parent(struct clk *clk) {}
108#endif
109
110static void dump_omap34xx_clocks(void)
111{
112 struct clk **c;
113#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
114 struct vdd_prcm_config *t1 = vdd1_rate_table;
115 struct vdd_prcm_config *t2 = vdd2_rate_table;
116
117 t1 = t1;
118 t2 = t2;
119#else
120
121 omap3_dpll_allow_idle(0);
122 omap3_dpll_deny_idle(0);
123 omap3_dpll_autoidle_read(0);
124 omap3_clk_recalc(0);
125 omap3_followparent_recalc(0);
126 omap3_propagate_rate(0);
127 omap3_table_recalc(0);
128 omap3_round_to_table_rate(0, 0);
129 omap3_select_table_rate(0, 0);
130#endif
131
132 for(c = ONCHIP_CLKS; c < ONCHIP_CLKS + ARRAY_SIZE(ONCHIP_CLKS); c++)
133 {
134 struct clk *cp = *c, *copy;
135 unsigned long rate;
136 copy = clk_get(NULL, cp->name);
137 if(!copy)
138 continue;
139 rate = clk_get_rate(copy);
140 if (rate < 1000000)
141 {
142 PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu KHz (%lu Hz)", __func__, cp->name, rate/1000, rate));
143 }
144 else
145 {
146 PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu MHz (%lu Hz)", __func__, cp->name, rate/1000000, rate));
147 }
148 }
149}
150
151#else
152
153static INLINE void dump_omap34xx_clocks(void) {}
154
155#endif
156
157#if defined(SGX_OCP_REGS_ENABLED)
158
159#define SYS_OMAP4430_OCP_REGS_SYS_PHYS_BASE (SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE + EUR_CR_OCP_REVISION)
160#define SYS_OMAP4430_OCP_REGS_SIZE 0x110
161
162static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
163
164static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
165{
166 PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
167
168 if(eError == PVRSRV_OK)
169 {
170 OSWriteHWReg(gpvOCPRegsLinAddr,
171 EUR_CR_OCP_DEBUG_CONFIG - EUR_CR_OCP_REVISION,
172 EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
173 }
174
175 return eError;
176}
177
178#else
179
180static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
181{
182 return EnableSGXClocks(psSysData);
183}
184
185#endif
186
187static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
188{
189 PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
190
191#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
192 if(eError == PVRSRV_OK)
193 {
194
195 EnableSGXClocksWrap(psSysData);
196 }
197#endif
198
199 return eError;
200}
201
202static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
203{
204#if defined(NO_HARDWARE)
205 PVRSRV_ERROR eError;
206 IMG_CPU_PHYADDR sCpuPAddr;
207#endif
208
209 PVR_UNREFERENCED_PARAMETER(psSysData);
210
211
212 gsSGXDeviceMap.ui32Flags = 0x0;
213
214#if defined(NO_HARDWARE)
215
216
217 eError = OSBaseAllocContigMemory(SYS_OMAP4430_SGX_REGS_SIZE,
218 &gsSGXRegsCPUVAddr,
219 &sCpuPAddr);
220 if(eError != PVRSRV_OK)
221 {
222 return eError;
223 }
224 gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
225 gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
226 gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE;
227#if defined(__linux__)
228
229 gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
230#else
231
232 gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;
233#endif
234
235 OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP4430_SGX_REGS_SIZE);
236
237
238
239
240 gsSGXDeviceMap.ui32IRQ = 0;
241
242#else
243
244 gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE;
245 gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
246 gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE;
247
248 gsSGXDeviceMap.ui32IRQ = SYS_OMAP4430_SGX_IRQ;
249
250#endif
251
252#if defined(PDUMP)
253 {
254
255 static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
256 gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
257 }
258#endif
259
260
261
262
263
264 return PVRSRV_OK;
265}
266
267
268IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)
269{
270 static IMG_CHAR aszVersionString[100];
271 SYS_DATA *psSysData;
272 IMG_UINT32 ui32SGXRevision;
273 IMG_INT32 i32Count;
274#if !defined(NO_HARDWARE)
275 IMG_VOID *pvRegsLinAddr;
276
277 pvRegsLinAddr = OSMapPhysToLin(sRegRegion,
278 SYS_OMAP4430_SGX_REGS_SIZE,
279 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
280 IMG_NULL);
281 if(!pvRegsLinAddr)
282 {
283 return IMG_NULL;
284 }
285
286 ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),
287 EUR_CR_CORE_REVISION);
288#else
289 ui32SGXRevision = 0;
290#endif
291
292 SysAcquireData(&psSysData);
293
294 i32Count = OSSNPrintf(aszVersionString, 100,
295 "SGX revision = %u.%u.%u",
296 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
297 >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
298 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
299 >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
300 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
301 >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
302 );
303
304#if !defined(NO_HARDWARE)
305 OSUnMapPhysToLin(pvRegsLinAddr,
306 SYS_OMAP4430_SGX_REGS_SIZE,
307 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
308 IMG_NULL);
309#endif
310
311 if(i32Count == -1)
312 {
313 return IMG_NULL;
314 }
315
316 return aszVersionString;
317}
318
319
320PVRSRV_ERROR SysInitialise(IMG_VOID)
321{
322 IMG_UINT32 i;
323 PVRSRV_ERROR eError;
324 PVRSRV_DEVICE_NODE *psDeviceNode;
325#if !defined(NO_OMAP_TIMER)
326 IMG_CPU_PHYADDR TimerRegPhysBase;
327#endif
328#if !defined(SGX_DYNAMIC_TIMING_INFO)
329 SGX_TIMING_INFORMATION* psTimingInfo;
330#endif
331 gpsSysData = &gsSysData;
332 OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
333
334 gpsSysSpecificData = &gsSysSpecificData;
335 OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));
336
337 gpsSysData->pvSysSpecificData = gpsSysSpecificData;
338
339 eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
340 if (eError != PVRSRV_OK)
341 {
342 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
343 (IMG_VOID)SysDeinitialise(gpsSysData);
344 gpsSysData = IMG_NULL;
345 return eError;
346 }
347 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);
348
349 gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
350
351
352 for(i=0; i<SYS_DEVICE_COUNT; i++)
353 {
354 gpsSysData->sDeviceID[i].uiID = i;
355 gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
356 }
357
358 gpsSysData->psDeviceNodeList = IMG_NULL;
359 gpsSysData->psQueueList = IMG_NULL;
360
361 eError = SysInitialiseCommon(gpsSysData);
362 if (eError != PVRSRV_OK)
363 {
364 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));
365 (IMG_VOID)SysDeinitialise(gpsSysData);
366 gpsSysData = IMG_NULL;
367 return eError;
368 }
369
370#if !defined(NO_OMAP_TIMER)
371 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
372 gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
373 gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
374 OSReservePhys(TimerRegPhysBase,
375 4,
376 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
377 (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
378 &gpsSysData->hSOCTimerRegisterOSMemHandle);
379#endif
380
381#if !defined(SGX_DYNAMIC_TIMING_INFO)
382
383 psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
384 psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
385 psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
386#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
387 psTimingInfo->bEnableActivePM = IMG_TRUE;
388#else
389 psTimingInfo->bEnableActivePM = IMG_FALSE;
390#endif
391 psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
392 psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
393#endif
394
395
396
397 gpsSysSpecificData->ui32SrcClockDiv = 3;
398
399
400
401
402
403 eError = SysLocateDevices(gpsSysData);
404 if (eError != PVRSRV_OK)
405 {
406 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
407 (IMG_VOID)SysDeinitialise(gpsSysData);
408 gpsSysData = IMG_NULL;
409 return eError;
410 }
411 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
412
413#if defined(SGX_OCP_REGS_ENABLED)
414 {
415 IMG_SYS_PHYADDR sOCPRegsSysPBase;
416 IMG_CPU_PHYADDR sOCPRegsCpuPBase;
417
418 sOCPRegsSysPBase.uiAddr = SYS_OMAP4430_OCP_REGS_SYS_PHYS_BASE;
419 sOCPRegsCpuPBase = SysSysPAddrToCpuPAddr(sOCPRegsSysPBase);
420
421 gpvOCPRegsLinAddr = OSMapPhysToLin(sOCPRegsCpuPBase,
422 SYS_OMAP4430_OCP_REGS_SIZE,
423 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
424 IMG_NULL);
425
426 if (gpvOCPRegsLinAddr == IMG_NULL)
427 {
428 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to map OCP registers"));
429 return PVRSRV_ERROR_BAD_MAPPING;
430 }
431 }
432#endif
433
434
435
436
437 eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
438 DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
439 if (eError != PVRSRV_OK)
440 {
441 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
442 (IMG_VOID)SysDeinitialise(gpsSysData);
443 gpsSysData = IMG_NULL;
444 return eError;
445 }
446 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);
447
448
449
450
451 psDeviceNode = gpsSysData->psDeviceNodeList;
452 while(psDeviceNode)
453 {
454
455 switch(psDeviceNode->sDevId.eDeviceType)
456 {
457 case PVRSRV_DEVICE_TYPE_SGX:
458 {
459 DEVICE_MEMORY_INFO *psDevMemoryInfo;
460 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
461
462
463
464
465 psDeviceNode->psLocalDevMemArena = IMG_NULL;
466
467
468 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
469 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
470
471
472 for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
473 {
474 psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
475 }
476
477 gpsSGXDevNode = psDeviceNode;
478 gsSysSpecificData.psSGXDevNode = psDeviceNode;
479
480 break;
481 }
482 default:
483 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));
484 return PVRSRV_ERROR_INIT_FAILURE;
485 }
486
487
488 psDeviceNode = psDeviceNode->psNext;
489 }
490
491 eError = EnableSystemClocksWrap(gpsSysData);
492 if (eError != PVRSRV_OK)
493 {
494 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError));
495 (IMG_VOID)SysDeinitialise(gpsSysData);
496 gpsSysData = IMG_NULL;
497 return eError;
498 }
499 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
500#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
501 eError = EnableSGXClocksWrap(gpsSysData);
502 if (eError != PVRSRV_OK)
503 {
504 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
505 (IMG_VOID)SysDeinitialise(gpsSysData);
506 gpsSysData = IMG_NULL;
507 return eError;
508 }
509#endif
510
511 dump_omap34xx_clocks();
512
513 eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);
514 if (eError != PVRSRV_OK)
515 {
516 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
517 (IMG_VOID)SysDeinitialise(gpsSysData);
518 gpsSysData = IMG_NULL;
519 return eError;
520 }
521 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV);
522
523#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
524
525 DisableSGXClocks(gpsSysData);
526#endif
527
528 return PVRSRV_OK;
529}
530
531
532PVRSRV_ERROR SysFinalise(IMG_VOID)
533{
534 PVRSRV_ERROR eError = PVRSRV_OK;
535
536#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
537 eError = EnableSGXClocksWrap(gpsSysData);
538 if (eError != PVRSRV_OK)
539 {
540 PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
541 (IMG_VOID)SysDeinitialise(gpsSysData);
542 gpsSysData = IMG_NULL;
543 return eError;
544 }
545#endif
546
547#if defined(SYS_USING_INTERRUPTS)
548
549 eError = OSInstallMISR(gpsSysData);
550 if (eError != PVRSRV_OK)
551 {
552 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR"));
553 (IMG_VOID)SysDeinitialise(gpsSysData);
554 gpsSysData = IMG_NULL;
555 return eError;
556 }
557 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR);
558
559
560 eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);
561 if (eError != PVRSRV_OK)
562 {
563 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR"));
564 (IMG_VOID)SysDeinitialise(gpsSysData);
565 gpsSysData = IMG_NULL;
566 return eError;
567 }
568 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
569#endif
570
571
572 gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);
573 if (!gpsSysData->pszVersionString)
574 {
575 PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));
576 }
577 else
578 {
579 PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
580 }
581
582#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
583
584 DisableSGXClocks(gpsSysData);
585#endif
586
587 gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;
588
589 return eError;
590}
591
592
593PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
594{
595 PVRSRV_ERROR eError;
596
597#if defined(SYS_USING_INTERRUPTS)
598 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
599 {
600 eError = OSUninstallDeviceLISR(psSysData);
601 if (eError != PVRSRV_OK)
602 {
603 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed"));
604 return eError;
605 }
606 }
607
608 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR))
609 {
610 eError = OSUninstallMISR(psSysData);
611 if (eError != PVRSRV_OK)
612 {
613 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));
614 return eError;
615 }
616 }
617#else
618 PVR_UNREFERENCED_PARAMETER(psSysData);
619#endif
620
621 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV))
622 {
623#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
624 PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));
625
626 eError = EnableSGXClocksWrap(gpsSysData);
627 if (eError != PVRSRV_OK)
628 {
629 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed"));
630 return eError;
631 }
632#endif
633
634
635 eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID);
636 if (eError != PVRSRV_OK)
637 {
638 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));
639 return eError;
640 }
641 }
642
643#if defined(SGX_OCP_REGS_ENABLED)
644 OSUnMapPhysToLin(gpvOCPRegsLinAddr,
645 SYS_OMAP4430_OCP_REGS_SIZE,
646 PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
647 IMG_NULL);
648#endif
649
650
651
652 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))
653 {
654 DisableSystemClocks(gpsSysData);
655 }
656
657 if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA))
658 {
659 eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);
660 if (eError != PVRSRV_OK)
661 {
662 PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));
663 return eError;
664 }
665 }
666
667#if !defined(NO_OMAP_TIMER)
668 if(gpsSysData->pvSOCTimerRegisterKM)
669 {
670 OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
671 4,
672 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
673 gpsSysData->hSOCTimerRegisterOSMemHandle);
674 }
675#endif
676
677 SysDeinitialiseCommon(gpsSysData);
678
679#if defined(NO_HARDWARE)
680 if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))
681 {
682
683 OSBaseFreeContigMemory(SYS_OMAP4430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);
684 }
685#endif
686
687 gpsSysSpecificData->ui32SysSpecificData = 0;
688 gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;
689
690 gpsSysData = IMG_NULL;
691
692 return PVRSRV_OK;
693}
694
695
696PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
697 IMG_VOID **ppvDeviceMap)
698{
699
700 switch(eDeviceType)
701 {
702 case PVRSRV_DEVICE_TYPE_SGX:
703 {
704
705 *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
706
707 break;
708 }
709 default:
710 {
711 PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
712 }
713 }
714 return PVRSRV_OK;
715}
716
717
718IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
719 IMG_CPU_PHYADDR CpuPAddr)
720{
721 IMG_DEV_PHYADDR DevPAddr;
722
723 PVR_UNREFERENCED_PARAMETER(eDeviceType);
724
725
726 DevPAddr.uiAddr = CpuPAddr.uiAddr;
727
728 return DevPAddr;
729}
730
731IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
732{
733 IMG_CPU_PHYADDR cpu_paddr;
734
735
736 cpu_paddr.uiAddr = sys_paddr.uiAddr;
737 return cpu_paddr;
738}
739
740IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
741{
742 IMG_SYS_PHYADDR sys_paddr;
743
744
745 sys_paddr.uiAddr = cpu_paddr.uiAddr;
746 return sys_paddr;
747}
748
749
750IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
751{
752 IMG_DEV_PHYADDR DevPAddr;
753
754 PVR_UNREFERENCED_PARAMETER(eDeviceType);
755
756
757 DevPAddr.uiAddr = SysPAddr.uiAddr;
758
759 return DevPAddr;
760}
761
762
763IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
764{
765 IMG_SYS_PHYADDR SysPAddr;
766
767 PVR_UNREFERENCED_PARAMETER(eDeviceType);
768
769
770 SysPAddr.uiAddr = DevPAddr.uiAddr;
771
772 return SysPAddr;
773}
774
775
776IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
777{
778 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
779}
780
781
782IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
783{
784 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
785}
786
787
788IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
789 PVRSRV_DEVICE_NODE *psDeviceNode)
790{
791 PVR_UNREFERENCED_PARAMETER(psSysData);
792#if defined(NO_HARDWARE)
793
794 return 0xFFFFFFFF;
795#else
796
797 return psDeviceNode->ui32SOCInterruptBit;
798#endif
799}
800
801
802IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
803{
804 PVR_UNREFERENCED_PARAMETER(psSysData);
805 PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
806
807
808 OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM,
809 EUR_CR_EVENT_HOST_CLEAR);
810}
811
812
813PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
814{
815 PVRSRV_ERROR eError = PVRSRV_OK;
816
817 if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3)
818 {
819 PVR_TRACE(("SysSystemPrePowerState: Entering state D3"));
820
821#if defined(SYS_USING_INTERRUPTS)
822 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
823 {
824#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
825 IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);
826#endif
827 eError = OSUninstallDeviceLISR(gpsSysData);
828#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
829 if (bWrapped)
830 {
831 UnwrapSystemPowerChange(&gsSysSpecificData);
832 }
833#endif
834 if (eError != PVRSRV_OK)
835 {
836 PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError));
837 return eError;
838 }
839 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
840 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
841 }
842#endif
843
844 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))
845 {
846 DisableSystemClocks(gpsSysData);
847
848 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
849 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
850 }
851 }
852
853 return eError;
854}
855
856
857PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
858{
859 PVRSRV_ERROR eError = PVRSRV_OK;
860
861 if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0)
862 {
863 PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));
864
865 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS))
866 {
867 eError = EnableSystemClocksWrap(gpsSysData);
868 if (eError != PVRSRV_OK)
869 {
870 PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError));
871 return eError;
872 }
873 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
874 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
875 }
876
877#if defined(SYS_USING_INTERRUPTS)
878 if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR))
879 {
880#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
881 IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);
882#endif
883
884 eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);
885#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
886 if (bWrapped)
887 {
888 UnwrapSystemPowerChange(&gsSysSpecificData);
889 }
890#endif
891 if (eError != PVRSRV_OK)
892 {
893 PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError));
894 return eError;
895 }
896 SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
897 SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
898 }
899#endif
900 }
901 return eError;
902}
903
904
905PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
906 PVRSRV_DEV_POWER_STATE eNewPowerState,
907 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
908{
909 PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
910
911 if (ui32DeviceIndex != gui32SGXDeviceID)
912 {
913 return PVRSRV_OK;
914 }
915
916#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
917 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
918 {
919 PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));
920 DisableSGXClocks(gpsSysData);
921 }
922#else
923 PVR_UNREFERENCED_PARAMETER(eNewPowerState );
924#endif
925 return PVRSRV_OK;
926}
927
928
929PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
930 PVRSRV_DEV_POWER_STATE eNewPowerState,
931 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
932{
933 PVRSRV_ERROR eError = PVRSRV_OK;
934
935 PVR_UNREFERENCED_PARAMETER(eNewPowerState);
936
937 if (ui32DeviceIndex != gui32SGXDeviceID)
938 {
939 return eError;
940 }
941
942#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
943 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
944 {
945 PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));
946 eError = EnableSGXClocksWrap(gpsSysData);
947 }
948#else
949 PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
950#endif
951
952 return eError;
953}
954
955
956PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID,
957 IMG_VOID *pvIn,
958 IMG_UINT32 ulInSize,
959 IMG_VOID *pvOut,
960 IMG_UINT32 ulOutSize)
961{
962 PVR_UNREFERENCED_PARAMETER(ui32ID);
963 PVR_UNREFERENCED_PARAMETER(pvIn);
964 PVR_UNREFERENCED_PARAMETER(ulInSize);
965 PVR_UNREFERENCED_PARAMETER(pvOut);
966 PVR_UNREFERENCED_PARAMETER(ulOutSize);
967
968 if ((ui32ID == OEM_GET_EXT_FUNCS) &&
969 (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))
970 {
971
972 PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut;
973 psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;
974 return PVRSRV_OK;
975 }
976
977 return PVRSRV_ERROR_INVALID_PARAMS;
978}
diff --git a/drivers/gpu/pvr/omap4/sysconfig.h b/drivers/gpu/pvr/omap4/sysconfig.h
new file mode 100644
index 00000000000..7fcf84b2e8d
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/sysconfig.h
@@ -0,0 +1,67 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SOCCONFIG_H__)
28#define __SOCCONFIG_H__
29
30#include "syscommon.h"
31
32#define VS_PRODUCT_NAME "OMAP4"
33
34#if defined(SGX_CLK_PER_192)
35#define SYS_SGX_CLOCK_SPEED 192000000
36#else
37#if defined(SGX_CLK_CORE_DIV8)
38#define SYS_SGX_CLOCK_SPEED 190464000
39#else
40#if defined(SGX_CLK_CORE_DIV5)
41#if defined(CONFIG_SGX_REV110)
42#define SYS_SGX_CLOCK_SPEED 304742400
43#endif
44#if defined(CONFIG_SGX_REV120)
45#define SYS_SGX_CLOCK_SPEED 320000000
46#endif
47#endif
48#endif
49#endif
50
51#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100)
52#define SYS_SGX_PDS_TIMER_FREQ (1000)
53
54#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS)
55#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (100)
56#endif
57
58
59
60#define SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE 0x56000000
61#define SYS_OMAP4430_SGX_REGS_SIZE 0xFFFF
62
63#define SYS_OMAP4430_SGX_IRQ 53 /* OMAP 4 IRQs are offset by 32 */
64
65
66
67#endif
diff --git a/drivers/gpu/pvr/omap4/sysinfo.h b/drivers/gpu/pvr/omap4/sysinfo.h
new file mode 100644
index 00000000000..07718276b8d
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/sysinfo.h
@@ -0,0 +1,40 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SYSINFO_H__)
28#define __SYSINFO_H__
29
30#if defined(PVR_LINUX_USING_WORKQUEUES)
31#define MAX_HW_TIME_US (1000000)
32#else
33#define MAX_HW_TIME_US (500000)
34#endif
35
36#define WAIT_TRY_COUNT (10000)
37
38#define SYS_DEVICE_COUNT 3
39
40#endif
diff --git a/drivers/gpu/pvr/omap4/syslocal.h b/drivers/gpu/pvr/omap4/syslocal.h
new file mode 100644
index 00000000000..ecf203b912e
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/syslocal.h
@@ -0,0 +1,137 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SYSLOCAL_H__)
28#define __SYSLOCAL_H__
29
30#if defined(__linux__)
31
32#include <linux/version.h>
33#include <linux/clk.h>
34#if defined(PVR_LINUX_USING_WORKQUEUES)
35#include <linux/mutex.h>
36#else
37#include <linux/spinlock.h>
38#endif
39#include <asm/atomic.h>
40
41#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
42#include <linux/semaphore.h>
43#include <linux/resource.h>
44#else
45#include <asm/semaphore.h>
46#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
47#include <asm/arch/resource.h>
48#endif
49#endif
50
51#endif
52
53#if defined (__cplusplus)
54extern "C" {
55#endif
56
57
58
59IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion);
60
61IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);
62PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);
63
64IMG_VOID DisableSGXClocks(SYS_DATA *psSysData);
65PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);
66
67#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001
68#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002
69#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004
70#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008
71#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010
72#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020
73#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040
74#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080
75#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100
76
77#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200
78#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400
79
80#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))
81
82#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))
83
84#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)
85
86typedef struct _SYS_SPECIFIC_DATA_TAG_
87{
88 IMG_UINT32 ui32SysSpecificData;
89 PVRSRV_DEVICE_NODE *psSGXDevNode;
90 IMG_BOOL bSGXInitComplete;
91#if !defined(__linux__)
92 IMG_BOOL bSGXClocksEnabled;
93#endif
94 IMG_UINT32 ui32SrcClockDiv;
95#if defined(__linux__)
96 IMG_BOOL bSysClocksOneTimeInit;
97 atomic_t sSGXClocksEnabled;
98#if defined(PVR_LINUX_USING_WORKQUEUES)
99 struct mutex sPowerLock;
100#else
101 IMG_BOOL bConstraintNotificationsEnabled;
102 spinlock_t sPowerLock;
103 atomic_t sPowerLockCPU;
104 spinlock_t sNotifyLock;
105 atomic_t sNotifyLockCPU;
106 IMG_BOOL bCallVDD2PostFunc;
107#endif
108 struct clk *psCORE_CK;
109 struct clk *psSGX_FCK;
110 struct clk *psSGX_ICK;
111 struct clk *psMPU_CK;
112#if !defined(NO_OMAP_TIMER)
113#if defined(DEBUG) || defined(TIMING)
114 struct clk *psGPT11_FCK;
115 struct clk *psGPT11_ICK;
116#endif
117#endif
118#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
119 struct constraint_handle *pVdd2Handle;
120#endif
121#endif
122} SYS_SPECIFIC_DATA;
123
124extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
125
126#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
127IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
128IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
129#endif
130
131#if defined(__cplusplus)
132}
133#endif
134
135#endif
136
137
diff --git a/drivers/gpu/pvr/omap4/sysutils.c b/drivers/gpu/pvr/omap4/sysutils.c
new file mode 100644
index 00000000000..d2c4231315c
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/sysutils.c
@@ -0,0 +1,33 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(__linux__)
28#if defined(PVR_LINUX_USING_WORKQUEUES)
29#include "sysutils_linux_wqueue_compat.c"
30#else
31#include "sysutils_linux.c"
32#endif
33#endif
diff --git a/drivers/gpu/pvr/omap4/sysutils_linux_wqueue_compat.c b/drivers/gpu/pvr/omap4/sysutils_linux_wqueue_compat.c
new file mode 100644
index 00000000000..fa0cc696f80
--- /dev/null
+++ b/drivers/gpu/pvr/omap4/sysutils_linux_wqueue_compat.c
@@ -0,0 +1,238 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <linux/version.h>
28#include <linux/clk.h>
29#include <linux/err.h>
30#include <linux/hardirq.h>
31#include <linux/mutex.h>
32
33#include "sgxdefs.h"
34#include "services_headers.h"
35#include "sysinfo.h"
36#include "sgxapi_km.h"
37#include "sysconfig.h"
38#include "sgxinfokm.h"
39#include "syslocal.h"
40
41#if !defined(PVR_LINUX_USING_WORKQUEUES)
42#error "PVR_LINUX_USING_WORKQUEUES must be defined"
43#endif
44
45#define ONE_MHZ 1000000
46#define HZ_TO_MHZ(m) ((m) / ONE_MHZ)
47
48#if defined(SUPPORT_OMAP3430_SGXFCLK_96M)
49#define SGX_PARENT_CLOCK "cm_96m_fck"
50#else
51#define SGX_PARENT_CLOCK "core_ck"
52#endif
53
54PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData)
55{
56 return PVRSRV_OK;
57}
58
59IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData)
60{
61}
62
63IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
64{
65 return IMG_TRUE;
66}
67
68IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
69{
70}
71
72static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2)
73{
74 if (rate1 >= rate2)
75 {
76 return val * (rate1 / rate2);
77 }
78
79 return val / (rate2 / rate1);
80}
81
82static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)
83{
84 return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED);
85}
86
87static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)
88{
89 return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate);
90}
91
92IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)
93{
94 IMG_UINT32 rate;
95
96#if defined(NO_HARDWARE)
97 rate = SYS_SGX_CLOCK_SPEED;
98#else
99 PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);
100
101 rate = SYS_SGX_CLOCK_SPEED;
102 PVR_ASSERT(rate != 0);
103#endif
104 psTimingInfo->ui32CoreClockSpeed = rate;
105 psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);
106 psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate);
107#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
108 psTimingInfo->bEnableActivePM = IMG_TRUE;
109#else
110 psTimingInfo->bEnableActivePM = IMG_FALSE;
111#endif
112 psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
113}
114
115PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
116{
117#if !defined(NO_HARDWARE)
118 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
119
120 if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)
121 {
122 return PVRSRV_OK;
123 }
124
125 PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));
126
127
128 atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
129
130#else
131 PVR_UNREFERENCED_PARAMETER(psSysData);
132#endif
133 return PVRSRV_OK;
134}
135
136
137IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
138{
139#if !defined(NO_HARDWARE)
140 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
141
142
143 if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)
144 {
145 return;
146 }
147
148 PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
149
150 atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
151
152#else
153 PVR_UNREFERENCED_PARAMETER(psSysData);
154#endif
155}
156
157PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
158{
159 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
160 struct clk *psCLK;
161 IMG_INT res;
162 PVRSRV_ERROR eError;
163
164#if defined(DEBUG) || defined(TIMING)
165 IMG_INT rate;
166 struct clk *sys_ck;
167 IMG_CPU_PHYADDR TimerRegPhysBase;
168 IMG_HANDLE hTimerEnable;
169 IMG_UINT32 *pui32TimerEnable;
170
171#endif
172
173 PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));
174
175 if (!psSysSpecData->bSysClocksOneTimeInit)
176 {
177 mutex_init(&psSysSpecData->sPowerLock);
178
179 atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
180 psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
181 }
182
183 eError = PVRSRV_OK;
184 goto Exit;
185
186#if !defined(NO_OMAP_TIMER)
187#if defined(DEBUG) || defined(TIMING)
188ExitDisableGPT11ICK:
189ExitDisableGPT11FCK:
190ExitUnRegisterConstraintNotifications:
191#endif
192#endif
193Exit:
194 return eError;
195}
196
197IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
198{
199#if !defined(NO_OMAP_TIMER)
200#if defined(DEBUG) || defined(TIMING)
201 SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
202 IMG_CPU_PHYADDR TimerRegPhysBase;
203 IMG_HANDLE hTimerDisable;
204 IMG_UINT32 *pui32TimerDisable;
205#endif
206#endif
207
208 PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));
209
210 DisableSGXClocks(psSysData);
211
212#if !defined(NO_OMAP_TIMER)
213#if defined(DEBUG) || defined(TIMING)
214
215 TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
216 pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
217 4,
218 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
219 &hTimerDisable);
220
221 if (pui32TimerDisable == IMG_NULL)
222 {
223 PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));
224 }
225 else
226 {
227 *pui32TimerDisable = 0;
228
229 OSUnMapPhysToLin(pui32TimerDisable,
230 4,
231 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
232 hTimerDisable);
233 }
234
235
236#endif
237#endif
238}
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb.h b/drivers/gpu/pvr/omaplfb/omaplfb.h
new file mode 100644
index 00000000000..f16e8e04098
--- /dev/null
+++ b/drivers/gpu/pvr/omaplfb/omaplfb.h
@@ -0,0 +1,166 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __OMAPLFB_H__
28#define __OMAPLFB_H__
29
30extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
31
32typedef void * OMAP_HANDLE;
33
34typedef enum tag_omap_bool
35{
36 OMAP_FALSE = 0,
37 OMAP_TRUE = 1,
38} OMAP_BOOL, *OMAP_PBOOL;
39
40typedef struct OMAPLFB_BUFFER_TAG
41{
42 unsigned long ulBufferSize;
43 IMG_SYS_PHYADDR sSysAddr;
44 IMG_CPU_VIRTADDR sCPUVAddr;
45 PVRSRV_SYNC_DATA* psSyncData;
46 struct OMAPLFB_BUFFER_TAG* psNext;
47
48} OMAPLFB_BUFFER;
49
50typedef struct OMAPLFB_FLIP_ITEM_TAG
51{
52 OMAP_HANDLE hCmdComplete;
53 unsigned long ulSwapInterval;
54 OMAP_BOOL bValid;
55 OMAP_BOOL bFlipped;
56 OMAP_BOOL bCmdCompleted;
57 IMG_SYS_PHYADDR* sSysAddr;
58
59} OMAPLFB_FLIP_ITEM;
60
61typedef struct PVRPDP_SWAPCHAIN_TAG
62{
63 unsigned long ulBufferCount;
64 OMAPLFB_BUFFER* psBuffer;
65 OMAPLFB_FLIP_ITEM* psFlipItems;
66 unsigned long ulInsertIndex;
67 unsigned long ulRemoveIndex;
68 PVRSRV_DC_DISP2SRV_KMJTABLE* psPVRJTable;
69 OMAP_BOOL bFlushCommands;
70 unsigned long ulSetFlushStateRefCount;
71 OMAP_BOOL bBlanked;
72 spinlock_t* psSwapChainLock;
73 void* pvDevInfo;
74
75} OMAPLFB_SWAPCHAIN;
76
77typedef struct OMAPLFB_FBINFO_TAG
78{
79 unsigned long ulFBSize;
80 unsigned long ulBufferSize;
81 unsigned long ulRoundedBufferSize;
82 unsigned long ulWidth;
83 unsigned long ulHeight;
84 unsigned long ulByteStride;
85 IMG_SYS_PHYADDR sSysAddr;
86 IMG_CPU_VIRTADDR sCPUVAddr;
87 PVRSRV_PIXEL_FORMAT ePixelFormat;
88
89}OMAPLFB_FBINFO;
90
91typedef struct OMAPLFB_DEVINFO_TAG
92{
93 IMG_UINT32 uDeviceID;
94 OMAPLFB_BUFFER sSystemBuffer;
95 PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable;
96 PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable;
97 OMAPLFB_FBINFO sFBInfo;
98 OMAPLFB_SWAPCHAIN* psSwapChain;
99 OMAP_BOOL bFlushCommands;
100 struct fb_info* psLINFBInfo;
101 struct notifier_block sLINNotifBlock;
102 OMAP_BOOL bDeviceSuspended;
103 struct mutex sSwapChainLockMutex;
104 IMG_DEV_VIRTADDR sDisplayDevVAddr;
105 DISPLAY_INFO sDisplayInfo;
106 DISPLAY_FORMAT sDisplayFormat;
107 DISPLAY_DIMS sDisplayDim;
108 struct workqueue_struct* sync_display_wq;
109 struct work_struct sync_display_work;
110
111} OMAPLFB_DEVINFO;
112
113typedef enum _OMAP_ERROR_
114{
115 OMAP_OK = 0,
116 OMAP_ERROR_GENERIC = 1,
117 OMAP_ERROR_OUT_OF_MEMORY = 2,
118 OMAP_ERROR_TOO_FEW_BUFFERS = 3,
119 OMAP_ERROR_INVALID_PARAMS = 4,
120 OMAP_ERROR_INIT_FAILURE = 5,
121 OMAP_ERROR_CANT_REGISTER_CALLBACK = 6,
122 OMAP_ERROR_INVALID_DEVICE = 7,
123 OMAP_ERROR_DEVICE_REGISTER_FAILED = 8
124
125} OMAP_ERROR;
126
127#define OMAPLFB_PAGE_SIZE 4096
128#define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1)
129#define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK)
130
131#define OMAPLFB_PAGE_ROUNDUP(x) (((x)+OMAPLFB_PAGE_MASK) & OMAPLFB_PAGE_TRUNC)
132
133#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver"
134#define DRVNAME "omaplfb"
135#define DEVNAME DRVNAME
136#define DRIVER_PREFIX DRVNAME
137
138#define FRAMEBUFFER_COUNT num_registered_fb
139
140#ifdef DEBUG
141#define DEBUG_PRINTK(format, ...) printk("DEBUG " DRIVER_PREFIX \
142 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
143#else
144#define DEBUG_PRINTK(format,...)
145#endif
146
147#define WARNING_PRINTK(format, ...) printk("WARNING " DRIVER_PREFIX \
148 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
149#define ERROR_PRINTK(format, ...) printk("ERROR " DRIVER_PREFIX \
150 " (%s %i): " format "\n", __func__, __LINE__, ## __VA_ARGS__)
151
152OMAP_ERROR OMAPLFBInit(void);
153OMAP_ERROR OMAPLFBDeinit(void);
154void *OMAPLFBAllocKernelMem(unsigned long ulSize);
155void OMAPLFBFreeKernelMem(void *pvMem);
156void OMAPLFBWaitForSync(OMAPLFB_DEVINFO *psDevInfo);
157OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName,
158 PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
159void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr);
160#ifdef LDM_PLATFORM
161void OMAPLFBDriverSuspend(void);
162void OMAPLFBDriverResume(void);
163#endif
164
165#endif
166
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
new file mode 100644
index 00000000000..a2ad4e6e5d6
--- /dev/null
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
@@ -0,0 +1,1723 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <linux/version.h>
28#include <linux/kernel.h>
29#include <linux/console.h>
30#include <linux/fb.h>
31
32#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
33#include <plat/vrfb.h>
34#include <plat/display.h>
35#else
36#include <mach/vrfb.h>
37#include <mach/display.h>
38#endif
39
40#ifdef RELEASE
41#include <../drivers/video/omap2/omapfb/omapfb.h>
42#undef DEBUG
43#else
44#undef DEBUG
45#include <../drivers/video/omap2/omapfb/omapfb.h>
46#endif
47
48#include <linux/module.h>
49#include <linux/string.h>
50#include <linux/notifier.h>
51
52#include "img_defs.h"
53#include "servicesext.h"
54#include "kerneldisplay.h"
55#include "omaplfb.h"
56
57#define OMAPLFB_COMMAND_COUNT 1
58#define MAX_BUFFERS_FLIPPING 3
59/* Put 0 as desired bpp to use the default in the framebuffer */
60#define DESIRED_BPP 0 /* Possible values 32,16,0 */
61
62/* Pointer Display->Services */
63static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = NULL;
64
65/* Pointer to the display devices */
66static OMAPLFB_DEVINFO *pDisplayDevices = NULL;
67
68static void OMAPLFBSyncIHandler(struct work_struct*);
69
70/*
71 * Swap to display buffer. This buffer refers to one inside the
72 * framebuffer memory.
73 * in: hDevice, hBuffer, ui32SwapInterval, hPrivateTag, ui32ClipRectCount,
74 * psClipRect
75 */
76static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
77 IMG_HANDLE hBuffer,
78 IMG_UINT32 ui32SwapInterval,
79 IMG_HANDLE hPrivateTag,
80 IMG_UINT32 ui32ClipRectCount,
81 IMG_RECT *psClipRect)
82{
83 /* Nothing to do */
84 return PVRSRV_OK;
85}
86
87/*
88 * Set display destination rectangle.
89 * in: hDevice, hSwapChain, psRect
90 */
91static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
92 IMG_HANDLE hSwapChain,
93 IMG_RECT *psRect)
94{
95 /* Nothing to do */
96 return PVRSRV_ERROR_NOT_SUPPORTED;
97}
98
99/*
100 * Set display source rectangle.
101 * in: hDevice, hSwapChain, psRect
102 */
103static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
104 IMG_HANDLE hSwapChain,
105 IMG_RECT *psRect)
106{
107 /* Nothing to do */
108 return PVRSRV_ERROR_NOT_SUPPORTED;
109}
110
111/*
112 * Set display destination colour key.
113 * in: hDevice, hSwapChain, ui32CKColour
114 */
115static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
116 IMG_HANDLE hSwapChain,
117 IMG_UINT32 ui32CKColour)
118{
119 /* Nothing to do */
120 return PVRSRV_ERROR_NOT_SUPPORTED;
121}
122
123/*
124 * Set display source colour key.
125 * in: hDevice, hSwapChain, ui32CKColour
126 */
127static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
128 IMG_HANDLE hSwapChain,
129 IMG_UINT32 ui32CKColour)
130{
131 /* Nothing to do */
132 return PVRSRV_ERROR_NOT_SUPPORTED;
133}
134
135/*
136 * Closes the display.
137 * in: hDevice
138 */
139static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
140{
141 /* Nothing to do */
142 return PVRSRV_OK;
143}
144
145/*
146 * Flushes the sync queue present in the specified swap chain.
147 * in: psSwapChain
148 */
149static void FlushInternalSyncQueue(OMAPLFB_SWAPCHAIN *psSwapChain)
150{
151#ifdef DEBUG
152 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *) psSwapChain->pvDevInfo;
153#endif
154 OMAPLFB_FLIP_ITEM *psFlipItem;
155 unsigned long ulMaxIndex;
156 unsigned long i;
157
158 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
159 ulMaxIndex = psSwapChain->ulBufferCount - 1;
160
161#ifdef DEBUG
162 DEBUG_PRINTK("Flushing sync queue on display %u",
163 psDevInfo->uDeviceID);
164#endif
165 for(i = 0; i < psSwapChain->ulBufferCount; i++)
166 {
167 if (psFlipItem->bValid == OMAP_FALSE)
168 continue;
169
170 DEBUG_PRINTK("Flushing swap buffer index %lu",
171 psSwapChain->ulRemoveIndex);
172
173 /* Flip the buffer if it hasn't been flipped */
174 if(psFlipItem->bFlipped == OMAP_FALSE)
175 {
176 OMAPLFBFlip(psSwapChain,
177 (unsigned long)psFlipItem->sSysAddr);
178 }
179
180 /* If the command didn't complete, assume it did */
181 if(psFlipItem->bCmdCompleted == OMAP_FALSE)
182 {
183 DEBUG_PRINTK("Calling command complete for swap "
184 "buffer index %lu",
185 psSwapChain->ulRemoveIndex);
186 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
187 (IMG_HANDLE)psFlipItem->hCmdComplete,
188 IMG_TRUE);
189 }
190
191 psSwapChain->ulRemoveIndex++;
192 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
193 psSwapChain->ulRemoveIndex = 0;
194
195 /* Put the state of the buffer to be used again later */
196 psFlipItem->bFlipped = OMAP_FALSE;
197 psFlipItem->bCmdCompleted = OMAP_FALSE;
198 psFlipItem->bValid = OMAP_FALSE;
199 psFlipItem =
200 &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
201 }
202
203 psSwapChain->ulInsertIndex = 0;
204 psSwapChain->ulRemoveIndex = 0;
205}
206
207/*
208 * Sets the flush state of the specified display device
209 * at the swap chain level without blocking the call.
210 * in: psDevInfo, bFlushState
211 */
212static void SetFlushStateInternalNoLock(OMAPLFB_DEVINFO* psDevInfo,
213 OMAP_BOOL bFlushState)
214{
215 OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
216
217 /* Nothing to do if there is no swap chain */
218 if (psSwapChain == NULL){
219 DEBUG_PRINTK("Swap chain is null, nothing to do for"
220 " display %u", psDevInfo->uDeviceID);
221 return;
222 }
223
224 if (bFlushState)
225 {
226 DEBUG_PRINTK("Desired flushState is true for display %u",
227 psDevInfo->uDeviceID);
228 if (psSwapChain->ulSetFlushStateRefCount == 0)
229 {
230 psSwapChain->bFlushCommands = OMAP_TRUE;
231 FlushInternalSyncQueue(psSwapChain);
232 }
233 psSwapChain->ulSetFlushStateRefCount++;
234 }
235 else
236 {
237 DEBUG_PRINTK("Desired flushState is false for display %u",
238 psDevInfo->uDeviceID);
239 if (psSwapChain->ulSetFlushStateRefCount != 0)
240 {
241 psSwapChain->ulSetFlushStateRefCount--;
242 if (psSwapChain->ulSetFlushStateRefCount == 0)
243 {
244 psSwapChain->bFlushCommands = OMAP_FALSE;
245 }
246 }
247 }
248}
249
250/*
251 * Sets the flush state of the specified display device
252 * at the swap chain level blocking the call if needed.
253 * in: psDevInfo, bFlushState
254 */
255static IMG_VOID SetFlushStateInternal(OMAPLFB_DEVINFO* psDevInfo,
256 OMAP_BOOL bFlushState)
257{
258 DEBUG_PRINTK("Executing for display %u",
259 psDevInfo->uDeviceID);
260 mutex_lock(&psDevInfo->sSwapChainLockMutex);
261 SetFlushStateInternalNoLock(psDevInfo, bFlushState);
262 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
263}
264
265/*
266 * Sets the flush state of the specified display device
267 * at device level blocking the call if needed.
268 * in: psDevInfo, bFlushState
269 */
270static void SetFlushStateExternal(OMAPLFB_DEVINFO* psDevInfo,
271 OMAP_BOOL bFlushState)
272{
273 DEBUG_PRINTK("Executing for display %u",
274 psDevInfo->uDeviceID);
275 mutex_lock(&psDevInfo->sSwapChainLockMutex);
276 if (psDevInfo->bFlushCommands != bFlushState)
277 {
278 psDevInfo->bFlushCommands = bFlushState;
279 SetFlushStateInternalNoLock(psDevInfo, bFlushState);
280 }
281 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
282}
283
284/*
285 * Unblank the framebuffer display
286 * in: psDevInfo
287 */
288static OMAP_ERROR UnBlankDisplay(OMAPLFB_DEVINFO *psDevInfo)
289{
290 DEBUG_PRINTK("Executing for display %u",
291 psDevInfo->uDeviceID);
292
293 acquire_console_sem();
294 if (fb_blank(psDevInfo->psLINFBInfo, FB_BLANK_UNBLANK))
295 {
296 release_console_sem();
297 WARNING_PRINTK("fb_blank failed");
298 return OMAP_ERROR_GENERIC;
299 }
300 release_console_sem();
301
302 return OMAP_OK;
303}
304
305/*
306 * Framebuffer listener
307 * in: psNotif, event, data
308 */
309static int FrameBufferEvents(struct notifier_block *psNotif,
310 unsigned long event, void *data)
311{
312 OMAPLFB_DEVINFO *psDevInfo;
313 OMAPLFB_SWAPCHAIN *psSwapChain;
314 struct fb_event *psFBEvent = (struct fb_event *)data;
315 OMAP_BOOL bBlanked;
316 int i;
317
318 DEBUG_PRINTK("Framebuffer event (%lu) happened", event);
319 if (event != FB_EVENT_BLANK){
320 DEBUG_PRINTK("Ignoring");
321 return 0;
322 }
323
324 DEBUG_PRINTK("Event is FB_EVENT_BLANK");
325
326 psDevInfo = 0;
327 for(i = 0; i < FRAMEBUFFER_COUNT; i++)
328 {
329 if(psFBEvent->info == (&pDisplayDevices[i])->psLINFBInfo)
330 {
331 psDevInfo = &pDisplayDevices[i];
332 break;
333 }
334 }
335
336 if(!psDevInfo)
337 {
338 WARNING_PRINTK("Unable to find the display related to "
339 " the framebuffer event");
340 return 1;
341 }
342
343 psSwapChain = psDevInfo->psSwapChain;
344
345 if(!psSwapChain)
346 {
347 DEBUG_PRINTK("No swapchain associated with this display");
348 return 0;
349 }
350
351 bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ?
352 OMAP_TRUE: OMAP_FALSE;
353
354 /* Check if the blank state is the same as the swap chain */
355 if (bBlanked != psSwapChain->bBlanked)
356 {
357 DEBUG_PRINTK("Executing for display %u",
358 psDevInfo->uDeviceID);
359
360 /* Set the new blank state in the swap chain */
361 psSwapChain->bBlanked = bBlanked;
362
363 if (bBlanked)
364 {
365 DEBUG_PRINTK("Requesting flush state true for"
366 " display %u", psDevInfo->uDeviceID);
367 SetFlushStateInternal(psDevInfo, OMAP_TRUE);
368 }
369 else
370 {
371 DEBUG_PRINTK("Requesting flush state false for"
372 " display %u", psDevInfo->uDeviceID);
373 SetFlushStateInternal(psDevInfo, OMAP_FALSE);
374 }
375 }
376 else
377 {
378 DEBUG_PRINTK("Ignoring event for display %u",
379 psDevInfo->uDeviceID);
380 }
381
382 return 0;
383}
384
385/*
386 * Registers a listener for changes in the framebuffer
387 * in: psDevInfo
388 */
389static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
390{
391 OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
392 OMAP_ERROR eError;
393
394 memset(&psDevInfo->sLINNotifBlock, 0,
395 sizeof(psDevInfo->sLINNotifBlock));
396
397 /* Register the function to listen the changes */
398 psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents;
399 psSwapChain->bBlanked = OMAP_FALSE;
400
401 DEBUG_PRINTK("Registering framebuffer event listener for"
402 " display %u", psDevInfo->uDeviceID);
403
404 if (fb_register_client(&psDevInfo->sLINNotifBlock))
405 {
406 WARNING_PRINTK("fb_register_client failed for"
407 " display %u", psDevInfo->uDeviceID);
408 return OMAP_ERROR_GENERIC;
409 }
410
411 eError = UnBlankDisplay(psDevInfo);
412 if (eError != OMAP_OK)
413 {
414 WARNING_PRINTK("UnBlankDisplay failed for"
415 " display %u", psDevInfo->uDeviceID);
416 return eError;
417 }
418
419 return OMAP_OK;
420}
421
422/*
423 * Unregister a listener from the framebuffer
424 * in: psDevInfo
425 */
426static OMAP_ERROR DisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
427{
428 DEBUG_PRINTK("Removing framebuffer event listener for"
429 " display %u", psDevInfo->uDeviceID);
430
431 if (fb_unregister_client(&psDevInfo->sLINNotifBlock))
432 {
433 WARNING_PRINTK("fb_unregister_client failed for"
434 " display %u", psDevInfo->uDeviceID);
435 return OMAP_ERROR_GENERIC;
436 }
437
438 return OMAP_OK;
439}
440
441/*
442 * Opens the display.
443 * in: ui32DeviceID, phDevice
444 * out: psSystemBufferSyncData
445 */
446static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
447 IMG_HANDLE *phDevice,
448 PVRSRV_SYNC_DATA* psSystemBufferSyncData)
449{
450 OMAPLFB_DEVINFO *psDevInfo;
451 int i;
452
453 psDevInfo = 0;
454 for(i = 0; i < FRAMEBUFFER_COUNT; i++)
455 {
456 if (ui32DeviceID == (&pDisplayDevices[i])->uDeviceID)
457 {
458 psDevInfo = &pDisplayDevices[i];
459 break;
460 }
461 }
462
463 if(!psDevInfo)
464 {
465 WARNING_PRINTK("Unable to identify display device with id %i",
466 (int)ui32DeviceID);
467 return 1;
468 }
469
470 psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
471 if ( UnBlankDisplay(psDevInfo) != OMAP_OK)
472 {
473 WARNING_PRINTK("UnBlankDisplay failed for"
474 " display %u", psDevInfo->uDeviceID);
475 return PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED;
476 }
477 *phDevice = (IMG_HANDLE)psDevInfo;
478
479 return PVRSRV_OK;
480}
481
482/*
483 * Gets the available formats for the display.
484 * in: hDevice
485 * out: pui32NumFormats, psFormat
486 */
487static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
488 IMG_UINT32 *pui32NumFormats,
489 DISPLAY_FORMAT *psFormat)
490{
491 OMAPLFB_DEVINFO *psDevInfo;
492 if(!hDevice || !pui32NumFormats)
493 {
494 ERROR_PRINTK("Invalid parameters");
495 return PVRSRV_ERROR_INVALID_PARAMS;
496 }
497
498 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
499 *pui32NumFormats = 1;
500
501 if(psFormat)
502 psFormat[0] = psDevInfo->sDisplayFormat;
503 else
504 WARNING_PRINTK("Display format is null for"
505 " display %u", psDevInfo->uDeviceID);
506
507 return PVRSRV_OK;
508}
509
510/*
511 * Gets the available dimensions for the display.
512 * in: hDevice, psFormat
513 * out: pui32NumDims, psDim
514 */
515static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
516 DISPLAY_FORMAT *psFormat,
517 IMG_UINT32 *pui32NumDims,
518 DISPLAY_DIMS *psDim)
519{
520 OMAPLFB_DEVINFO *psDevInfo;
521 if(!hDevice || !psFormat || !pui32NumDims)
522 {
523 ERROR_PRINTK("Invalid parameters");
524 return PVRSRV_ERROR_INVALID_PARAMS;
525 }
526
527 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
528 *pui32NumDims = 1;
529
530 if(psDim)
531 psDim[0] = psDevInfo->sDisplayDim;
532 else
533 WARNING_PRINTK("Display dimensions are null for"
534 " display %u", psDevInfo->uDeviceID);
535
536 return PVRSRV_OK;
537}
538
539/*
540 * Gets the display framebuffer physical address.
541 * in: hDevice
542 * out: phBuffer
543 */
544static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
545{
546 OMAPLFB_DEVINFO *psDevInfo;
547
548 if(!hDevice || !phBuffer)
549 {
550 ERROR_PRINTK("Invalid parameters");
551 return PVRSRV_ERROR_INVALID_PARAMS;
552 }
553
554 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
555 *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
556
557 return PVRSRV_OK;
558}
559
560/*
561 * Gets the display general information.
562 * in: hDevice
563 * out: psDCInfo
564 */
565static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
566{
567 OMAPLFB_DEVINFO *psDevInfo;
568
569 if(!hDevice || !psDCInfo)
570 {
571 ERROR_PRINTK("Invalid parameters");
572 return PVRSRV_ERROR_INVALID_PARAMS;
573 }
574
575 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
576 *psDCInfo = psDevInfo->sDisplayInfo;
577
578 return PVRSRV_OK;
579}
580
581/*
582 * Gets the display framebuffer virtual address.
583 * in: hDevice
584 * out: ppsSysAddr, pui32ByteSize, ppvCpuVAddr, phOSMapInfo, pbIsContiguous
585 */
586static PVRSRV_ERROR GetDCBufferAddr(
587 IMG_HANDLE hDevice,
588 IMG_HANDLE hBuffer,
589 IMG_SYS_PHYADDR **ppsSysAddr,
590 IMG_UINT32 *pui32ByteSize,
591 IMG_VOID **ppvCpuVAddr,
592 IMG_HANDLE *phOSMapInfo,
593 IMG_BOOL *pbIsContiguous,
594 IMG_UINT32 *pui32TilingStride)
595{
596 OMAPLFB_DEVINFO *psDevInfo;
597 OMAPLFB_BUFFER *psSystemBuffer;
598
599 if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize )
600 {
601 ERROR_PRINTK("Invalid parameters");
602 return PVRSRV_ERROR_INVALID_PARAMS;
603 }
604
605 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
606 psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer;
607 *ppsSysAddr = &psSystemBuffer->sSysAddr;
608 *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize;
609
610 if (ppvCpuVAddr)
611 *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
612
613 if (phOSMapInfo)
614 *phOSMapInfo = (IMG_HANDLE)0;
615
616 if (pbIsContiguous)
617 *pbIsContiguous = IMG_TRUE;
618
619 return PVRSRV_OK;
620}
621
622/*
623 * Creates a swap chain. Called when a 3D application begins.
624 * in: hDevice, ui32Flags, ui32BufferCount, psDstSurfAttrib, psSrcSurfAttrib
625 * ui32OEMFlags
626 * out: phSwapChain, ppsSyncData, pui32SwapChainID
627 */
628static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
629 IMG_UINT32 ui32Flags,
630 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
631 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
632 IMG_UINT32 ui32BufferCount,
633 PVRSRV_SYNC_DATA **ppsSyncData,
634 IMG_UINT32 ui32OEMFlags,
635 IMG_HANDLE *phSwapChain,
636 IMG_UINT32 *pui32SwapChainID)
637{
638 OMAPLFB_DEVINFO *psDevInfo;
639 OMAPLFB_SWAPCHAIN *psSwapChain;
640 OMAPLFB_BUFFER *psBuffer;
641 OMAPLFB_FLIP_ITEM *psFlipItems;
642 IMG_UINT32 i;
643 PVRSRV_ERROR eError = PVRSRV_OK;
644 IMG_UINT32 ui32BuffersToSkip;
645
646 if(!hDevice || !psDstSurfAttrib || !psSrcSurfAttrib ||
647 !ppsSyncData || !phSwapChain)
648 {
649 ERROR_PRINTK("Invalid parameters");
650 return PVRSRV_ERROR_INVALID_PARAMS;
651 }
652 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
653
654 if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
655 {
656 ERROR_PRINTK("Unable to operate with 0 MaxSwapChains for"
657 " display %u", psDevInfo->uDeviceID);
658 return PVRSRV_ERROR_NOT_SUPPORTED;
659 }
660
661 if(psDevInfo->psSwapChain != NULL)
662 {
663 ERROR_PRINTK("Swap chain already exists for"
664 " display %u", psDevInfo->uDeviceID);
665 return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
666 }
667
668 if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
669 {
670 ERROR_PRINTK("Too many buffers. Trying to use %u buffers while"
671 " there is only %u available for display %u",
672 (unsigned int)ui32BufferCount,
673 (unsigned int)psDevInfo->
674 sDisplayInfo.ui32MaxSwapChainBuffers,
675 psDevInfo->uDeviceID);
676 return PVRSRV_ERROR_TOOMANYBUFFERS;
677 }
678
679
680 if ((psDevInfo->sFBInfo.ulRoundedBufferSize *
681 (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize)
682 {
683 ERROR_PRINTK("Too many buffers. Trying to use %u buffers "
684 "(%lu bytes each) while there is only %lu memory for"
685 " display %u",
686 (unsigned int)ui32BufferCount,
687 psDevInfo->sFBInfo.ulRoundedBufferSize,
688 psDevInfo->sFBInfo.ulFBSize,
689 psDevInfo->uDeviceID);
690 return PVRSRV_ERROR_TOOMANYBUFFERS;
691 }
692
693 ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers -
694 ui32BufferCount;
695
696 if((psDstSurfAttrib->pixelformat !=
697 psDevInfo->sDisplayFormat.pixelformat) ||
698 (psDstSurfAttrib->sDims.ui32ByteStride !=
699 psDevInfo->sDisplayDim.ui32ByteStride) ||
700 (psDstSurfAttrib->sDims.ui32Width !=
701 psDevInfo->sDisplayDim.ui32Width) ||
702 (psDstSurfAttrib->sDims.ui32Height !=
703 psDevInfo->sDisplayDim.ui32Height))
704 {
705 ERROR_PRINTK("Destination surface attributes differ from the"
706 " current framebuffer for display %u",
707 psDevInfo->uDeviceID);
708 return PVRSRV_ERROR_INVALID_PARAMS;
709 }
710
711 if((psDstSurfAttrib->pixelformat !=
712 psSrcSurfAttrib->pixelformat) ||
713 (psDstSurfAttrib->sDims.ui32ByteStride !=
714 psSrcSurfAttrib->sDims.ui32ByteStride) ||
715 (psDstSurfAttrib->sDims.ui32Width !=
716 psSrcSurfAttrib->sDims.ui32Width) ||
717 (psDstSurfAttrib->sDims.ui32Height !=
718 psSrcSurfAttrib->sDims.ui32Height))
719 {
720 ERROR_PRINTK("Destination surface attributes differ from the"
721 " target destination surface for display %u",
722 psDevInfo->uDeviceID);
723 return PVRSRV_ERROR_INVALID_PARAMS;
724 }
725
726 /* Allocate memory needed for the swap chain */
727 psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(
728 sizeof(OMAPLFB_SWAPCHAIN));
729 if(!psSwapChain)
730 {
731 ERROR_PRINTK("Out of memory to allocate swap chain for"
732 " display %u", psDevInfo->uDeviceID);
733 return PVRSRV_ERROR_OUT_OF_MEMORY;
734 }
735
736 DEBUG_PRINTK("Creating swap chain 0x%lx for display %u",
737 (unsigned long)psSwapChain, psDevInfo->uDeviceID);
738
739 /* Allocate memory for the buffer abstraction structures */
740 psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(
741 sizeof(OMAPLFB_BUFFER) * ui32BufferCount);
742 if(!psBuffer)
743 {
744 ERROR_PRINTK("Out of memory to allocate the buffer"
745 " abstraction structures for display %u",
746 psDevInfo->uDeviceID);
747 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
748 goto ErrorFreeSwapChain;
749 }
750
751 /* Allocate memory for the flip item abstraction structures */
752 psFlipItems = (OMAPLFB_FLIP_ITEM *)OMAPLFBAllocKernelMem(
753 sizeof(OMAPLFB_FLIP_ITEM) * ui32BufferCount);
754 if (!psFlipItems)
755 {
756 ERROR_PRINTK("Out of memory to allocate the flip item"
757 " abstraction structures for display %u",
758 psDevInfo->uDeviceID);
759 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
760 goto ErrorFreeBuffers;
761 }
762
763 /* Assign to the swap chain structure the initial data */
764 psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
765 psSwapChain->psBuffer = psBuffer;
766 psSwapChain->psFlipItems = psFlipItems;
767 psSwapChain->ulInsertIndex = 0;
768 psSwapChain->ulRemoveIndex = 0;
769 psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
770 psSwapChain->pvDevInfo = (void*)psDevInfo;
771
772 /*
773 * Init the workqueue (single thread, freezable and real time)
774 * and its own work for this display
775 */
776 INIT_WORK(&psDevInfo->sync_display_work, OMAPLFBSyncIHandler);
777 psDevInfo->sync_display_wq =
778 __create_workqueue("pvr_display_sync_wq", 1, 1, 1);
779
780 DEBUG_PRINTK("Swap chain will have %u buffers for display %u",
781 (unsigned int)ui32BufferCount, psDevInfo->uDeviceID);
782 /* Link the buffers available like a circular list */
783 for(i=0; i<ui32BufferCount-1; i++)
784 {
785 psBuffer[i].psNext = &psBuffer[i+1];
786 }
787 psBuffer[i].psNext = &psBuffer[0];
788
789 /* Initialize each buffer abstraction structure */
790 for(i=0; i<ui32BufferCount; i++)
791 {
792 IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
793 IMG_UINT32 ui32BufferOffset = ui32SwapBuffer *
794 (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize;
795 psBuffer[i].psSyncData = ppsSyncData[i];
796 psBuffer[i].sSysAddr.uiAddr =
797 psDevInfo->sFBInfo.sSysAddr.uiAddr +
798 ui32BufferOffset;
799 psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr +
800 ui32BufferOffset;
801 DEBUG_PRINTK("Display %u buffer index %u has physical "
802 "address 0x%x",
803 psDevInfo->uDeviceID,
804 (unsigned int)i,
805 (unsigned int)psBuffer[i].sSysAddr.uiAddr);
806 }
807
808 /* Initialize each flip item abstraction structure */
809 for(i=0; i<ui32BufferCount; i++)
810 {
811 psFlipItems[i].bValid = OMAP_FALSE;
812 psFlipItems[i].bFlipped = OMAP_FALSE;
813 psFlipItems[i].bCmdCompleted = OMAP_FALSE;
814 }
815
816 mutex_lock(&psDevInfo->sSwapChainLockMutex);
817
818 psDevInfo->psSwapChain = psSwapChain;
819 psSwapChain->bFlushCommands = psDevInfo->bFlushCommands;
820 if (psSwapChain->bFlushCommands)
821 psSwapChain->ulSetFlushStateRefCount = 1;
822 else
823 psSwapChain->ulSetFlushStateRefCount = 0;
824
825 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
826
827 if (EnableLFBEventNotification(psDevInfo)!= OMAP_OK)
828 {
829 WARNING_PRINTK("Couldn't enable framebuffer event"
830 " notification for display %u",
831 psDevInfo->uDeviceID);
832 goto ErrorUnRegisterDisplayClient;
833 }
834
835 *phSwapChain = (IMG_HANDLE)psSwapChain;
836
837 return PVRSRV_OK;
838
839ErrorUnRegisterDisplayClient:
840 OMAPLFBFreeKernelMem(psFlipItems);
841ErrorFreeBuffers:
842 OMAPLFBFreeKernelMem(psBuffer);
843ErrorFreeSwapChain:
844 OMAPLFBFreeKernelMem(psSwapChain);
845
846 return eError;
847}
848
849/*
850 * Destroy a swap chain. Called when a 3D application ends.
851 * in: hDevice, hSwapChain
852 */
853static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
854 IMG_HANDLE hSwapChain)
855{
856 OMAPLFB_DEVINFO *psDevInfo;
857 OMAPLFB_SWAPCHAIN *psSwapChain;
858 OMAP_ERROR eError;
859
860 if(!hDevice || !hSwapChain)
861 {
862 ERROR_PRINTK("Invalid parameters");
863 return PVRSRV_ERROR_INVALID_PARAMS;
864 }
865
866 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
867 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
868
869 if (psSwapChain != psDevInfo->psSwapChain)
870 {
871 ERROR_PRINTK("Swap chain handler differs from the one "
872 "present in the display device pointer");
873 return PVRSRV_ERROR_INVALID_PARAMS;
874 }
875
876 DEBUG_PRINTK("Destroying swap chain for display %u",
877 psDevInfo->uDeviceID);
878
879 eError = DisableLFBEventNotification(psDevInfo);
880 if (eError != OMAP_OK)
881 {
882 WARNING_PRINTK("Couldn't disable framebuffer event "
883 "notification");
884 }
885
886 mutex_lock(&psDevInfo->sSwapChainLockMutex);
887
888 FlushInternalSyncQueue(psSwapChain);
889
890 /*
891 * Present the buffer which is at the base of address of
892 * the framebuffer
893 */
894 OMAPLFBFlip(psSwapChain,
895 (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr);
896 psDevInfo->psSwapChain = NULL;
897
898 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
899
900 /* Destroy the workqueue */
901 flush_workqueue(psDevInfo->sync_display_wq);
902 destroy_workqueue(psDevInfo->sync_display_wq);
903
904 OMAPLFBFreeKernelMem(psSwapChain->psFlipItems);
905 OMAPLFBFreeKernelMem(psSwapChain->psBuffer);
906 OMAPLFBFreeKernelMem(psSwapChain);
907
908 return PVRSRV_OK;
909}
910
911
912/*
913 * Get display buffers. These are the buffers that can be allocated
914 * inside the framebuffer memory.
915 * in: hDevice, hSwapChain
916 * out: pui32BufferCount, phBuffer
917 */
918static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
919 IMG_HANDLE hSwapChain,
920 IMG_UINT32 *pui32BufferCount,
921 IMG_HANDLE *phBuffer)
922{
923 OMAPLFB_DEVINFO *psDevInfo;
924 OMAPLFB_SWAPCHAIN *psSwapChain;
925 unsigned long i;
926
927 if(!hDevice || !hSwapChain || !pui32BufferCount || !phBuffer)
928 {
929 ERROR_PRINTK("Invalid parameters");
930 return PVRSRV_ERROR_INVALID_PARAMS;
931 }
932
933 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
934 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
935 if (psSwapChain != psDevInfo->psSwapChain)
936 {
937 ERROR_PRINTK("Swap chain handler differs from the one "
938 "present in the display device %u pointer",
939 psDevInfo->uDeviceID);
940 return PVRSRV_ERROR_INVALID_PARAMS;
941 }
942 *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
943
944 for(i=0; i<psSwapChain->ulBufferCount; i++)
945 phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
946
947 return PVRSRV_OK;
948}
949
950/*
951 * Sets the display state.
952 * in: ui32State, hDevice
953 */
954static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
955{
956 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
957
958 switch (ui32State)
959 {
960 case DC_STATE_FLUSH_COMMANDS:
961 DEBUG_PRINTK("Setting state to flush commands for"
962 " display %u", psDevInfo->uDeviceID);
963 SetFlushStateExternal(psDevInfo, OMAP_TRUE);
964 break;
965 case DC_STATE_NO_FLUSH_COMMANDS:
966 DEBUG_PRINTK("Setting state to not flush commands for"
967 " display %u", psDevInfo->uDeviceID);
968 SetFlushStateExternal(psDevInfo, OMAP_FALSE);
969 break;
970 default:
971 WARNING_PRINTK("Unknown command state %u for display"
972 " %u", (unsigned int)ui32State,
973 psDevInfo->uDeviceID);
974 break;
975 }
976}
977
978/*
979 * Swap to display system buffer. This buffer refers to the one which
980 * is that fits in the framebuffer memory.
981 * in: hDevice, hSwapChain
982 */
983static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
984 IMG_HANDLE hSwapChain)
985{
986 OMAPLFB_DEVINFO *psDevInfo;
987 OMAPLFB_SWAPCHAIN *psSwapChain;
988
989 if(!hDevice || !hSwapChain)
990 {
991 ERROR_PRINTK("Invalid parameters");
992 return PVRSRV_ERROR_INVALID_PARAMS;
993 }
994
995 psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
996 psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
997
998 DEBUG_PRINTK("Executing for display %u",
999 psDevInfo->uDeviceID);
1000
1001 if (psSwapChain != psDevInfo->psSwapChain)
1002 {
1003 ERROR_PRINTK("Swap chain handler differs from the one "
1004 "present in the display device %u pointer",
1005 psDevInfo->uDeviceID);
1006 return PVRSRV_ERROR_INVALID_PARAMS;
1007 }
1008
1009 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1010
1011 FlushInternalSyncQueue(psSwapChain);
1012 OMAPLFBFlip(psSwapChain,
1013 (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr);
1014
1015 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1016
1017 return PVRSRV_OK;
1018}
1019
1020/*
1021 * Handles the synchronization with the display
1022 * in: work
1023 */
1024static void OMAPLFBSyncIHandler(struct work_struct *work)
1025{
1026 OMAPLFB_DEVINFO *psDevInfo = container_of(work, OMAPLFB_DEVINFO,
1027 sync_display_work);
1028 OMAPLFB_FLIP_ITEM *psFlipItem;
1029 OMAPLFB_SWAPCHAIN *psSwapChain;
1030 unsigned long ulMaxIndex;
1031
1032 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1033
1034 psSwapChain = psDevInfo->psSwapChain;
1035 if (!psSwapChain || psSwapChain->bFlushCommands)
1036 goto ExitUnlock;
1037
1038 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
1039 ulMaxIndex = psSwapChain->ulBufferCount - 1;
1040
1041 /* Synchronize with the display */
1042 OMAPLFBWaitForSync(psDevInfo);
1043
1044 /* Iterate through the flip items and flip them if necessary */
1045 while(psFlipItem->bValid)
1046 {
1047 if(psFlipItem->bFlipped)
1048 {
1049 if(!psFlipItem->bCmdCompleted)
1050 {
1051 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
1052 (IMG_HANDLE)psFlipItem->hCmdComplete,
1053 IMG_TRUE);
1054 psFlipItem->bCmdCompleted = OMAP_TRUE;
1055 }
1056 psFlipItem->ulSwapInterval--;
1057
1058 if(psFlipItem->ulSwapInterval == 0)
1059 {
1060 psSwapChain->ulRemoveIndex++;
1061 if(psSwapChain->ulRemoveIndex > ulMaxIndex)
1062 psSwapChain->ulRemoveIndex = 0;
1063 psFlipItem->bCmdCompleted = OMAP_FALSE;
1064 psFlipItem->bFlipped = OMAP_FALSE;
1065 psFlipItem->bValid = OMAP_FALSE;
1066 }
1067 else
1068 {
1069 /*
1070 * Here the swap interval is not zero yet
1071 * we need to schedule another work until
1072 * it reaches zero
1073 */
1074 queue_work(psDevInfo->sync_display_wq,
1075 &psDevInfo->sync_display_work);
1076 goto ExitUnlock;
1077 }
1078 }
1079 else
1080 {
1081 OMAPLFBFlip(psSwapChain,
1082 (unsigned long)psFlipItem->sSysAddr);
1083 psFlipItem->bFlipped = OMAP_TRUE;
1084 /*
1085 * If the flip has been presented here then we need
1086 * in the next sync execute the command complete,
1087 * schedule another work
1088 */
1089 queue_work(psDevInfo->sync_display_wq,
1090 &psDevInfo->sync_display_work);
1091 goto ExitUnlock;
1092 }
1093 psFlipItem =
1094 &psSwapChain->psFlipItems[psSwapChain->ulRemoveIndex];
1095 }
1096
1097ExitUnlock:
1098 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1099}
1100
1101/*
1102 * Performs a flip. This function takes the necessary steps to present
1103 * the buffer to be flipped in the display.
1104 * in: hCmdCookie, ui32DataSize, pvData
1105 */
1106static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
1107 IMG_UINT32 ui32DataSize,
1108 IMG_VOID *pvData)
1109{
1110 DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1111 OMAPLFB_DEVINFO *psDevInfo;
1112 OMAPLFB_BUFFER *psBuffer;
1113 OMAPLFB_SWAPCHAIN *psSwapChain;
1114#if defined(SYS_USING_INTERRUPTS)
1115 OMAPLFB_FLIP_ITEM* psFlipItem;
1116#endif
1117
1118 if(!hCmdCookie || !pvData)
1119 {
1120 WARNING_PRINTK("Ignoring call with NULL parameters");
1121 return IMG_FALSE;
1122 }
1123
1124 psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
1125
1126 if (psFlipCmd == IMG_NULL ||
1127 sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
1128 {
1129 WARNING_PRINTK("NULL command or command data size is wrong");
1130 return IMG_FALSE;
1131 }
1132
1133 psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice;
1134 psBuffer = (OMAPLFB_BUFFER*)psFlipCmd->hExtBuffer;
1135 psSwapChain = (OMAPLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
1136
1137 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1138
1139 if (psDevInfo->bDeviceSuspended)
1140 {
1141 /* If is suspended then assume the commands are completed */
1142 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
1143 hCmdCookie, IMG_TRUE);
1144 goto ExitTrueUnlock;
1145 }
1146
1147#if defined(SYS_USING_INTERRUPTS)
1148
1149 if( psFlipCmd->ui32SwapInterval == 0 ||
1150 psSwapChain->bFlushCommands == OMAP_TRUE)
1151 {
1152#endif
1153 OMAPLFBFlip(psSwapChain,
1154 (unsigned long)psBuffer->sSysAddr.uiAddr);
1155 psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(
1156 hCmdCookie, IMG_TRUE);
1157
1158#if defined(SYS_USING_INTERRUPTS)
1159 goto ExitTrueUnlock;
1160 }
1161
1162 psFlipItem = &psSwapChain->psFlipItems[psSwapChain->ulInsertIndex];
1163
1164 if(psFlipItem->bValid == OMAP_FALSE)
1165 {
1166 unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1;
1167
1168 /*
1169 * If both indexes are equal the queue is empty,
1170 * present immediatly
1171 */
1172 if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex)
1173 {
1174 OMAPLFBFlip(psSwapChain,
1175 (unsigned long)psBuffer->sSysAddr.uiAddr);
1176 psFlipItem->bFlipped = OMAP_TRUE;
1177 }
1178 else
1179 psFlipItem->bFlipped = OMAP_FALSE;
1180
1181 /*
1182 * The buffer is queued here, must be consumed by the workqueue
1183 */
1184 psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie;
1185 psFlipItem->ulSwapInterval =
1186 (unsigned long)psFlipCmd->ui32SwapInterval;
1187 psFlipItem->sSysAddr = &psBuffer->sSysAddr;
1188 psFlipItem->bValid = OMAP_TRUE;
1189
1190 psSwapChain->ulInsertIndex++;
1191 if(psSwapChain->ulInsertIndex > ulMaxIndex)
1192 psSwapChain->ulInsertIndex = 0;
1193
1194 /* Give work to the workqueue to sync with the display */
1195 queue_work(psDevInfo->sync_display_wq, &psDevInfo->sync_display_work);
1196
1197 goto ExitTrueUnlock;
1198 }
1199
1200 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1201 return IMG_FALSE;
1202#endif
1203
1204ExitTrueUnlock:
1205 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1206 return IMG_TRUE;
1207}
1208
1209#if defined(LDM_PLATFORM)
1210
1211/*
1212 * Function called when the driver must suspend
1213 */
1214void OMAPLFBDriverSuspend(void)
1215{
1216 OMAPLFB_DEVINFO *psDevInfo;
1217 int i;
1218
1219 if(!pDisplayDevices)
1220 return;
1221
1222 for(i = 0; i < FRAMEBUFFER_COUNT; i++)
1223 {
1224 psDevInfo = &pDisplayDevices[i];
1225
1226 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1227
1228 if (psDevInfo->bDeviceSuspended)
1229 {
1230 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1231 continue;
1232 }
1233
1234 psDevInfo->bDeviceSuspended = OMAP_TRUE;
1235 SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE);
1236
1237 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1238 }
1239}
1240
1241/*
1242 * Function called when the driver must resume
1243 */
1244void OMAPLFBDriverResume(void)
1245{
1246 OMAPLFB_DEVINFO *psDevInfo;
1247 int i;
1248
1249 if(!pDisplayDevices)
1250 return;
1251
1252 for(i = 0; i < FRAMEBUFFER_COUNT; i++)
1253 {
1254 psDevInfo = &pDisplayDevices[i];
1255
1256 mutex_lock(&psDevInfo->sSwapChainLockMutex);
1257
1258 if (!psDevInfo->bDeviceSuspended)
1259 {
1260 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1261 continue;
1262 }
1263
1264 SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE);
1265 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1266
1267 mutex_unlock(&psDevInfo->sSwapChainLockMutex);
1268 }
1269}
1270#endif /* defined(LDM_PLATFORM) */
1271
1272/*
1273 * Frees the kernel framebuffer
1274 * in: psDevInfo
1275 */
1276static void DeInitDev(OMAPLFB_DEVINFO *psDevInfo)
1277{
1278 struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
1279 struct module *psLINFBOwner;
1280
1281 acquire_console_sem();
1282 psLINFBOwner = psLINFBInfo->fbops->owner;
1283
1284 if (psLINFBInfo->fbops->fb_release != NULL)
1285 (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);
1286
1287 module_put(psLINFBOwner);
1288
1289 release_console_sem();
1290}
1291
1292/*
1293 * Deinitialization routine for the 3rd party display driver
1294 */
1295OMAP_ERROR OMAPLFBDeinit(void)
1296{
1297 OMAPLFB_DEVINFO *psDevInfo;
1298 PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable;
1299 int i;
1300
1301 DEBUG_PRINTK("Deinitializing 3rd party display driver");
1302
1303 if(!pDisplayDevices)
1304 return OMAP_OK;
1305
1306 for(i = 0; i < FRAMEBUFFER_COUNT; i++)
1307 {
1308 psDevInfo = &pDisplayDevices[i];
1309
1310 /* Remove the ProcessFlip command callback */
1311 psJTable = &psDevInfo->sPVRJTable;
1312 if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(
1313 psDevInfo->uDeviceID,
1314 OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1315 {
1316 ERROR_PRINTK("Unable to remove callback for "
1317 "ProcessFlip command for display %u",
1318 psDevInfo->uDeviceID);
1319 return OMAP_ERROR_GENERIC;
1320 }
1321
1322 /* Remove the display device from services */
1323 if (psJTable->pfnPVRSRVRemoveDCDevice(
1324 psDevInfo->uDeviceID) != PVRSRV_OK)
1325 {
1326 ERROR_PRINTK("Unable to remove the display %u "
1327 "from services", psDevInfo->uDeviceID);
1328 return OMAP_ERROR_GENERIC;
1329 }
1330
1331 DeInitDev(psDevInfo);
1332 }
1333
1334 OMAPLFBFreeKernelMem(pDisplayDevices);
1335
1336 return OMAP_OK;
1337}
1338
1339/*
1340 * Extracts the framebuffer data from the kernel driver
1341 * in: psDevInfo
1342 */
1343static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo, int fb_idx)
1344{
1345 struct fb_info *psLINFBInfo;
1346 struct module *psLINFBOwner;
1347 OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
1348 unsigned long FBSize;
1349 int buffers_available;
1350
1351 /* Check if the framebuffer index to use is valid */
1352 if (fb_idx < 0 || fb_idx >= num_registered_fb)
1353 {
1354 ERROR_PRINTK("Framebuffer index %i out of range, "
1355 "only %i available", fb_idx, num_registered_fb);
1356 return OMAP_ERROR_INVALID_DEVICE;
1357 }
1358
1359 /* Get the framebuffer from the kernel */
1360 if (!registered_fb[fb_idx])
1361 {
1362 ERROR_PRINTK("Framebuffer index %i is null", fb_idx);
1363 return OMAP_ERROR_INVALID_DEVICE;
1364 }
1365
1366 psLINFBInfo = registered_fb[fb_idx];
1367
1368 /* Check the framebuffer width and height are valid */
1369 if(psLINFBInfo->var.xres <= 0 || psLINFBInfo->var.yres <= 0)
1370 {
1371 ERROR_PRINTK("Framebuffer %i has an invalid state, "
1372 "width and height are %u,%u", fb_idx,
1373 psLINFBInfo->var.xres, psLINFBInfo->var.yres);
1374 return OMAP_ERROR_INVALID_DEVICE;
1375 }
1376
1377 /* Configure framebuffer for flipping and desired bpp */
1378 psLINFBInfo->var.yres_virtual = psLINFBInfo->var.yres *
1379 MAX_BUFFERS_FLIPPING;
1380
1381 if(DESIRED_BPP != 0){
1382 psLINFBInfo->var.bits_per_pixel = DESIRED_BPP;
1383 if(DESIRED_BPP == 16){
1384 psLINFBInfo->var.red.offset = 11;
1385 psLINFBInfo->var.red.length = 5;
1386 psLINFBInfo->var.green.offset = 5;
1387 psLINFBInfo->var.green.length = 6;
1388 psLINFBInfo->var.blue.offset = 0;
1389 psLINFBInfo->var.blue.length = 5;
1390 psLINFBInfo->var.transp.offset = 0;
1391 psLINFBInfo->var.transp.length = 0;
1392 }
1393 else if(DESIRED_BPP == 32)
1394 {
1395 psLINFBInfo->var.red.offset = 16;
1396 psLINFBInfo->var.red.length = 8;
1397 psLINFBInfo->var.green.offset = 8;
1398 psLINFBInfo->var.green.length = 8;
1399 psLINFBInfo->var.blue.offset = 0;
1400 psLINFBInfo->var.blue.length = 8;
1401 psLINFBInfo->var.transp.offset = 0;
1402 psLINFBInfo->var.transp.length = 0;
1403 }
1404 else
1405 WARNING_PRINTK("Unknown bits per pixel format %i",
1406 DESIRED_BPP);
1407 }
1408 acquire_console_sem();
1409 psLINFBInfo->var.activate = FB_ACTIVATE_FORCE;
1410 fb_set_var(psLINFBInfo, &psLINFBInfo->var);
1411 buffers_available =
1412 psLINFBInfo->var.yres_virtual / psLINFBInfo->var.yres;
1413
1414 if(buffers_available <= 1)
1415 {
1416 /*
1417 * Flipping is not supported, return the framebuffer to
1418 * its original state
1419 */
1420 psLINFBInfo->var.yres_virtual = psLINFBInfo->var.yres;
1421 psLINFBInfo->var.activate = FB_ACTIVATE_FORCE;
1422 fb_set_var(psLINFBInfo, &psLINFBInfo->var);
1423 buffers_available = 1;
1424 }
1425 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = buffers_available;
1426
1427 psLINFBOwner = psLINFBInfo->fbops->owner;
1428 if (!try_module_get(psLINFBOwner))
1429 {
1430 ERROR_PRINTK("Couldn't get framebuffer module");
1431 release_console_sem();
1432 return OMAP_ERROR_GENERIC;
1433 }
1434
1435 if (psLINFBInfo->fbops->fb_open != NULL)
1436 {
1437 if (psLINFBInfo->fbops->fb_open(psLINFBInfo, 0))
1438 {
1439 ERROR_PRINTK("Couldn't open framebuffer with"
1440 " index %d", fb_idx);
1441 module_put(psLINFBOwner);
1442 release_console_sem();
1443 return OMAP_ERROR_GENERIC;
1444 }
1445 }
1446 psDevInfo->psLINFBInfo = psLINFBInfo;
1447
1448 /* Extract the needed data from the framebuffer structures */
1449 FBSize = (psLINFBInfo->screen_size) != 0 ?
1450 psLINFBInfo->screen_size : psLINFBInfo->fix.smem_len;
1451 DEBUG_PRINTK("Framebuffer index %d information:", fb_idx);
1452 DEBUG_PRINTK("*Physical address: 0x%lx",
1453 psLINFBInfo->fix.smem_start);
1454 DEBUG_PRINTK("*Virtual address: 0x%lx",
1455 (unsigned long)psLINFBInfo->screen_base);
1456 DEBUG_PRINTK("*Size (bytes): %lu",FBSize);
1457 DEBUG_PRINTK("*Width, height: %u,%u",
1458 psLINFBInfo->var.xres, psLINFBInfo->var.yres);
1459 DEBUG_PRINTK("*Virtual width, height: %u,%u",
1460 psLINFBInfo->var.xres_virtual, psLINFBInfo->var.yres_virtual);
1461 DEBUG_PRINTK("*Rotation: %u", psLINFBInfo->var.rotate);
1462 DEBUG_PRINTK("*Stride (bytes): %u",
1463 (unsigned int)psLINFBInfo->fix.line_length);
1464
1465 psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start;
1466 psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base;
1467 psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
1468 psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
1469 psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length;
1470 psPVRFBInfo->ulFBSize = FBSize;
1471 psPVRFBInfo->ulBufferSize =
1472 psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
1473
1474 /* XXX: Page aligning with 16bpp causes the
1475 * position of framebuffer address to look in the wrong place.
1476 */
1477 psPVRFBInfo->ulRoundedBufferSize =
1478 OMAPLFB_PAGE_ROUNDUP(psPVRFBInfo->ulBufferSize);
1479
1480 psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr;
1481 psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr;
1482
1483 /* Get the current bits per pixel configured in the framebuffer */
1484 DEBUG_PRINTK("*Bits per pixel: %d", psLINFBInfo->var.bits_per_pixel);
1485 if(psLINFBInfo->var.bits_per_pixel == 16)
1486 {
1487 if((psLINFBInfo->var.red.length == 5) &&
1488 (psLINFBInfo->var.green.length == 6) &&
1489 (psLINFBInfo->var.blue.length == 5) &&
1490 (psLINFBInfo->var.red.offset == 11) &&
1491 (psLINFBInfo->var.green.offset == 5) &&
1492 (psLINFBInfo->var.blue.offset == 0) &&
1493 (psLINFBInfo->var.red.msb_right == 0))
1494 {
1495 DEBUG_PRINTK("*Format: RGB565");
1496 psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565;
1497 }
1498 else
1499 WARNING_PRINTK("*Format: Unknown framebuffer"
1500 " format");
1501 }
1502 else if(psLINFBInfo->var.bits_per_pixel == 32)
1503 {
1504 if((psLINFBInfo->var.red.length == 8) &&
1505 (psLINFBInfo->var.green.length == 8) &&
1506 (psLINFBInfo->var.blue.length == 8) &&
1507 (psLINFBInfo->var.red.offset == 16) &&
1508 (psLINFBInfo->var.green.offset == 8) &&
1509 (psLINFBInfo->var.blue.offset == 0) &&
1510 (psLINFBInfo->var.red.msb_right == 0))
1511 {
1512 psPVRFBInfo->ePixelFormat =
1513 PVRSRV_PIXEL_FORMAT_ARGB8888;
1514 DEBUG_PRINTK("*Format: ARGB8888");
1515 }
1516 else
1517 WARNING_PRINTK("*Format: Unknown framebuffer"
1518 "format");
1519 }
1520 else
1521 WARNING_PRINTK("*Format: Unknown framebuffer format");
1522
1523 release_console_sem();
1524 return OMAP_OK;
1525}
1526
1527/*
1528 * Initialization routine for the 3rd party display driver
1529 */
1530OMAP_ERROR OMAPLFBInit(void)
1531{
1532 OMAPLFB_DEVINFO *psDevInfo;
1533 PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
1534 IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2];
1535 int i;
1536
1537 DEBUG_PRINTK("Initializing 3rd party display driver");
1538 DEBUG_PRINTK("Found %u framebuffers", FRAMEBUFFER_COUNT);
1539
1540#if defined(REQUIRES_TWO_FRAMEBUFFERS)
1541 /*
1542 * Fail hard if there isn't at least two framebuffers available
1543 */
1544 if(FRAMEBUFFER_COUNT < 2)
1545 {
1546 ERROR_PRINTK("Driver needs at least two framebuffers");
1547 return OMAP_ERROR_INIT_FAILURE;
1548 }
1549#endif
1550
1551 /*
1552 * Obtain the function pointer for the jump table from
1553 * services to fill it with the function pointers that we want
1554 */
1555 if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable",
1556 &pfnGetPVRJTable) != OMAP_OK)
1557 {
1558 ERROR_PRINTK("Unable to get the function to get the"
1559 " jump table display->services");
1560 return OMAP_ERROR_INIT_FAILURE;
1561 }
1562
1563 /*
1564 * Allocate the display device structures, one per framebuffer
1565 */
1566 pDisplayDevices = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(
1567 sizeof(OMAPLFB_DEVINFO) * FRAMEBUFFER_COUNT);
1568 if(!pDisplayDevices)
1569 {
1570 pDisplayDevices = NULL;
1571 ERROR_PRINTK("Out of memory");
1572 return OMAP_ERROR_OUT_OF_MEMORY;
1573 }
1574 memset(pDisplayDevices, 0, sizeof(OMAPLFB_DEVINFO) *
1575 FRAMEBUFFER_COUNT);
1576
1577 /*
1578 * Initialize each display device
1579 */
1580 for (i = FRAMEBUFFER_COUNT - 1; i >= 0; i--)
1581 {
1582 DEBUG_PRINTK("-> Initializing display device %i", i);
1583 /*
1584 * Here we get the framebuffer data for each display device
1585 * and check for error
1586 */
1587 if(InitDev(&pDisplayDevices[i], i) != OMAP_OK)
1588 {
1589 ERROR_PRINTK("Unable to initialize display "
1590 "device %i",i);
1591 OMAPLFBFreeKernelMem(pDisplayDevices);
1592 pDisplayDevices = NULL;
1593 return OMAP_ERROR_INIT_FAILURE;
1594 }
1595
1596 /*
1597 * Populate each display device structure
1598 */
1599 DEBUG_PRINTK("-> Populating display device %i", i);
1600 psDevInfo = &pDisplayDevices[i];
1601
1602 if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
1603 {
1604 ERROR_PRINTK("Unable to get the jump table"
1605 " display->services");
1606 return OMAP_ERROR_INIT_FAILURE;
1607 }
1608
1609 mutex_init(&psDevInfo->sSwapChainLockMutex);
1610
1611 psDevInfo->psSwapChain = 0;
1612 psDevInfo->bFlushCommands = OMAP_FALSE;
1613 psDevInfo->bDeviceSuspended = OMAP_FALSE;
1614
1615 if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 1)
1616 {
1617 if(MAX_BUFFERS_FLIPPING == 1)
1618 {
1619 DEBUG_PRINTK("Flipping support is possible"
1620 " but you decided not to use it, "
1621 "no swap chain will be created");
1622 }
1623
1624 DEBUG_PRINTK("Flipping support");
1625 if(psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers >
1626 MAX_BUFFERS_FLIPPING)
1627 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers =
1628 MAX_BUFFERS_FLIPPING;
1629 }
1630 else
1631 {
1632 DEBUG_PRINTK("Flipping not supported, no swap chain"
1633 " will be created");
1634 }
1635
1636 if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0)
1637 {
1638 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0;
1639 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0;
1640 }
1641 else
1642 {
1643 psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
1644 psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
1645 }
1646 psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
1647
1648 /* Get the display and framebuffer needed info */
1649 strncpy(psDevInfo->sDisplayInfo.szDisplayName,
1650 DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
1651 psDevInfo->sDisplayFormat.pixelformat =
1652 psDevInfo->sFBInfo.ePixelFormat;
1653 psDevInfo->sDisplayDim.ui32Width =
1654 (IMG_UINT32)psDevInfo->sFBInfo.ulWidth;
1655 psDevInfo->sDisplayDim.ui32Height =
1656 (IMG_UINT32)psDevInfo->sFBInfo.ulHeight;
1657 psDevInfo->sDisplayDim.ui32ByteStride =
1658 (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride;
1659 psDevInfo->sSystemBuffer.sSysAddr =
1660 psDevInfo->sFBInfo.sSysAddr;
1661 psDevInfo->sSystemBuffer.sCPUVAddr =
1662 psDevInfo->sFBInfo.sCPUVAddr;
1663 psDevInfo->sSystemBuffer.ulBufferSize =
1664 psDevInfo->sFBInfo.ulRoundedBufferSize;
1665 DEBUG_PRINTK("Buffers available: %u (%lu bytes per buffer)",
1666 psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers,
1667 psDevInfo->sFBInfo.ulBufferSize);
1668
1669 /* Populate the function table that services will use */
1670 psDevInfo->sDCJTable.ui32TableSize =
1671 sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
1672 psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
1673 psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
1674 psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
1675 psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
1676 psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
1677 psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
1678 psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
1679 psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
1680 psDevInfo->sDCJTable.pfnDestroyDCSwapChain =
1681 DestroyDCSwapChain;
1682 psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
1683 psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
1684 psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
1685 psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
1686 psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
1687 psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
1688 psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
1689 psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
1690
1691 /* Register the display device */
1692 if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice(
1693 &psDevInfo->sDCJTable,
1694 &psDevInfo->uDeviceID) != PVRSRV_OK)
1695 {
1696 ERROR_PRINTK("Unable to register the jump table"
1697 " services->display");
1698 return OMAP_ERROR_DEVICE_REGISTER_FAILED;
1699 }
1700
1701 DEBUG_PRINTK("Display device %i registered with id %u",
1702 i, psDevInfo->uDeviceID);
1703
1704 /*
1705 * Register the ProcessFlip function to notify when a frame is
1706 * ready to be flipped
1707 */
1708 pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
1709 aui32SyncCountList[DC_FLIP_COMMAND][0] = 0;
1710 aui32SyncCountList[DC_FLIP_COMMAND][1] = 2;
1711 if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(
1712 psDevInfo->uDeviceID, &pfnCmdProcList[0],
1713 aui32SyncCountList, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
1714 {
1715 ERROR_PRINTK("Unable to register callback for "
1716 "ProcessFlip command");
1717 return OMAP_ERROR_CANT_REGISTER_CALLBACK;
1718 }
1719
1720 }
1721 return OMAP_OK;
1722}
1723
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_linux.c b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
new file mode 100644
index 00000000000..4f1ac9b0da5
--- /dev/null
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_linux.c
@@ -0,0 +1,437 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28#include <linux/config.h>
29#endif
30
31#include <linux/version.h>
32#include <linux/module.h>
33#include <linux/fb.h>
34#include <asm/io.h>
35
36#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
37#include <plat/vrfb.h>
38#include <plat/display.h>
39#else
40#include <mach/vrfb.h>
41#include <mach/display.h>
42#endif
43
44#ifdef RELEASE
45#include <../drivers/video/omap2/omapfb/omapfb.h>
46#undef DEBUG
47#else
48#undef DEBUG
49#include <../drivers/video/omap2/omapfb/omapfb.h>
50#endif
51
52#if defined(CONFIG_OUTER_CACHE) /* Kernel config option */
53#include <asm/cacheflush.h>
54#define HOST_PAGESIZE (4096)
55#define HOST_PAGEMASK (~(HOST_PAGESIZE-1))
56#define HOST_PAGEALIGN(addr) (((addr)+HOST_PAGESIZE-1)&HOST_PAGEMASK)
57#endif
58
59#if defined(LDM_PLATFORM)
60#include <linux/platform_device.h>
61#if defined(SGX_EARLYSUSPEND)
62#include <linux/earlysuspend.h>
63#endif
64#endif
65
66
67#include "img_defs.h"
68#include "servicesext.h"
69#include "kerneldisplay.h"
70#include "omaplfb.h"
71#include "pvrmodule.h"
72
73MODULE_SUPPORTED_DEVICE(DEVNAME);
74
75#if defined(CONFIG_OUTER_CACHE) /* Kernel config option */
76#if defined(__arm__)
77static void per_cpu_cache_flush_arm(void *arg)
78{
79 PVR_UNREFERENCED_PARAMETER(arg);
80 flush_cache_all();
81}
82#endif
83#endif
84
85/*
86 * Kernel malloc
87 * in: ui32ByteSize
88 */
89void *OMAPLFBAllocKernelMem(unsigned long ui32ByteSize)
90{
91 void *p;
92
93#if defined(CONFIG_OUTER_CACHE) /* Kernel config option */
94 IMG_VOID *pvPageAlignedCPUPAddr;
95 IMG_VOID *pvPageAlignedCPUVAddr;
96 IMG_UINT32 ui32PageOffset;
97 IMG_UINT32 ui32PageCount;
98#endif
99 p = kmalloc(ui32ByteSize, GFP_KERNEL);
100
101 if(!p)
102 return 0;
103
104#if defined(CONFIG_OUTER_CACHE) /* Kernel config option */
105 ui32PageOffset = (IMG_UINT32) p & (HOST_PAGESIZE - 1);
106 ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / HOST_PAGESIZE;
107
108 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINT8 *)p - ui32PageOffset);
109 pvPageAlignedCPUPAddr = (IMG_VOID*) __pa(pvPageAlignedCPUVAddr);
110
111#if defined(__arm__)
112 on_each_cpu(per_cpu_cache_flush_arm, NULL, 1);
113#endif
114 outer_cache.flush_range((unsigned long) pvPageAlignedCPUPAddr, (unsigned long) ((pvPageAlignedCPUPAddr + HOST_PAGESIZE*ui32PageCount) - 1));
115#endif
116 return p;
117}
118
119/*
120 * Kernel free
121 * in: pvMem
122 */
123void OMAPLFBFreeKernelMem(void *pvMem)
124{
125 kfree(pvMem);
126}
127
128/*
129 * Here we get the function pointer to get jump table from
130 * services using an external function.
131 * in: szFunctionName
132 * out: ppfnFuncTable
133 */
134OMAP_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName,
135 PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
136{
137 if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
138 {
139 ERROR_PRINTK("Unable to get function pointer for %s"
140 " from services", szFunctionName);
141 return OMAP_ERROR_INVALID_PARAMS;
142 }
143 *ppfnFuncTable = PVRGetDisplayClassJTable;
144
145 return OMAP_OK;
146}
147
148
149#if defined(FLIP_TECHNIQUE_FRAMEBUFFER)
150/*
151 * Presents the flip in the display with the framebuffer API
152 * in: psSwapChain, aPhyAddr
153 */
154void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
155{
156 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
157 struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
158 struct omapfb_info *ofbi = FB2OFB(framebuffer);
159 struct omapfb2_device *fbdev = ofbi->fbdev;
160 /* Get the framebuffer physical address base */
161 unsigned long fb_base_phyaddr =
162 psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
163
164 omapfb_lock(fbdev);
165
166 /* Calculate the virtual Y to move in the framebuffer */
167 framebuffer->var.yoffset =
168 (aPhyAddr - fb_base_phyaddr) / framebuffer->fix.line_length;
169 framebuffer->var.activate = FB_ACTIVATE_FORCE;
170 fb_set_var(framebuffer, &framebuffer->var);
171
172 omapfb_unlock(fbdev);
173}
174
175#elif defined(FLIP_TECHNIQUE_OVERLAY)
176/*
177 * Presents the flip in the display with the DSS2 overlay API
178 * in: psSwapChain, aPhyAddr
179 */
180void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
181{
182 OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)psSwapChain->pvDevInfo;
183 struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
184 struct omapfb_info *ofbi = FB2OFB(framebuffer);
185 struct omapfb2_device *fbdev = ofbi->fbdev;
186 unsigned long fb_offset =
187 aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
188 struct omap_overlay* overlay;
189 struct omap_overlay_info overlay_info;
190 int i;
191
192 fb_offset = aPhyAddr - psDevInfo->sSystemBuffer.sSysAddr.uiAddr;
193
194 omapfb_lock(fbdev);
195
196 for(i = 0; i < ofbi->num_overlays ; i++)
197 {
198 overlay = ofbi->overlays[i];
199 overlay->get_overlay_info( overlay, &overlay_info );
200
201 /* If the overlay is not enabled don't update it */
202 if(!overlay_info.enabled)
203 continue;
204
205 overlay_info.paddr = framebuffer->fix.smem_start + fb_offset;
206 overlay_info.vaddr = framebuffer->screen_base + fb_offset;
207 overlay->set_overlay_info(overlay, &overlay_info);
208 overlay->manager->apply(overlay->manager);
209
210#if 0
211 /* FIXME: Update call takes a long time in 2.6.35.
212 * Needs to be resolved in the display driver
213 * before we can enable this.
214 */
215 if(overlay->manager->device->driver->update)
216 {
217 overlay->manager->device->driver->update(
218 overlay->manager->device, 0, 0,
219 overlay_info.width,
220 overlay_info.height);
221 }
222#endif
223
224 }
225
226 omapfb_unlock(fbdev);
227}
228
229#else
230#error No flipping technique selected, please define \
231 FLIP_TECHNIQUE_FRAMEBUFFER or FLIP_TECHNIQUE_OVERLAY
232#endif
233
234/*
235 * Synchronize with the display to prevent tearing
236 * On DSI panels the display->sync function is used to handle FRAMEDONE IRQ
237 * On DPI panels the display->wait_vsync is used to handle VSYNC IRQ
238 * in: psDevInfo
239 */
240void OMAPLFBWaitForSync(OMAPLFB_DEVINFO *psDevInfo)
241{
242 struct fb_info * framebuffer = psDevInfo->psLINFBInfo;
243 struct omap_dss_device *display = fb2display(framebuffer);
244 if (display)
245 {
246 display->manager->wait_for_vsync(display->manager);
247 }
248}
249
250#if defined(LDM_PLATFORM)
251
252static volatile OMAP_BOOL bDeviceSuspended;
253
254/*
255 * Common suspend driver function
256 * in: psSwapChain, aPhyAddr
257 */
258static void OMAPLFBCommonSuspend(void)
259{
260 if (bDeviceSuspended)
261 {
262 DEBUG_PRINTK("Driver is already suspended");
263 return;
264 }
265
266 OMAPLFBDriverSuspend();
267 bDeviceSuspended = OMAP_TRUE;
268}
269
270#if 0
271/*
272 * Function called when the driver is requested to release
273 * in: pDevice
274 */
275static void OMAPLFBDeviceRelease_Entry(struct device unref__ *pDevice)
276{
277 DEBUG_PRINTK("Requested driver release");
278 OMAPLFBCommonSuspend();
279}
280
281static struct platform_device omaplfb_device = {
282 .name = DEVNAME,
283 .id = -1,
284 .dev = {
285 .release = OMAPLFBDeviceRelease_Entry
286 }
287};
288#endif
289
290#if defined(SGX_EARLYSUSPEND)
291
292static struct early_suspend omaplfb_early_suspend;
293
294/*
295 * Android specific, driver is requested to be suspended
296 * in: ea_event
297 */
298static void OMAPLFBDriverSuspend_Entry(struct early_suspend *ea_event)
299{
300 DEBUG_PRINTK("Requested driver suspend");
301 OMAPLFBCommonSuspend();
302}
303
304/*
305 * Android specific, driver is requested to be suspended
306 * in: ea_event
307 */
308static void OMAPLFBDriverResume_Entry(struct early_suspend *ea_event)
309{
310 DEBUG_PRINTK("Requested driver resume");
311 OMAPLFBDriverResume();
312 bDeviceSuspended = OMAP_FALSE;
313}
314
315static struct platform_driver omaplfb_driver = {
316 .driver = {
317 .name = DRVNAME,
318 }
319};
320
321#else /* defined(SGX_EARLYSUSPEND) */
322
323/*
324 * Function called when the driver is requested to be suspended
325 * in: pDevice, state
326 */
327static int OMAPLFBDriverSuspend_Entry(struct platform_device unref__ *pDevice,
328 pm_message_t unref__ state)
329{
330 DEBUG_PRINTK("Requested driver suspend");
331 OMAPLFBCommonSuspend();
332 return 0;
333}
334
335/*
336 * Function called when the driver is requested to resume
337 * in: pDevice
338 */
339static int OMAPLFBDriverResume_Entry(struct platform_device unref__ *pDevice)
340{
341 DEBUG_PRINTK("Requested driver resume");
342 OMAPLFBDriverResume();
343 bDeviceSuspended = OMAP_FALSE;
344 return 0;
345}
346
347/*
348 * Function called when the driver is requested to shutdown
349 * in: pDevice
350 */
351static IMG_VOID OMAPLFBDriverShutdown_Entry(
352 struct platform_device unref__ *pDevice)
353{
354 DEBUG_PRINTK("Requested driver shutdown");
355 OMAPLFBCommonSuspend();
356}
357
358static struct platform_driver omaplfb_driver = {
359 .driver = {
360 .name = DRVNAME,
361 },
362 .suspend = OMAPLFBDriverSuspend_Entry,
363 .resume = OMAPLFBDriverResume_Entry,
364 .shutdown = OMAPLFBDriverShutdown_Entry,
365};
366
367#endif /* defined(SGX_EARLYSUSPEND) */
368
369#endif /* defined(LDM_PLATFORM) */
370
371/*
372 * Driver init function
373 */
374static int __init OMAPLFB_Init(void)
375{
376 if(OMAPLFBInit() != OMAP_OK)
377 {
378 WARNING_PRINTK("Driver init failed");
379 return -ENODEV;
380 }
381
382#if defined(LDM_PLATFORM)
383 DEBUG_PRINTK("Registering platform driver");
384 if (platform_driver_register(&omaplfb_driver))
385 {
386 WARNING_PRINTK("Unable to register platform driver");
387 if(OMAPLFBDeinit() != OMAP_OK)
388 WARNING_PRINTK("Driver cleanup failed\n");
389 return -ENODEV;
390 }
391#if 0
392 DEBUG_PRINTK("Registering device driver");
393 if (platform_device_register(&omaplfb_device))
394 {
395 WARNING_PRINTK("Unable to register platform device");
396 platform_driver_unregister(&omaplfb_driver);
397 if(OMAPLFBDeinit() != OMAP_OK)
398 WARNING_PRINTK("Driver cleanup failed\n");
399 return -ENODEV;
400 }
401#endif
402
403#if defined(SGX_EARLYSUSPEND)
404 omaplfb_early_suspend.suspend = OMAPLFBDriverSuspend_Entry;
405 omaplfb_early_suspend.resume = OMAPLFBDriverResume_Entry;
406 omaplfb_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
407 register_early_suspend(&omaplfb_early_suspend);
408 DEBUG_PRINTK("Registered early suspend support");
409#endif
410
411#endif
412 return 0;
413}
414
415/*
416 * Driver exit function
417 */
418static IMG_VOID __exit OMAPLFB_Cleanup(IMG_VOID)
419{
420#if defined(LDM_PLATFORM)
421#if 0
422 DEBUG_PRINTK(format,...)("Removing platform device");
423 platform_device_unregister(&omaplfb_device);
424#endif
425 DEBUG_PRINTK("Removing platform driver");
426 platform_driver_unregister(&omaplfb_driver);
427#if defined(SGX_EARLYSUSPEND)
428 unregister_early_suspend(&omaplfb_early_suspend);
429#endif
430#endif
431 if(OMAPLFBDeinit() != OMAP_OK)
432 WARNING_PRINTK("Driver cleanup failed");
433}
434
435late_initcall(OMAPLFB_Init);
436module_exit(OMAPLFB_Cleanup);
437
diff --git a/drivers/gpu/pvr/osfunc.c b/drivers/gpu/pvr/osfunc.c
new file mode 100644
index 00000000000..e465228de64
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc.c
@@ -0,0 +1,2906 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/version.h>
32#include <asm/io.h>
33#include <asm/page.h>
34#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
35#include <asm/system.h>
36#endif
37#include <asm/cacheflush.h>
38#include <linux/mm.h>
39#include <linux/pagemap.h>
40#include <linux/hugetlb.h>
41#include <linux/slab.h>
42#include <linux/vmalloc.h>
43#include <linux/delay.h>
44#include <linux/pci.h>
45
46#include <linux/string.h>
47#include <linux/sched.h>
48#include <linux/interrupt.h>
49#include <asm/hardirq.h>
50#include <linux/timer.h>
51#include <linux/capability.h>
52#include <asm/uaccess.h>
53#include <linux/spinlock.h>
54#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
55 defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
56 defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
57 defined(PVR_LINUX_USING_WORKQUEUES)
58#include <linux/workqueue.h>
59#endif
60
61#include "img_types.h"
62#include "services_headers.h"
63#include "mm.h"
64#include "pvrmmap.h"
65#include "mmap.h"
66#include "env_data.h"
67#include "proc.h"
68#include "mutex.h"
69#include "event.h"
70#include "linkage.h"
71#include "pvr_uaccess.h"
72
73#define EVENT_OBJECT_TIMEOUT_MS (100)
74
75#define HOST_ALLOC_MEM_USING_KMALLOC ((IMG_HANDLE)0)
76#define HOST_ALLOC_MEM_USING_VMALLOC ((IMG_HANDLE)1)
77
78#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
79PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
80#else
81PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
82#endif
83{
84 PVR_UNREFERENCED_PARAMETER(ui32Flags);
85
86#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
87 *ppvCpuVAddr = _KMallocWrapper(ui32Size, pszFilename, ui32Line);
88#else
89 *ppvCpuVAddr = KMallocWrapper(ui32Size);
90#endif
91 if(*ppvCpuVAddr)
92 {
93 if (phBlockAlloc)
94 {
95
96 *phBlockAlloc = HOST_ALLOC_MEM_USING_KMALLOC;
97 }
98 }
99 else
100 {
101 if (!phBlockAlloc)
102 {
103 return PVRSRV_ERROR_OUT_OF_MEMORY;
104 }
105
106
107#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
108 *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line);
109#else
110 *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED);
111#endif
112 if (!*ppvCpuVAddr)
113 {
114 return PVRSRV_ERROR_OUT_OF_MEMORY;
115 }
116
117
118 *phBlockAlloc = HOST_ALLOC_MEM_USING_VMALLOC;
119 }
120
121 return PVRSRV_OK;
122}
123
124
125#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
126PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
127#else
128PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
129#endif
130{
131 PVR_UNREFERENCED_PARAMETER(ui32Flags);
132 PVR_UNREFERENCED_PARAMETER(ui32Size);
133
134 if (hBlockAlloc == HOST_ALLOC_MEM_USING_VMALLOC)
135 {
136#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
137 _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
138#else
139 VFreeWrapper(pvCpuVAddr);
140#endif
141 }
142 else
143 {
144#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
145 _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
146#else
147 KFreeWrapper(pvCpuVAddr);
148#endif
149 }
150
151 return PVRSRV_OK;
152}
153
154
155PVRSRV_ERROR
156OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags,
157 IMG_UINT32 ui32Size,
158 IMG_UINT32 ui32PageSize,
159 IMG_VOID **ppvCpuVAddr,
160 IMG_HANDLE *phOSMemHandle)
161{
162 LinuxMemArea *psLinuxMemArea;
163
164 PVR_UNREFERENCED_PARAMETER(ui32PageSize);
165
166#if 0
167
168 if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
169 {
170 ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
171 ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
172 }
173#endif
174
175 switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
176 {
177 case PVRSRV_HAP_KERNEL_ONLY:
178 {
179 psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
180 if(!psLinuxMemArea)
181 {
182 return PVRSRV_ERROR_OUT_OF_MEMORY;
183 }
184 break;
185 }
186 case PVRSRV_HAP_SINGLE_PROCESS:
187 {
188
189
190 psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
191 if(!psLinuxMemArea)
192 {
193 return PVRSRV_ERROR_OUT_OF_MEMORY;
194 }
195 PVRMMapRegisterArea(psLinuxMemArea);
196 break;
197 }
198
199 case PVRSRV_HAP_MULTI_PROCESS:
200 {
201
202#if defined(VIVT_CACHE) || defined(__sh__)
203
204 ui32AllocFlags &= ~PVRSRV_HAP_CACHED;
205#endif
206 psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
207 if(!psLinuxMemArea)
208 {
209 return PVRSRV_ERROR_OUT_OF_MEMORY;
210 }
211 PVRMMapRegisterArea(psLinuxMemArea);
212 break;
213 }
214 default:
215 PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags));
216 *ppvCpuVAddr = NULL;
217 *phOSMemHandle = (IMG_HANDLE)0;
218 return PVRSRV_ERROR_INVALID_PARAMS;
219 }
220
221 *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
222 *phOSMemHandle = psLinuxMemArea;
223
224 LinuxMemAreaRegister(psLinuxMemArea);
225
226 return PVRSRV_OK;
227}
228
229
230PVRSRV_ERROR
231OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle)
232{
233 LinuxMemArea *psLinuxMemArea;
234 PVRSRV_ERROR eError;
235
236 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
237 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
238
239 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
240
241 switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
242 {
243 case PVRSRV_HAP_KERNEL_ONLY:
244 break;
245 case PVRSRV_HAP_SINGLE_PROCESS:
246 case PVRSRV_HAP_MULTI_PROCESS:
247 eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
248 if (eError != PVRSRV_OK)
249 {
250 PVR_DPF((PVR_DBG_ERROR,
251 "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%d, "
252 "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
253 ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
254 return eError;
255 }
256 break;
257 default:
258 PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n",
259 __FUNCTION__, ui32AllocFlags));
260 return PVRSRV_ERROR_INVALID_PARAMS;
261 }
262
263 LinuxMemAreaDeepFree(psLinuxMemArea);
264
265 return PVRSRV_OK;
266}
267
268
269PVRSRV_ERROR
270OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
271 IMG_UINT32 ui32ByteOffset,
272 IMG_UINT32 ui32Bytes,
273 IMG_UINT32 ui32Flags,
274 IMG_HANDLE *phOSMemHandleRet)
275{
276 LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea;
277 PVRSRV_ERROR eError;
278
279 psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
280
281 psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes);
282 if(!psLinuxMemArea)
283 {
284 *phOSMemHandleRet = NULL;
285 return PVRSRV_ERROR_OUT_OF_MEMORY;
286 }
287 *phOSMemHandleRet = psLinuxMemArea;
288
289
290 if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY)
291 {
292 return PVRSRV_OK;
293 }
294
295 eError = PVRMMapRegisterArea(psLinuxMemArea);
296 if(eError != PVRSRV_OK)
297 {
298 goto failed_register_area;
299 }
300
301 return PVRSRV_OK;
302
303failed_register_area:
304 *phOSMemHandleRet = NULL;
305 LinuxMemAreaDeepFree(psLinuxMemArea);
306 return eError;
307}
308
309PVRSRV_ERROR
310OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags)
311{
312 LinuxMemArea *psLinuxMemArea;
313 PVRSRV_ERROR eError;
314
315 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
316 PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
317
318 if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0)
319 {
320 eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
321 if(eError != PVRSRV_OK)
322 {
323 return eError;
324 }
325 }
326 LinuxMemAreaDeepFree(psLinuxMemArea);
327
328 return PVRSRV_OK;
329}
330
331
332IMG_CPU_PHYADDR
333OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset)
334{
335 PVR_ASSERT(hOSMemHandle);
336
337 return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
338}
339
340
341
342IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
343{
344#if defined(USE_UNOPTIMISED_MEMCPY)
345 IMG_UINT8 *Src,*Dst;
346 IMG_INT i;
347
348 Src=(IMG_UINT8 *)pvSrc;
349 Dst=(IMG_UINT8 *)pvDst;
350 for(i=0;i<ui32Size;i++)
351 {
352 Dst[i]=Src[i];
353 }
354#else
355 memcpy(pvDst, pvSrc, ui32Size);
356#endif
357}
358
359
360IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
361{
362#if defined(USE_UNOPTIMISED_MEMSET)
363 IMG_UINT8 *Buff;
364 IMG_INT i;
365
366 Buff=(IMG_UINT8 *)pvDest;
367 for(i=0;i<ui32Size;i++)
368 {
369 Buff[i]=ui8Value;
370 }
371#else
372 memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
373#endif
374}
375
376
377IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
378{
379 return (strcpy(pszDest, pszSrc));
380}
381
382IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
383{
384 va_list argList;
385 IMG_INT32 iCount;
386
387 va_start(argList, pszFormat);
388 iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
389 va_end(argList);
390
391 return iCount;
392}
393
394IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
395{
396 volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
397
398 if(*pui32Access)
399 {
400 if(psResource->ui32ID == ui32ID)
401 {
402 psResource->ui32ID = 0;
403 *pui32Access = 0;
404 }
405 else
406 {
407 PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process."));
408 }
409 }
410 else
411 {
412 PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked"));
413 }
414}
415
416
417PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
418{
419 psResource->ui32ID = 0;
420 psResource->ui32Lock = 0;
421
422 return PVRSRV_OK;
423}
424
425
426PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
427{
428 OSBreakResourceLock (psResource, psResource->ui32ID);
429
430 return PVRSRV_OK;
431}
432
433
434PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
435{
436 ENV_DATA *psEnvData;
437 PVRSRV_ERROR eError;
438
439
440 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
441 "Environment Data");
442 if (eError != PVRSRV_OK)
443 {
444 return eError;
445 }
446
447 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE,
448 &psEnvData->pvBridgeData, IMG_NULL,
449 "Bridge Data");
450 if (eError != PVRSRV_OK)
451 {
452 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
453
454 return eError;
455 }
456
457
458
459 psEnvData->bMISRInstalled = IMG_FALSE;
460 psEnvData->bLISRInstalled = IMG_FALSE;
461
462
463 *ppvEnvSpecificData = psEnvData;
464
465 return PVRSRV_OK;
466}
467
468
469PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData)
470{
471 ENV_DATA *psEnvData = (ENV_DATA*)pvEnvSpecificData;
472
473 PVR_ASSERT(!psEnvData->bMISRInstalled);
474 PVR_ASSERT(!psEnvData->bLISRInstalled);
475
476 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
477 psEnvData->pvBridgeData = IMG_NULL;
478
479 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
480
481
482 return PVRSRV_OK;
483}
484
485
486
487IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
488{
489 schedule();
490}
491
492
493
494IMG_UINT32 OSClockus(IMG_VOID)
495{
496 IMG_UINT32 time, j = jiffies;
497
498 time = j * (1000000 / HZ);
499
500 return time;
501}
502
503
504
505IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus)
506{
507 udelay(ui32Timeus);
508}
509
510
511IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID)
512{
513 if (in_interrupt())
514 {
515 return KERNEL_ID;
516 }
517
518#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
519 return (IMG_UINT32)current->pgrp;
520#else
521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
522 return (IMG_UINT32)task_tgid_nr(current);
523#else
524 return (IMG_UINT32)current->tgid;
525#endif
526#endif
527}
528
529
530IMG_UINT32 OSGetPageSize(IMG_VOID)
531{
532#if defined(__sh__)
533 IMG_UINT32 ui32ReturnValue = PAGE_SIZE;
534
535 return (ui32ReturnValue);
536#else
537 return PAGE_SIZE;
538#endif
539}
540
541#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
542static irqreturn_t DeviceISRWrapper(int irq, void *dev_id
543#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
544 , struct pt_regs *regs
545#endif
546 )
547{
548 PVRSRV_DEVICE_NODE *psDeviceNode;
549 IMG_BOOL bStatus = IMG_FALSE;
550
551 PVR_UNREFERENCED_PARAMETER(irq);
552
553#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
554 PVR_UNREFERENCED_PARAMETER(regs);
555#endif
556 psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id;
557 if(!psDeviceNode)
558 {
559 PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n"));
560 goto out;
561 }
562
563 bStatus = PVRSRVDeviceLISR(psDeviceNode);
564
565 if (bStatus)
566 {
567 OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
568 }
569
570out:
571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
572 return bStatus ? IRQ_HANDLED : IRQ_NONE;
573#endif
574}
575
576
577
578static irqreturn_t SystemISRWrapper(int irq, void *dev_id
579#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
580 , struct pt_regs *regs
581#endif
582 )
583{
584 SYS_DATA *psSysData;
585 IMG_BOOL bStatus = IMG_FALSE;
586
587 PVR_UNREFERENCED_PARAMETER(irq);
588
589#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
590 PVR_UNREFERENCED_PARAMETER(regs);
591#endif
592 psSysData = (SYS_DATA *)dev_id;
593 if(!psSysData)
594 {
595 PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n"));
596 goto out;
597 }
598
599 bStatus = PVRSRVSystemLISR(psSysData);
600
601 if (bStatus)
602 {
603 OSScheduleMISR((IMG_VOID *)psSysData);
604 }
605
606out:
607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
608 return bStatus ? IRQ_HANDLED : IRQ_NONE;
609#endif
610}
611PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
612 IMG_UINT32 ui32Irq,
613 IMG_CHAR *pszISRName,
614 IMG_VOID *pvDeviceNode)
615{
616 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
617 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
618
619 if (psEnvData->bLISRInstalled)
620 {
621 PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
622 return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
623 }
624
625 PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", pszISRName, ui32Irq, pvDeviceNode));
626
627 if(request_irq(ui32Irq, DeviceISRWrapper,
628#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
629 SA_SHIRQ
630#else
631 IRQF_SHARED
632#endif
633 , pszISRName, pvDeviceNode))
634 {
635 PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq));
636
637 return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
638 }
639
640 psEnvData->ui32IRQ = ui32Irq;
641 psEnvData->pvISRCookie = pvDeviceNode;
642 psEnvData->bLISRInstalled = IMG_TRUE;
643
644 return PVRSRV_OK;
645}
646
647PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData)
648{
649 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
650 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
651
652 if (!psEnvData->bLISRInstalled)
653 {
654 PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed"));
655 return PVRSRV_ERROR_ISR_NOT_INSTALLED;
656 }
657
658 PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
659
660 free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
661
662 psEnvData->bLISRInstalled = IMG_FALSE;
663
664 return PVRSRV_OK;
665}
666
667
668PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq)
669{
670 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
671 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
672
673 if (psEnvData->bLISRInstalled)
674 {
675 PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
676 return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
677 }
678
679 PVR_TRACE(("Installing system LISR on IRQ %d with cookie %p", ui32Irq, pvSysData));
680
681 if(request_irq(ui32Irq, SystemISRWrapper,
682#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
683 SA_SHIRQ
684#else
685 IRQF_SHARED
686#endif
687 , PVRSRV_MODNAME, pvSysData))
688 {
689 PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
690
691 return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
692 }
693
694 psEnvData->ui32IRQ = ui32Irq;
695 psEnvData->pvISRCookie = pvSysData;
696 psEnvData->bLISRInstalled = IMG_TRUE;
697
698 return PVRSRV_OK;
699}
700
701
702PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData)
703{
704 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
705 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
706
707 if (!psEnvData->bLISRInstalled)
708 {
709 PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed"));
710 return PVRSRV_ERROR_ISR_NOT_INSTALLED;
711 }
712
713 PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
714
715 free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
716
717 psEnvData->bLISRInstalled = IMG_FALSE;
718
719 return PVRSRV_OK;
720}
721
722#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
723static void MISRWrapper(
724#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
725 void *data
726#else
727 struct work_struct *data
728#endif
729)
730{
731 ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
732 SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
733
734 PVRSRVMISR(psSysData);
735}
736
737
738PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
739{
740 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
741 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
742
743 if (psEnvData->bMISRInstalled)
744 {
745 PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
746 return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
747 }
748
749 PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
750
751 psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
752
753 if (psEnvData->psWorkQueue == IMG_NULL)
754 {
755 PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
756 return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
757 }
758
759 INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
760#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
761 , (void *)&psEnvData->sMISRWork
762#endif
763 );
764
765 psEnvData->pvMISRData = pvSysData;
766 psEnvData->bMISRInstalled = IMG_TRUE;
767
768 return PVRSRV_OK;
769}
770
771
772PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
773{
774 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
775 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
776
777 if (!psEnvData->bMISRInstalled)
778 {
779 PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
780 return PVRSRV_ERROR_ISR_NOT_INSTALLED;
781 }
782
783 PVR_TRACE(("Uninstalling MISR"));
784
785 destroy_workqueue(psEnvData->psWorkQueue);
786
787 psEnvData->bMISRInstalled = IMG_FALSE;
788
789 return PVRSRV_OK;
790}
791
792
793PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
794{
795 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
796 ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
797
798 if (psEnvData->bMISRInstalled)
799 {
800 queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
801 }
802
803 return PVRSRV_OK;
804}
805#else
806#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
807static void MISRWrapper(
808#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
809 void *data
810#else
811 struct work_struct *data
812#endif
813)
814{
815 ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
816 SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
817
818 PVRSRVMISR(psSysData);
819}
820
821
822PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
823{
824 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
825 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
826
827 if (psEnvData->bMISRInstalled)
828 {
829 PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
830 return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
831 }
832
833 PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
834
835 INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
836#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
837 , (void *)&psEnvData->sMISRWork
838#endif
839 );
840
841 psEnvData->pvMISRData = pvSysData;
842 psEnvData->bMISRInstalled = IMG_TRUE;
843
844 return PVRSRV_OK;
845}
846
847
848PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
849{
850 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
851 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
852
853 if (!psEnvData->bMISRInstalled)
854 {
855 PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
856 return PVRSRV_ERROR_ISR_NOT_INSTALLED;
857 }
858
859 PVR_TRACE(("Uninstalling MISR"));
860
861 flush_scheduled_work();
862
863 psEnvData->bMISRInstalled = IMG_FALSE;
864
865 return PVRSRV_OK;
866}
867
868
869PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
870{
871 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
872 ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
873
874 if (psEnvData->bMISRInstalled)
875 {
876 schedule_work(&psEnvData->sMISRWork);
877 }
878
879 return PVRSRV_OK;
880}
881
882#else
883
884
885static void MISRWrapper(unsigned long data)
886{
887 SYS_DATA *psSysData;
888
889 psSysData = (SYS_DATA *)data;
890
891 PVRSRVMISR(psSysData);
892}
893
894
895PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
896{
897 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
898 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
899
900 if (psEnvData->bMISRInstalled)
901 {
902 PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
903 return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
904 }
905
906 PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
907
908 tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
909
910 psEnvData->bMISRInstalled = IMG_TRUE;
911
912 return PVRSRV_OK;
913}
914
915
916PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
917{
918 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
919 ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
920
921 if (!psEnvData->bMISRInstalled)
922 {
923 PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
924 return PVRSRV_ERROR_ISR_NOT_INSTALLED;
925 }
926
927 PVR_TRACE(("Uninstalling MISR"));
928
929 tasklet_kill(&psEnvData->sMISRTasklet);
930
931 psEnvData->bMISRInstalled = IMG_FALSE;
932
933 return PVRSRV_OK;
934}
935
936PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
937{
938 SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
939 ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
940
941 if (psEnvData->bMISRInstalled)
942 {
943 tasklet_schedule(&psEnvData->sMISRTasklet);
944 }
945
946 return PVRSRV_OK;
947}
948
949#endif
950#endif
951
952#endif
953
954IMG_VOID OSPanic(IMG_VOID)
955{
956 BUG();
957}
958
959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
960#define OS_TAS(p) xchg((p), 1)
961#else
962#define OS_TAS(p) tas(p)
963#endif
964PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE *psResource,
965 IMG_UINT32 ui32ID)
966
967{
968 PVRSRV_ERROR eError = PVRSRV_OK;
969
970 if(!OS_TAS(&psResource->ui32Lock))
971 psResource->ui32ID = ui32ID;
972 else
973 eError = PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE;
974
975 return eError;
976}
977
978
979PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
980{
981 volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
982 PVRSRV_ERROR eError = PVRSRV_OK;
983
984 if(*pui32Access)
985 {
986 if(psResource->ui32ID == ui32ID)
987 {
988 psResource->ui32ID = 0;
989 *pui32Access = 0;
990 }
991 else
992 {
993 PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource));
994 PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID));
995 eError = PVRSRV_ERROR_INVALID_LOCK_ID;
996 }
997 }
998 else
999 {
1000 PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
1001 eError = PVRSRV_ERROR_RESOURCE_NOT_LOCKED;
1002 }
1003
1004 return eError;
1005}
1006
1007
1008IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
1009{
1010 volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
1011
1012 return (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID)
1013 ? IMG_TRUE
1014 : IMG_FALSE;
1015}
1016
1017
1018IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE hOSMemHandle,
1019 IMG_VOID *pvLinAddr)
1020{
1021 IMG_CPU_PHYADDR CpuPAddr;
1022 LinuxMemArea *psLinuxMemArea;
1023 IMG_UINTPTR_T uiByteOffset;
1024 IMG_UINT32 ui32ByteOffset;
1025
1026 PVR_ASSERT(hOSMemHandle != IMG_NULL);
1027
1028
1029
1030 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
1031
1032 uiByteOffset = (IMG_UINTPTR_T)pvLinAddr - (IMG_UINTPTR_T)LinuxMemAreaToCpuVAddr(psLinuxMemArea);
1033 ui32ByteOffset = (IMG_UINT32)uiByteOffset;
1034
1035 CpuPAddr = LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
1036
1037 return CpuPAddr;
1038}
1039
1040
1041IMG_VOID *
1042OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
1043 IMG_UINT32 ui32Bytes,
1044 IMG_UINT32 ui32MappingFlags,
1045 IMG_HANDLE *phOSMemHandle)
1046{
1047 if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
1048 {
1049
1050 if(phOSMemHandle == IMG_NULL)
1051 {
1052 IMG_VOID *pvIORemapCookie;
1053 pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
1054 if(pvIORemapCookie == IMG_NULL)
1055 {
1056 return IMG_NULL;
1057 }
1058 return pvIORemapCookie;
1059 }
1060 else
1061 {
1062 LinuxMemArea *psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
1063
1064 if(psLinuxMemArea == IMG_NULL)
1065 {
1066 return IMG_NULL;
1067 }
1068
1069 *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
1070 return LinuxMemAreaToCpuVAddr(psLinuxMemArea);
1071 }
1072 }
1073
1074 PVR_DPF((PVR_DBG_ERROR,
1075 "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
1076 " (Use OSReservePhys otherwise)"));
1077
1078 return IMG_NULL;
1079}
1080
1081IMG_BOOL
1082OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hOSMemHandle)
1083{
1084 PVR_TRACE(("%s: unmapping %d bytes from %p", __FUNCTION__, ui32Bytes, pvLinAddr));
1085
1086 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
1087
1088 if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
1089 {
1090 if (hOSMemHandle == IMG_NULL)
1091 {
1092 IOUnmapWrapper(pvLinAddr);
1093 }
1094 else
1095 {
1096 LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
1097
1098 PVR_ASSERT(LinuxMemAreaToCpuVAddr(psLinuxMemArea) == pvLinAddr);
1099
1100 FreeIORemapLinuxMemArea(psLinuxMemArea);
1101 }
1102
1103 return IMG_TRUE;
1104 }
1105
1106 PVR_DPF((PVR_DBG_ERROR,
1107 "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
1108 " (Use OSUnReservePhys otherwise)"));
1109 return IMG_FALSE;
1110}
1111
1112static PVRSRV_ERROR
1113RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr,
1114 IMG_VOID *pvCPUVAddr,
1115 IMG_UINT32 ui32Bytes,
1116 IMG_BOOL bPhysContig,
1117 IMG_UINT32 ui32MappingFlags,
1118 IMG_HANDLE *phOSMemHandle)
1119{
1120 LinuxMemArea *psLinuxMemArea;
1121
1122 switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
1123 {
1124 case PVRSRV_HAP_KERNEL_ONLY:
1125 {
1126 psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
1127
1128 if(!psLinuxMemArea)
1129 {
1130 return PVRSRV_ERROR_BAD_MAPPING;
1131 }
1132 break;
1133 }
1134 case PVRSRV_HAP_SINGLE_PROCESS:
1135 {
1136 psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
1137
1138 if(!psLinuxMemArea)
1139 {
1140 return PVRSRV_ERROR_BAD_MAPPING;
1141 }
1142 PVRMMapRegisterArea(psLinuxMemArea);
1143 break;
1144 }
1145 case PVRSRV_HAP_MULTI_PROCESS:
1146 {
1147
1148#if defined(VIVT_CACHE) || defined(__sh__)
1149
1150 ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
1151#endif
1152 psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
1153
1154 if(!psLinuxMemArea)
1155 {
1156 return PVRSRV_ERROR_BAD_MAPPING;
1157 }
1158 PVRMMapRegisterArea(psLinuxMemArea);
1159 break;
1160 }
1161 default:
1162 PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
1163 *phOSMemHandle = (IMG_HANDLE)0;
1164 return PVRSRV_ERROR_INVALID_FLAGS;
1165 }
1166
1167 *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
1168
1169 LinuxMemAreaRegister(psLinuxMemArea);
1170
1171 return PVRSRV_OK;
1172}
1173
1174
1175PVRSRV_ERROR
1176OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
1177 IMG_VOID *pvCPUVAddr,
1178 IMG_UINT32 ui32Bytes,
1179 IMG_UINT32 ui32MappingFlags,
1180 IMG_HANDLE *phOSMemHandle)
1181{
1182 IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr);
1183
1184 return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle);
1185}
1186
1187
1188PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle)
1189{
1190 return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle);
1191}
1192
1193
1194PVRSRV_ERROR
1195OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
1196 IMG_UINT32 ui32Bytes,
1197 IMG_UINT32 ui32MappingFlags,
1198 IMG_HANDLE hOSMemHandle)
1199{
1200 LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
1201 PVRSRV_ERROR eError;
1202
1203 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
1204 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
1205
1206 switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
1207 {
1208 case PVRSRV_HAP_KERNEL_ONLY:
1209 break;
1210 case PVRSRV_HAP_SINGLE_PROCESS:
1211 case PVRSRV_HAP_MULTI_PROCESS:
1212 {
1213 eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
1214 if (eError != PVRSRV_OK)
1215 {
1216 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
1217 __FUNCTION__, pvCpuVAddr, ui32Bytes,
1218 ui32MappingFlags, hOSMemHandle));
1219 return eError;
1220 }
1221 break;
1222 }
1223 default:
1224 {
1225 PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags));
1226 return PVRSRV_ERROR_INVALID_PARAMS;
1227 }
1228 }
1229
1230 LinuxMemAreaDeepFree(psLinuxMemArea);
1231
1232 return PVRSRV_OK;
1233}
1234
1235PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
1236{
1237 return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
1238}
1239
1240PVRSRV_ERROR
1241OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
1242 IMG_UINT32 ui32Bytes,
1243 IMG_UINT32 ui32MappingFlags,
1244 IMG_VOID **ppvCpuVAddr,
1245 IMG_HANDLE *phOSMemHandle)
1246{
1247 LinuxMemArea *psLinuxMemArea;
1248
1249#if 0
1250
1251 if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS)
1252 {
1253 ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
1254 ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS;
1255 }
1256#endif
1257
1258 switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
1259 {
1260 case PVRSRV_HAP_KERNEL_ONLY:
1261 {
1262
1263 psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
1264 if(!psLinuxMemArea)
1265 {
1266 return PVRSRV_ERROR_BAD_MAPPING;
1267 }
1268 break;
1269 }
1270 case PVRSRV_HAP_SINGLE_PROCESS:
1271 {
1272
1273 psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
1274 if(!psLinuxMemArea)
1275 {
1276 return PVRSRV_ERROR_BAD_MAPPING;
1277 }
1278 PVRMMapRegisterArea(psLinuxMemArea);
1279 break;
1280 }
1281 case PVRSRV_HAP_MULTI_PROCESS:
1282 {
1283
1284#if defined(VIVT_CACHE) || defined(__sh__)
1285
1286 ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
1287#endif
1288 psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
1289 if(!psLinuxMemArea)
1290 {
1291 return PVRSRV_ERROR_BAD_MAPPING;
1292 }
1293 PVRMMapRegisterArea(psLinuxMemArea);
1294 break;
1295 }
1296 default:
1297 PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags));
1298 *ppvCpuVAddr = NULL;
1299 *phOSMemHandle = (IMG_HANDLE)0;
1300 return PVRSRV_ERROR_INVALID_FLAGS;
1301 }
1302
1303 *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
1304 *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
1305
1306 LinuxMemAreaRegister(psLinuxMemArea);
1307
1308 return PVRSRV_OK;
1309}
1310
1311PVRSRV_ERROR
1312OSUnReservePhys(IMG_VOID *pvCpuVAddr,
1313 IMG_UINT32 ui32Bytes,
1314 IMG_UINT32 ui32MappingFlags,
1315 IMG_HANDLE hOSMemHandle)
1316{
1317 LinuxMemArea *psLinuxMemArea;
1318 PVRSRV_ERROR eError;
1319
1320 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
1321 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
1322
1323 psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
1324
1325 switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
1326 {
1327 case PVRSRV_HAP_KERNEL_ONLY:
1328 break;
1329 case PVRSRV_HAP_SINGLE_PROCESS:
1330 case PVRSRV_HAP_MULTI_PROCESS:
1331 {
1332 eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
1333 if (eError != PVRSRV_OK)
1334 {
1335 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
1336 __FUNCTION__, pvCpuVAddr, ui32Bytes,
1337 ui32MappingFlags, hOSMemHandle));
1338 return eError;
1339 }
1340 break;
1341 }
1342 default:
1343 {
1344 PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
1345 return PVRSRV_ERROR_INVALID_PARAMS;
1346 }
1347 }
1348
1349 LinuxMemAreaDeepFree(psLinuxMemArea);
1350
1351 return PVRSRV_OK;
1352}
1353
1354
1355PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr)
1356{
1357#if !defined(NO_HARDWARE)
1358 PVR_UNREFERENCED_PARAMETER(ui32Size);
1359 PVR_UNREFERENCED_PARAMETER(pvLinAddr);
1360 PVR_UNREFERENCED_PARAMETER(psPhysAddr);
1361 PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__));
1362
1363 return PVRSRV_ERROR_OUT_OF_MEMORY;
1364#else
1365 IMG_VOID *pvKernLinAddr;
1366
1367#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
1368 pvKernLinAddr = _KMallocWrapper(ui32Size, __FILE__, __LINE__);
1369#else
1370 pvKernLinAddr = KMallocWrapper(ui32Size);
1371#endif
1372 if (!pvKernLinAddr)
1373 {
1374 return PVRSRV_ERROR_OUT_OF_MEMORY;
1375 }
1376
1377 *pvLinAddr = pvKernLinAddr;
1378
1379 psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
1380
1381 return PVRSRV_OK;
1382#endif
1383}
1384
1385
1386PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr)
1387{
1388#if !defined(NO_HARDWARE)
1389 PVR_UNREFERENCED_PARAMETER(ui32Size);
1390 PVR_UNREFERENCED_PARAMETER(pvLinAddr);
1391 PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
1392
1393 PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__));
1394#else
1395 PVR_UNREFERENCED_PARAMETER(ui32Size);
1396 PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
1397
1398 KFreeWrapper(pvLinAddr);
1399#endif
1400 return PVRSRV_OK;
1401}
1402
1403IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
1404{
1405#if !defined(NO_HARDWARE)
1406 return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
1407#else
1408 return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
1409#endif
1410}
1411
1412IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
1413{
1414#if !defined(NO_HARDWARE)
1415 writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
1416#else
1417 *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value;
1418#endif
1419}
1420
1421#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1422
1423PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
1424{
1425 int err;
1426 IMG_UINT32 i;
1427 PVR_PCI_DEV *psPVRPCI;
1428
1429 PVR_TRACE(("OSPCISetDev"));
1430
1431 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL,
1432 "PCI Device") != PVRSRV_OK)
1433 {
1434 PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure"));
1435 return IMG_NULL;
1436 }
1437
1438 psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
1439 psPVRPCI->ePCIFlags = eFlags;
1440
1441 err = pci_enable_device(psPVRPCI->psPCIDev);
1442 if (err != 0)
1443 {
1444 PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err));
1445 return IMG_NULL;
1446 }
1447
1448 if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
1449 {
1450 pci_set_master(psPVRPCI->psPCIDev);
1451 }
1452
1453 if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
1454 {
1455#if defined(CONFIG_PCI_MSI)
1456 err = pci_enable_msi(psPVRPCI->psPCIDev);
1457 if (err != 0)
1458 {
1459 PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err));
1460 psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;
1461 }
1462#else
1463 PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
1464#endif
1465 }
1466
1467
1468 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
1469 {
1470 psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
1471 }
1472
1473 return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
1474}
1475
1476PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags)
1477{
1478 struct pci_dev *psPCIDev;
1479
1480 psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL);
1481 if (psPCIDev == NULL)
1482 {
1483 PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device"));
1484 return IMG_NULL;
1485 }
1486
1487 return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
1488}
1489
1490PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
1491{
1492 PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
1493
1494 *pui32IRQ = psPVRPCI->psPCIDev->irq;
1495
1496 return PVRSRV_OK;
1497}
1498
1499enum HOST_PCI_ADDR_RANGE_FUNC
1500{
1501 HOST_PCI_ADDR_RANGE_FUNC_LEN,
1502 HOST_PCI_ADDR_RANGE_FUNC_START,
1503 HOST_PCI_ADDR_RANGE_FUNC_END,
1504 HOST_PCI_ADDR_RANGE_FUNC_REQUEST,
1505 HOST_PCI_ADDR_RANGE_FUNC_RELEASE
1506};
1507
1508static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc,
1509 PVRSRV_PCI_DEV_HANDLE hPVRPCI,
1510 IMG_UINT32 ui32Index)
1511{
1512 PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
1513
1514 if (ui32Index >= DEVICE_COUNT_RESOURCE)
1515 {
1516 PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range"));
1517 return 0;
1518
1519 }
1520
1521 switch (eFunc)
1522 {
1523 case HOST_PCI_ADDR_RANGE_FUNC_LEN:
1524 return pci_resource_len(psPVRPCI->psPCIDev, ui32Index);
1525 case HOST_PCI_ADDR_RANGE_FUNC_START:
1526 return pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
1527 case HOST_PCI_ADDR_RANGE_FUNC_END:
1528 return pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
1529 case HOST_PCI_ADDR_RANGE_FUNC_REQUEST:
1530 {
1531 int err;
1532
1533 err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, PVRSRV_MODNAME);
1534 if (err != 0)
1535 {
1536 PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err));
1537 return 0;
1538 }
1539 psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE;
1540 return 1;
1541 }
1542 case HOST_PCI_ADDR_RANGE_FUNC_RELEASE:
1543 if (psPVRPCI->abPCIResourceInUse[ui32Index])
1544 {
1545 pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index);
1546 psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE;
1547 }
1548 return 1;
1549 default:
1550 PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function"));
1551 break;
1552 }
1553
1554 return 0;
1555}
1556
1557IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
1558{
1559 return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index);
1560}
1561
1562IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
1563{
1564 return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index);
1565}
1566
1567IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
1568{
1569 return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index);
1570}
1571
1572PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
1573 IMG_UINT32 ui32Index)
1574{
1575 return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
1576}
1577
1578PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
1579{
1580 return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
1581}
1582
1583PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
1584{
1585 PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
1586 int i;
1587
1588 PVR_TRACE(("OSPCIReleaseDev"));
1589
1590
1591 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
1592 {
1593 if (psPVRPCI->abPCIResourceInUse[i])
1594 {
1595 PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i));
1596 pci_release_region(psPVRPCI->psPCIDev, i);
1597 psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
1598 }
1599 }
1600
1601#if defined(CONFIG_PCI_MSI)
1602 if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)
1603 {
1604 pci_disable_msi(psPVRPCI->psPCIDev);
1605 }
1606#endif
1607
1608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
1609 if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
1610 {
1611 pci_clear_master(psPVRPCI->psPCIDev);
1612 }
1613#endif
1614 pci_disable_device(psPVRPCI->psPCIDev);
1615
1616 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
1617
1618
1619 return PVRSRV_OK;
1620}
1621
1622PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
1623{
1624 PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
1625 int i;
1626 int err;
1627
1628 PVR_TRACE(("OSPCISuspendDev"));
1629
1630
1631 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
1632 {
1633 if (psPVRPCI->abPCIResourceInUse[i])
1634 {
1635 pci_release_region(psPVRPCI->psPCIDev, i);
1636 }
1637 }
1638
1639 err = pci_save_state(psPVRPCI->psPCIDev);
1640 if (err != 0)
1641 {
1642 PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err));
1643 return PVRSRV_ERROR_PCI_CALL_FAILED;
1644 }
1645
1646 pci_disable_device(psPVRPCI->psPCIDev);
1647
1648 err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND));
1649 switch(err)
1650 {
1651 case 0:
1652 break;
1653 case -EIO:
1654 PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM"));
1655 break;
1656 case -EINVAL:
1657 PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state"));
1658 break;
1659 default:
1660 PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err));
1661 break;
1662 }
1663
1664 return PVRSRV_OK;
1665}
1666
1667PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
1668{
1669 PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
1670 int err;
1671 int i;
1672
1673 PVR_TRACE(("OSPCIResumeDev"));
1674
1675 err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
1676 switch(err)
1677 {
1678 case 0:
1679 break;
1680 case -EIO:
1681 PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM"));
1682 break;
1683 case -EINVAL:
1684 PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state"));
1685 return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
1686 default:
1687 PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
1688 return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
1689 }
1690
1691 err = pci_restore_state(psPVRPCI->psPCIDev);
1692 if (err != 0)
1693 {
1694 PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
1695 return PVRSRV_ERROR_PCI_CALL_FAILED;
1696 }
1697
1698 err = pci_enable_device(psPVRPCI->psPCIDev);
1699 if (err != 0)
1700 {
1701 PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
1702 return PVRSRV_ERROR_PCI_CALL_FAILED;
1703 }
1704
1705 if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)
1706 pci_set_master(psPVRPCI->psPCIDev);
1707
1708
1709 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
1710 {
1711 if (psPVRPCI->abPCIResourceInUse[i])
1712 {
1713 err = pci_request_region(psPVRPCI->psPCIDev, i, PVRSRV_MODNAME);
1714 if (err != 0)
1715 {
1716 PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
1717 }
1718 }
1719
1720 }
1721
1722 return PVRSRV_OK;
1723}
1724
1725#endif
1726
1727#define OS_MAX_TIMERS 8
1728
1729typedef struct TIMER_CALLBACK_DATA_TAG
1730{
1731 IMG_BOOL bInUse;
1732 PFN_TIMER_FUNC pfnTimerFunc;
1733 IMG_VOID *pvData;
1734 struct timer_list sTimer;
1735 IMG_UINT32 ui32Delay;
1736 IMG_BOOL bActive;
1737#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1738 struct work_struct sWork;
1739#endif
1740}TIMER_CALLBACK_DATA;
1741
1742#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1743static struct workqueue_struct *psTimerWorkQueue;
1744#endif
1745
1746static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
1747
1748#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1749DEFINE_MUTEX(sTimerStructLock);
1750#else
1751
1752static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
1753#endif
1754
1755static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
1756{
1757 if (!psTimerCBData->bActive)
1758 return;
1759
1760
1761 psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
1762
1763
1764 mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
1765}
1766
1767
1768static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
1769{
1770 TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
1771
1772#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1773 int res;
1774
1775 res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
1776 if (res == 0)
1777 {
1778 PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));
1779 }
1780#else
1781 OSTimerCallbackBody(psTimerCBData);
1782#endif
1783}
1784
1785
1786#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1787static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
1788{
1789 TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
1790
1791 OSTimerCallbackBody(psTimerCBData);
1792}
1793#endif
1794
1795IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
1796{
1797 TIMER_CALLBACK_DATA *psTimerCBData;
1798 IMG_UINT32 ui32i;
1799#if !defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1800 unsigned long ulLockFlags;
1801#endif
1802
1803
1804 if(!pfnTimerFunc)
1805 {
1806 PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));
1807 return IMG_NULL;
1808 }
1809
1810
1811#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1812 mutex_lock(&sTimerStructLock);
1813#else
1814 spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
1815#endif
1816 for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
1817 {
1818 psTimerCBData = &sTimers[ui32i];
1819 if (!psTimerCBData->bInUse)
1820 {
1821 psTimerCBData->bInUse = IMG_TRUE;
1822 break;
1823 }
1824 }
1825#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1826 mutex_unlock(&sTimerStructLock);
1827#else
1828 spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
1829#endif
1830 if (ui32i >= OS_MAX_TIMERS)
1831 {
1832 PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use"));
1833 return IMG_NULL;
1834 }
1835
1836 psTimerCBData->pfnTimerFunc = pfnTimerFunc;
1837 psTimerCBData->pvData = pvData;
1838 psTimerCBData->bActive = IMG_FALSE;
1839
1840
1841
1842
1843 psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
1844 ? 1
1845 : ((HZ * ui32MsTimeout) / 1000);
1846
1847 init_timer(&psTimerCBData->sTimer);
1848
1849
1850
1851 psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
1852 psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
1853
1854 return (IMG_HANDLE)(ui32i + 1);
1855}
1856
1857
1858static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
1859{
1860 IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1;
1861
1862 PVR_ASSERT(ui32i < OS_MAX_TIMERS);
1863
1864 return &sTimers[ui32i];
1865}
1866
1867PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
1868{
1869 TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
1870
1871 PVR_ASSERT(psTimerCBData->bInUse);
1872 PVR_ASSERT(!psTimerCBData->bActive);
1873
1874
1875 psTimerCBData->bInUse = IMG_FALSE;
1876
1877 return PVRSRV_OK;
1878}
1879
1880
1881PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
1882{
1883 TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
1884
1885 PVR_ASSERT(psTimerCBData->bInUse);
1886 PVR_ASSERT(!psTimerCBData->bActive);
1887
1888
1889 psTimerCBData->bActive = IMG_TRUE;
1890
1891
1892 psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
1893
1894
1895 add_timer(&psTimerCBData->sTimer);
1896
1897 return PVRSRV_OK;
1898}
1899
1900
1901PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
1902{
1903 TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
1904
1905 PVR_ASSERT(psTimerCBData->bInUse);
1906 PVR_ASSERT(psTimerCBData->bActive);
1907
1908
1909 psTimerCBData->bActive = IMG_FALSE;
1910 smp_mb();
1911
1912#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1913 flush_workqueue(psTimerWorkQueue);
1914#endif
1915
1916
1917 del_timer_sync(&psTimerCBData->sTimer);
1918
1919#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
1920
1921 flush_workqueue(psTimerWorkQueue);
1922#endif
1923
1924 return PVRSRV_OK;
1925}
1926
1927
1928PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
1929{
1930
1931 PVRSRV_ERROR eError = PVRSRV_OK;
1932
1933 if(psEventObject)
1934 {
1935 if(pszName)
1936 {
1937
1938 strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
1939 }
1940 else
1941 {
1942
1943 static IMG_UINT16 ui16NameIndex = 0;
1944 snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
1945 }
1946
1947 if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
1948 {
1949 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1950 }
1951
1952 }
1953 else
1954 {
1955 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
1956 eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;
1957 }
1958
1959 return eError;
1960
1961}
1962
1963
1964PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject)
1965{
1966 PVRSRV_ERROR eError = PVRSRV_OK;
1967
1968 if(psEventObject)
1969 {
1970 if(psEventObject->hOSEventKM)
1971 {
1972 LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
1973 }
1974 else
1975 {
1976 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hOSEventKM is not a valid pointer"));
1977 eError = PVRSRV_ERROR_INVALID_PARAMS;
1978 }
1979 }
1980 else
1981 {
1982 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
1983 eError = PVRSRV_ERROR_INVALID_PARAMS;
1984 }
1985
1986 return eError;
1987}
1988
1989PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM)
1990{
1991 PVRSRV_ERROR eError;
1992
1993 if(hOSEventKM)
1994 {
1995 eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
1996 }
1997 else
1998 {
1999 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: hOSEventKM is not a valid handle"));
2000 eError = PVRSRV_ERROR_INVALID_PARAMS;
2001 }
2002
2003 return eError;
2004}
2005
2006PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject,
2007 IMG_HANDLE *phOSEvent)
2008{
2009 PVRSRV_ERROR eError = PVRSRV_OK;
2010
2011 if(psEventObject)
2012 {
2013 if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK)
2014 {
2015 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed"));
2016 eError = PVRSRV_ERROR_INVALID_PARAMS;
2017 }
2018
2019 }
2020 else
2021 {
2022 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
2023 eError = PVRSRV_ERROR_INVALID_PARAMS;
2024 }
2025
2026 return eError;
2027}
2028
2029PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject,
2030 IMG_HANDLE hOSEventKM)
2031{
2032 PVRSRV_ERROR eError = PVRSRV_OK;
2033
2034 if(psEventObject)
2035 {
2036 if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK)
2037 {
2038 PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
2039 eError = PVRSRV_ERROR_INVALID_PARAMS;
2040 }
2041
2042 }
2043 else
2044 {
2045 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
2046 eError = PVRSRV_ERROR_INVALID_PARAMS;
2047 }
2048
2049 return eError;
2050
2051}
2052
2053PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM)
2054{
2055 PVRSRV_ERROR eError;
2056
2057 if(hOSEventKM)
2058 {
2059 eError = LinuxEventObjectSignal(hOSEventKM);
2060 }
2061 else
2062 {
2063 PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignal: hOSEventKM is not a valid handle"));
2064 eError = PVRSRV_ERROR_INVALID_PARAMS;
2065 }
2066
2067 return eError;
2068}
2069
2070IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
2071{
2072 return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE;
2073}
2074
2075PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess,
2076 IMG_VOID *pvDest,
2077 IMG_VOID *pvSrc,
2078 IMG_UINT32 ui32Bytes)
2079{
2080 PVR_UNREFERENCED_PARAMETER(pvProcess);
2081
2082 if(pvr_copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
2083 return PVRSRV_OK;
2084 else
2085 return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
2086}
2087
2088PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess,
2089 IMG_VOID *pvDest,
2090 IMG_VOID *pvSrc,
2091 IMG_UINT32 ui32Bytes)
2092{
2093 PVR_UNREFERENCED_PARAMETER(pvProcess);
2094
2095 if(pvr_copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
2096 return PVRSRV_OK;
2097 else
2098 return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
2099}
2100
2101IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes)
2102{
2103 IMG_INT linuxType;
2104
2105 if (eVerification == PVR_VERIFY_READ)
2106 {
2107 linuxType = VERIFY_READ;
2108 }
2109 else
2110 {
2111 PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
2112 linuxType = VERIFY_WRITE;
2113 }
2114
2115 return access_ok(linuxType, pvUserPtr, ui32Bytes);
2116}
2117
2118typedef enum _eWrapMemType_
2119{
2120 WRAP_TYPE_NULL = 0,
2121 WRAP_TYPE_GET_USER_PAGES,
2122 WRAP_TYPE_FIND_VMA
2123} eWrapMemType;
2124
2125typedef struct _sWrapMemInfo_
2126{
2127 eWrapMemType eType;
2128 IMG_INT iNumPages;
2129 IMG_INT iNumPagesMapped;
2130 struct page **ppsPages;
2131 IMG_SYS_PHYADDR *psPhysAddr;
2132 IMG_INT iPageOffset;
2133#if defined(DEBUG)
2134 IMG_UINT32 ulStartAddr;
2135 IMG_UINT32 ulBeyondEndAddr;
2136 struct vm_area_struct *psVMArea;
2137#endif
2138} sWrapMemInfo;
2139
2140
2141static IMG_BOOL CPUVAddrToPFN(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr, IMG_UINT32 *pulPFN, struct page **ppsPage)
2142{
2143#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
2144 pgd_t *psPGD;
2145 pud_t *psPUD;
2146 pmd_t *psPMD;
2147 pte_t *psPTE;
2148 struct mm_struct *psMM = psVMArea->vm_mm;
2149 spinlock_t *psPTLock;
2150 IMG_BOOL bRet = IMG_FALSE;
2151
2152 *pulPFN = 0;
2153 *ppsPage = NULL;
2154
2155 psPGD = pgd_offset(psMM, ulCPUVAddr);
2156 if (pgd_none(*psPGD) || pgd_bad(*psPGD))
2157 return bRet;
2158
2159 psPUD = pud_offset(psPGD, ulCPUVAddr);
2160 if (pud_none(*psPUD) || pud_bad(*psPUD))
2161 return bRet;
2162
2163 psPMD = pmd_offset(psPUD, ulCPUVAddr);
2164 if (pmd_none(*psPMD) || pmd_bad(*psPMD))
2165 return bRet;
2166
2167 psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
2168
2169 if ((pte_none(*psPTE) == 0) && (pte_present(*psPTE) != 0) && (pte_write(*psPTE) != 0))
2170 {
2171 *pulPFN = pte_pfn(*psPTE);
2172 bRet = IMG_TRUE;
2173
2174 if (pfn_valid(*pulPFN))
2175 {
2176 *ppsPage = pfn_to_page(*pulPFN);
2177
2178 get_page(*ppsPage);
2179 }
2180 }
2181
2182 pte_unmap_unlock(psPTE, psPTLock);
2183
2184 return bRet;
2185#else
2186 return IMG_FALSE;
2187#endif
2188}
2189
2190PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
2191{
2192 sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
2193 IMG_INT i;
2194
2195 if (psInfo == IMG_NULL)
2196 {
2197 PVR_DPF((PVR_DBG_WARNING,
2198 "OSReleasePhysPageAddr: called with null wrap handle"));
2199 return PVRSRV_OK;
2200 }
2201
2202 switch (psInfo->eType)
2203 {
2204 case WRAP_TYPE_NULL:
2205 {
2206 PVR_DPF((PVR_DBG_WARNING,
2207 "OSReleasePhysPageAddr: called with wrap type WRAP_TYPE_NULL"));
2208 break;
2209 }
2210 case WRAP_TYPE_GET_USER_PAGES:
2211 {
2212 for (i = 0; i < psInfo->iNumPagesMapped; i++)
2213 {
2214 struct page *psPage = psInfo->ppsPages[i];
2215
2216 PVR_ASSERT(psPage != NULL);
2217
2218
2219 if (psInfo->iNumPagesMapped == psInfo->iNumPages)
2220 {
2221 if (!PageReserved(psPage))
2222 {
2223 SetPageDirty(psPage);
2224 }
2225 }
2226 page_cache_release(psPage);
2227 }
2228 break;
2229 }
2230 case WRAP_TYPE_FIND_VMA:
2231 {
2232 for (i = 0; i < psInfo->iNumPages; i++)
2233 {
2234 if (psInfo->ppsPages[i] != IMG_NULL)
2235 {
2236 put_page(psInfo->ppsPages[i]);
2237 }
2238 }
2239 break;
2240 }
2241 default:
2242 {
2243 PVR_DPF((PVR_DBG_ERROR,
2244 "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
2245 return PVRSRV_ERROR_INVALID_WRAP_TYPE;
2246 }
2247 }
2248
2249 if (psInfo->ppsPages != IMG_NULL)
2250 {
2251 kfree(psInfo->ppsPages);
2252 }
2253
2254 if (psInfo->psPhysAddr != IMG_NULL)
2255 {
2256 kfree(psInfo->psPhysAddr);
2257 }
2258
2259 kfree(psInfo);
2260
2261 return PVRSRV_OK;
2262}
2263
2264PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID *pvCPUVAddr,
2265 IMG_UINT32 ui32Bytes,
2266 IMG_SYS_PHYADDR *psSysPAddr,
2267 IMG_HANDLE *phOSWrapMem)
2268{
2269 IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr;
2270 IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes;
2271 IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig;
2272 IMG_UINT32 ulStartAddr;
2273 IMG_UINT32 ulAddrRange;
2274 IMG_UINT32 ulBeyondEndAddr;
2275 IMG_UINT32 ulAddr;
2276 IMG_INT i;
2277 struct vm_area_struct *psVMArea;
2278 sWrapMemInfo *psInfo = NULL;
2279 IMG_BOOL bHavePageStructs = IMG_FALSE;
2280 IMG_BOOL bHaveNoPageStructs = IMG_FALSE;
2281 IMG_BOOL bPFNMismatch = IMG_FALSE;
2282 IMG_BOOL bMMapSemHeld = IMG_FALSE;
2283 PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
2284
2285
2286 ulStartAddr = ulStartAddrOrig & PAGE_MASK;
2287 ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
2288 ulAddrRange = ulBeyondEndAddr - ulStartAddr;
2289
2290
2291 if (ulBeyondEndAddr <= ulStartAddr)
2292 {
2293 PVR_DPF((PVR_DBG_ERROR,
2294 "OSAcquirePhysPageAddr: Invalid address range (start %x, length %x)",
2295 ulStartAddrOrig, ulAddrRangeOrig));
2296 goto error;
2297 }
2298
2299
2300 psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
2301 if (psInfo == NULL)
2302 {
2303 PVR_DPF((PVR_DBG_ERROR,
2304 "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
2305 goto error;
2306 }
2307 memset(psInfo, 0, sizeof(*psInfo));
2308
2309#if defined(DEBUG)
2310 psInfo->ulStartAddr = ulStartAddrOrig;
2311 psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig;
2312#endif
2313
2314 psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT);
2315 psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK);
2316
2317
2318 psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL);
2319 if (psInfo->psPhysAddr == NULL)
2320 {
2321 PVR_DPF((PVR_DBG_ERROR,
2322 "OSAcquirePhysPageAddr: Couldn't allocate page array"));
2323 goto error;
2324 }
2325 memset(psInfo->psPhysAddr, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr));
2326
2327
2328 psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages), GFP_KERNEL);
2329 if (psInfo->ppsPages == NULL)
2330 {
2331 PVR_DPF((PVR_DBG_ERROR,
2332 "OSAcquirePhysPageAddr: Couldn't allocate page array"));
2333 goto error;
2334 }
2335 memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
2336
2337
2338 eError = PVRSRV_ERROR_BAD_MAPPING;
2339
2340
2341 psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
2342
2343
2344 down_read(&current->mm->mmap_sem);
2345 bMMapSemHeld = IMG_TRUE;
2346
2347
2348 psInfo->iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
2349
2350 if (psInfo->iNumPagesMapped >= 0)
2351 {
2352
2353 if (psInfo->iNumPagesMapped != psInfo->iNumPages)
2354 {
2355 PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, psInfo->iNumPagesMapped));
2356
2357 goto error;
2358 }
2359
2360
2361 for (i = 0; i < psInfo->iNumPages; i++)
2362 {
2363 IMG_CPU_PHYADDR CPUPhysAddr;
2364 IMG_UINT32 ulPFN;
2365
2366 ulPFN = page_to_pfn(psInfo->ppsPages[i]);
2367 CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
2368 if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
2369 {
2370 PVR_DPF((PVR_DBG_ERROR,
2371 "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
2372
2373 goto error;
2374 }
2375 psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
2376 psSysPAddr[i] = psInfo->psPhysAddr[i];
2377
2378 }
2379
2380 goto exit;
2381 }
2382
2383 PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), using CPU page table", psInfo->iNumPagesMapped));
2384
2385
2386 psInfo->eType = WRAP_TYPE_NULL;
2387 psInfo->iNumPagesMapped = 0;
2388 memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
2389
2390
2391
2392 psInfo->eType = WRAP_TYPE_FIND_VMA;
2393
2394 psVMArea = find_vma(current->mm, ulStartAddrOrig);
2395 if (psVMArea == NULL)
2396 {
2397 PVR_DPF((PVR_DBG_ERROR,
2398 "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %x", ulStartAddrOrig));
2399
2400 goto error;
2401 }
2402#if defined(DEBUG)
2403 psInfo->psVMArea = psVMArea;
2404#endif
2405
2406
2407 if (ulStartAddrOrig < psVMArea->vm_start)
2408 {
2409 PVR_DPF((PVR_DBG_ERROR,
2410 "OSAcquirePhysPageAddr: Start address %x is outside of the region returned by find_vma", ulStartAddrOrig));
2411 goto error;
2412 }
2413
2414
2415 if (ulBeyondEndAddrOrig > psVMArea->vm_end)
2416 {
2417 PVR_DPF((PVR_DBG_ERROR,
2418 "OSAcquirePhysPageAddr: End address %x is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
2419 goto error;
2420 }
2421
2422
2423 if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED))
2424 {
2425 PVR_DPF((PVR_DBG_ERROR,
2426 "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags));
2427 goto error;
2428 }
2429
2430
2431 if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE))
2432 {
2433 PVR_DPF((PVR_DBG_ERROR,
2434 "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags));
2435 goto error;
2436 }
2437
2438 for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
2439 {
2440 IMG_CPU_PHYADDR CPUPhysAddr;
2441 IMG_UINT32 ulPFN = 0;
2442
2443 PVR_ASSERT(i < psInfo->iNumPages);
2444
2445 if (!CPUVAddrToPFN(psVMArea, ulAddr, &ulPFN, &psInfo->ppsPages[i]))
2446 {
2447 PVR_DPF((PVR_DBG_ERROR,
2448 "OSAcquirePhysPageAddr: Invalid CPU virtual address"));
2449
2450 goto error;
2451 }
2452 if (psInfo->ppsPages[i] == NULL)
2453 {
2454
2455 bHaveNoPageStructs = IMG_TRUE;
2456
2457#if defined(VM_PFNMAP)
2458 if ((psVMArea->vm_flags & VM_PFNMAP) != 0)
2459 {
2460 IMG_UINT32 ulPFNRaw = ((ulAddr - psVMArea->vm_start) >> PAGE_SHIFT) + psVMArea->vm_pgoff;
2461
2462 if (ulPFNRaw != ulPFN)
2463 {
2464 bPFNMismatch = IMG_TRUE;
2465 }
2466 }
2467#endif
2468 }
2469 else
2470 {
2471 bHavePageStructs = IMG_TRUE;
2472
2473 psInfo->iNumPagesMapped++;
2474
2475 PVR_ASSERT(ulPFN == page_to_pfn(psInfo->ppsPages[i]));
2476 }
2477
2478 CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
2479 if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
2480 {
2481 PVR_DPF((PVR_DBG_ERROR,
2482 "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
2483
2484 goto error;
2485 }
2486
2487 psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
2488 psSysPAddr[i] = psInfo->psPhysAddr[i];
2489 }
2490 PVR_ASSERT(i == psInfo->iNumPages);
2491
2492#if defined(VM_MIXEDMAP)
2493 if ((psVMArea->vm_flags & VM_MIXEDMAP) != 0)
2494 {
2495 goto exit;
2496 }
2497#endif
2498
2499 if (bHavePageStructs && bHaveNoPageStructs)
2500 {
2501 PVR_DPF((PVR_DBG_ERROR,
2502 "OSAcquirePhysPageAddr: Region is VM_MIXEDMAP, but isn't marked as such"));
2503 goto error;
2504 }
2505
2506 if (!bHaveNoPageStructs)
2507 {
2508
2509 goto exit;
2510 }
2511
2512#if defined(VM_PFNMAP)
2513 if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
2514#endif
2515 {
2516 PVR_DPF((PVR_DBG_ERROR,
2517 "OSAcquirePhysPageAddr: Region is VM_PFNMAP, but isn't marked as such"));
2518 goto error;
2519 }
2520
2521 if (bPFNMismatch)
2522 {
2523 PVR_DPF((PVR_DBG_ERROR,
2524 "OSAcquirePhysPageAddr: PFN calculation mismatch for VM_PFNMAP region"));
2525 goto error;
2526 }
2527
2528exit:
2529 PVR_ASSERT(bMMapSemHeld);
2530 up_read(&current->mm->mmap_sem);
2531
2532
2533 *phOSWrapMem = (IMG_HANDLE)psInfo;
2534
2535 if (bHaveNoPageStructs)
2536 {
2537 PVR_DPF((PVR_DBG_WARNING,
2538 "OSAcquirePhysPageAddr: Region contains pages which can't be locked down (no page structures)"));
2539 }
2540
2541 PVR_ASSERT(psInfo->eType != 0);
2542
2543#if 0
2544
2545
2546 OSCleanCPUCacheRangeKM(pvCPUVAddr, (IMG_VOID *)((IMG_CHAR *)pvCPUVAddr + ui32Bytes));
2547#endif
2548
2549 return PVRSRV_OK;
2550
2551error:
2552 if (bMMapSemHeld)
2553 {
2554 up_read(&current->mm->mmap_sem);
2555 }
2556 OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
2557
2558 PVR_ASSERT(eError != PVRSRV_OK);
2559
2560 return eError;
2561}
2562
2563typedef void (*InnerCacheOp_t)(const void *pvStart, const void *pvEnd);
2564typedef void (*OuterCacheOp_t)(unsigned long ulStart, unsigned long ulEnd);
2565
2566#if defined(CONFIG_OUTER_CACHE)
2567
2568typedef unsigned long (*MemAreaToPhys_t)(LinuxMemArea *psLinuxMemArea,
2569 IMG_VOID *pvRangeAddrStart,
2570 IMG_UINT32 ui32PageNumOffset,
2571 IMG_UINT32 ui32PageNum);
2572
2573static unsigned long VMallocAreaToPhys(LinuxMemArea *psLinuxMemArea,
2574 IMG_VOID *pvRangeAddrStart,
2575 IMG_UINT32 ui32PageNumOffset,
2576 IMG_UINT32 ui32PageNum)
2577{
2578 return vmalloc_to_pfn(pvRangeAddrStart + ui32PageNum * PAGE_SIZE) << PAGE_SHIFT;
2579}
2580
2581static unsigned long ExternalKVAreaToPhys(LinuxMemArea *psLinuxMemArea,
2582 IMG_VOID *pvRangeAddrStart,
2583 IMG_UINT32 ui32PageNumOffset,
2584 IMG_UINT32 ui32PageNum)
2585{
2586 IMG_SYS_PHYADDR SysPAddr;
2587 IMG_CPU_PHYADDR CpuPAddr;
2588 SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageNumOffset + ui32PageNum];
2589 CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
2590 return CpuPAddr.uiAddr;
2591}
2592
2593static unsigned long AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea,
2594 IMG_VOID *pvRangeAddrStart,
2595 IMG_UINT32 ui32PageNumOffset,
2596 IMG_UINT32 ui32PageNum)
2597{
2598 struct page *pPage;
2599 pPage = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageNumOffset + ui32PageNum];
2600 return page_to_pfn(pPage) << PAGE_SHIFT;
2601}
2602
2603#endif
2604
2605static
2606IMG_VOID *FindMMapBaseVAddr(struct list_head *psMMapOffsetStructList,
2607 IMG_VOID *pvRangeAddrStart, IMG_UINT32 ui32Length)
2608{
2609 PKV_OFFSET_STRUCT psOffsetStruct;
2610 IMG_VOID *pvMinVAddr;
2611
2612
2613 list_for_each_entry(psOffsetStruct, psMMapOffsetStructList, sAreaItem)
2614 {
2615 if(OSGetCurrentProcessIDKM() != psOffsetStruct->ui32PID)
2616 continue;
2617
2618 pvMinVAddr = (IMG_VOID *)psOffsetStruct->ui32UserVAddr;
2619
2620
2621 if(pvRangeAddrStart >= pvMinVAddr &&
2622 ui32Length <= psOffsetStruct->ui32RealByteSize)
2623 return pvMinVAddr;
2624 }
2625
2626 return IMG_NULL;
2627}
2628
2629static
2630IMG_BOOL CheckExecuteCacheOp(IMG_HANDLE hOSMemHandle,
2631 IMG_VOID *pvRangeAddrStart,
2632 IMG_UINT32 ui32Length,
2633 InnerCacheOp_t pfnInnerCacheOp,
2634 OuterCacheOp_t pfnOuterCacheOp)
2635{
2636 LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
2637 IMG_UINT32 ui32AreaLength, ui32AreaOffset = 0;
2638 struct list_head *psMMapOffsetStructList;
2639 IMG_VOID *pvMinVAddr;
2640
2641#if defined(CONFIG_OUTER_CACHE)
2642 MemAreaToPhys_t pfnMemAreaToPhys;
2643 IMG_UINT32 ui32PageNumOffset = 0;
2644#endif
2645
2646 PVR_ASSERT(psLinuxMemArea != IMG_NULL);
2647
2648 ui32AreaLength = psLinuxMemArea->ui32ByteSize;
2649 psMMapOffsetStructList = &psLinuxMemArea->sMMapOffsetStructList;
2650
2651 PVR_ASSERT(ui32Length <= ui32AreaLength);
2652
2653 if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
2654 {
2655 ui32AreaOffset = psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
2656 psLinuxMemArea = psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
2657 }
2658
2659
2660 PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
2661
2662 switch(psLinuxMemArea->eAreaType)
2663 {
2664 case LINUX_MEM_AREA_VMALLOC:
2665 {
2666 pvMinVAddr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + ui32AreaOffset;
2667
2668
2669 if(pvRangeAddrStart < pvMinVAddr &&
2670 ui32AreaOffset + ui32Length > ui32AreaLength)
2671 goto err_blocked;
2672
2673#if defined(CONFIG_OUTER_CACHE)
2674 pfnMemAreaToPhys = VMallocAreaToPhys;
2675#endif
2676 break;
2677 }
2678
2679 case LINUX_MEM_AREA_EXTERNAL_KV:
2680 {
2681
2682 PVR_ASSERT(psLinuxMemArea->uData.sExternalKV.bPhysContig != IMG_TRUE);
2683
2684
2685 PVR_ASSERT(psLinuxMemArea->uData.sExternalKV.pvExternalKV == IMG_NULL);
2686
2687
2688
2689 pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
2690 pvRangeAddrStart, ui32Length);
2691 if(!pvMinVAddr)
2692 goto err_blocked;
2693
2694#if defined(CONFIG_OUTER_CACHE)
2695 ui32PageNumOffset = (ui32AreaOffset + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
2696 pfnMemAreaToPhys = ExternalKVAreaToPhys;
2697#endif
2698 break;
2699 }
2700
2701 case LINUX_MEM_AREA_ALLOC_PAGES:
2702 {
2703 pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
2704 pvRangeAddrStart, ui32Length);
2705 if(!pvMinVAddr)
2706 goto err_blocked;
2707
2708#if defined(CONFIG_OUTER_CACHE)
2709 ui32PageNumOffset = (ui32AreaOffset + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
2710 pfnMemAreaToPhys = AllocPagesAreaToPhys;
2711#endif
2712 break;
2713 }
2714
2715 default:
2716 PVR_DBG_BREAK;
2717 }
2718
2719
2720 pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
2721
2722#if defined(CONFIG_OUTER_CACHE)
2723
2724 {
2725 unsigned long ulStart, ulEnd, ulLength, ulStartOffset, ulEndOffset;
2726 IMG_UINT32 i, ui32NumPages;
2727
2728
2729 ulLength = (unsigned long)ui32Length;
2730 ulStartOffset = ((unsigned long)pvRangeAddrStart) & (PAGE_SIZE - 1);
2731 ulEndOffset = ((unsigned long)pvRangeAddrStart + ulLength) & (PAGE_SIZE - 1);
2732
2733
2734 ui32NumPages = (ulStartOffset + ulLength + PAGE_SIZE - 1) >> PAGE_SHIFT;
2735
2736 for(i = 0; i < ui32NumPages; i++)
2737 {
2738 ulStart = pfnMemAreaToPhys(psLinuxMemArea, pvRangeAddrStart,
2739 ui32PageNumOffset, i);
2740 ulEnd = ulStart + PAGE_SIZE;
2741
2742 if(i == ui32NumPages - 1 && ulEndOffset != 0)
2743 ulEnd = ulStart + ulEndOffset;
2744
2745 if(i == 0)
2746 ulStart += ulStartOffset;
2747
2748 pfnOuterCacheOp(ulStart, ulEnd);
2749 }
2750 }
2751#endif
2752
2753 return IMG_TRUE;
2754
2755err_blocked:
2756 PVR_DPF((PVR_DBG_WARNING, "%s: Blocked cache op on virtual range "
2757 "%p-%p (type %d)", __func__,
2758 pvRangeAddrStart, pvRangeAddrStart + ui32Length,
2759 psLinuxMemArea->eAreaType));
2760 return IMG_FALSE;
2761}
2762
2763#if defined(__i386__)
2764
2765#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1))
2766
2767static void per_cpu_cache_flush(void *arg)
2768{
2769 PVR_UNREFERENCED_PARAMETER(arg);
2770 wbinvd();
2771}
2772
2773static void x86_flush_cache_range(const void *pvStart, const void *pvEnd)
2774{
2775 IMG_BYTE *pbStart = (IMG_BYTE *)pvStart;
2776 IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd;
2777 IMG_BYTE *pbBase;
2778
2779 pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd,
2780 boot_cpu_data.x86_clflush_size);
2781
2782 mb();
2783 for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size)
2784 clflush(pbBase);
2785 mb();
2786}
2787
2788IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
2789{
2790
2791 on_each_cpu(per_cpu_cache_flush, NULL, 1);
2792}
2793
2794IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
2795{
2796 on_each_cpu(per_cpu_cache_flush, NULL, 1);
2797}
2798
2799IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2800 IMG_VOID *pvRangeAddrStart,
2801 IMG_UINT32 ui32Length)
2802{
2803
2804 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2805 x86_flush_cache_range, IMG_NULL);
2806}
2807
2808IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2809 IMG_VOID *pvRangeAddrStart,
2810 IMG_UINT32 ui32Length)
2811{
2812
2813 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2814 x86_flush_cache_range, IMG_NULL);
2815}
2816
2817IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2818 IMG_VOID *pvRangeAddrStart,
2819 IMG_UINT32 ui32Length)
2820{
2821
2822 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2823 x86_flush_cache_range, IMG_NULL);
2824}
2825
2826#else
2827
2828#if defined(__arm__)
2829
2830IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
2831{
2832
2833 flush_cache_all();
2834}
2835
2836IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
2837{
2838 flush_cache_all();
2839}
2840
2841IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2842 IMG_VOID *pvRangeAddrStart,
2843 IMG_UINT32 ui32Length)
2844{
2845 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2846 dmac_flush_range, outer_flush_range);
2847}
2848
2849IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2850 IMG_VOID *pvRangeAddrStart,
2851 IMG_UINT32 ui32Length)
2852{
2853 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2854 dmac_clean_range, outer_clean_range);
2855}
2856
2857IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
2858 IMG_VOID *pvRangeAddrStart,
2859 IMG_UINT32 ui32Length)
2860{
2861 return CheckExecuteCacheOp(hOSMemHandle, pvRangeAddrStart, ui32Length,
2862 dmac_inv_range, outer_inv_range);
2863}
2864
2865#else
2866
2867#error "Implement CPU cache flush/clean/invalidate primitives for this CPU!"
2868
2869#endif
2870
2871#endif
2872
2873PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
2874{
2875#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
2876 {
2877 IMG_UINT32 ui32i;
2878
2879 psTimerWorkQueue = create_workqueue("pvr_timer");
2880 if (psTimerWorkQueue == NULL)
2881 {
2882 PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));
2883 return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
2884
2885 }
2886
2887 for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
2888 {
2889 TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
2890
2891 INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
2892 }
2893 }
2894#endif
2895 return PVRSRV_OK;
2896}
2897
2898IMG_VOID PVROSFuncDeInit(IMG_VOID)
2899{
2900#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
2901 if (psTimerWorkQueue != NULL)
2902 {
2903 destroy_workqueue(psTimerWorkQueue);
2904 }
2905#endif
2906}
diff --git a/drivers/gpu/pvr/osfunc.h b/drivers/gpu/pvr/osfunc.h
new file mode 100644
index 00000000000..8ffbea60aeb
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc.h
@@ -0,0 +1,576 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifdef DEBUG_RELEASE_BUILD
28#pragma optimize( "", off )
29#define DEBUG 1
30#endif
31
32#ifndef __OSFUNC_H__
33#define __OSFUNC_H__
34
35#if defined (__cplusplus)
36extern "C" {
37#endif
38
39#if defined(__linux__) && defined(__KERNEL__)
40#include <linux/hardirq.h>
41#include <linux/string.h>
42#include <asm/system.h>
43#if defined(__arm__)
44#include <asm/memory.h>
45#endif
46#endif
47
48
49
50 #define PVRSRV_PAGEABLE_SELECT PVRSRV_OS_PAGEABLE_HEAP
51
52#define KERNEL_ID 0xffffffffL
53#define POWER_MANAGER_ID 0xfffffffeL
54#define ISR_ID 0xfffffffdL
55#define TIMER_ID 0xfffffffcL
56
57
58#define HOST_PAGESIZE OSGetPageSize
59#define HOST_PAGEMASK (HOST_PAGESIZE()-1)
60#define HOST_PAGEALIGN(addr) (((addr) + HOST_PAGEMASK) & ~HOST_PAGEMASK)
61
62#define PVRSRV_OS_HEAP_MASK 0xf
63#define PVRSRV_OS_PAGEABLE_HEAP 0x1
64#define PVRSRV_OS_NON_PAGEABLE_HEAP 0x2
65
66
67IMG_UINT32 OSClockus(IMG_VOID);
68IMG_SIZE_T OSGetPageSize(IMG_VOID);
69PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
70 IMG_UINT32 ui32Irq,
71 IMG_CHAR *pszISRName,
72 IMG_VOID *pvDeviceNode);
73PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData);
74PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq);
75PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData);
76PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData);
77PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData);
78IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE, IMG_VOID* pvLinAddr);
79IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
80IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle);
81IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
82
83PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle);
84PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
85
86#if defined(__linux__) && defined(__KERNEL__)
87
88IMG_VOID OSFlushCPUCacheKM(IMG_VOID);
89
90IMG_VOID OSCleanCPUCacheKM(IMG_VOID);
91
92IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
93 IMG_VOID *pvRangeAddrStart,
94 IMG_UINT32 ui32Length);
95IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
96 IMG_VOID *pvRangeAddrStart,
97 IMG_UINT32 ui32Length);
98IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
99 IMG_VOID *pvRangeAddrStart,
100 IMG_UINT32 ui32Length);
101
102#else
103
104#ifdef INLINE_IS_PRAGMA
105#pragma inline(OSFlushCPUCacheKM)
106#endif
107static INLINE IMG_VOID OSFlushCPUCacheKM(IMG_VOID) {}
108
109#ifdef INLINE_IS_PRAGMA
110#pragma inline(OSCleanCPUCacheKM)
111#endif
112static INLINE IMG_VOID OSCleanCPUCacheKM(IMG_VOID) {}
113
114#ifdef INLINE_IS_PRAGMA
115#pragma inline(OSFlushCPUCacheRangeKM)
116#endif
117static INLINE IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
118 IMG_VOID *pvRangeAddrStart,
119 IMG_UINT32 ui32Length)
120{
121 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
122 PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
123 PVR_UNREFERENCED_PARAMETER(ui32Length);
124 return IMG_FALSE;
125}
126
127#ifdef INLINE_IS_PRAGMA
128#pragma inline(OSCleanCPUCacheRangeKM)
129#endif
130static INLINE IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
131 IMG_VOID *pvRangeAddrStart,
132 IMG_UINT32 ui32Length)
133{
134 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
135 PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
136 PVR_UNREFERENCED_PARAMETER(ui32Length);
137 return IMG_FALSE;
138}
139
140#ifdef INLINE_IS_PRAGMA
141#pragma inline(OSInvalidateCPUCacheRangeKM)
142#endif
143static INLINE IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
144 IMG_VOID *pvRangeAddrStart,
145 IMG_UINT32 ui32Length)
146{
147 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
148 PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
149 PVR_UNREFERENCED_PARAMETER(ui32Length);
150 return IMG_FALSE;
151}
152
153#endif
154
155#if defined(__linux__)
156PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
157 IMG_VOID *pvCpuVAddr,
158 IMG_SIZE_T ui32Bytes,
159 IMG_UINT32 ui32Flags,
160 IMG_HANDLE *phOSMemHandle);
161PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
162 IMG_SIZE_T ui32Bytes,
163 IMG_UINT32 ui32Flags,
164 IMG_HANDLE hOSMemHandle);
165#else
166#ifdef INLINE_IS_PRAGMA
167#pragma inline(OSRegisterDiscontigMem)
168#endif
169static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
170 IMG_VOID *pvCpuVAddr,
171 IMG_SIZE_T ui32Bytes,
172 IMG_UINT32 ui32Flags,
173 IMG_HANDLE *phOSMemHandle)
174{
175 PVR_UNREFERENCED_PARAMETER(pBasePAddr);
176 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
177 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
178 PVR_UNREFERENCED_PARAMETER(ui32Flags);
179 PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
180
181 return PVRSRV_ERROR_NOT_SUPPORTED;
182}
183
184#ifdef INLINE_IS_PRAGMA
185#pragma inline(OSUnRegisterDiscontigMem)
186#endif
187static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
188 IMG_SIZE_T ui32Bytes,
189 IMG_UINT32 ui32Flags,
190 IMG_HANDLE hOSMemHandle)
191{
192 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
193 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
194 PVR_UNREFERENCED_PARAMETER(ui32Flags);
195 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
196
197 return PVRSRV_ERROR_NOT_SUPPORTED;
198}
199#endif
200
201
202#if defined(__linux__)
203#ifdef INLINE_IS_PRAGMA
204#pragma inline(OSReserveDiscontigPhys)
205#endif
206static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
207{
208#if defined(__linux__)
209 *ppvCpuVAddr = IMG_NULL;
210 return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle);
211#else
212 extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr);
213
214
215 return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, ppvCpuVAddr, phOSMemHandle);
216#endif
217}
218
219static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
220{
221#if defined(__linux__)
222 OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
223#endif
224
225 return PVRSRV_OK;
226}
227#else
228
229
230#ifdef INLINE_IS_PRAGMA
231#pragma inline(OSReserveDiscontigPhys)
232#endif
233static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
234{
235 PVR_UNREFERENCED_PARAMETER(pBasePAddr);
236 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
237 PVR_UNREFERENCED_PARAMETER(ui32Flags);
238 PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr);
239 PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
240
241 return PVRSRV_ERROR_NOT_SUPPORTED;
242}
243
244#ifdef INLINE_IS_PRAGMA
245#pragma inline(OSUnReserveDiscontigPhys)
246#endif
247static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
248{
249 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
250 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
251 PVR_UNREFERENCED_PARAMETER(ui32Flags);
252 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
253
254 return PVRSRV_ERROR_NOT_SUPPORTED;
255}
256#endif
257
258PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
259 IMG_VOID *pvCpuVAddr,
260 IMG_SIZE_T ui32Bytes,
261 IMG_UINT32 ui32Flags,
262 IMG_HANDLE *phOSMemHandle);
263PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr,
264 IMG_SIZE_T ui32Bytes,
265 IMG_UINT32 ui32Flags,
266 IMG_HANDLE hOSMemHandle);
267
268
269
270#if defined(__linux__)
271PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
272 IMG_UINTPTR_T ui32ByteOffset,
273 IMG_SIZE_T ui32Bytes,
274 IMG_UINT32 ui32Flags,
275 IMG_HANDLE *phOSMemHandleRet);
276PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags);
277#else
278#ifdef INLINE_IS_PRAGMA
279#pragma inline(OSGetSubMemHandle)
280#endif
281static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
282 IMG_UINTPTR_T ui32ByteOffset,
283 IMG_SIZE_T ui32Bytes,
284 IMG_UINT32 ui32Flags,
285 IMG_HANDLE *phOSMemHandleRet)
286{
287 PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
288 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
289 PVR_UNREFERENCED_PARAMETER(ui32Flags);
290
291 *phOSMemHandleRet = hOSMemHandle;
292 return PVRSRV_OK;
293}
294
295static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags)
296{
297 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
298 PVR_UNREFERENCED_PARAMETER(ui32Flags);
299 return PVRSRV_OK;
300}
301#endif
302
303IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID);
304IMG_UINTPTR_T OSGetCurrentThreadID( IMG_VOID );
305IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
306
307PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_UINT32 ui32PageSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc);
308PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc);
309
310
311#ifdef PVRSRV_LOG_MEMORY_ALLOCS
312 #define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \
313 (PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \
314 OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
315
316 #define OSAllocPages(flags, size, pageSize, linAddr, pageAlloc) \
317 (PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \
318 OSAllocPages_Impl(flags, size, pageSize, linAddr, pageAlloc))
319
320 #define OSFreeMem(flags, size, linAddr, blockAlloc) \
321 (PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \
322 OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
323#else
324 #define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \
325 OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
326
327 #define OSAllocPages OSAllocPages_Impl
328
329 #define OSFreeMem(flags, size, linAddr, blockAlloc) \
330 OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
331#endif
332
333#ifdef PVRSRV_DEBUG_OS_MEMORY
334
335 PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
336 IMG_UINT32 ui32Size,
337 IMG_PVOID *ppvCpuVAddr,
338 IMG_HANDLE *phBlockAlloc,
339 IMG_CHAR *pszFilename,
340 IMG_UINT32 ui32Line);
341
342 PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
343 IMG_UINT32 ui32Size,
344 IMG_PVOID pvCpuVAddr,
345 IMG_HANDLE hBlockAlloc,
346 IMG_CHAR *pszFilename,
347 IMG_UINT32 ui32Line);
348
349
350 typedef struct
351 {
352 IMG_UINT8 sGuardRegionBefore[8];
353 IMG_CHAR sFileName[128];
354 IMG_UINT32 uLineNo;
355 IMG_SIZE_T uSize;
356 IMG_SIZE_T uSizeParityCheck;
357 enum valid_tag
358 { isFree = 0x277260FF,
359 isAllocated = 0x260511AA
360 } eValid;
361 } OSMEM_DEBUG_INFO;
362
363 #define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO))
364 #define TEST_BUFFER_PADDING_AFTER (8)
365 #define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER)
366#else
367 #define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations
368 #define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations
369#endif
370
371#if defined(__linux__) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
372 PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
373 PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
374
375 #define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl
376 #define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl
377#else
378 PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc);
379 PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc);
380
381 #define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
382 OSAllocMem_Impl(flags, size, addr, blockAlloc)
383 #define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
384 OSFreeMem_Impl(flags, size, addr, blockAlloc)
385#endif
386
387
388#if defined(__linux__)
389IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_SIZE_T ui32ByteOffset);
390#else
391#ifdef INLINE_IS_PRAGMA
392#pragma inline(OSMemHandleToCpuPAddr)
393#endif
394static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_SIZE_T ui32ByteOffset)
395{
396 IMG_CPU_PHYADDR sCpuPAddr;
397 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
398 PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
399 sCpuPAddr.uiAddr = 0;
400 return sCpuPAddr;
401}
402#endif
403PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData);
404PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData);
405IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc);
406IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
407#define OSStringLength(pszString) strlen(pszString)
408
409PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName,
410 PVRSRV_EVENTOBJECT *psEventObject);
411PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject);
412PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM);
413PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM);
414PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject,
415 IMG_HANDLE *phOSEvent);
416PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject,
417 IMG_HANDLE hOSEventKM);
418
419
420PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr);
421PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr);
422
423IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T ui32Size,IMG_HANDLE *phMemBlock);
424IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess);
425IMG_VOID OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess);
426
427IMG_VOID UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_SIZE_T ui32Size, IMG_HANDLE hMemBlock);
428
429PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie,
430 IMG_SYS_PHYADDR sCPUPhysAddr,
431 IMG_SIZE_T uiSizeInBytes,
432 IMG_UINT32 ui32CacheFlags,
433 IMG_PVOID *ppvUserAddr,
434 IMG_SIZE_T *puiActualSize,
435 IMG_HANDLE hMappingHandle);
436
437PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie,
438 IMG_PVOID pvUserAddr,
439 IMG_PVOID pvProcess);
440
441PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
442PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
443IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
444PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource);
445PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource);
446IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
447IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
448IMG_VOID OSReleaseThreadQuanta(IMG_VOID);
449IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg);
450IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value);
451
452#ifndef OSReadHWReg
453IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
454#endif
455#ifndef OSWriteHWReg
456IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
457#endif
458
459typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*);
460IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout);
461PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer);
462PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer);
463PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer);
464
465PVRSRV_ERROR OSGetSysMemSize(IMG_SIZE_T *pui32Bytes);
466
467typedef enum _HOST_PCI_INIT_FLAGS_
468{
469 HOST_PCI_INIT_FLAG_BUS_MASTER = 0x00000001,
470 HOST_PCI_INIT_FLAG_MSI = 0x00000002,
471 HOST_PCI_INIT_FLAG_FORCE_I32 = 0x7fffffff
472} HOST_PCI_INIT_FLAGS;
473
474struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_;
475typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE;
476
477PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags);
478PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags);
479PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
480PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ);
481IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
482IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
483IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
484PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
485PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
486PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
487PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
488
489PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData);
490
491IMG_VOID OSPanic(IMG_VOID);
492
493IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID);
494
495typedef enum _img_verify_test
496{
497 PVR_VERIFY_WRITE = 0,
498 PVR_VERIFY_READ
499} IMG_VERIFY_TEST;
500
501IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T ui32Bytes);
502
503PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
504PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
505
506#if defined(__linux__)
507PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
508 IMG_SIZE_T ui32Bytes,
509 IMG_SYS_PHYADDR *psSysPAddr,
510 IMG_HANDLE *phOSWrapMem);
511PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem);
512#else
513#ifdef INLINE_IS_PRAGMA
514#pragma inline(OSAcquirePhysPageAddr)
515#endif
516static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
517 IMG_SIZE_T ui32Bytes,
518 IMG_SYS_PHYADDR *psSysPAddr,
519 IMG_HANDLE *phOSWrapMem)
520{
521 PVR_UNREFERENCED_PARAMETER(pvCPUVAddr);
522 PVR_UNREFERENCED_PARAMETER(ui32Bytes);
523 PVR_UNREFERENCED_PARAMETER(psSysPAddr);
524 PVR_UNREFERENCED_PARAMETER(phOSWrapMem);
525 return PVRSRV_OK;
526}
527#ifdef INLINE_IS_PRAGMA
528#pragma inline(OSReleasePhysPageAddr)
529#endif
530static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
531{
532 PVR_UNREFERENCED_PARAMETER(hOSWrapMem);
533 return PVRSRV_OK;
534}
535#endif
536
537#if defined(__linux__) && defined(__KERNEL__)
538
539#define OS_SUPPORTS_IN_LISR
540
541static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData)
542{
543 PVR_UNREFERENCED_PARAMETER(pvSysData);
544 return (in_irq()) ? IMG_TRUE : IMG_FALSE;
545}
546
547static inline IMG_VOID OSWriteMemoryBarrier(IMG_VOID)
548{
549 wmb();
550}
551
552static inline IMG_VOID OSMemoryBarrier(IMG_VOID)
553{
554 mb();
555}
556
557#else
558
559#ifdef INLINE_IS_PRAGMA
560#pragma inline(OSWriteMemoryBarrier)
561#endif
562static INLINE IMG_VOID OSWriteMemoryBarrier(IMG_VOID) { }
563
564#ifdef INLINE_IS_PRAGMA
565#pragma inline(OSMemoryBarrier)
566#endif
567static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { }
568
569#endif
570
571#if defined (__cplusplus)
572}
573#endif
574
575#endif
576
diff --git a/drivers/gpu/pvr/osfunc_common.c b/drivers/gpu/pvr/osfunc_common.c
new file mode 100644
index 00000000000..25ac6677fbc
--- /dev/null
+++ b/drivers/gpu/pvr/osfunc_common.c
@@ -0,0 +1,31 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "img_types.h"
28#include "services_headers.h"
29#include "osfunc.h"
30
31
diff --git a/drivers/gpu/pvr/osperproc.c b/drivers/gpu/pvr/osperproc.c
new file mode 100644
index 00000000000..882234f5df5
--- /dev/null
+++ b/drivers/gpu/pvr/osperproc.c
@@ -0,0 +1,113 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "osperproc.h"
29
30#include "env_perproc.h"
31#include "proc.h"
32
33extern IMG_UINT32 gui32ReleasePID;
34
35PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
36{
37 PVRSRV_ERROR eError;
38 IMG_HANDLE hBlockAlloc;
39 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
40
41 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
42 sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
43 phOsPrivateData,
44 &hBlockAlloc,
45 "Environment per Process Data");
46
47 if (eError != PVRSRV_OK)
48 {
49 *phOsPrivateData = IMG_NULL;
50
51 PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError));
52 return eError;
53 }
54
55 psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData;
56 OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc));
57
58 psEnvPerProc->hBlockAlloc = hBlockAlloc;
59
60
61 LinuxMMapPerProcessConnect(psEnvPerProc);
62
63#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
64
65 INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
66#endif
67
68 return PVRSRV_OK;
69}
70
71PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
72{
73 PVRSRV_ERROR eError;
74 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
75
76 if (hOsPrivateData == IMG_NULL)
77 {
78 return PVRSRV_OK;
79 }
80
81 psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData;
82
83
84 LinuxMMapPerProcessDisconnect(psEnvPerProc);
85
86
87 RemovePerProcessProcDir(psEnvPerProc);
88
89 eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
90 sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
91 hOsPrivateData,
92 psEnvPerProc->hBlockAlloc);
93
94
95 if (eError != PVRSRV_OK)
96 {
97 PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError));
98 }
99
100 return PVRSRV_OK;
101}
102
103PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
104{
105 return LinuxMMapPerProcessHandleOptions(psHandleBase);
106}
107
108IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID)
109{
110 if(!gui32ReleasePID)
111 return NULL;
112 return PVRSRVPerProcessPrivateData(gui32ReleasePID);
113}
diff --git a/drivers/gpu/pvr/osperproc.h b/drivers/gpu/pvr/osperproc.h
new file mode 100644
index 00000000000..80a912f2488
--- /dev/null
+++ b/drivers/gpu/pvr/osperproc.h
@@ -0,0 +1,76 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __OSPERPROC_H__
28#define __OSPERPROC_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#if defined(__linux__)
35PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData);
36PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
37
38PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
39#else
40#ifdef INLINE_IS_PRAGMA
41#pragma inline(OSPerProcessPrivateDataInit)
42#endif
43static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
44{
45 PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
46
47 return PVRSRV_OK;
48}
49
50#ifdef INLINE_IS_PRAGMA
51#pragma inline(OSPerProcessPrivateDataDeInit)
52#endif
53static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
54{
55 PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
56
57 return PVRSRV_OK;
58}
59
60#ifdef INLINE_IS_PRAGMA
61#pragma inline(OSPerProcessSetHandleOptions)
62#endif
63static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
64{
65 PVR_UNREFERENCED_PARAMETER(psHandleBase);
66
67 return PVRSRV_OK;
68}
69#endif
70
71#if defined (__cplusplus)
72}
73#endif
74
75#endif
76
diff --git a/drivers/gpu/pvr/pdump.c b/drivers/gpu/pvr/pdump.c
new file mode 100644
index 00000000000..0cae749cd46
--- /dev/null
+++ b/drivers/gpu/pvr/pdump.c
@@ -0,0 +1,627 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined (SUPPORT_SGX) || defined (SUPPORT_VGX)
28#if defined (PDUMP)
29
30#include <asm/atomic.h>
31#include <stdarg.h>
32#if defined (SUPPORT_SGX)
33#include "sgxdefs.h"
34#endif
35#include "services_headers.h"
36
37#include "pvrversion.h"
38#include "pvr_debug.h"
39
40#include "dbgdrvif.h"
41#if defined (SUPPORT_SGX)
42#include "sgxmmu.h"
43#endif
44#include "mm.h"
45#include "pdump_km.h"
46#include "pdump_int.h"
47
48#include <linux/kernel.h>
49#include <linux/string.h>
50
51static IMG_BOOL PDumpWriteString2 (IMG_CHAR * pszString, IMG_UINT32 ui32Flags);
52static IMG_BOOL PDumpWriteILock (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags);
53static IMG_VOID DbgSetFrame (PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
54static IMG_VOID DbgSetMarker (PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
55
56#define PDUMP_DATAMASTER_PIXEL (1)
57#define PDUMP_DATAMASTER_EDM (3)
58
59#define MAX_FILE_SIZE 0x40000000
60
61static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
62
63static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
64
65
66
67IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
68 "ScriptStream2",
69 "DriverInfoStream"};
70typedef struct PDBG_PDUMP_STATE_TAG
71{
72 PDBG_STREAM psStream[PDUMP_NUM_STREAMS];
73 IMG_UINT32 ui32ParamFileNum;
74
75 IMG_CHAR *pszMsg;
76 IMG_CHAR *pszScript;
77 IMG_CHAR *pszFile;
78
79} PDBG_PDUMP_STATE;
80
81static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL};
82
83#define SZ_MSG_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
84#define SZ_SCRIPT_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
85#define SZ_FILENAME_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
86
87
88
89
90IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
91
92static inline IMG_BOOL PDumpSuspended(IMG_VOID)
93{
94 return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
95}
96
97PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
98 IMG_UINT32 *pui32MaxLen)
99{
100 *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
101 *pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
102 if ((!*phScript) || PDumpSuspended())
103 {
104 return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
105 }
106 return PVRSRV_OK;
107}
108
109PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg,
110 IMG_UINT32 *pui32MaxLen)
111{
112 *ppszMsg = gsDBGPdumpState.pszMsg;
113 *pui32MaxLen = SZ_MSG_SIZE_MAX;
114 if ((!*ppszMsg) || PDumpSuspended())
115 {
116 return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
117 }
118 return PVRSRV_OK;
119}
120
121PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
122 IMG_UINT32 *pui32MaxLen)
123{
124 *ppszFile = gsDBGPdumpState.pszFile;
125 *pui32MaxLen = SZ_FILENAME_SIZE_MAX;
126 if ((!*ppszFile) || PDumpSuspended())
127 {
128 return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
129 }
130 return PVRSRV_OK;
131}
132
133IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags)
134{
135 return PDumpWriteString2(hScript, ui32Flags);
136}
137
138PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...)
139{
140 IMG_CHAR* pszBuf = hBuf;
141 IMG_INT32 n;
142 va_list vaArgs;
143
144 va_start(vaArgs, pszFormat);
145
146 n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs);
147
148 va_end(vaArgs);
149
150 if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
151 {
152 PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
153
154 return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
155 }
156
157#if defined(PDUMP_DEBUG_OUTFILES)
158 g_ui32EveryLineCounter++;
159#endif
160 return PVRSRV_OK;
161}
162
163PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
164{
165 IMG_INT32 n;
166
167 n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
168
169 if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
170 {
171 PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
172
173 return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
174 }
175
176 return PVRSRV_OK;
177}
178
179IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
180{
181 PVR_UNREFERENCED_PARAMETER(pszFormat);
182
183
184}
185
186PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...)
187{
188 IMG_INT32 n;
189 va_list vaArgs;
190
191 va_start(vaArgs, pszFormat);
192
193 n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
194
195 va_end(vaArgs);
196
197 if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1)
198 {
199 PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
200
201 return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
202 }
203
204 return PVRSRV_OK;
205}
206
207IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
208{
209 IMG_CHAR* pszBuf = hBuffer;
210 IMG_UINT32 ui32Count = 0;
211
212 while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) )
213 {
214 ui32Count++;
215 }
216 return(ui32Count);
217}
218
219IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
220{
221 IMG_UINT32 ui32Count;
222 IMG_CHAR* pszBuf = hBuffer;
223
224
225 ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
226
227
228 if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
229 {
230 pszBuf[ui32Count] = '\n';
231 ui32Count++;
232 pszBuf[ui32Count] = '\0';
233 }
234 if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax))
235 {
236 pszBuf[ui32Count-1] = '\r';
237 pszBuf[ui32Count] = '\n';
238 ui32Count++;
239 pszBuf[ui32Count] = '\0';
240 }
241}
242
243IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream)
244{
245 return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream];
246}
247
248IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream)
249{
250 PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream];
251 return gpfnDbgDrv->pfnGetStreamOffset(psStream);
252}
253
254IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID)
255{
256 return gsDBGPdumpState.ui32ParamFileNum;
257}
258
259IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream,
260 IMG_UINT8 *psui8Data,
261 IMG_UINT32 ui32Size,
262 IMG_UINT32 ui32Flags)
263{
264 PDBG_STREAM psStream = (PDBG_STREAM)hStream;
265 return PDumpWriteILock(psStream,
266 psui8Data,
267 ui32Size,
268 ui32Flags);
269}
270
271IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
272{
273
274 PVR_UNREFERENCED_PARAMETER(hStream);
275 PVR_UNREFERENCED_PARAMETER(ui32Size);
276 PVR_UNREFERENCED_PARAMETER(ui32Flags);
277}
278
279IMG_BOOL PDumpOSJTInitialised(IMG_VOID)
280{
281 if(gpfnDbgDrv)
282 {
283 return IMG_TRUE;
284 }
285 return IMG_FALSE;
286}
287
288inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID)
289{
290 return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
291}
292
293IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
294 IMG_HANDLE hOSMemHandle,
295 IMG_UINT32 ui32Offset,
296 IMG_UINT8 *pui8LinAddr,
297 IMG_UINT32 ui32PageSize,
298 IMG_DEV_PHYADDR *psDevPAddr)
299{
300 IMG_CPU_PHYADDR sCpuPAddr;
301
302 PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
303 PVR_UNREFERENCED_PARAMETER(ui32PageSize);
304
305
306
307 PVR_ASSERT (hOSMemHandle != IMG_NULL);
308
309 sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
310 PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
311
312
313 *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
314}
315
316IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
317 IMG_UINT32 ui32Offset,
318 IMG_PUINT8 pui8LinAddr,
319 IMG_UINT32 ui32DataPageMask,
320 IMG_UINT32 *pui32PageOffset)
321{
322 if(hOSMemHandle)
323 {
324
325 IMG_CPU_PHYADDR sCpuPAddr;
326
327 PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
328
329 sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
330 *pui32PageOffset = sCpuPAddr.uiAddr & ui32DataPageMask;
331 }
332 else
333 {
334 PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
335 PVR_UNREFERENCED_PARAMETER(ui32Offset);
336
337 *pui32PageOffset = ((IMG_UINT32)pui8LinAddr & ui32DataPageMask);
338 }
339}
340
341IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
342 PDUMP_DDWMODE eDbgDrvWriteMode,
343 IMG_UINT8 *pui8Data,
344 IMG_UINT32 ui32BCount,
345 IMG_UINT32 ui32Level,
346 IMG_UINT32 ui32DbgDrvFlags)
347{
348 switch(eDbgDrvWriteMode)
349 {
350 case PDUMP_WRITE_MODE_CONTINUOUS:
351 PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
352 return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, ui32Level);
353 case PDUMP_WRITE_MODE_LASTFRAME:
354 return gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, ui32Level, ui32DbgDrvFlags);
355 case PDUMP_WRITE_MODE_BINCM:
356 PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
357 return gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, ui32Level);
358 case PDUMP_WRITE_MODE_PERSISTENT:
359 PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
360 return gpfnDbgDrv->pfnWritePersist(psStream, pui8Data, ui32BCount, ui32Level);
361 default:
362 PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
363 break;
364 }
365 return 0xFFFFFFFFU;
366}
367
368IMG_VOID PDumpOSReleaseExecution(IMG_VOID)
369{
370 OSReleaseThreadQuanta();
371}
372
373IMG_VOID PDumpInit(IMG_VOID)
374{
375 IMG_UINT32 i;
376 DBGKM_CONNECT_NOTIFIER sConnectNotifier;
377
378
379 if (!gpfnDbgDrv)
380 {
381 DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv);
382
383
384
385 if (gpfnDbgDrv == IMG_NULL)
386 {
387 return;
388 }
389
390
391 sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify;
392 gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
393
394 if(!gsDBGPdumpState.pszFile)
395 {
396 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0,
397 "Filename string") != PVRSRV_OK)
398 {
399 goto init_failed;
400 }
401 }
402
403 if(!gsDBGPdumpState.pszMsg)
404 {
405 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0,
406 "Message string") != PVRSRV_OK)
407 {
408 goto init_failed;
409 }
410 }
411
412 if(!gsDBGPdumpState.pszScript)
413 {
414 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0,
415 "Script string") != PVRSRV_OK)
416 {
417 goto init_failed;
418 }
419 }
420
421 for(i=0; i < PDUMP_NUM_STREAMS; i++)
422 {
423 gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i],
424 DEBUG_CAPMODE_FRAMED,
425 DEBUG_OUTMODE_STREAMENABLE,
426 0,
427 10);
428
429 gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1);
430 gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0);
431 }
432
433 PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME);
434 PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FILE);
435 PDUMPCOMMENT("Start of Init Phase");
436 }
437
438 return;
439
440init_failed:
441
442 if(gsDBGPdumpState.pszFile)
443 {
444 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
445 gsDBGPdumpState.pszFile = IMG_NULL;
446 }
447
448 if(gsDBGPdumpState.pszScript)
449 {
450 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
451 gsDBGPdumpState.pszScript = IMG_NULL;
452 }
453
454 if(gsDBGPdumpState.pszMsg)
455 {
456 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
457 gsDBGPdumpState.pszMsg = IMG_NULL;
458 }
459
460
461 sConnectNotifier.pfnConnectNotifier = 0;
462 gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
463
464 gpfnDbgDrv = IMG_NULL;
465}
466
467
468IMG_VOID PDumpDeInit(IMG_VOID)
469{
470 IMG_UINT32 i;
471 DBGKM_CONNECT_NOTIFIER sConnectNotifier;
472
473 for(i=0; i < PDUMP_NUM_STREAMS; i++)
474 {
475 gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]);
476 }
477
478 if(gsDBGPdumpState.pszFile)
479 {
480 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
481 gsDBGPdumpState.pszFile = IMG_NULL;
482 }
483
484 if(gsDBGPdumpState.pszScript)
485 {
486 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
487 gsDBGPdumpState.pszScript = IMG_NULL;
488 }
489
490 if(gsDBGPdumpState.pszMsg)
491 {
492 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
493 gsDBGPdumpState.pszMsg = IMG_NULL;
494 }
495
496
497 sConnectNotifier.pfnConnectNotifier = 0;
498 gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
499
500 gpfnDbgDrv = IMG_NULL;
501}
502
503PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID)
504{
505 IMG_UINT32 i;
506
507 if (gpfnDbgDrv)
508 {
509 PDUMPCOMMENT("Start Init Phase");
510 for(i=0; i < PDUMP_NUM_STREAMS; i++)
511 {
512 gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]);
513 }
514 }
515 return PVRSRV_OK;
516}
517
518PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID)
519{
520 IMG_UINT32 i;
521
522 if (gpfnDbgDrv)
523 {
524 PDUMPCOMMENT("Stop Init Phase");
525
526 for(i=0; i < PDUMP_NUM_STREAMS; i++)
527 {
528 gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]);
529 }
530 }
531 return PVRSRV_OK;
532}
533
534IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
535{
536 return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
537}
538
539
540IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
541{
542 if (PDumpSuspended())
543 {
544 return IMG_FALSE;
545 }
546 return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE);
547}
548
549PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
550{
551 IMG_UINT32 ui32Stream;
552
553 for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
554 {
555 if (gsDBGPdumpState.psStream[ui32Stream])
556 {
557 DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame);
558 }
559 }
560
561 return PVRSRV_OK;
562}
563
564
565static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
566{
567 return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
568}
569
570
571static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
572{
573 IMG_UINT32 ui32Written = 0;
574 if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0))
575 {
576 return IMG_TRUE;
577 }
578
579
580
581
582 if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2])
583 {
584 IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]);
585
586 if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE)
587 {
588 if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags)))
589 {
590 DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos);
591 gsDBGPdumpState.ui32ParamFileNum++;
592 }
593 }
594 }
595
596 ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags);
597
598 if (ui32Written == 0xFFFFFFFF)
599 {
600 return IMG_FALSE;
601 }
602
603 return IMG_TRUE;
604}
605
606static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame)
607{
608 gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
609}
610
611static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
612{
613 gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
614}
615
616IMG_VOID PDumpSuspendKM(IMG_VOID)
617{
618 atomic_inc(&gsPDumpSuspended);
619}
620
621IMG_VOID PDumpResumeKM(IMG_VOID)
622{
623 atomic_dec(&gsPDumpSuspended);
624}
625
626#endif
627#endif
diff --git a/drivers/gpu/pvr/pdump.h b/drivers/gpu/pvr/pdump.h
new file mode 100644
index 00000000000..00d884b4ae6
--- /dev/null
+++ b/drivers/gpu/pvr/pdump.h
@@ -0,0 +1,37 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SERVICES_PDUMP_H_
28#define _SERVICES_PDUMP_H_
29
30#define PDUMP_FLAGS_NEVER 0x08000000UL
31#define PDUMP_FLAGS_LASTFRAME 0x10000000UL
32#define PDUMP_FLAGS_RESETLFBUFFER 0x20000000UL
33#define PDUMP_FLAGS_CONTINUOUS 0x40000000UL
34#define PDUMP_FLAGS_PERSISTENT 0x80000000UL
35
36#endif
37
diff --git a/drivers/gpu/pvr/pdump_common.c b/drivers/gpu/pvr/pdump_common.c
new file mode 100644
index 00000000000..430efe4eba0
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_common.c
@@ -0,0 +1,2248 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(PDUMP)
28#include <stdarg.h>
29
30#include "services_headers.h"
31#if defined(SUPPORT_SGX)
32#include "sgxdefs.h"
33#endif
34#include "perproc.h"
35
36#include "pdump_km.h"
37#include "pdump_int.h"
38
39#if !defined(PDUMP_TEMP_BUFFER_SIZE)
40#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
41#endif
42
43#if 1
44#define PDUMP_DBG(a) PDumpOSDebugPrintf (a)
45#else
46#define PDUMP_DBG(a)
47#endif
48
49#define PDUMP_DATAMASTER_PIXEL (1)
50#define PDUMP_DATAMASTER_EDM (3)
51
52#define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x)))
53#define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x)
54#define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x))
55#define MAX_PDUMP_MMU_CONTEXTS (32)
56static IMG_VOID *gpvTempBuffer = IMG_NULL;
57static IMG_HANDLE ghTempBufferBlockAlloc;
58static IMG_UINT16 gui16MMUContextUsage = 0;
59
60#if defined(PDUMP_DEBUG_OUTFILES)
61IMG_UINT32 g_ui32EveryLineCounter = 1U;
62#endif
63
64#ifdef INLINE_IS_PRAGMA
65#pragma inline(_PDumpIsPersistent)
66#endif
67static INLINE
68IMG_BOOL _PDumpIsPersistent(IMG_VOID)
69{
70 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
71 if(psPerProc == IMG_NULL)
72 {
73
74 return IMG_FALSE;
75 }
76 return psPerProc->bPDumpPersistent;
77}
78
79#if defined(PDUMP_DEBUG_OUTFILES)
80static INLINE
81IMG_UINT32 _PDumpGetPID(IMG_VOID)
82{
83 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
84 if(psPerProc == IMG_NULL)
85 {
86
87 return 0;
88 }
89 return psPerProc->ui32PID;
90}
91#endif
92
93static IMG_VOID *GetTempBuffer(IMG_VOID)
94{
95
96 if (gpvTempBuffer == IMG_NULL)
97 {
98 PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
99 PDUMP_TEMP_BUFFER_SIZE,
100 &gpvTempBuffer,
101 &ghTempBufferBlockAlloc,
102 "PDUMP Temporary Buffer");
103 if (eError != PVRSRV_OK)
104 {
105 PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
106 }
107 }
108
109 return gpvTempBuffer;
110}
111
112static IMG_VOID FreeTempBuffer(IMG_VOID)
113{
114
115 if (gpvTempBuffer != IMG_NULL)
116 {
117 PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
118 PDUMP_TEMP_BUFFER_SIZE,
119 gpvTempBuffer,
120 ghTempBufferBlockAlloc);
121 if (eError != PVRSRV_OK)
122 {
123 PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
124 }
125 else
126 {
127 gpvTempBuffer = IMG_NULL;
128 }
129 }
130}
131
132IMG_VOID PDumpInitCommon(IMG_VOID)
133{
134
135 (IMG_VOID) GetTempBuffer();
136
137
138 PDumpInit();
139}
140
141IMG_VOID PDumpDeInitCommon(IMG_VOID)
142{
143
144 FreeTempBuffer();
145
146
147 PDumpDeInit();
148}
149
150IMG_BOOL PDumpIsSuspended(IMG_VOID)
151{
152 return PDumpOSIsSuspended();
153}
154
155
156
157PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
158 IMG_UINT32 ui32Reg,
159 IMG_UINT32 ui32Data,
160 IMG_UINT32 ui32Flags)
161{
162 PVRSRV_ERROR eErr;
163 PDUMP_GET_SCRIPT_STRING()
164 PDUMP_DBG(("PDumpRegWithFlagsKM"));
165
166 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
167 pszPDumpRegName, ui32Reg, ui32Data);
168 if(eErr != PVRSRV_OK)
169 {
170 return eErr;
171 }
172 PDumpOSWriteString2(hScript, ui32Flags);
173
174 return PVRSRV_OK;
175}
176
177PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
178 IMG_UINT32 ui32Reg,
179 IMG_UINT32 ui32Data)
180{
181 return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
182}
183
184PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
185 IMG_UINT32 ui32RegAddr,
186 IMG_UINT32 ui32RegValue,
187 IMG_UINT32 ui32Mask,
188 IMG_UINT32 ui32Flags)
189{
190
191 #define POLL_DELAY 1000U
192 #define POLL_COUNT_LONG (2000000000U / POLL_DELAY)
193 #define POLL_COUNT_SHORT (1000000U / POLL_DELAY)
194
195 PVRSRV_ERROR eErr;
196 IMG_UINT32 ui32PollCount;
197
198 PDUMP_GET_SCRIPT_STRING();
199 PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
200 if ( _PDumpIsPersistent() )
201 {
202
203 return PVRSRV_OK;
204 }
205
206#if 0
207 if (((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
208 (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK) != 0) ||
209 ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
210 (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK) != 0) ||
211 ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
212 (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK) != 0))
213 {
214 ui32PollCount = POLL_COUNT_LONG;
215 }
216 else
217#endif
218 {
219 ui32PollCount = POLL_COUNT_LONG;
220 }
221
222 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
223 pszPDumpRegName, ui32RegAddr, ui32RegValue,
224 ui32Mask, 0, ui32PollCount, POLL_DELAY);
225 if(eErr != PVRSRV_OK)
226 {
227 return eErr;
228 }
229 PDumpOSWriteString2(hScript, ui32Flags);
230
231 return PVRSRV_OK;
232}
233
234
235PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask)
236{
237 return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS);
238}
239
240PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID,
241 IMG_UINT32 ui32DevVAddr,
242 IMG_CPU_VIRTADDR pvLinAddr,
243 IMG_HANDLE hOSMemHandle,
244 IMG_UINT32 ui32NumBytes,
245 IMG_UINT32 ui32PageSize,
246 IMG_HANDLE hUniqueTag)
247{
248 PVRSRV_ERROR eErr;
249 IMG_PUINT8 pui8LinAddr;
250 IMG_UINT32 ui32Offset;
251 IMG_UINT32 ui32NumPages;
252 IMG_DEV_PHYADDR sDevPAddr;
253 IMG_UINT32 ui32Page;
254 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
255
256 PDUMP_GET_SCRIPT_STRING();
257 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
258
259
260#if !defined(LINUX)
261 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0);
262#endif
263
264 PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0);
265 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0);
266
267
268
269 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n",
270 psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize);
271 if(eErr != PVRSRV_OK)
272 {
273 return eErr;
274 }
275 PDumpOSWriteString2(hScript, ui32Flags);
276
277
278
279 pui8LinAddr = (IMG_PUINT8) pvLinAddr;
280 ui32Offset = 0;
281 ui32NumPages = ui32NumBytes / ui32PageSize;
282 while (ui32NumPages)
283 {
284 ui32NumPages--;
285
286
287
288
289
290
291
292
293
294
295
296 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
297 hOSMemHandle,
298 ui32Offset,
299 pui8LinAddr,
300 ui32PageSize,
301 &sDevPAddr);
302 ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize);
303
304 pui8LinAddr += ui32PageSize;
305 ui32Offset += ui32PageSize;
306
307 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n",
308 psDevID->pszPDumpDevName,
309 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
310 ui32Page * ui32PageSize,
311 ui32PageSize,
312 ui32PageSize,
313 ui32Page * ui32PageSize);
314 if(eErr != PVRSRV_OK)
315 {
316 return eErr;
317 }
318 PDumpOSWriteString2(hScript, ui32Flags);
319 }
320 return PVRSRV_OK;
321}
322
323PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId,
324 IMG_HANDLE hOSMemHandle,
325 IMG_UINT32 ui32Offset,
326 IMG_CPU_VIRTADDR pvLinAddr,
327 IMG_UINT32 ui32PTSize,
328 IMG_HANDLE hUniqueTag)
329{
330 PVRSRV_ERROR eErr;
331 IMG_DEV_PHYADDR sDevPAddr;
332 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
333
334 PDUMP_GET_SCRIPT_STRING();
335
336 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
337 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
338
339
340
341 eErr = PDumpOSBufprintf(hScript,
342 ui32MaxLen,
343 "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
344 psDevId->pszPDumpDevName,
345 ui32PTSize,
346 ui32PTSize);
347 if(eErr != PVRSRV_OK)
348 {
349 return eErr;
350 }
351 PDumpOSWriteString2(hScript, ui32Flags);
352
353
354
355
356
357
358
359
360 PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
361 hOSMemHandle,
362 ui32Offset,
363 (IMG_PUINT8) pvLinAddr,
364 ui32PTSize,
365 &sDevPAddr);
366
367 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n",
368 psDevId->pszPDumpDevName,
369 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
370 sDevPAddr.uiAddr,
371 ui32PTSize,
372 ui32PTSize,
373 sDevPAddr.uiAddr);
374 if(eErr != PVRSRV_OK)
375 {
376 return eErr;
377 }
378 PDumpOSWriteString2(hScript, ui32Flags);
379
380 return PVRSRV_OK;
381}
382
383PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap,
384 IMG_DEV_VIRTADDR sDevVAddr,
385 IMG_UINT32 ui32NumBytes,
386 IMG_UINT32 ui32PageSize,
387 IMG_HANDLE hUniqueTag,
388 IMG_BOOL bInterleaved)
389{
390 PVRSRV_ERROR eErr;
391 IMG_UINT32 ui32NumPages, ui32PageCounter;
392 IMG_DEV_PHYADDR sDevPAddr;
393 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
394 PVRSRV_DEVICE_NODE *psDeviceNode;
395
396 PDUMP_GET_SCRIPT_STRING();
397
398 PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
399 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
400
401 psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
402 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
403
404
405
406 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n",
407 psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
408 if(eErr != PVRSRV_OK)
409 {
410 return eErr;
411 }
412 PDumpOSWriteString2(hScript, ui32Flags);
413
414
415
416 ui32NumPages = ui32NumBytes / ui32PageSize;
417 for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
418 {
419 if (!bInterleaved || (ui32PageCounter % 2) == 0)
420 {
421 sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
422 {
423 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
424 psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr);
425 if(eErr != PVRSRV_OK)
426 {
427 return eErr;
428 }
429 PDumpOSWriteString2(hScript, ui32Flags);
430 }
431 }
432 else
433 {
434
435 }
436
437 sDevVAddr.uiAddr += ui32PageSize;
438 }
439 return PVRSRV_OK;
440}
441
442PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID,
443 IMG_HANDLE hOSMemHandle,
444 IMG_CPU_VIRTADDR pvLinAddr,
445 IMG_UINT32 ui32PTSize,
446 IMG_HANDLE hUniqueTag)
447{
448 PVRSRV_ERROR eErr;
449 IMG_DEV_PHYADDR sDevPAddr;
450 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
451
452 PDUMP_GET_SCRIPT_STRING();
453
454 PVR_UNREFERENCED_PARAMETER(ui32PTSize);
455 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
456
457
458 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0);
459
460
461
462 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
463 if(eErr != PVRSRV_OK)
464 {
465 return eErr;
466 }
467 PDumpOSWriteString2(hScript, ui32Flags);
468
469
470
471
472
473
474
475
476 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
477 hOSMemHandle,
478 0,
479 (IMG_PUINT8) pvLinAddr,
480 ui32PTSize,
481 &sDevPAddr);
482
483 {
484 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
485 psDevID->pszPDumpDevName,
486 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
487 sDevPAddr.uiAddr);
488 if(eErr != PVRSRV_OK)
489 {
490 return eErr;
491 }
492 PDumpOSWriteString2(hScript, ui32Flags);
493 }
494
495 return PVRSRV_OK;
496}
497
498PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
499 IMG_UINT32 ui32Reg,
500 IMG_UINT32 ui32Data,
501 IMG_UINT32 ui32Flags,
502 IMG_HANDLE hUniqueTag)
503{
504 PVRSRV_ERROR eErr;
505 IMG_CHAR *pszRegString;
506 PDUMP_GET_SCRIPT_STRING()
507
508 if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
509 {
510 pszRegString = psMMUAttrib->pszPDRegRegion;
511 }
512 else
513 {
514 pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
515 }
516
517
518
519#if defined(SGX_FEATURE_36BIT_MMU)
520 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
521 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
522 psMMUAttrib->sDevId.pszPDumpDevName,
523 psMMUAttrib->sDevId.pszPDumpDevName,
524 (IMG_UINT32)hUniqueTag,
525 (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
526 if(eErr != PVRSRV_OK)
527 {
528 return eErr;
529 }
530 PDumpOSWriteString2(hScript, ui32Flags);
531 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n",
532 psMMUAttrib->sDevId.pszPDumpDevName,
533 psMMUAttrib->sDevId.pszPDumpDevName);
534 if(eErr != PVRSRV_OK)
535 {
536 return eErr;
537 }
538 PDumpOSWriteString2(hScript, ui32Flags);
539 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
540 "WRW :%s:0x%08X: %s:$1\r\n",
541 pszRegString,
542 ui32Reg,
543 psMMUAttrib->sDevId.pszPDumpDevName);
544 if(eErr != PVRSRV_OK)
545 {
546 return eErr;
547 }
548 PDumpOSWriteString2(hScript, ui32Flags);
549#else
550 eErr = PDumpOSBufprintf(hScript,
551 ui32MaxLen,
552 "WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
553 pszRegString,
554 ui32Reg,
555 psMMUAttrib->sDevId.pszPDumpDevName,
556 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
557 (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift,
558 ui32Data & ~psMMUAttrib->ui32PDEMask);
559 if(eErr != PVRSRV_OK)
560 {
561 return eErr;
562 }
563 PDumpOSWriteString2(hScript, ui32Flags);
564#endif
565 return PVRSRV_OK;
566}
567
568PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib,
569 IMG_UINT32 ui32Reg,
570 IMG_UINT32 ui32Data,
571 IMG_HANDLE hUniqueTag)
572{
573 return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
574}
575
576PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
577 IMG_UINT32 ui32Offset,
578 IMG_UINT32 ui32Value,
579 IMG_UINT32 ui32Mask,
580 PDUMP_POLL_OPERATOR eOperator,
581 IMG_UINT32 ui32Flags,
582 IMG_HANDLE hUniqueTag)
583{
584 #define MEMPOLL_DELAY (1000)
585 #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY)
586
587 PVRSRV_ERROR eErr;
588 IMG_UINT32 ui32PageOffset;
589 IMG_UINT8 *pui8LinAddr;
590 IMG_DEV_PHYADDR sDevPAddr;
591 IMG_DEV_VIRTADDR sDevVPageAddr;
592 PDUMP_MMU_ATTRIB *psMMUAttrib;
593
594 PDUMP_GET_SCRIPT_STRING();
595 if ( _PDumpIsPersistent() )
596 {
597
598 return PVRSRV_OK;
599 }
600
601
602 PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->ui32AllocSize);
603
604 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
605
606
607
608 eErr = PDumpOSBufprintf(hScript,
609 ui32MaxLen,
610 "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
611 psMMUAttrib->sDevId.pszPDumpDevName,
612 psMemInfo->sDevVAddr.uiAddr + ui32Offset,
613 ui32Value,
614 ui32Mask,
615 eOperator,
616 MEMPOLL_COUNT,
617 MEMPOLL_DELAY);
618 if(eErr != PVRSRV_OK)
619 {
620 return eErr;
621 }
622 PDumpOSWriteString2(hScript, ui32Flags);
623
624
625 pui8LinAddr = psMemInfo->pvLinAddrKM;
626
627
628 pui8LinAddr += ui32Offset;
629
630
631
632
633 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
634 ui32Offset,
635 pui8LinAddr,
636 psMMUAttrib->ui32DataPageMask,
637 &ui32PageOffset);
638
639
640 sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
641
642 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
643
644
645 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
646
647
648 sDevPAddr.uiAddr += ui32PageOffset;
649
650 eErr = PDumpOSBufprintf(hScript,
651 ui32MaxLen,
652 "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n",
653 psMMUAttrib->sDevId.pszPDumpDevName,
654 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
655 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
656 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
657 ui32Value,
658 ui32Mask,
659 eOperator,
660 MEMPOLL_COUNT,
661 MEMPOLL_DELAY);
662 if(eErr != PVRSRV_OK)
663 {
664 return eErr;
665 }
666 PDumpOSWriteString2(hScript, ui32Flags);
667
668 return PVRSRV_OK;
669}
670
671PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
672 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
673 IMG_UINT32 ui32Offset,
674 IMG_UINT32 ui32Bytes,
675 IMG_UINT32 ui32Flags,
676 IMG_HANDLE hUniqueTag)
677{
678 PVRSRV_ERROR eErr;
679 IMG_UINT32 ui32NumPages;
680 IMG_UINT32 ui32PageByteOffset;
681 IMG_UINT32 ui32BlockBytes;
682 IMG_UINT8* pui8LinAddr;
683 IMG_UINT8* pui8DataLinAddr = IMG_NULL;
684 IMG_DEV_VIRTADDR sDevVPageAddr;
685 IMG_DEV_VIRTADDR sDevVAddr;
686 IMG_DEV_PHYADDR sDevPAddr;
687 IMG_UINT32 ui32ParamOutPos;
688 PDUMP_MMU_ATTRIB *psMMUAttrib;
689 IMG_UINT32 ui32DataPageSize;
690
691 PDUMP_GET_SCRIPT_AND_FILE_STRING();
692
693 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
694
695
696
697 PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize);
698
699 if (!PDumpOSJTInitialised())
700 {
701 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
702 }
703
704
705 if (ui32Bytes == 0 || PDumpOSIsSuspended())
706 {
707 return PVRSRV_OK;
708 }
709
710
711 if(pvAltLinAddr)
712 {
713 pui8DataLinAddr = pvAltLinAddr;
714 }
715 else if(psMemInfo->pvLinAddrKM)
716 {
717 pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
718 }
719 pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
720 sDevVAddr = psMemInfo->sDevVAddr;
721
722
723 sDevVAddr.uiAddr += ui32Offset;
724 pui8LinAddr += ui32Offset;
725
726 PVR_ASSERT(pui8DataLinAddr);
727
728 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
729
730 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
731
732
733
734 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
735 pui8DataLinAddr,
736 ui32Bytes,
737 ui32Flags))
738 {
739 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
740 }
741
742 if (PDumpOSGetParamFileNum() == 0)
743 {
744 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
745 }
746 else
747 {
748 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
749 }
750 if(eErr != PVRSRV_OK)
751 {
752 return eErr;
753 }
754
755
756
757 eErr = PDumpOSBufprintf(hScript,
758 ui32MaxLenScript,
759 "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
760 psMMUAttrib->sDevId.pszPDumpDevName,
761 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
762 psMemInfo->sDevVAddr.uiAddr,
763 ui32Offset,
764 ui32Bytes,
765 ui32ParamOutPos,
766 pszFileName);
767 if(eErr != PVRSRV_OK)
768 {
769 return eErr;
770 }
771 PDumpOSWriteString2(hScript, ui32Flags);
772
773
774
775
776 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
777 ui32Offset,
778 pui8LinAddr,
779 psMMUAttrib->ui32DataPageMask,
780 &ui32PageByteOffset);
781 ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
782 ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
783
784 while(ui32NumPages)
785 {
786 ui32NumPages--;
787
788
789 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
790
791 if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
792 {
793
794 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
795 }
796
797
798 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
799
800
801 sDevPAddr.uiAddr += ui32PageByteOffset;
802
803
804 if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
805 {
806
807 ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
808 }
809 else
810 {
811
812 ui32BlockBytes = ui32Bytes;
813 }
814
815 eErr = PDumpOSBufprintf(hScript,
816 ui32MaxLenScript,
817 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
818 psMMUAttrib->sDevId.pszPDumpDevName,
819 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
820 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
821 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
822 ui32BlockBytes,
823 ui32ParamOutPos,
824 pszFileName);
825 if(eErr != PVRSRV_OK)
826 {
827 return eErr;
828 }
829 PDumpOSWriteString2(hScript, ui32Flags);
830
831
832
833#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
834
835 ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
836#else
837
838 ui32PageByteOffset = 0;
839#endif
840
841 ui32Bytes -= ui32BlockBytes;
842
843 sDevVAddr.uiAddr += ui32BlockBytes;
844
845 pui8LinAddr += ui32BlockBytes;
846
847 ui32ParamOutPos += ui32BlockBytes;
848 }
849
850 return PVRSRV_OK;
851}
852
853PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
854 IMG_HANDLE hOSMemHandle,
855 IMG_CPU_VIRTADDR pvLinAddr,
856 IMG_UINT32 ui32Bytes,
857 IMG_UINT32 ui32Flags,
858 IMG_BOOL bInitialisePages,
859 IMG_HANDLE hUniqueTag1,
860 IMG_HANDLE hUniqueTag2)
861{
862 PDUMP_MMU_ATTRIB sMMUAttrib;
863
864
865 sMMUAttrib = *psMMUAttrib;
866 sMMUAttrib.ui32PTSize = HOST_PAGESIZE();
867 return PDumpMemPTEntriesKM( &sMMUAttrib,
868 hOSMemHandle,
869 pvLinAddr,
870 ui32Bytes,
871 ui32Flags,
872 bInitialisePages,
873 hUniqueTag1,
874 hUniqueTag2);
875}
876
877PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
878 IMG_HANDLE hOSMemHandle,
879 IMG_CPU_VIRTADDR pvLinAddr,
880 IMG_UINT32 ui32Bytes,
881 IMG_UINT32 ui32Flags,
882 IMG_BOOL bInitialisePages,
883 IMG_HANDLE hUniqueTag1,
884 IMG_HANDLE hUniqueTag2)
885{
886 PVRSRV_ERROR eErr;
887 IMG_UINT32 ui32NumPages;
888 IMG_UINT32 ui32PageOffset;
889 IMG_UINT32 ui32BlockBytes;
890 IMG_UINT8* pui8LinAddr;
891 IMG_DEV_PHYADDR sDevPAddr;
892 IMG_CPU_PHYADDR sCpuPAddr;
893 IMG_UINT32 ui32Offset;
894 IMG_UINT32 ui32ParamOutPos;
895 IMG_UINT32 ui32PageMask;
896
897 PDUMP_GET_SCRIPT_AND_FILE_STRING();
898 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
899
900 if (!PDumpOSJTInitialised())
901 {
902 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
903 }
904
905 if (!pvLinAddr)
906 {
907 return PVRSRV_ERROR_INVALID_PARAMS;
908 }
909
910 if (PDumpOSIsSuspended())
911 {
912 return PVRSRV_OK;
913 }
914
915 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
916
917 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
918
919 if (bInitialisePages)
920 {
921
922
923
924 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
925 pvLinAddr,
926 ui32Bytes,
927 ui32Flags | PDUMP_FLAGS_CONTINUOUS))
928 {
929 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
930 }
931
932 if (PDumpOSGetParamFileNum() == 0)
933 {
934 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
935 }
936 else
937 {
938 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
939 }
940 if(eErr != PVRSRV_OK)
941 {
942 return eErr;
943 }
944 }
945
946
947
948
949
950
951 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
952
953
954
955
956 ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
957 ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
958 pui8LinAddr = (IMG_UINT8*) pvLinAddr;
959
960 while (ui32NumPages)
961 {
962 ui32NumPages--;
963
964
965
966
967
968
969 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
970 sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
971
972
973 if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
974 {
975
976 ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
977 }
978 else
979 {
980
981 ui32BlockBytes = ui32Bytes;
982 }
983
984
985
986
987 if (bInitialisePages)
988 {
989 eErr = PDumpOSBufprintf(hScript,
990 ui32MaxLenScript,
991 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
992 psMMUAttrib->sDevId.pszPDumpDevName,
993 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
994 sDevPAddr.uiAddr & ~ui32PageMask,
995 sDevPAddr.uiAddr & ui32PageMask,
996 ui32BlockBytes,
997 ui32ParamOutPos,
998 pszFileName);
999 if(eErr != PVRSRV_OK)
1000 {
1001 return eErr;
1002 }
1003 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1004 }
1005 else
1006 {
1007 for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
1008 {
1009 IMG_UINT32 ui32PTE = *((IMG_UINT32 *) (pui8LinAddr + ui32Offset));
1010
1011 if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
1012 {
1013
1014#if defined(SGX_FEATURE_36BIT_MMU)
1015 eErr = PDumpOSBufprintf(hScript,
1016 ui32MaxLenScript,
1017 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
1018 psMMUAttrib->sDevId.pszPDumpDevName,
1019 psMMUAttrib->sDevId.pszPDumpDevName,
1020 (IMG_UINT32)hUniqueTag2,
1021 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
1022 if(eErr != PVRSRV_OK)
1023 {
1024 return eErr;
1025 }
1026 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1027 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
1028 psMMUAttrib->sDevId.pszPDumpDevName,
1029 psMMUAttrib->sDevId.pszPDumpDevName);
1030 if(eErr != PVRSRV_OK)
1031 {
1032 return eErr;
1033 }
1034 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1035 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
1036 psMMUAttrib->sDevId.pszPDumpDevName,
1037 psMMUAttrib->sDevId.pszPDumpDevName,
1038 ui32PTE & ~psMMUAttrib->ui32PDEMask);
1039 if(eErr != PVRSRV_OK)
1040 {
1041 return eErr;
1042 }
1043 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1044 eErr = PDumpOSBufprintf(hScript,
1045 ui32MaxLenScript,
1046 "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n",
1047 psMMUAttrib->sDevId.pszPDumpDevName,
1048 (IMG_UINT32)hUniqueTag1,
1049 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1050 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1051 psMMUAttrib->sDevId.pszPDumpDevName);
1052 if(eErr != PVRSRV_OK)
1053 {
1054 return eErr;
1055 }
1056 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1057#else
1058 eErr = PDumpOSBufprintf(hScript,
1059 ui32MaxLenScript,
1060 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
1061 psMMUAttrib->sDevId.pszPDumpDevName,
1062 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1063 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1064 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1065 psMMUAttrib->sDevId.pszPDumpDevName,
1066 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
1067 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift,
1068 ui32PTE & ~psMMUAttrib->ui32PDEMask);
1069 if(eErr != PVRSRV_OK)
1070 {
1071 return eErr;
1072 }
1073 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1074#endif
1075 }
1076 else
1077 {
1078 PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
1079 eErr = PDumpOSBufprintf(hScript,
1080 ui32MaxLenScript,
1081 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n",
1082 psMMUAttrib->sDevId.pszPDumpDevName,
1083 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1084 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1085 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1086 (ui32PTE << psMMUAttrib->ui32PTEAlignShift),
1087 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2);
1088 if(eErr != PVRSRV_OK)
1089 {
1090 return eErr;
1091 }
1092 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1093 }
1094 }
1095 }
1096
1097
1098
1099
1100 ui32PageOffset = 0;
1101
1102 ui32Bytes -= ui32BlockBytes;
1103
1104 pui8LinAddr += ui32BlockBytes;
1105
1106 ui32ParamOutPos += ui32BlockBytes;
1107 }
1108
1109 return PVRSRV_OK;
1110}
1111
1112PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1113 IMG_UINT32 ui32Offset,
1114 IMG_DEV_PHYADDR sPDDevPAddr,
1115 IMG_HANDLE hUniqueTag1,
1116 IMG_HANDLE hUniqueTag2)
1117{
1118 PVRSRV_ERROR eErr;
1119 IMG_UINT32 ui32PageByteOffset;
1120 IMG_DEV_VIRTADDR sDevVAddr;
1121 IMG_DEV_VIRTADDR sDevVPageAddr;
1122 IMG_DEV_PHYADDR sDevPAddr;
1123 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
1124 IMG_UINT32 ui32ParamOutPos;
1125 PDUMP_MMU_ATTRIB *psMMUAttrib;
1126 IMG_UINT32 ui32PageMask;
1127
1128 PDUMP_GET_SCRIPT_AND_FILE_STRING();
1129
1130 if (!PDumpOSJTInitialised())
1131 {
1132 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
1133 }
1134
1135 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
1136 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
1137
1138 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
1139
1140
1141 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
1142 (IMG_UINT8 *)&sPDDevPAddr,
1143 sizeof(IMG_DEV_PHYADDR),
1144 ui32Flags))
1145 {
1146 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1147 }
1148
1149 if (PDumpOSGetParamFileNum() == 0)
1150 {
1151 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1152 }
1153 else
1154 {
1155 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1156 }
1157 if(eErr != PVRSRV_OK)
1158 {
1159 return eErr;
1160 }
1161
1162
1163 eErr = PDumpOSBufprintf(hScript,
1164 ui32MaxLenScript,
1165 "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1166 psMMUAttrib->sDevId.pszPDumpDevName,
1167 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1168 sPDDevPAddr.uiAddr & ~ui32PageMask,
1169 sPDDevPAddr.uiAddr & ui32PageMask,
1170 sizeof(IMG_DEV_PHYADDR),
1171 ui32ParamOutPos,
1172 pszFileName);
1173 if(eErr != PVRSRV_OK)
1174 {
1175 return eErr;
1176 }
1177 PDumpOSWriteString2(hScript, ui32Flags);
1178
1179
1180 sDevVAddr = psMemInfo->sDevVAddr;
1181 ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
1182
1183 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
1184 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1185
1186 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
1187 sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
1188
1189 if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL)
1190 {
1191#if defined(SGX_FEATURE_36BIT_MMU)
1192 eErr = PDumpOSBufprintf(hScript,
1193 ui32MaxLenScript,
1194 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
1195 psMMUAttrib->sDevId.pszPDumpDevName,
1196 psMMUAttrib->sDevId.pszPDumpDevName,
1197 (IMG_UINT32)hUniqueTag2,
1198 sPDDevPAddr.uiAddr);
1199 if(eErr != PVRSRV_OK)
1200 {
1201 return eErr;
1202 }
1203 PDumpOSWriteString2(hScript, ui32Flags);
1204
1205 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND :%s:$2 :%s:$1 0xFFFFFFFF\r\n",
1206 psMMUAttrib->sDevId.pszPDumpDevName,
1207 psMMUAttrib->sDevId.pszPDumpDevName);
1208 if(eErr != PVRSRV_OK)
1209 {
1210 return eErr;
1211 }
1212 PDumpOSWriteString2(hScript, ui32Flags);
1213
1214 eErr = PDumpOSBufprintf(hScript,
1215 ui32MaxLenScript,
1216 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
1217 psMMUAttrib->sDevId.pszPDumpDevName,
1218 (IMG_UINT32)hUniqueTag1,
1219 (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask),
1220 (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask),
1221 psMMUAttrib->sDevId.pszPDumpDevName);
1222 if(eErr != PVRSRV_OK)
1223 {
1224 return eErr;
1225 }
1226 PDumpOSWriteString2(hScript, ui32Flags);
1227
1228 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n",
1229 psMMUAttrib->sDevId.pszPDumpDevName,
1230 psMMUAttrib->sDevId.pszPDumpDevName);
1231 if(eErr != PVRSRV_OK)
1232 {
1233 return eErr;
1234 }
1235 PDumpOSWriteString2(hScript, ui32Flags);
1236
1237 eErr = PDumpOSBufprintf(hScript,
1238 ui32MaxLenScript,
1239 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
1240 psMMUAttrib->sDevId.pszPDumpDevName,
1241 (IMG_UINT32)hUniqueTag1,
1242 (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask),
1243 (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask),
1244 psMMUAttrib->sDevId.pszPDumpDevName);
1245 if(eErr != PVRSRV_OK)
1246 {
1247 return eErr;
1248 }
1249 PDumpOSWriteString2(hScript, ui32Flags);
1250#else
1251 eErr = PDumpOSBufprintf(hScript,
1252 ui32MaxLenScript,
1253 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
1254 psMMUAttrib->sDevId.pszPDumpDevName,
1255 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1256 sDevPAddr.uiAddr & ~ui32PageMask,
1257 sDevPAddr.uiAddr & ui32PageMask,
1258 psMMUAttrib->sDevId.pszPDumpDevName,
1259 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
1260 sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
1261 sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask);
1262 if(eErr != PVRSRV_OK)
1263 {
1264 return eErr;
1265 }
1266#endif
1267 }
1268 else
1269 {
1270 PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid));
1271 eErr = PDumpOSBufprintf(hScript,
1272 ui32MaxLenScript,
1273 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n",
1274 psMMUAttrib->sDevId.pszPDumpDevName,
1275 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1276 sDevPAddr.uiAddr & ~ui32PageMask,
1277 sDevPAddr.uiAddr & ui32PageMask,
1278 sPDDevPAddr.uiAddr);
1279 if(eErr != PVRSRV_OK)
1280 {
1281 return eErr;
1282 }
1283 }
1284 PDumpOSWriteString2(hScript, ui32Flags);
1285
1286 return PVRSRV_OK;
1287}
1288
1289PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
1290{
1291 PVRSRV_ERROR eErr;
1292 IMG_CHAR pszCommentPrefix[] = "-- ";
1293#if defined(PDUMP_DEBUG_OUTFILES)
1294 IMG_CHAR pszTemp[256];
1295#endif
1296 IMG_UINT32 ui32LenCommentPrefix;
1297 PDUMP_GET_SCRIPT_STRING();
1298 PDUMP_DBG(("PDumpCommentKM"));
1299#if defined(PDUMP_DEBUG_OUTFILES)
1300
1301 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
1302#endif
1303
1304 PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
1305
1306
1307 ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
1308
1309
1310 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
1311 (IMG_UINT8*)pszCommentPrefix,
1312 ui32LenCommentPrefix,
1313 ui32Flags))
1314 {
1315 if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1316 {
1317 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1318 }
1319 else
1320 {
1321 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1322 }
1323 }
1324#if defined(PDUMP_DEBUG_OUTFILES)
1325
1326 eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
1327 _PDumpGetPID(),
1328 g_ui32EveryLineCounter,
1329 pszComment);
1330
1331
1332 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1333 pszTemp);
1334#else
1335 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1336 pszComment);
1337#endif
1338 if( (eErr != PVRSRV_OK) &&
1339 (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
1340 {
1341 return eErr;
1342 }
1343 PDumpOSWriteString2(hScript, ui32Flags);
1344 return PVRSRV_OK;
1345}
1346
1347PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
1348{
1349 PVRSRV_ERROR eErr;
1350 PDUMP_va_list ap;
1351 PDUMP_GET_MSG_STRING();
1352
1353
1354 PDUMP_va_start(ap, pszFormat);
1355 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1356 PDUMP_va_end(ap);
1357
1358 if(eErr != PVRSRV_OK)
1359 {
1360 return eErr;
1361 }
1362 return PDumpCommentKM(pszMsg, ui32Flags);
1363}
1364
1365PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
1366{
1367 PVRSRV_ERROR eErr;
1368 PDUMP_va_list ap;
1369 PDUMP_GET_MSG_STRING();
1370
1371
1372 PDUMP_va_start(ap, pszFormat);
1373 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1374 PDUMP_va_end(ap);
1375
1376 if(eErr != PVRSRV_OK)
1377 {
1378 return eErr;
1379 }
1380 return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
1381}
1382
1383PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
1384{
1385 PVRSRV_ERROR eErr;
1386 IMG_UINT32 ui32MsgLen;
1387 PDUMP_GET_MSG_STRING();
1388
1389
1390 eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
1391 if(eErr != PVRSRV_OK)
1392 {
1393 return eErr;
1394 }
1395
1396
1397 PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
1398 ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
1399
1400 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
1401 (IMG_UINT8*)pszMsg,
1402 ui32MsgLen,
1403 ui32Flags))
1404 {
1405 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1406 {
1407 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1408 }
1409 else
1410 {
1411 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1412 }
1413 }
1414 return PVRSRV_OK;
1415}
1416
1417PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode,
1418 IMG_CHAR *pszFileName,
1419 IMG_UINT32 ui32FileOffset,
1420 IMG_UINT32 ui32Width,
1421 IMG_UINT32 ui32Height,
1422 IMG_UINT32 ui32StrideInBytes,
1423 IMG_DEV_VIRTADDR sDevBaseAddr,
1424 IMG_HANDLE hDevMemContext,
1425 IMG_UINT32 ui32Size,
1426 PDUMP_PIXEL_FORMAT ePixelFormat,
1427 PDUMP_MEM_FORMAT eMemFormat,
1428 IMG_UINT32 ui32PDumpFlags)
1429{
1430 PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
1431
1432 PVRSRV_ERROR eErr;
1433 PDUMP_GET_SCRIPT_STRING();
1434
1435 if ( _PDumpIsPersistent() )
1436 {
1437 return PVRSRV_OK;
1438 }
1439
1440 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
1441
1442
1443
1444
1445 PVR_UNREFERENCED_PARAMETER(hDevMemContext);
1446
1447#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1448
1449 eErr = PDumpOSBufprintf(hScript,
1450 ui32MaxLen,
1451 "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
1452 pszFileName,
1453 pszFileName,
1454 psDevId->pszPDumpDevName,
1455 PDUMP_DATAMASTER_PIXEL,
1456 sDevBaseAddr.uiAddr,
1457 ui32Size,
1458 ui32FileOffset,
1459 ePixelFormat,
1460 ui32Width,
1461 ui32Height,
1462 ui32StrideInBytes,
1463 eMemFormat);
1464#else
1465 eErr = PDumpOSBufprintf(hScript,
1466 ui32MaxLen,
1467 "SII %s %s.bin :%s:v:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
1468 pszFileName,
1469 pszFileName,
1470 psDevId->pszPDumpDevName,
1471 sDevBaseAddr.uiAddr,
1472 ui32Size,
1473 ui32FileOffset,
1474 ePixelFormat,
1475 ui32Width,
1476 ui32Height,
1477 ui32StrideInBytes,
1478 eMemFormat);
1479#endif
1480 if(eErr != PVRSRV_OK)
1481 {
1482 return eErr;
1483 }
1484
1485 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1486 return PVRSRV_OK;
1487}
1488
1489PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName,
1490 IMG_CHAR *pszFileName,
1491 IMG_UINT32 ui32FileOffset,
1492 IMG_UINT32 ui32Address,
1493 IMG_UINT32 ui32Size,
1494 IMG_UINT32 ui32PDumpFlags)
1495{
1496 PVRSRV_ERROR eErr;
1497 PDUMP_GET_SCRIPT_STRING();
1498
1499 PVR_UNREFERENCED_PARAMETER(ui32Size);
1500
1501 eErr = PDumpOSBufprintf(hScript,
1502 ui32MaxLen,
1503 "SAB :%s:0x%08X 0x%08X %s\r\n",
1504 pszPDumpRegName,
1505 ui32Address,
1506 ui32FileOffset,
1507 pszFileName);
1508 if(eErr != PVRSRV_OK)
1509 {
1510 return eErr;
1511 }
1512
1513 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1514
1515 return PVRSRV_OK;
1516}
1517
1518IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
1519{
1520 IMG_BOOL bFrameDumped;
1521
1522
1523
1524 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
1525 bFrameDumped = PDumpIsCaptureFrameKM();
1526 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
1527
1528 return bFrameDumped;
1529}
1530
1531static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1532 IMG_CHAR *pszFileName,
1533 IMG_UINT32 ui32Address,
1534 IMG_UINT32 ui32Size,
1535 IMG_UINT32 *pui32FileOffset,
1536 IMG_UINT32 ui32Flags)
1537{
1538 PVRSRV_ERROR eErr;
1539 PDUMP_GET_SCRIPT_STRING();
1540
1541 eErr = PDumpOSBufprintf(hScript,
1542 ui32MaxLen,
1543 "SAB :%s:0x%08X 0x%08X %s\r\n",
1544 psDevId->pszPDumpRegName,
1545 ui32Address,
1546 *pui32FileOffset,
1547 pszFileName);
1548 if(eErr != PVRSRV_OK)
1549 {
1550 return eErr;
1551 }
1552
1553 PDumpOSWriteString2(hScript, ui32Flags);
1554 *pui32FileOffset += ui32Size;
1555 return PVRSRV_OK;
1556}
1557
1558static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
1559 IMG_CHAR *pszFileName,
1560 IMG_UINT32 *pui32Registers,
1561 IMG_UINT32 ui32NumRegisters,
1562 IMG_UINT32 *pui32FileOffset,
1563 IMG_UINT32 ui32Size,
1564 IMG_UINT32 ui32Flags)
1565{
1566 IMG_UINT32 i;
1567 for (i = 0; i < ui32NumRegisters; i++)
1568 {
1569 PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
1570 }
1571}
1572
1573PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
1574 IMG_UINT32 ui32DumpFrameNum,
1575 IMG_BOOL bLastFrame,
1576 IMG_UINT32 *pui32Registers,
1577 IMG_UINT32 ui32NumRegisters)
1578{
1579 PVRSRV_ERROR eErr;
1580 IMG_UINT32 ui32FileOffset, ui32Flags;
1581
1582 PDUMP_GET_FILE_STRING();
1583
1584 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
1585 ui32FileOffset = 0;
1586
1587 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
1588 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
1589 if(eErr != PVRSRV_OK)
1590 {
1591 return eErr;
1592 }
1593
1594 PDumpRegisterRange(psDevId,
1595 pszFileName,
1596 pui32Registers,
1597 ui32NumRegisters,
1598 &ui32FileOffset,
1599 sizeof(IMG_UINT32),
1600 ui32Flags);
1601
1602 return PVRSRV_OK;
1603}
1604
1605PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1606 IMG_UINT32 ui32DumpFrameNum,
1607 IMG_UINT32 ui32TAKickCount,
1608 IMG_BOOL bLastFrame,
1609 IMG_UINT32 *pui32Registers,
1610 IMG_UINT32 ui32NumRegisters)
1611{
1612 PVRSRV_ERROR eErr;
1613 IMG_UINT32 ui32FileOffset, ui32Flags;
1614
1615 PDUMP_GET_FILE_STRING();
1616
1617 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
1618 ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
1619
1620 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
1621 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
1622 if(eErr != PVRSRV_OK)
1623 {
1624 return eErr;
1625 }
1626
1627 PDumpRegisterRange(psDevId,
1628 pszFileName,
1629 pui32Registers,
1630 ui32NumRegisters,
1631 &ui32FileOffset,
1632 sizeof(IMG_UINT32),
1633 ui32Flags);
1634 return PVRSRV_OK;
1635}
1636
1637PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1638 IMG_UINT32 ui32DumpFrameNum,
1639 IMG_BOOL bLastFrame,
1640 IMG_UINT32 *pui32Registers,
1641 IMG_UINT32 ui32NumRegisters)
1642{
1643 PVRSRV_ERROR eErr;
1644 IMG_UINT32 ui32FileOffset, ui32Flags;
1645
1646 PDUMP_GET_FILE_STRING();
1647
1648 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
1649 ui32FileOffset = 0UL;
1650
1651 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
1652 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
1653 if(eErr != PVRSRV_OK)
1654 {
1655 return eErr;
1656 }
1657
1658 PDumpRegisterRange(psDevId,
1659 pszFileName,
1660 pui32Registers,
1661 ui32NumRegisters,
1662 &ui32FileOffset,
1663 sizeof(IMG_UINT32),
1664 ui32Flags);
1665
1666 return PVRSRV_OK;
1667}
1668
1669PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
1670 const IMG_UINT32 ui32RegOffset,
1671 IMG_UINT32 ui32Flags)
1672{
1673 PVRSRV_ERROR eErr;
1674 PDUMP_GET_SCRIPT_STRING();
1675
1676 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
1677 pszPDumpRegName,
1678 ui32RegOffset);
1679 if(eErr != PVRSRV_OK)
1680 {
1681 return eErr;
1682 }
1683 PDumpOSWriteString2(hScript, ui32Flags);
1684 return PVRSRV_OK;
1685}
1686
1687PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1688 IMG_CHAR *pszFileName,
1689 IMG_UINT32 ui32FileOffset,
1690 IMG_DEV_VIRTADDR sDevBaseAddr,
1691 IMG_UINT32 ui32Size,
1692 IMG_UINT32 ui32DataMaster,
1693 IMG_UINT32 ui32PDumpFlags)
1694{
1695 PVRSRV_ERROR eErr;
1696 PDUMP_GET_SCRIPT_STRING();
1697
1698#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1699 PVR_UNREFERENCED_PARAMETER(ui32DataMaster);
1700#endif
1701
1702 eErr = PDumpOSBufprintf(hScript,
1703 ui32MaxLen,
1704#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1705 "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
1706 psDevId->pszPDumpDevName,
1707 ui32DataMaster,
1708#else
1709 "SAB :%s:v:0x%08X 0x%08X 0x%08X %s.bin\r\n",
1710 psDevId->pszPDumpDevName,
1711#endif
1712 sDevBaseAddr.uiAddr,
1713 ui32Size,
1714 ui32FileOffset,
1715 pszFileName);
1716 if(eErr != PVRSRV_OK)
1717 {
1718 return eErr;
1719 }
1720
1721 PDumpOSWriteString2(hScript, ui32PDumpFlags);
1722 return PVRSRV_OK;
1723}
1724
1725PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
1726 const IMG_UINT32 ui32RegOffset,
1727 IMG_BOOL bLastFrame)
1728{
1729 PVRSRV_ERROR eErr;
1730 PDUMP_GET_SCRIPT_STRING();
1731
1732 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
1733 psDevId->pszPDumpRegName,
1734 ui32RegOffset);
1735 if(eErr != PVRSRV_OK)
1736 {
1737 return eErr;
1738 }
1739 PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
1740 return PVRSRV_OK;
1741}
1742
1743
1744PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1745 IMG_CHAR *pszFileName,
1746 IMG_CHAR *pszBufferType,
1747 IMG_UINT32 ui32FileOffset,
1748 IMG_DEV_VIRTADDR sDevBaseAddr,
1749 IMG_UINT32 ui32Size,
1750 IMG_UINT32 ui32PDumpFlags)
1751{
1752 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
1753 pszBufferType);
1754 PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
1755 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
1756 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
1757 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
1758 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
1759 PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
1760 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
1761 PDUMP_DATAMASTER_EDM, ui32PDumpFlags);
1762}
1763
1764
1765PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1766 IMG_CHAR *pszFileName,
1767 IMG_UINT32 ui32FileOffset,
1768 IMG_DEV_VIRTADDR sDevBaseAddr,
1769 IMG_UINT32 ui32Size,
1770 IMG_UINT32 ui32PDumpFlags)
1771{
1772 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
1773 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
1774 PDUMP_DATAMASTER_EDM, ui32PDumpFlags);
1775}
1776
1777
1778PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
1779 IMG_UINT32 ui32ROffOffset,
1780 IMG_UINT32 ui32WPosVal,
1781 IMG_UINT32 ui32PacketSize,
1782 IMG_UINT32 ui32BufferSize,
1783 IMG_UINT32 ui32Flags,
1784 IMG_HANDLE hUniqueTag)
1785{
1786 PVRSRV_ERROR eErr;
1787 IMG_UINT32 ui32PageOffset;
1788 IMG_UINT8 *pui8LinAddr;
1789 IMG_DEV_VIRTADDR sDevVAddr;
1790 IMG_DEV_PHYADDR sDevPAddr;
1791 IMG_DEV_VIRTADDR sDevVPageAddr;
1792
1793 PDUMP_MMU_ATTRIB *psMMUAttrib;
1794
1795 PDUMP_GET_SCRIPT_STRING();
1796
1797 psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
1798
1799
1800 PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->ui32AllocSize);
1801
1802 pui8LinAddr = psROffMemInfo->pvLinAddrKM;
1803 sDevVAddr = psROffMemInfo->sDevVAddr;
1804
1805
1806 pui8LinAddr += ui32ROffOffset;
1807 sDevVAddr.uiAddr += ui32ROffOffset;
1808
1809
1810
1811
1812 PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
1813 ui32ROffOffset,
1814 pui8LinAddr,
1815 psMMUAttrib->ui32DataPageMask,
1816 &ui32PageOffset);
1817
1818
1819 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
1820
1821 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1822
1823
1824 BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
1825
1826
1827 sDevPAddr.uiAddr += ui32PageOffset;
1828
1829 eErr = PDumpOSBufprintf(hScript,
1830 ui32MaxLen,
1831 "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
1832 psMMUAttrib->sDevId.pszPDumpDevName,
1833 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
1834 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
1835 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
1836 ui32WPosVal,
1837 ui32PacketSize,
1838 ui32BufferSize);
1839 if(eErr != PVRSRV_OK)
1840 {
1841 return eErr;
1842 }
1843 PDumpOSWriteString2(hScript, ui32Flags);
1844 return PVRSRV_OK;
1845}
1846
1847
1848PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
1849{
1850 PVRSRV_ERROR eErr;
1851 PDUMP_GET_SCRIPT_STRING();
1852 PDUMP_DBG(("PDumpIDLWithFlags"));
1853
1854 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
1855 if(eErr != PVRSRV_OK)
1856 {
1857 return eErr;
1858 }
1859 PDumpOSWriteString2(hScript, ui32Flags);
1860 return PVRSRV_OK;
1861}
1862
1863
1864PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
1865{
1866 return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
1867}
1868
1869PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
1870 IMG_PVOID pvAltLinAddrUM,
1871 IMG_PVOID pvLinAddrUM,
1872 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1873 IMG_UINT32 ui32Offset,
1874 IMG_UINT32 ui32Bytes,
1875 IMG_UINT32 ui32Flags,
1876 IMG_HANDLE hUniqueTag)
1877{
1878 IMG_VOID *pvAddrUM;
1879 IMG_VOID *pvAddrKM;
1880 IMG_UINT32 ui32BytesDumped;
1881 IMG_UINT32 ui32CurrentOffset;
1882
1883 if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
1884 {
1885
1886 return PDumpMemKM(IMG_NULL,
1887 psMemInfo,
1888 ui32Offset,
1889 ui32Bytes,
1890 ui32Flags,
1891 hUniqueTag);
1892 }
1893
1894 pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
1895
1896 pvAddrKM = GetTempBuffer();
1897
1898
1899 PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
1900 if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
1901 {
1902 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
1903 return PVRSRV_ERROR_INVALID_PARAMS;
1904 }
1905
1906 if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
1907 {
1908 PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
1909 }
1910
1911 ui32CurrentOffset = ui32Offset;
1912 for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
1913 {
1914 PVRSRV_ERROR eError;
1915 IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
1916
1917 eError = OSCopyFromUser(psPerProc,
1918 pvAddrKM,
1919 pvAddrUM,
1920 ui32BytesToDump);
1921 if (eError != PVRSRV_OK)
1922 {
1923 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
1924 return eError;
1925 }
1926
1927 eError = PDumpMemKM(pvAddrKM,
1928 psMemInfo,
1929 ui32CurrentOffset,
1930 ui32BytesToDump,
1931 ui32Flags,
1932 hUniqueTag);
1933
1934 if (eError != PVRSRV_OK)
1935 {
1936
1937 if (ui32BytesDumped != 0)
1938 {
1939 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
1940 }
1941 PVR_ASSERT(ui32BytesDumped == 0);
1942 return eError;
1943 }
1944
1945 VPTR_INC(pvAddrUM, ui32BytesToDump);
1946 ui32CurrentOffset += ui32BytesToDump;
1947 ui32BytesDumped += ui32BytesToDump;
1948 }
1949
1950 return PVRSRV_OK;
1951}
1952
1953
1954static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
1955{
1956 IMG_UINT32 i;
1957
1958
1959 for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
1960 {
1961 if((gui16MMUContextUsage & (1U << i)) == 0)
1962 {
1963
1964 gui16MMUContextUsage |= 1U << i;
1965 *pui32MMUContextID = i;
1966 return PVRSRV_OK;
1967 }
1968 }
1969
1970 PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
1971
1972 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
1973}
1974
1975
1976static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
1977{
1978 if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
1979 {
1980
1981 gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
1982 return PVRSRV_OK;
1983 }
1984
1985 PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
1986
1987 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
1988}
1989
1990
1991PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
1992 IMG_CHAR *pszMemSpace,
1993 IMG_UINT32 *pui32MMUContextID,
1994 IMG_UINT32 ui32MMUType,
1995 IMG_HANDLE hUniqueTag1,
1996 IMG_HANDLE hOSMemHandle,
1997 IMG_VOID *pvPDCPUAddr)
1998{
1999 IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
2000 IMG_CPU_PHYADDR sCpuPAddr;
2001 IMG_DEV_PHYADDR sDevPAddr;
2002 IMG_UINT32 ui32MMUContextID;
2003 PVRSRV_ERROR eError;
2004
2005 eError = _PdumpAllocMMUContext(&ui32MMUContextID);
2006 if(eError != PVRSRV_OK)
2007 {
2008 PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eError));
2009 return eError;
2010 }
2011
2012
2013
2014 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
2015 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
2016
2017 sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
2018
2019 PDumpComment("Set MMU Context\r\n");
2020
2021 PDumpComment("MMU :%s:v%d %d :%s:PA_%08X%08X\r\n",
2022 pszMemSpace,
2023 ui32MMUContextID,
2024 ui32MMUType,
2025 pszMemSpace,
2026 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
2027 sDevPAddr.uiAddr);
2028
2029
2030 *pui32MMUContextID = ui32MMUContextID;
2031
2032 return PVRSRV_OK;
2033}
2034
2035
2036PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
2037 IMG_CHAR *pszMemSpace,
2038 IMG_UINT32 ui32MMUContextID,
2039 IMG_UINT32 ui32MMUType)
2040{
2041 PVRSRV_ERROR eError;
2042
2043 PVR_UNREFERENCED_PARAMETER(eDeviceType);
2044
2045
2046 PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
2047
2048 PDumpComment("MMU :%s:v%d %d\r\n",
2049 pszMemSpace,
2050 ui32MMUContextID,
2051 ui32MMUType);
2052
2053 eError = _PdumpFreeMMUContext(ui32MMUContextID);
2054 if(eError != PVRSRV_OK)
2055 {
2056 PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eError));
2057 return eError;
2058 }
2059
2060 return PVRSRV_OK;
2061}
2062
2063PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
2064 IMG_CHAR *pszFileName,
2065 IMG_UINT32 ui32FileOffset,
2066 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
2067 IMG_UINT32 uiAddr,
2068 IMG_UINT32 ui32Size,
2069 IMG_UINT32 ui32PDumpFlags,
2070 IMG_HANDLE hUniqueTag)
2071{
2072 IMG_DEV_PHYADDR sDevPAddr;
2073 IMG_DEV_VIRTADDR sDevVPageAddr;
2074 IMG_UINT32 ui32PageOffset;
2075
2076 PDUMP_GET_SCRIPT_STRING();
2077
2078
2079
2080
2081 ui32PageOffset = (IMG_UINT32)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask;
2082
2083
2084 sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
2085
2086
2087 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
2088
2089
2090 sDevPAddr.uiAddr += ui32PageOffset;
2091
2092 PDumpOSBufprintf(hScript,
2093 ui32MaxLen,
2094 "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
2095 psMMUAttrib->sDevId.pszPDumpDevName,
2096 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
2097 sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask,
2098 sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask,
2099 ui32Size,
2100 ui32FileOffset,
2101 pszFileName);
2102
2103 PDumpOSWriteString2(hScript, ui32PDumpFlags);
2104
2105 return PVRSRV_OK;
2106}
2107
2108PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
2109 IMG_UINT32 ui32RegOffset,
2110 IMG_UINT32 ui32WPosVal,
2111 IMG_UINT32 ui32PacketSize,
2112 IMG_UINT32 ui32BufferSize,
2113 IMG_UINT32 ui32Flags)
2114{
2115 PDUMP_GET_SCRIPT_STRING();
2116
2117 PDumpOSBufprintf(hScript,
2118 ui32MaxLen,
2119 "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
2120 pszPDumpRegName,
2121 ui32RegOffset,
2122 ui32WPosVal,
2123 ui32PacketSize,
2124 ui32BufferSize);
2125 PDumpOSWriteString2(hScript, ui32Flags);
2126
2127 return PVRSRV_OK;
2128}
2129
2130
2131#include "syscommon.h"
2132
2133IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
2134{
2135 SYS_DATA *psSysData;
2136 PVRSRV_DEVICE_NODE *psThis;
2137 PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
2138
2139
2140 SysAcquireData(&psSysData);
2141
2142 psThis = psSysData->psDeviceNodeList;
2143 while (psThis)
2144 {
2145 if (psThis->pfnPDumpInitDevice)
2146 {
2147
2148 psThis->pfnPDumpInitDevice(psThis);
2149 }
2150 psThis = psThis->psNext;
2151 }
2152}
2153
2154IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
2155{
2156 IMG_UINT32 ui32BytesWritten = 0;
2157 IMG_UINT32 ui32Off = 0;
2158
2159
2160 if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
2161 {
2162 return ui32BCount;
2163 }
2164
2165 while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
2166 {
2167 if ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0)
2168 {
2169
2170
2171
2172 if (psStream->bInitPhaseComplete)
2173 {
2174
2175 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2176 PDUMP_WRITE_MODE_PERSISTENT,
2177 &pui8Data[ui32Off], ui32BCount, 1, 0);
2178 }
2179 }
2180
2181 if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
2182 {
2183
2184
2185 if (((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
2186 (psStream->ui32Start == 0xFFFFFFFFU) &&
2187 (psStream->ui32End == 0xFFFFFFFFU) &&
2188 psStream->bInitPhaseComplete)
2189 {
2190 ui32BytesWritten = ui32BCount;
2191 }
2192 else
2193 {
2194 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2195 PDUMP_WRITE_MODE_CONTINUOUS,
2196 &pui8Data[ui32Off], ui32BCount, 1, 0);
2197 }
2198 }
2199 else
2200 {
2201 if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
2202 {
2203 IMG_UINT32 ui32DbgFlags;
2204
2205 ui32DbgFlags = 0;
2206 if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
2207 {
2208 ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
2209 }
2210
2211 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2212 PDUMP_WRITE_MODE_LASTFRAME,
2213 &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
2214 }
2215 else
2216 {
2217 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2218 PDUMP_WRITE_MODE_BINCM,
2219 &pui8Data[ui32Off], ui32BCount, 1, 0);
2220 }
2221 }
2222
2223
2224
2225
2226 if (ui32BytesWritten == 0)
2227 {
2228 PDumpOSReleaseExecution();
2229 }
2230
2231 if (ui32BytesWritten != 0xFFFFFFFF)
2232 {
2233 ui32Off += ui32BytesWritten;
2234 ui32BCount -= ui32BytesWritten;
2235 }
2236
2237
2238 }
2239
2240
2241
2242 return ui32BytesWritten;
2243}
2244
2245
2246
2247#else
2248#endif
diff --git a/drivers/gpu/pvr/pdump_int.h b/drivers/gpu/pvr/pdump_int.h
new file mode 100644
index 00000000000..3c038883a2b
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_int.h
@@ -0,0 +1,67 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PDUMP_INT_H__
28#define __PDUMP_INT_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#if !defined(_UITRON)
35#include "dbgdrvif.h"
36
37IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID);
38
39#endif
40
41typedef enum
42{
43
44 PDUMP_WRITE_MODE_CONTINUOUS = 0,
45
46 PDUMP_WRITE_MODE_LASTFRAME,
47
48 PDUMP_WRITE_MODE_BINCM,
49
50 PDUMP_WRITE_MODE_PERSISTENT
51} PDUMP_DDWMODE;
52
53
54IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags);
55
56IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
57 PDUMP_DDWMODE eDbgDrvWriteMode,
58 IMG_UINT8 *pui8Data,
59 IMG_UINT32 ui32BCount,
60 IMG_UINT32 ui32Level,
61 IMG_UINT32 ui32DbgDrvFlags);
62
63#if defined (__cplusplus)
64}
65#endif
66#endif
67
diff --git a/drivers/gpu/pvr/pdump_km.h b/drivers/gpu/pvr/pdump_km.h
new file mode 100644
index 00000000000..782f883608e
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_km.h
@@ -0,0 +1,403 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _PDUMP_KM_H_
28#define _PDUMP_KM_H_
29
30
31#include "pdump_osfunc.h"
32
33#if defined(__cplusplus)
34extern "C" {
35#endif
36
37#include "pdump.h"
38
39#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0
40#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0
41
42#define PDUMP_STREAM_PARAM2 0
43#define PDUMP_STREAM_SCRIPT2 1
44#define PDUMP_STREAM_DRIVERINFO 2
45#define PDUMP_NUM_STREAMS 3
46
47#if defined(PDUMP_DEBUG_OUTFILES)
48extern IMG_UINT32 g_ui32EveryLineCounter;
49#endif
50
51#ifndef PDUMP
52#define MAKEUNIQUETAG(hMemInfo) (0)
53#endif
54
55#ifdef PDUMP
56
57#define MAKEUNIQUETAG(hMemInfo) (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)(hMemInfo))->sMemBlk.hBuffer))->pMapping)
58
59 IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
60 IMG_UINT32 ui32Offset,
61 IMG_UINT32 ui32Value,
62 IMG_UINT32 ui32Mask,
63 PDUMP_POLL_OPERATOR eOperator,
64 IMG_UINT32 ui32Flags,
65 IMG_HANDLE hUniqueTag);
66
67 IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData,
68 IMG_PVOID pvAltLinAddr,
69 IMG_PVOID pvLinAddr,
70 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
71 IMG_UINT32 ui32Offset,
72 IMG_UINT32 ui32Bytes,
73 IMG_UINT32 ui32Flags,
74 IMG_HANDLE hUniqueTag);
75
76 IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
77 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
78 IMG_UINT32 ui32Offset,
79 IMG_UINT32 ui32Bytes,
80 IMG_UINT32 ui32Flags,
81 IMG_HANDLE hUniqueTag);
82 PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_TYPE eDeviceType,
83 IMG_DEV_PHYADDR *pPages,
84 IMG_UINT32 ui32NumPages,
85 IMG_DEV_VIRTADDR sDevAddr,
86 IMG_UINT32 ui32Start,
87 IMG_UINT32 ui32Length,
88 IMG_UINT32 ui32Flags,
89 IMG_HANDLE hUniqueTag);
90
91 PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
92 IMG_HANDLE hOSMemHandle,
93 IMG_CPU_VIRTADDR pvLinAddr,
94 IMG_UINT32 ui32Bytes,
95 IMG_UINT32 ui32Flags,
96 IMG_BOOL bInitialisePages,
97 IMG_HANDLE hUniqueTag1,
98 IMG_HANDLE hUniqueTag2);
99
100 PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
101 IMG_HANDLE hOSMemHandle,
102 IMG_CPU_VIRTADDR pvLinAddr,
103 IMG_UINT32 ui32Bytes,
104 IMG_UINT32 ui32Flags,
105 IMG_BOOL bInitialisePages,
106 IMG_HANDLE hUniqueTag1,
107 IMG_HANDLE hUniqueTag2);
108 IMG_VOID PDumpInitCommon(IMG_VOID);
109 IMG_VOID PDumpDeInitCommon(IMG_VOID);
110 IMG_VOID PDumpInit(IMG_VOID);
111 IMG_VOID PDumpDeInit(IMG_VOID);
112 IMG_BOOL PDumpIsSuspended(IMG_VOID);
113 PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID);
114 PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID);
115 IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame);
116 IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags);
117 IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags);
118
119 PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
120 IMG_UINT32 ui32RegAddr,
121 IMG_UINT32 ui32RegValue,
122 IMG_UINT32 ui32Flags);
123 PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
124 IMG_UINT32 ui32RegAddr,
125 IMG_UINT32 ui32RegValue,
126 IMG_UINT32 ui32Mask,
127 IMG_UINT32 ui32Flags);
128 PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName,
129 IMG_UINT32 ui32RegAddr,
130 IMG_UINT32 ui32RegValue,
131 IMG_UINT32 ui32Mask);
132
133 IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(PVRSRV_DEVICE_NODE *psDeviceNode,
134 IMG_CHAR *pszFileName,
135 IMG_UINT32 ui32FileOffset,
136 IMG_UINT32 ui32Width,
137 IMG_UINT32 ui32Height,
138 IMG_UINT32 ui32StrideInBytes,
139 IMG_DEV_VIRTADDR sDevBaseAddr,
140 IMG_HANDLE hDevMemContext,
141 IMG_UINT32 ui32Size,
142 PDUMP_PIXEL_FORMAT ePixelFormat,
143 PDUMP_MEM_FORMAT eMemFormat,
144 IMG_UINT32 ui32PDumpFlags);
145 IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszPDumpRegName,
146 IMG_CHAR *pszFileName,
147 IMG_UINT32 ui32FileOffset,
148 IMG_UINT32 ui32Address,
149 IMG_UINT32 ui32Size,
150 IMG_UINT32 ui32PDumpFlags);
151
152 PVRSRV_ERROR PDumpRegKM(IMG_CHAR* pszPDumpRegName,
153 IMG_UINT32 dwReg,
154 IMG_UINT32 dwData);
155
156 PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
157 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags,
158 IMG_CHAR* pszFormat,
159 ...) IMG_FORMAT_PRINTF(2, 3);
160
161 PVRSRV_ERROR PDumpPDReg(PDUMP_MMU_ATTRIB *psMMUAttrib,
162 IMG_UINT32 ui32Reg,
163 IMG_UINT32 ui32dwData,
164 IMG_HANDLE hUniqueTag);
165 PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
166 IMG_UINT32 ui32Reg,
167 IMG_UINT32 ui32Data,
168 IMG_UINT32 ui32Flags,
169 IMG_HANDLE hUniqueTag);
170
171 IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID);
172 IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID);
173
174 IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_TYPE eDeviceType,
175 IMG_UINT32 ui32DevVAddr,
176 IMG_PUINT32 pui32PhysPages,
177 IMG_UINT32 ui32NumPages,
178 IMG_HANDLE hUniqueTag);
179 PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
180 IMG_CHAR *pszMemSpace,
181 IMG_UINT32 *pui32MMUContextID,
182 IMG_UINT32 ui32MMUType,
183 IMG_HANDLE hUniqueTag1,
184 IMG_HANDLE hOSMemHandle,
185 IMG_VOID *pvPDCPUAddr);
186 PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
187 IMG_CHAR *pszMemSpace,
188 IMG_UINT32 ui32MMUContextID,
189 IMG_UINT32 ui32MMUType);
190
191 PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
192 IMG_UINT32 ui32Offset,
193 IMG_DEV_PHYADDR sPDDevPAddr,
194 IMG_HANDLE hUniqueTag1,
195 IMG_HANDLE hUniqueTag2);
196
197 IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame);
198
199 PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
200 IMG_CHAR *pszFileName,
201 IMG_UINT32 ui32FileOffset,
202 IMG_DEV_VIRTADDR sDevBaseAddr,
203 IMG_UINT32 ui32Size,
204 IMG_UINT32 ui32DataMaster,
205 IMG_UINT32 ui32PDumpFlags);
206
207 PVRSRV_ERROR PDumpTASignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
208 IMG_UINT32 ui32DumpFrameNum,
209 IMG_UINT32 ui32TAKickCount,
210 IMG_BOOL bLastFrame,
211 IMG_UINT32 *pui32Registers,
212 IMG_UINT32 ui32NumRegisters);
213
214 PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
215 IMG_UINT32 ui32DumpFrameNum,
216 IMG_BOOL bLastFrame,
217 IMG_UINT32 *pui32Registers,
218 IMG_UINT32 ui32NumRegisters);
219
220 PVRSRV_ERROR PDumpCounterRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
221 IMG_UINT32 ui32DumpFrameNum,
222 IMG_BOOL bLastFrame,
223 IMG_UINT32 *pui32Registers,
224 IMG_UINT32 ui32NumRegisters);
225
226 PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
227 const IMG_UINT32 dwRegOffset,
228 IMG_UINT32 ui32Flags);
229
230 PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
231 const IMG_UINT32 dwRegOffset,
232 IMG_BOOL bLastFrame);
233
234 PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
235 PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
236
237 PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_IDENTIFIER *psDevID,
238 IMG_UINT32 ui32DevVAddr,
239 IMG_CPU_VIRTADDR pvLinAddr,
240 IMG_HANDLE hOSMemHandle,
241 IMG_UINT32 ui32NumBytes,
242 IMG_UINT32 ui32PageSize,
243 IMG_HANDLE hUniqueTag);
244 PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_IDENTIFIER *psDevId,
245 IMG_HANDLE hOSMemHandle,
246 IMG_UINT32 ui32Offset,
247 IMG_CPU_VIRTADDR pvLinAddr,
248 IMG_UINT32 ui32NumBytes,
249 IMG_HANDLE hUniqueTag);
250 PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_ *psBMHeap,
251 IMG_DEV_VIRTADDR sDevVAddr,
252 IMG_UINT32 ui32NumBytes,
253 IMG_UINT32 ui32PageSize,
254 IMG_HANDLE hUniqueTag,
255 IMG_BOOL bInterleaved);
256 PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_IDENTIFIER *psDevID,
257 IMG_HANDLE hOSMemHandle,
258 IMG_CPU_VIRTADDR pvLinAddr,
259 IMG_UINT32 ui32NumBytes,
260 IMG_HANDLE hUniqueTag);
261
262 IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId,
263 IMG_CHAR *pszFileName,
264 IMG_UINT32 ui32FileOffset,
265 IMG_DEV_VIRTADDR sDevBaseAddr,
266 IMG_UINT32 ui32Size,
267 IMG_UINT32 ui32PDumpFlags);
268
269 PVRSRV_ERROR PDumpSignatureBuffer(PVRSRV_DEVICE_IDENTIFIER *psDevId,
270 IMG_CHAR *pszFileName,
271 IMG_CHAR *pszBufferType,
272 IMG_UINT32 ui32FileOffset,
273 IMG_DEV_VIRTADDR sDevBaseAddr,
274 IMG_UINT32 ui32Size,
275 IMG_UINT32 ui32PDumpFlags);
276
277 PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
278 IMG_UINT32 ui32ROffOffset,
279 IMG_UINT32 ui32WPosVal,
280 IMG_UINT32 ui32PacketSize,
281 IMG_UINT32 ui32BufferSize,
282 IMG_UINT32 ui32Flags,
283 IMG_HANDLE hUniqueTag);
284
285 PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
286 IMG_UINT32 ui32RegOffset,
287 IMG_UINT32 ui32WPosVal,
288 IMG_UINT32 ui32PacketSize,
289 IMG_UINT32 ui32BufferSize,
290 IMG_UINT32 ui32Flags);
291
292 IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName,
293 IMG_UINT32 ui32FileOffset,
294 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
295 IMG_UINT32 uiAddr,
296 IMG_UINT32 ui32Size,
297 IMG_UINT32 ui32PDumpFlags,
298 IMG_HANDLE hUniqueTag);
299
300 IMG_VOID PDumpSuspendKM(IMG_VOID);
301 IMG_VOID PDumpResumeKM(IMG_VOID);
302
303
304 PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
305 IMG_CHAR *pszFileName,
306 IMG_UINT32 ui32FileOffset,
307 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
308 IMG_UINT32 uiAddr,
309 IMG_UINT32 ui32Size,
310 IMG_UINT32 ui32PDumpFlags,
311 IMG_HANDLE hUniqueTag);
312
313 #define PDUMPMEMPOL PDumpMemPolKM
314 #define PDUMPMEM PDumpMemKM
315 #define PDUMPMEMPTENTRIES PDumpMemPTEntriesKM
316 #define PDUMPPDENTRIES PDumpMemPDEntriesKM
317 #define PDUMPMEMUM PDumpMemUM
318 #define PDUMPINIT PDumpInitCommon
319 #define PDUMPDEINIT PDumpDeInitCommon
320 #define PDUMPISLASTFRAME PDumpIsLastCaptureFrameKM
321 #define PDUMPTESTFRAME PDumpIsCaptureFrameKM
322 #define PDUMPTESTNEXTFRAME PDumpTestNextFrame
323 #define PDUMPREGWITHFLAGS PDumpRegWithFlagsKM
324 #define PDUMPREG PDumpRegKM
325 #define PDUMPCOMMENT PDumpComment
326 #define PDUMPCOMMENTWITHFLAGS PDumpCommentWithFlags
327 #define PDUMPREGPOL PDumpRegPolKM
328 #define PDUMPREGPOLWITHFLAGS PDumpRegPolWithFlagsKM
329 #define PDUMPMALLOCPAGES PDumpMallocPages
330 #define PDUMPMALLOCPAGETABLE PDumpMallocPageTable
331 #define PDUMPSETMMUCONTEXT PDumpSetMMUContext
332 #define PDUMPCLEARMMUCONTEXT PDumpClearMMUContext
333 #define PDUMPFREEPAGES PDumpFreePages
334 #define PDUMPFREEPAGETABLE PDumpFreePageTable
335 #define PDUMPPDREG PDumpPDReg
336 #define PDUMPPDREGWITHFLAGS PDumpPDRegWithFlags
337 #define PDUMPCBP PDumpCBP
338 #define PDUMPREGBASEDCBP PDumpRegBasedCBP
339 #define PDUMPMALLOCPAGESPHYS PDumpMallocPagesPhys
340 #define PDUMPENDINITPHASE PDumpStopInitPhaseKM
341 #define PDUMPBITMAPKM PDumpBitmapKM
342 #define PDUMPDRIVERINFO PDumpDriverInfoKM
343 #define PDUMPIDLWITHFLAGS PDumpIDLWithFlags
344 #define PDUMPIDL PDumpIDL
345 #define PDUMPSUSPEND PDumpSuspendKM
346 #define PDUMPRESUME PDumpResumeKM
347
348#else
349 #if ((defined(LINUX) || defined(GCC_IA32)) || defined(GCC_ARM))
350 #define PDUMPMEMPOL(args...)
351 #define PDUMPMEM(args...)
352 #define PDUMPMEMPTENTRIES(args...)
353 #define PDUMPPDENTRIES(args...)
354 #define PDUMPMEMUM(args...)
355 #define PDUMPINIT(args...)
356 #define PDUMPDEINIT(args...)
357 #define PDUMPISLASTFRAME(args...)
358 #define PDUMPTESTFRAME(args...)
359 #define PDUMPTESTNEXTFRAME(args...)
360 #define PDUMPREGWITHFLAGS(args...)
361 #define PDUMPREG(args...)
362 #define PDUMPCOMMENT(args...)
363 #define PDUMPREGPOL(args...)
364 #define PDUMPREGPOLWITHFLAGS(args...)
365 #define PDUMPMALLOCPAGES(args...)
366 #define PDUMPMALLOCPAGETABLE(args...)
367 #define PDUMPSETMMUCONTEXT(args...)
368 #define PDUMPCLEARMMUCONTEXT(args...)
369 #define PDUMPFREEPAGES(args...)
370 #define PDUMPFREEPAGETABLE(args...)
371 #define PDUMPPDREG(args...)
372 #define PDUMPPDREGWITHFLAGS(args...)
373 #define PDUMPSYNC(args...)
374 #define PDUMPCOPYTOMEM(args...)
375 #define PDUMPWRITE(args...)
376 #define PDUMPCBP(args...)
377 #define PDUMPREGBASEDCBP(args...)
378 #define PDUMPCOMMENTWITHFLAGS(args...)
379 #define PDUMPMALLOCPAGESPHYS(args...)
380 #define PDUMPENDINITPHASE(args...)
381 #define PDUMPMSVDXREG(args...)
382 #define PDUMPMSVDXREGWRITE(args...)
383 #define PDUMPMSVDXREGREAD(args...)
384 #define PDUMPMSVDXPOLEQ(args...)
385 #define PDUMPMSVDXPOL(args...)
386 #define PDUMPBITMAPKM(args...)
387 #define PDUMPDRIVERINFO(args...)
388 #define PDUMPIDLWITHFLAGS(args...)
389 #define PDUMPIDL(args...)
390 #define PDUMPSUSPEND(args...)
391 #define PDUMPRESUME(args...)
392 #define PDUMPMSVDXWRITEREF(args...)
393 #else
394 #error Compiler not specified
395 #endif
396#endif
397
398#if defined (__cplusplus)
399}
400#endif
401
402#endif
403
diff --git a/drivers/gpu/pvr/pdump_osfunc.h b/drivers/gpu/pvr/pdump_osfunc.h
new file mode 100644
index 00000000000..334c98da3ad
--- /dev/null
+++ b/drivers/gpu/pvr/pdump_osfunc.h
@@ -0,0 +1,135 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stdarg.h>
28
29#if defined(__cplusplus)
30extern "C" {
31#endif
32
33
34#define MAX_PDUMP_STRING_LENGTH (256)
35
36
37#define PDUMP_GET_SCRIPT_STRING() \
38 IMG_HANDLE hScript; \
39 IMG_UINT32 ui32MaxLen; \
40 PVRSRV_ERROR eError; \
41 eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
42 if(eError != PVRSRV_OK) return eError;
43
44#define PDUMP_GET_MSG_STRING() \
45 IMG_CHAR *pszMsg; \
46 IMG_UINT32 ui32MaxLen; \
47 PVRSRV_ERROR eError; \
48 eError = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\
49 if(eError != PVRSRV_OK) return eError;
50
51#define PDUMP_GET_FILE_STRING() \
52 IMG_CHAR *pszFileName; \
53 IMG_UINT32 ui32MaxLen; \
54 PVRSRV_ERROR eError; \
55 eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
56 if(eError != PVRSRV_OK) return eError;
57
58#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \
59 IMG_HANDLE hScript; \
60 IMG_CHAR *pszFileName; \
61 IMG_UINT32 ui32MaxLenScript; \
62 IMG_UINT32 ui32MaxLenFileName; \
63 PVRSRV_ERROR eError; \
64 eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
65 if(eError != PVRSRV_OK) return eError; \
66 eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
67 if(eError != PVRSRV_OK) return eError;
68
69
70 PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
71
72
73 PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
74
75
76 PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
77
78
79
80
81#define PDUMP_va_list va_list
82#define PDUMP_va_start va_start
83#define PDUMP_va_end va_end
84
85
86
87IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream);
88
89IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream);
90
91IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID);
92
93IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags);
94
95IMG_BOOL PDumpOSIsSuspended(IMG_VOID);
96
97IMG_BOOL PDumpOSJTInitialised(IMG_VOID);
98
99IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream,
100 IMG_UINT8 *psui8Data,
101 IMG_UINT32 ui32Size,
102 IMG_UINT32 ui32Flags);
103
104IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags);
105
106PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
107
108IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
109
110PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
111
112PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
113
114IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
115
116IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
117
118IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
119 IMG_HANDLE hOSMemHandle,
120 IMG_UINT32 ui32Offset,
121 IMG_UINT8 *pui8LinAddr,
122 IMG_UINT32 ui32PageSize,
123 IMG_DEV_PHYADDR *psDevPAddr);
124
125IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
126 IMG_UINT32 ui32Offset,
127 IMG_PUINT8 pui8LinAddr,
128 IMG_UINT32 ui32DataPageMask,
129 IMG_UINT32 *pui32PageOffset);
130
131IMG_VOID PDumpOSReleaseExecution(IMG_VOID);
132
133#if defined (__cplusplus)
134}
135#endif
diff --git a/drivers/gpu/pvr/pdumpdefs.h b/drivers/gpu/pvr/pdumpdefs.h
new file mode 100644
index 00000000000..83ccbb2c80c
--- /dev/null
+++ b/drivers/gpu/pvr/pdumpdefs.h
@@ -0,0 +1,99 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__PDUMPDEFS_H__)
28#define __PDUMPDEFS_H__
29
30typedef enum _PDUMP_PIXEL_FORMAT_
31{
32 PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
33 PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1,
34 PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2,
35 PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3,
36 PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4,
37 PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5,
38 PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6,
39 PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7,
40 PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8,
41 PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9,
42 PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10,
43 PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11,
44 PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12,
45 PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13,
46 PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14,
47 PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15,
48 PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16,
49 PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17,
50 PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18,
51 PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19,
52 PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20,
53 PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21,
54 PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22,
55 PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23,
56 PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24,
57 PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25,
58 PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26,
59 PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27,
60 PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28,
61 PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29,
62 PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30,
63 PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31,
64 PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32,
65 PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33,
66 PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34,
67 PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35,
68 PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36,
69 PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37,
70 PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38,
71
72 PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
73
74} PDUMP_PIXEL_FORMAT;
75
76typedef enum _PDUMP_MEM_FORMAT_
77{
78 PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0,
79 PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1,
80 PVRSRV_PDUMP_MEM_FORMAT_TILED = 8,
81 PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9,
82 PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10,
83
84 PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff
85} PDUMP_MEM_FORMAT;
86
87typedef enum _PDUMP_POLL_OPERATOR
88{
89 PDUMP_POLL_OPERATOR_EQUAL = 0,
90 PDUMP_POLL_OPERATOR_LESS = 1,
91 PDUMP_POLL_OPERATOR_LESSEQUAL = 2,
92 PDUMP_POLL_OPERATOR_GREATER = 3,
93 PDUMP_POLL_OPERATOR_GREATEREQUAL = 4,
94 PDUMP_POLL_OPERATOR_NOTEQUAL = 5,
95} PDUMP_POLL_OPERATOR;
96
97
98#endif
99
diff --git a/drivers/gpu/pvr/perproc.c b/drivers/gpu/pvr/perproc.c
new file mode 100644
index 00000000000..62f4a3f1144
--- /dev/null
+++ b/drivers/gpu/pvr/perproc.c
@@ -0,0 +1,283 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "resman.h"
29#include "handle.h"
30#include "perproc.h"
31#include "osperproc.h"
32
33#define HASH_TAB_INIT_SIZE 32
34
35static HASH_TABLE *psHashTab = IMG_NULL;
36
37static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
38{
39 PVRSRV_ERROR eError;
40 IMG_UINTPTR_T uiPerProc;
41
42 PVR_ASSERT(psPerProc != IMG_NULL);
43
44 if (psPerProc == IMG_NULL)
45 {
46 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
47 return PVRSRV_ERROR_INVALID_PARAMS;
48 }
49
50 uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
51 if (uiPerProc == 0)
52 {
53 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
54
55 PVR_ASSERT(psPerProc->ui32PID == 0);
56 }
57 else
58 {
59 PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
60 PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
61 }
62
63
64 if (psPerProc->psHandleBase != IMG_NULL)
65 {
66 eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
67 if (eError != PVRSRV_OK)
68 {
69 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
70 return eError;
71 }
72 }
73
74
75 if (psPerProc->hPerProcData != IMG_NULL)
76 {
77 eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
78
79 if (eError != PVRSRV_OK)
80 {
81 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
82 return eError;
83 }
84 }
85
86
87 eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
88 if (eError != PVRSRV_OK)
89 {
90 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
91 return eError;
92 }
93
94 eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
95 sizeof(*psPerProc),
96 psPerProc,
97 psPerProc->hBlockAlloc);
98
99 if (eError != PVRSRV_OK)
100 {
101 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
102 return eError;
103 }
104
105 return PVRSRV_OK;
106}
107
108
109PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
110{
111 PVRSRV_PER_PROCESS_DATA *psPerProc;
112
113 PVR_ASSERT(psHashTab != IMG_NULL);
114
115
116 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
117 return psPerProc;
118}
119
120
121PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID)
122{
123 PVRSRV_PER_PROCESS_DATA *psPerProc;
124 IMG_HANDLE hBlockAlloc;
125 PVRSRV_ERROR eError = PVRSRV_OK;
126
127 PVR_ASSERT(psHashTab != IMG_NULL);
128
129
130 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
131
132 if (psPerProc == IMG_NULL)
133 {
134
135 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
136 sizeof(*psPerProc),
137 (IMG_PVOID *)&psPerProc,
138 &hBlockAlloc,
139 "Per Process Data");
140 if (eError != PVRSRV_OK)
141 {
142 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
143 return eError;
144 }
145 OSMemSet(psPerProc, 0, sizeof(*psPerProc));
146 psPerProc->hBlockAlloc = hBlockAlloc;
147
148 if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
149 {
150 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
151 eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
152 goto failure;
153 }
154
155 psPerProc->ui32PID = ui32PID;
156 psPerProc->ui32RefCount = 0;
157
158
159 eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
160 if (eError != PVRSRV_OK)
161 {
162 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
163 goto failure;
164 }
165
166
167 eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
168 &psPerProc->hPerProcData,
169 psPerProc,
170 PVRSRV_HANDLE_TYPE_PERPROC_DATA,
171 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
172 if (eError != PVRSRV_OK)
173 {
174 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
175 goto failure;
176 }
177
178
179 eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
180 if (eError != PVRSRV_OK)
181 {
182 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
183 goto failure;
184 }
185
186
187 eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
188 if (eError != PVRSRV_OK)
189 {
190 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
191 goto failure;
192 }
193
194
195 eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
196 if (eError != PVRSRV_OK)
197 {
198 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
199 goto failure;
200 }
201 }
202
203 psPerProc->ui32RefCount++;
204 PVR_DPF((PVR_DBG_MESSAGE,
205 "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
206 ui32PID, psPerProc->ui32RefCount));
207
208 return eError;
209
210failure:
211 (IMG_VOID)FreePerProcessData(psPerProc);
212 return eError;
213}
214
215
216IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID)
217{
218 PVRSRV_ERROR eError;
219 PVRSRV_PER_PROCESS_DATA *psPerProc;
220
221 PVR_ASSERT(psHashTab != IMG_NULL);
222
223 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
224 if (psPerProc == IMG_NULL)
225 {
226 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
227 }
228 else
229 {
230 psPerProc->ui32RefCount--;
231 if (psPerProc->ui32RefCount == 0)
232 {
233 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
234 "Last close from process 0x%x received", ui32PID));
235
236
237 PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
238
239
240 eError = FreePerProcessData(psPerProc);
241 if (eError != PVRSRV_OK)
242 {
243 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
244 }
245 }
246 }
247
248 eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
249 if (eError != PVRSRV_OK)
250 {
251 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
252 }
253}
254
255
256PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
257{
258 PVR_ASSERT(psHashTab == IMG_NULL);
259
260
261 psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
262 if (psHashTab == IMG_NULL)
263 {
264 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
265 return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
266 }
267
268 return PVRSRV_OK;
269}
270
271PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
272{
273
274 if (psHashTab != IMG_NULL)
275 {
276
277 HASH_Delete(psHashTab);
278 psHashTab = IMG_NULL;
279 }
280
281 return PVRSRV_OK;
282}
283
diff --git a/drivers/gpu/pvr/perproc.h b/drivers/gpu/pvr/perproc.h
new file mode 100644
index 00000000000..0b7542b930f
--- /dev/null
+++ b/drivers/gpu/pvr/perproc.h
@@ -0,0 +1,113 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PERPROC_H__
28#define __PERPROC_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "img_types.h"
35#include "resman.h"
36
37#include "handle.h"
38
39typedef struct _PVRSRV_PER_PROCESS_DATA_
40{
41 IMG_UINT32 ui32PID;
42 IMG_HANDLE hBlockAlloc;
43 PRESMAN_CONTEXT hResManContext;
44 IMG_HANDLE hPerProcData;
45 PVRSRV_HANDLE_BASE *psHandleBase;
46#if defined (PVR_SECURE_HANDLES)
47
48 IMG_BOOL bHandlesBatched;
49#endif
50 IMG_UINT32 ui32RefCount;
51
52
53 IMG_BOOL bInitProcess;
54#if defined(PDUMP)
55
56 IMG_BOOL bPDumpPersistent;
57#endif
58
59 IMG_HANDLE hOsPrivateData;
60} PVRSRV_PER_PROCESS_DATA;
61
62PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID);
63
64PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID);
65IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID);
66
67PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID);
68PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID);
69
70#ifdef INLINE_IS_PRAGMA
71#pragma inline(PVRSRVFindPerProcessData)
72#endif
73static INLINE
74PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID)
75{
76 return PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
77}
78
79
80#ifdef INLINE_IS_PRAGMA
81#pragma inline(PVRSRVProcessPrivateData)
82#endif
83static INLINE
84IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc)
85{
86 return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL;
87}
88
89
90#ifdef INLINE_IS_PRAGMA
91#pragma inline(PVRSRVPerProcessPrivateData)
92#endif
93static INLINE
94IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID)
95{
96 return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID));
97}
98
99#ifdef INLINE_IS_PRAGMA
100#pragma inline(PVRSRVFindPerProcessPrivateData)
101#endif
102static INLINE
103IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID)
104{
105 return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData());
106}
107
108#if defined (__cplusplus)
109}
110#endif
111
112#endif
113
diff --git a/drivers/gpu/pvr/power.c b/drivers/gpu/pvr/power.c
new file mode 100644
index 00000000000..ba0eced9ba1
--- /dev/null
+++ b/drivers/gpu/pvr/power.c
@@ -0,0 +1,727 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "pdump_km.h"
29
30#include "lists.h"
31
32static IMG_BOOL gbInitServerRunning = IMG_FALSE;
33static IMG_BOOL gbInitServerRan = IMG_FALSE;
34static IMG_BOOL gbInitSuccessful = IMG_FALSE;
35
36IMG_EXPORT
37PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState)
38{
39
40 switch(eInitServerState)
41 {
42 case PVRSRV_INIT_SERVER_RUNNING:
43 gbInitServerRunning = bState;
44 break;
45 case PVRSRV_INIT_SERVER_RAN:
46 gbInitServerRan = bState;
47 break;
48 case PVRSRV_INIT_SERVER_SUCCESSFUL:
49 gbInitSuccessful = bState;
50 break;
51 default:
52 PVR_DPF((PVR_DBG_ERROR,
53 "PVRSRVSetInitServerState : Unknown state %x", eInitServerState));
54 return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE;
55 }
56
57 return PVRSRV_OK;
58}
59
60IMG_EXPORT
61IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState)
62{
63 IMG_BOOL bReturnVal;
64
65 switch(eInitServerState)
66 {
67 case PVRSRV_INIT_SERVER_RUNNING:
68 bReturnVal = gbInitServerRunning;
69 break;
70 case PVRSRV_INIT_SERVER_RAN:
71 bReturnVal = gbInitServerRan;
72 break;
73 case PVRSRV_INIT_SERVER_SUCCESSFUL:
74 bReturnVal = gbInitSuccessful;
75 break;
76 default:
77 PVR_DPF((PVR_DBG_ERROR,
78 "PVRSRVGetInitServerState : Unknown state %x", eInitServerState));
79 bReturnVal = IMG_FALSE;
80 }
81
82 return bReturnVal;
83}
84
85static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
86{
87 return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2);
88}
89
90
91IMG_EXPORT
92PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID,
93 IMG_BOOL bSystemPowerEvent)
94{
95 PVRSRV_ERROR eError;
96 SYS_DATA *psSysData;
97 IMG_UINT32 ui32Timeout = 1000000;
98
99#if defined(SUPPORT_LMA)
100
101 ui32Timeout *= 60;
102#endif
103
104 SysAcquireData(&psSysData);
105
106#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
107 eError = SysPowerLockWrap(psSysData);
108 if (eError != PVRSRV_OK)
109 {
110 return eError;
111 }
112#endif
113 do
114 {
115 eError = OSLockResource(&psSysData->sPowerStateChangeResource,
116 ui32CallerID);
117 if (eError == PVRSRV_OK)
118 {
119 break;
120 }
121 else if (ui32CallerID == ISR_ID)
122 {
123
124
125 eError = PVRSRV_ERROR_RETRY;
126 break;
127 }
128
129 OSWaitus(1);
130 ui32Timeout--;
131 } while (ui32Timeout > 0);
132
133#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
134 if (eError != PVRSRV_OK)
135 {
136 SysPowerLockUnwrap(psSysData);
137 }
138#endif
139
140 if ((eError == PVRSRV_OK) &&
141 !bSystemPowerEvent &&
142 !_IsSystemStatePowered(psSysData->eCurrentPowerState))
143 {
144
145 PVRSRVPowerUnlock(ui32CallerID);
146 eError = PVRSRV_ERROR_RETRY;
147 }
148
149 return eError;
150}
151
152
153IMG_EXPORT
154IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID)
155{
156 OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID);
157#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
158 SysPowerLockUnwrap(gpsSysData);
159#endif
160}
161
162
163static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
164{
165 PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
166 PVRSRV_ERROR eError;
167
168
169 IMG_BOOL bAllDevices;
170 IMG_UINT32 ui32DeviceIndex;
171 PVRSRV_DEV_POWER_STATE eNewPowerState;
172
173
174 bAllDevices = va_arg(va, IMG_BOOL);
175 ui32DeviceIndex = va_arg(va, IMG_UINT32);
176 eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
177
178 if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
179 {
180 eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
181 psPowerDevice->eDefaultPowerState : eNewPowerState;
182
183 if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
184 {
185 if (psPowerDevice->pfnPrePower != IMG_NULL)
186 {
187
188 eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie,
189 eNewDevicePowerState,
190 psPowerDevice->eCurrentPowerState);
191 if (eError != PVRSRV_OK)
192 {
193 return eError;
194 }
195 }
196
197
198 eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex,
199 eNewDevicePowerState,
200 psPowerDevice->eCurrentPowerState);
201 if (eError != PVRSRV_OK)
202 {
203 return eError;
204 }
205 }
206 }
207
208 return PVRSRV_OK;
209}
210
211static
212PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices,
213 IMG_UINT32 ui32DeviceIndex,
214 PVRSRV_DEV_POWER_STATE eNewPowerState)
215{
216 PVRSRV_ERROR eError;
217 SYS_DATA *psSysData;
218
219 SysAcquireData(&psSysData);
220
221
222 eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
223 &PVRSRVDevicePrePowerStateKM_AnyVaCb,
224 bAllDevices,
225 ui32DeviceIndex,
226 eNewPowerState);
227
228 return eError;
229}
230
231static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
232{
233 PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
234 PVRSRV_ERROR eError;
235
236
237 IMG_BOOL bAllDevices;
238 IMG_UINT32 ui32DeviceIndex;
239 PVRSRV_DEV_POWER_STATE eNewPowerState;
240
241
242 bAllDevices = va_arg(va, IMG_BOOL);
243 ui32DeviceIndex = va_arg(va, IMG_UINT32);
244 eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
245
246 if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
247 {
248 eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
249 psPowerDevice->eDefaultPowerState : eNewPowerState;
250
251 if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
252 {
253
254 eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex,
255 eNewDevicePowerState,
256 psPowerDevice->eCurrentPowerState);
257 if (eError != PVRSRV_OK)
258 {
259 return eError;
260 }
261
262 if (psPowerDevice->pfnPostPower != IMG_NULL)
263 {
264
265 eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie,
266 eNewDevicePowerState,
267 psPowerDevice->eCurrentPowerState);
268 if (eError != PVRSRV_OK)
269 {
270 return eError;
271 }
272 }
273
274 psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
275 }
276 }
277 return PVRSRV_OK;
278}
279
280static
281PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices,
282 IMG_UINT32 ui32DeviceIndex,
283 PVRSRV_DEV_POWER_STATE eNewPowerState)
284{
285 PVRSRV_ERROR eError;
286 SYS_DATA *psSysData;
287
288 SysAcquireData(&psSysData);
289
290
291 eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
292 &PVRSRVDevicePostPowerStateKM_AnyVaCb,
293 bAllDevices,
294 ui32DeviceIndex,
295 eNewPowerState);
296
297 return eError;
298}
299
300
301IMG_EXPORT
302PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex,
303 PVRSRV_DEV_POWER_STATE eNewPowerState,
304 IMG_UINT32 ui32CallerID,
305 IMG_BOOL bRetainMutex)
306{
307 PVRSRV_ERROR eError;
308 SYS_DATA *psSysData;
309
310 SysAcquireData(&psSysData);
311
312 eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
313 if(eError != PVRSRV_OK)
314 {
315 return eError;
316 }
317
318 #if defined(PDUMP)
319 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
320 {
321
322
323
324
325 eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
326 if(eError != PVRSRV_OK)
327 {
328 goto Exit;
329 }
330
331 eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
332
333 if (eError != PVRSRV_OK)
334 {
335 goto Exit;
336 }
337
338 PDUMPSUSPEND();
339 }
340 #endif
341
342 eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
343 if(eError != PVRSRV_OK)
344 {
345 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
346 {
347 PDUMPRESUME();
348 }
349 goto Exit;
350 }
351
352 eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
353
354 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
355 {
356 PDUMPRESUME();
357 }
358
359Exit:
360
361 if(eError != PVRSRV_OK)
362 {
363 PVR_DPF((PVR_DBG_ERROR,
364 "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
365 }
366
367 if (!bRetainMutex || (eError != PVRSRV_OK))
368 {
369 PVRSRVPowerUnlock(ui32CallerID);
370 }
371
372 return eError;
373}
374
375
376IMG_EXPORT
377PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
378{
379 PVRSRV_ERROR eError;
380 SYS_DATA *psSysData;
381 PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
382
383 SysAcquireData(&psSysData);
384
385
386 eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE);
387 if(eError != PVRSRV_OK)
388 {
389 return eError;
390 }
391
392 if (_IsSystemStatePowered(eNewSysPowerState) !=
393 _IsSystemStatePowered(psSysData->eCurrentPowerState))
394 {
395 if (_IsSystemStatePowered(eNewSysPowerState))
396 {
397
398 eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
399 }
400 else
401 {
402 eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
403 }
404
405
406 eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
407 if (eError != PVRSRV_OK)
408 {
409 goto ErrorExit;
410 }
411 }
412
413 if (eNewSysPowerState != psSysData->eCurrentPowerState)
414 {
415
416 eError = SysSystemPrePowerState(eNewSysPowerState);
417 if (eError != PVRSRV_OK)
418 {
419 goto ErrorExit;
420 }
421 }
422
423 return eError;
424
425ErrorExit:
426
427 PVR_DPF((PVR_DBG_ERROR,
428 "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x",
429 psSysData->eCurrentPowerState, eNewSysPowerState, eError));
430
431
432 psSysData->eFailedPowerState = eNewSysPowerState;
433
434 PVRSRVPowerUnlock(KERNEL_ID);
435
436 return eError;
437}
438
439
440IMG_EXPORT
441PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
442{
443 PVRSRV_ERROR eError = PVRSRV_OK;
444 SYS_DATA *psSysData;
445 PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
446
447 SysAcquireData(&psSysData);
448
449 if (eNewSysPowerState != psSysData->eCurrentPowerState)
450 {
451
452 eError = SysSystemPostPowerState(eNewSysPowerState);
453 if (eError != PVRSRV_OK)
454 {
455 goto Exit;
456 }
457 }
458
459 if (_IsSystemStatePowered(eNewSysPowerState) !=
460 _IsSystemStatePowered(psSysData->eCurrentPowerState))
461 {
462 if (_IsSystemStatePowered(eNewSysPowerState))
463 {
464
465 eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
466 }
467 else
468 {
469 eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
470 }
471
472
473 eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
474 if (eError != PVRSRV_OK)
475 {
476 goto Exit;
477 }
478 }
479
480 PVR_DPF((PVR_DBG_MESSAGE,
481 "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK",
482 psSysData->eCurrentPowerState, eNewSysPowerState));
483
484 psSysData->eCurrentPowerState = eNewSysPowerState;
485
486Exit:
487
488 PVRSRVPowerUnlock(KERNEL_ID);
489
490
491 if (_IsSystemStatePowered(eNewSysPowerState) &&
492 PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
493 {
494
495
496
497 PVRSRVScheduleDeviceCallbacks();
498 }
499
500 return eError;
501}
502
503
504IMG_EXPORT
505PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
506{
507 PVRSRV_ERROR eError;
508 SYS_DATA *psSysData;
509
510 SysAcquireData(&psSysData);
511
512 eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState);
513 if(eError != PVRSRV_OK)
514 {
515 goto ErrorExit;
516 }
517
518 eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState);
519 if(eError != PVRSRV_OK)
520 {
521 goto ErrorExit;
522 }
523
524
525 psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
526
527 return PVRSRV_OK;
528
529ErrorExit:
530
531 PVR_DPF((PVR_DBG_ERROR,
532 "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x",
533 psSysData->eCurrentPowerState, eNewSysPowerState, eError));
534
535
536 psSysData->eFailedPowerState = eNewSysPowerState;
537
538 return eError;
539}
540
541
542PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex,
543 PFN_PRE_POWER pfnPrePower,
544 PFN_POST_POWER pfnPostPower,
545 PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange,
546 PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange,
547 IMG_HANDLE hDevCookie,
548 PVRSRV_DEV_POWER_STATE eCurrentPowerState,
549 PVRSRV_DEV_POWER_STATE eDefaultPowerState)
550{
551 PVRSRV_ERROR eError;
552 SYS_DATA *psSysData;
553 PVRSRV_POWER_DEV *psPowerDevice;
554
555 if (pfnPrePower == IMG_NULL &&
556 pfnPostPower == IMG_NULL)
557 {
558 return PVRSRVRemovePowerDevice(ui32DeviceIndex);
559 }
560
561 SysAcquireData(&psSysData);
562
563 eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
564 sizeof(PVRSRV_POWER_DEV),
565 (IMG_VOID **)&psPowerDevice, IMG_NULL,
566 "Power Device");
567 if(eError != PVRSRV_OK)
568 {
569 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
570 return eError;
571 }
572
573
574 psPowerDevice->pfnPrePower = pfnPrePower;
575 psPowerDevice->pfnPostPower = pfnPostPower;
576 psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
577 psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
578 psPowerDevice->hDevCookie = hDevCookie;
579 psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
580 psPowerDevice->eCurrentPowerState = eCurrentPowerState;
581 psPowerDevice->eDefaultPowerState = eDefaultPowerState;
582
583
584 List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice);
585
586 return (PVRSRV_OK);
587}
588
589
590PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
591{
592 SYS_DATA *psSysData;
593 PVRSRV_POWER_DEV *psPowerDev;
594
595 SysAcquireData(&psSysData);
596
597
598 psPowerDev = (PVRSRV_POWER_DEV*)
599 List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
600 &MatchPowerDeviceIndex_AnyVaCb,
601 ui32DeviceIndex);
602
603 if (psPowerDev)
604 {
605 List_PVRSRV_POWER_DEV_Remove(psPowerDev);
606 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL);
607
608 }
609
610 return (PVRSRV_OK);
611}
612
613
614IMG_EXPORT
615IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
616{
617 SYS_DATA *psSysData;
618 PVRSRV_POWER_DEV *psPowerDevice;
619
620 SysAcquireData(&psSysData);
621
622
623 if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) ||
624 OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID))
625 {
626 return IMG_FALSE;
627 }
628
629 psPowerDevice = (PVRSRV_POWER_DEV*)
630 List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
631 &MatchPowerDeviceIndex_AnyVaCb,
632 ui32DeviceIndex);
633 return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON))
634 ? IMG_TRUE : IMG_FALSE;
635}
636
637
638PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
639 IMG_BOOL bIdleDevice,
640 IMG_VOID *pvInfo)
641{
642 PVRSRV_ERROR eError = PVRSRV_OK;
643 SYS_DATA *psSysData;
644 PVRSRV_POWER_DEV *psPowerDevice;
645
646 PVR_UNREFERENCED_PARAMETER(pvInfo);
647
648 SysAcquireData(&psSysData);
649
650 if (bIdleDevice)
651 {
652
653 eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
654 if (eError != PVRSRV_OK)
655 {
656 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
657 return eError;
658 }
659 }
660
661
662 psPowerDevice = (PVRSRV_POWER_DEV*)
663 List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
664 &MatchPowerDeviceIndex_AnyVaCb,
665 ui32DeviceIndex);
666
667 if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
668 {
669 eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
670 bIdleDevice,
671 psPowerDevice->eCurrentPowerState);
672 if (eError != PVRSRV_OK)
673 {
674 PVR_DPF((PVR_DBG_ERROR,
675 "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
676 ui32DeviceIndex, eError));
677 }
678 }
679
680 if (bIdleDevice && eError != PVRSRV_OK)
681 {
682 PVRSRVPowerUnlock(KERNEL_ID);
683 }
684
685 return eError;
686}
687
688
689IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
690 IMG_BOOL bIdleDevice,
691 IMG_VOID *pvInfo)
692{
693 PVRSRV_ERROR eError;
694 SYS_DATA *psSysData;
695 PVRSRV_POWER_DEV *psPowerDevice;
696
697 PVR_UNREFERENCED_PARAMETER(pvInfo);
698
699 SysAcquireData(&psSysData);
700
701
702 psPowerDevice = (PVRSRV_POWER_DEV*)
703 List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
704 &MatchPowerDeviceIndex_AnyVaCb,
705 ui32DeviceIndex);
706
707 if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
708 {
709 eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
710 bIdleDevice,
711 psPowerDevice->eCurrentPowerState);
712 if (eError != PVRSRV_OK)
713 {
714 PVR_DPF((PVR_DBG_ERROR,
715 "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
716 ui32DeviceIndex, eError));
717 }
718 }
719
720
721 if (bIdleDevice)
722 {
723
724 PVRSRVPowerUnlock(KERNEL_ID);
725 }
726}
727
diff --git a/drivers/gpu/pvr/power.h b/drivers/gpu/pvr/power.h
new file mode 100644
index 00000000000..079f2128659
--- /dev/null
+++ b/drivers/gpu/pvr/power.h
@@ -0,0 +1,120 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef POWER_H
28#define POWER_H
29
30#if defined(__cplusplus)
31extern "C" {
32#endif
33
34
35
36typedef struct _PVRSRV_POWER_DEV_TAG_
37{
38 PFN_PRE_POWER pfnPrePower;
39 PFN_POST_POWER pfnPostPower;
40 PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange;
41 PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange;
42 IMG_HANDLE hDevCookie;
43 IMG_UINT32 ui32DeviceIndex;
44 PVRSRV_DEV_POWER_STATE eDefaultPowerState;
45 PVRSRV_DEV_POWER_STATE eCurrentPowerState;
46 struct _PVRSRV_POWER_DEV_TAG_ *psNext;
47 struct _PVRSRV_POWER_DEV_TAG_ **ppsThis;
48
49} PVRSRV_POWER_DEV;
50
51typedef enum _PVRSRV_INIT_SERVER_STATE_
52{
53 PVRSRV_INIT_SERVER_Unspecified = -1,
54 PVRSRV_INIT_SERVER_RUNNING = 0,
55 PVRSRV_INIT_SERVER_RAN = 1,
56 PVRSRV_INIT_SERVER_SUCCESSFUL = 2,
57 PVRSRV_INIT_SERVER_NUM = 3,
58 PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff
59
60} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE;
61
62IMG_IMPORT
63IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState);
64
65IMG_IMPORT
66PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState);
67
68
69
70IMG_IMPORT
71PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID,
72 IMG_BOOL bSystemPowerEvent);
73IMG_IMPORT
74IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID);
75
76IMG_IMPORT
77PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex,
78 PVRSRV_DEV_POWER_STATE eNewPowerState,
79 IMG_UINT32 ui32CallerID,
80 IMG_BOOL bRetainMutex);
81
82IMG_IMPORT
83PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
84IMG_IMPORT
85PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
86
87IMG_IMPORT
88PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState);
89
90IMG_IMPORT
91PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex,
92 PFN_PRE_POWER pfnPrePower,
93 PFN_POST_POWER pfnPostPower,
94 PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange,
95 PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange,
96 IMG_HANDLE hDevCookie,
97 PVRSRV_DEV_POWER_STATE eCurrentPowerState,
98 PVRSRV_DEV_POWER_STATE eDefaultPowerState);
99
100IMG_IMPORT
101PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex);
102
103IMG_IMPORT
104IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex);
105
106IMG_IMPORT
107PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
108 IMG_BOOL bIdleDevice,
109 IMG_VOID *pvInfo);
110
111IMG_IMPORT
112IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex,
113 IMG_BOOL bIdleDevice,
114 IMG_VOID *pvInfo);
115
116#if defined (__cplusplus)
117}
118#endif
119#endif
120
diff --git a/drivers/gpu/pvr/private_data.h b/drivers/gpu/pvr/private_data.h
new file mode 100644
index 00000000000..0751765f61f
--- /dev/null
+++ b/drivers/gpu/pvr/private_data.h
@@ -0,0 +1,67 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __INCLUDED_PRIVATE_DATA_H_
28#define __INCLUDED_PRIVATE_DATA_H_
29
30#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
31#include <linux/list.h>
32#include <drm/drmP.h>
33#endif
34
35typedef struct
36{
37
38 IMG_UINT32 ui32OpenPID;
39
40#if defined(PVR_SECURE_FD_EXPORT)
41
42 IMG_HANDLE hKernelMemInfo;
43#endif
44
45#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
46
47 struct list_head sDRMAuthListItem;
48
49 struct drm_file *psDRMFile;
50#endif
51
52#if defined(SUPPORT_MEMINFO_IDS)
53
54 IMG_UINT64 ui64Stamp;
55#endif
56
57
58 IMG_HANDLE hBlockAlloc;
59
60#if defined(SUPPORT_DRI_DRM_EXT)
61 IMG_PVOID pPriv;
62#endif
63}
64PVRSRV_FILE_PRIVATE_DATA;
65
66#endif
67
diff --git a/drivers/gpu/pvr/proc.c b/drivers/gpu/pvr/proc.c
new file mode 100644
index 00000000000..74f313262b8
--- /dev/null
+++ b/drivers/gpu/pvr/proc.c
@@ -0,0 +1,833 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/fs.h>
35#include <linux/proc_fs.h>
36#include <linux/seq_file.h>
37
38#include "services_headers.h"
39
40#include "queue.h"
41#include "resman.h"
42#include "pvrmmap.h"
43#include "pvr_debug.h"
44#include "pvrversion.h"
45#include "proc.h"
46#include "perproc.h"
47#include "env_perproc.h"
48#include "linkage.h"
49
50#include "lists.h"
51
52static struct proc_dir_entry * dir;
53
54static const IMG_CHAR PVRProcDirRoot[] = "pvr";
55
56static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
57static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
58static void pvr_proc_seq_stop (struct seq_file *m, void *v);
59static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
60static int pvr_proc_seq_show (struct seq_file *m, void *v);
61static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
62
63static struct file_operations pvr_proc_operations =
64{
65 .open = pvr_proc_open,
66 .read = seq_read,
67 .write = pvr_proc_write,
68 .llseek = seq_lseek,
69 .release = seq_release,
70};
71
72static struct seq_operations pvr_proc_seq_operations =
73{
74 .start = pvr_proc_seq_start,
75 .next = pvr_proc_seq_next,
76 .stop = pvr_proc_seq_stop,
77 .show = pvr_proc_seq_show,
78};
79
80static struct proc_dir_entry* g_pProcQueue;
81static struct proc_dir_entry* g_pProcVersion;
82static struct proc_dir_entry* g_pProcSysNodes;
83
84#ifdef DEBUG
85static struct proc_dir_entry* g_pProcDebugLevel;
86#endif
87
88#ifdef PVR_MANUAL_POWER_CONTROL
89static struct proc_dir_entry* g_pProcPowerLevel;
90#endif
91
92
93static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
94
95static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
96static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
97
98off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
99{
100 IMG_INT n;
101 size_t space = size - (size_t)off;
102 va_list ap;
103
104 va_start (ap, format);
105
106 n = vsnprintf (buffer+off, space, format, ap);
107
108 va_end (ap);
109
110 if (n >= (IMG_INT)space || n < 0)
111 {
112
113 buffer[size - 1] = 0;
114 return (off_t)(size - 1);
115 }
116 else
117 {
118 return (off + (off_t)n);
119 }
120}
121
122
123void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
124{
125 PVR_UNREFERENCED_PARAMETER(sfile);
126
127 if(!off)
128 return (void*)2;
129 return NULL;
130}
131
132
133void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
134{
135 PVR_UNREFERENCED_PARAMETER(sfile);
136
137 if(!off)
138 {
139 return PVR_PROC_SEQ_START_TOKEN;
140 }
141
142
143 if(off == 1)
144 return (void*)2;
145
146 return NULL;
147}
148
149
150static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
151{
152 IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
153
154 struct seq_file *seq = (struct seq_file*)file->private_data;
155 struct proc_dir_entry* pvr_proc_entry = PDE(inode);
156
157
158 seq->private = pvr_proc_entry->data;
159 return ret;
160}
161
162static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
163 size_t count, loff_t *ppos)
164{
165 struct inode *inode = file->f_path.dentry->d_inode;
166 struct proc_dir_entry * dp;
167
168 PVR_UNREFERENCED_PARAMETER(ppos);
169 dp = PDE(inode);
170
171 if (!dp->write_proc)
172 return -EIO;
173
174 return dp->write_proc(file, buffer, count, dp->data);
175}
176
177
178static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
179{
180 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
181 if(handlers->startstop != NULL)
182 handlers->startstop(proc_seq_file, IMG_TRUE);
183 return handlers->off2element(proc_seq_file, *pos);
184}
185
186static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
187{
188 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
189 PVR_UNREFERENCED_PARAMETER(v);
190
191 if(handlers->startstop != NULL)
192 handlers->startstop(proc_seq_file, IMG_FALSE);
193}
194
195static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
196{
197 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
198 (*pos)++;
199 if( handlers->next != NULL)
200 return handlers->next( proc_seq_file, v, *pos );
201 return handlers->off2element(proc_seq_file, *pos);
202}
203
204static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
205{
206 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
207 handlers->show( proc_seq_file,v );
208 return 0;
209}
210
211
212
213static struct proc_dir_entry* CreateProcEntryInDirSeq(
214 struct proc_dir_entry *pdir,
215 const IMG_CHAR * name,
216 IMG_VOID* data,
217 pvr_next_proc_seq_t next_handler,
218 pvr_show_proc_seq_t show_handler,
219 pvr_off2element_proc_seq_t off2element_handler,
220 pvr_startstop_proc_seq_t startstop_handler,
221 write_proc_t whandler
222 )
223{
224
225 struct proc_dir_entry * file;
226 mode_t mode;
227
228 if (!dir)
229 {
230 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
231 return NULL;
232 }
233
234 mode = S_IFREG;
235
236 if (show_handler)
237 {
238 mode |= S_IRUGO;
239 }
240
241 if (whandler)
242 {
243 mode |= S_IWUSR;
244 }
245
246 file=create_proc_entry(name, mode, pdir);
247
248 if (file)
249 {
250 PVR_PROC_SEQ_HANDLERS *seq_handlers;
251
252#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
253 file->owner = THIS_MODULE;
254#endif
255
256 file->proc_fops = &pvr_proc_operations;
257 file->write_proc = whandler;
258
259
260 file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
261 if(file->data)
262 {
263 seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
264 seq_handlers->next = next_handler;
265 seq_handlers->show = show_handler;
266 seq_handlers->off2element = off2element_handler;
267 seq_handlers->startstop = startstop_handler;
268 seq_handlers->data = data;
269
270 return file;
271 }
272 }
273
274 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
275 return NULL;
276}
277
278
279struct proc_dir_entry* CreateProcReadEntrySeq (
280 const IMG_CHAR * name,
281 IMG_VOID* data,
282 pvr_next_proc_seq_t next_handler,
283 pvr_show_proc_seq_t show_handler,
284 pvr_off2element_proc_seq_t off2element_handler,
285 pvr_startstop_proc_seq_t startstop_handler
286 )
287{
288 return CreateProcEntrySeq(name,
289 data,
290 next_handler,
291 show_handler,
292 off2element_handler,
293 startstop_handler,
294 NULL);
295}
296
297struct proc_dir_entry* CreateProcEntrySeq (
298 const IMG_CHAR * name,
299 IMG_VOID* data,
300 pvr_next_proc_seq_t next_handler,
301 pvr_show_proc_seq_t show_handler,
302 pvr_off2element_proc_seq_t off2element_handler,
303 pvr_startstop_proc_seq_t startstop_handler,
304 write_proc_t whandler
305 )
306{
307 return CreateProcEntryInDirSeq(
308 dir,
309 name,
310 data,
311 next_handler,
312 show_handler,
313 off2element_handler,
314 startstop_handler,
315 whandler
316 );
317}
318
319
320
321struct proc_dir_entry* CreatePerProcessProcEntrySeq (
322 const IMG_CHAR * name,
323 IMG_VOID* data,
324 pvr_next_proc_seq_t next_handler,
325 pvr_show_proc_seq_t show_handler,
326 pvr_off2element_proc_seq_t off2element_handler,
327 pvr_startstop_proc_seq_t startstop_handler,
328 write_proc_t whandler
329 )
330{
331 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
332 IMG_UINT32 ui32PID;
333
334 if (!dir)
335 {
336 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
337 return NULL;
338 }
339
340 ui32PID = OSGetCurrentProcessIDKM();
341
342 psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
343 if (!psPerProc)
344 {
345 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
346
347 return NULL;
348 }
349
350 if (!psPerProc->psProcDir)
351 {
352 IMG_CHAR dirname[16];
353 IMG_INT ret;
354
355 ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
356
357 if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
358 {
359 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
360 return NULL;
361 }
362 else
363 {
364 psPerProc->psProcDir = proc_mkdir(dirname, dir);
365 if (!psPerProc->psProcDir)
366 {
367 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
368 PVRProcDirRoot, ui32PID));
369 return NULL;
370 }
371 }
372 }
373
374 return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
375 show_handler,off2element_handler,startstop_handler,whandler);
376}
377
378
379IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
380{
381 if (dir)
382 {
383 void* data = proc_entry->data ;
384 PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
385
386 remove_proc_entry(proc_entry->name, dir);
387 if( data)
388 kfree( data );
389
390 }
391}
392
393IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
394{
395 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
396
397 psPerProc = LinuxTerminatingProcessPrivateData();
398 if (!psPerProc)
399 {
400 psPerProc = PVRSRVFindPerProcessPrivateData();
401 if (!psPerProc)
402 {
403 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
404 "remove %s, no per process data", proc_entry->name));
405 return;
406 }
407 }
408
409 if (psPerProc->psProcDir)
410 {
411 void* data = proc_entry->data ;
412 PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
413
414 remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
415 if(data)
416 kfree( data );
417 }
418}
419
420static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
421 IMG_INT count, IMG_INT *eof, IMG_VOID *data)
422{
423
424 pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
425
426 off_t len = pprn (page, (size_t)count, off);
427
428 if (len == END_OF_FILE)
429 {
430 len = 0;
431 *eof = 1;
432 }
433 else if (!len)
434 {
435 *start = (IMG_CHAR *) 0;
436 }
437 else
438 {
439 *start = (IMG_CHAR *) 1;
440 }
441
442 return len;
443}
444
445
446static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
447{
448 struct proc_dir_entry * file;
449 mode_t mode;
450
451 if (!pdir)
452 {
453 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
454
455 return -ENOMEM;
456 }
457
458 mode = S_IFREG;
459
460 if (rhandler)
461 {
462 mode |= S_IRUGO;
463 }
464
465 if (whandler)
466 {
467 mode |= S_IWUSR;
468 }
469
470 file = create_proc_entry(name, mode, pdir);
471
472 if (file)
473 {
474#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
475 file->owner = THIS_MODULE;
476#endif
477 file->read_proc = rhandler;
478 file->write_proc = whandler;
479 file->data = data;
480
481 PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
482
483 return 0;
484 }
485
486 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
487
488 return -ENOMEM;
489}
490
491
492IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
493{
494 return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
495}
496
497
498IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
499{
500 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
501 IMG_UINT32 ui32PID;
502
503 if (!dir)
504 {
505 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
506
507 return -ENOMEM;
508 }
509
510 ui32PID = OSGetCurrentProcessIDKM();
511
512 psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
513 if (!psPerProc)
514 {
515 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
516
517 return -ENOMEM;
518 }
519
520 if (!psPerProc->psProcDir)
521 {
522 IMG_CHAR dirname[16];
523 IMG_INT ret;
524
525 ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
526
527 if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
528 {
529 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
530
531 return -ENOMEM;
532 }
533 else
534 {
535 psPerProc->psProcDir = proc_mkdir(dirname, dir);
536 if (!psPerProc->psProcDir)
537 {
538 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
539
540 return -ENOMEM;
541 }
542 }
543 }
544
545 return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
546}
547
548
549IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
550{
551 struct proc_dir_entry * file;
552
553 if (!dir)
554 {
555 PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
556
557 return -ENOMEM;
558 }
559
560
561 file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
562
563 if (file)
564 {
565#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
566 file->owner = THIS_MODULE;
567#endif
568 return 0;
569 }
570
571 PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
572
573 return -ENOMEM;
574}
575
576
577IMG_INT CreateProcEntries(IMG_VOID)
578{
579 dir = proc_mkdir (PVRProcDirRoot, NULL);
580
581 if (!dir)
582 {
583 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot));
584
585 return -ENOMEM;
586 }
587
588 g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
589 g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
590 g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
591
592 if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
593 {
594 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
595
596 return -ENOMEM;
597 }
598
599
600#ifdef DEBUG
601
602 g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
603 ProcSeqShowDebugLevel,
604 ProcSeq1ElementOff2Element, NULL,
605 (IMG_VOID*)PVRDebugProcSetLevel);
606 if(!g_pProcDebugLevel)
607 {
608 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
609
610 return -ENOMEM;
611 }
612
613#ifdef PVR_MANUAL_POWER_CONTROL
614 g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
615 ProcSeqShowPowerLevel,
616 ProcSeq1ElementOff2Element, NULL,
617 PVRProcSetPowerLevel);
618 if(!g_pProcPowerLevel)
619 {
620 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
621
622 return -ENOMEM;
623 }
624#endif
625#endif
626
627 return 0;
628}
629
630
631IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
632{
633 if (dir)
634 {
635 remove_proc_entry(name, dir);
636 PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
637 }
638}
639
640
641IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
642{
643 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
644
645 psPerProc = LinuxTerminatingProcessPrivateData();
646 if (!psPerProc)
647 {
648 psPerProc = PVRSRVFindPerProcessPrivateData();
649 if (!psPerProc)
650 {
651 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
652 "remove %s, no per process data", name));
653 return;
654 }
655 }
656
657 if (psPerProc->psProcDir)
658 {
659 remove_proc_entry(name, psPerProc->psProcDir);
660
661 PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
662 }
663}
664
665
666IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
667{
668 if (psPerProc->psProcDir)
669 {
670 while (psPerProc->psProcDir->subdir)
671 {
672 PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
673
674 RemoveProcEntry(psPerProc->psProcDir->subdir->name);
675 }
676 RemoveProcEntry(psPerProc->psProcDir->name);
677 }
678}
679
680IMG_VOID RemoveProcEntries(IMG_VOID)
681{
682#ifdef DEBUG
683 RemoveProcEntrySeq( g_pProcDebugLevel );
684#ifdef PVR_MANUAL_POWER_CONTROL
685 RemoveProcEntrySeq( g_pProcPowerLevel );
686#endif
687#endif
688
689 RemoveProcEntrySeq(g_pProcQueue);
690 RemoveProcEntrySeq(g_pProcVersion);
691 RemoveProcEntrySeq(g_pProcSysNodes);
692
693 while (dir->subdir)
694 {
695 PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
696
697 RemoveProcEntry(dir->subdir->name);
698 }
699
700 remove_proc_entry(PVRProcDirRoot, NULL);
701}
702
703static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
704{
705 SYS_DATA * psSysData;
706 IMG_CHAR *pszSystemVersionString = "None";
707
708 if(el == PVR_PROC_SEQ_START_TOKEN)
709 {
710 seq_printf( sfile,
711 "Version %s (%s) %s\n",
712 PVRVERSION_STRING,
713 PVR_BUILD_TYPE, PVR_BUILD_DIR);
714 return;
715 }
716
717 SysAcquireData(&psSysData);
718
719 if(psSysData->pszVersionString)
720 {
721 pszSystemVersionString = psSysData->pszVersionString;
722 }
723
724 seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
725}
726
727static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
728{
729 switch (deviceType)
730 {
731 default:
732 {
733 static IMG_CHAR text[10];
734
735 sprintf(text, "?%x", (IMG_UINT)deviceType);
736
737 return text;
738 }
739 }
740}
741
742
743static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
744{
745 switch (deviceClass)
746 {
747 case PVRSRV_DEVICE_CLASS_3D:
748 {
749 return "3D";
750 }
751 case PVRSRV_DEVICE_CLASS_DISPLAY:
752 {
753 return "display";
754 }
755 case PVRSRV_DEVICE_CLASS_BUFFER:
756 {
757 return "buffer";
758 }
759 default:
760 {
761 static IMG_CHAR text[10];
762
763 sprintf(text, "?%x", (IMG_UINT)deviceClass);
764 return text;
765 }
766 }
767}
768
769static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
770{
771 off_t *pOff = va_arg(va, off_t*);
772 if (--(*pOff))
773 {
774 return IMG_NULL;
775 }
776 else
777 {
778 return psNode;
779 }
780}
781
782static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
783{
784 SYS_DATA * psSysData;
785 PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE*)el;
786
787 if(el == PVR_PROC_SEQ_START_TOKEN)
788 {
789 seq_printf( sfile,
790 "Registered nodes\n"
791 "Addr Type Class Index Ref pvDev Size Res\n");
792 return;
793 }
794
795 SysAcquireData(&psSysData);
796
797 seq_printf( sfile,
798 "%p %-8s %-8s %4d %2u %p %3u %p\n",
799 psDevNode,
800 deviceTypeToString(psDevNode->sDevId.eDeviceType),
801 deviceClassToString(psDevNode->sDevId.eDeviceClass),
802 psDevNode->sDevId.eDeviceClass,
803 psDevNode->ui32RefCount,
804 psDevNode->pvDevice,
805 psDevNode->ui32pvDeviceSize,
806 psDevNode->hResManContext);
807
808}
809
810static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
811{
812 SYS_DATA *psSysData;
813 PVRSRV_DEVICE_NODE *psDevNode;
814
815 PVR_UNREFERENCED_PARAMETER(sfile);
816
817 if(!off)
818 {
819 return PVR_PROC_SEQ_START_TOKEN;
820 }
821
822 SysAcquireData(&psSysData);
823
824
825 psDevNode = (PVRSRV_DEVICE_NODE*)
826 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
827 DecOffPsDev_AnyVaCb,
828 &off);
829
830
831 return (void*)psDevNode;
832}
833
diff --git a/drivers/gpu/pvr/proc.h b/drivers/gpu/pvr/proc.h
new file mode 100644
index 00000000000..823b666176b
--- /dev/null
+++ b/drivers/gpu/pvr/proc.h
@@ -0,0 +1,108 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SERVICES_PROC_H__
28#define __SERVICES_PROC_H__
29
30#include <asm/system.h>
31#include <linux/proc_fs.h>
32#include <linux/seq_file.h>
33
34#define END_OF_FILE (off_t) -1
35
36typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t);
37
38
39#define PVR_PROC_SEQ_START_TOKEN (void*)1
40typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t);
41typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t);
42typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*);
43typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start);
44
45typedef struct _PVR_PROC_SEQ_HANDLERS_ {
46 pvr_next_proc_seq_t *next;
47 pvr_show_proc_seq_t *show;
48 pvr_off2element_proc_seq_t *off2element;
49 pvr_startstop_proc_seq_t *startstop;
50 IMG_VOID *data;
51} PVR_PROC_SEQ_HANDLERS;
52
53
54void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off);
55
56void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off);
57
58off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
59 __attribute__((format(printf, 4, 5)));
60
61IMG_INT CreateProcEntries(IMG_VOID);
62
63IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler);
64
65IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
66
67IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
68
69IMG_VOID RemoveProcEntry(const IMG_CHAR * name);
70
71IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name);
72
73IMG_VOID RemoveProcEntries(IMG_VOID);
74
75struct proc_dir_entry* CreateProcReadEntrySeq (
76 const IMG_CHAR* name,
77 IMG_VOID* data,
78 pvr_next_proc_seq_t next_handler,
79 pvr_show_proc_seq_t show_handler,
80 pvr_off2element_proc_seq_t off2element_handler,
81 pvr_startstop_proc_seq_t startstop_handler
82 );
83
84struct proc_dir_entry* CreateProcEntrySeq (
85 const IMG_CHAR* name,
86 IMG_VOID* data,
87 pvr_next_proc_seq_t next_handler,
88 pvr_show_proc_seq_t show_handler,
89 pvr_off2element_proc_seq_t off2element_handler,
90 pvr_startstop_proc_seq_t startstop_handler,
91 write_proc_t whandler
92 );
93
94struct proc_dir_entry* CreatePerProcessProcEntrySeq (
95 const IMG_CHAR* name,
96 IMG_VOID* data,
97 pvr_next_proc_seq_t next_handler,
98 pvr_show_proc_seq_t show_handler,
99 pvr_off2element_proc_seq_t off2element_handler,
100 pvr_startstop_proc_seq_t startstop_handler,
101 write_proc_t whandler
102 );
103
104
105IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry);
106IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry);
107
108#endif
diff --git a/drivers/gpu/pvr/pvr_bridge.h b/drivers/gpu/pvr/pvr_bridge.h
new file mode 100644
index 00000000000..469ceb223cd
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge.h
@@ -0,0 +1,1450 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PVR_BRIDGE_H__
28#define __PVR_BRIDGE_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "servicesint.h"
35
36#ifdef __linux__
37
38 #include <linux/ioctl.h>
39
40 #define PVRSRV_IOC_GID 'g'
41 #define PVRSRV_IO(INDEX) _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
42 #define PVRSRV_IOW(INDEX) _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
43 #define PVRSRV_IOR(INDEX) _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
44 #define PVRSRV_IOWR(INDEX) _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
45
46#else
47
48 #error Unknown platform: Cannot define ioctls
49
50 #define PVRSRV_IO(INDEX) (PVRSRV_IOC_GID + (INDEX))
51 #define PVRSRV_IOW(INDEX) (PVRSRV_IOC_GID + (INDEX))
52 #define PVRSRV_IOR(INDEX) (PVRSRV_IOC_GID + (INDEX))
53 #define PVRSRV_IOWR(INDEX) (PVRSRV_IOC_GID + (INDEX))
54
55 #define PVRSRV_BRIDGE_BASE PVRSRV_IOC_GID
56#endif
57
58
59#define PVRSRV_BRIDGE_CORE_CMD_FIRST 0UL
60#define PVRSRV_BRIDGE_ENUM_DEVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0)
61#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1)
62#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2)
63#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3)
64#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4)
65#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5)
66#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6)
67#define PVRSRV_BRIDGE_FREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7)
68#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8)
69#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9)
70#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10)
71#define PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11)
72#define PVRSRV_BRIDGE_CONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12)
73#define PVRSRV_BRIDGE_DISCONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13)
74#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14)
75#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15)
76#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16)
77#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17)
78#define PVRSRV_BRIDGE_MAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18)
79#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19)
80#define PVRSRV_BRIDGE_MAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20)
81#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21)
82#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22)
83#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23)
84#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24)
85#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25)
86#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26)
87#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
88#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
89
90#define PVRSRV_BRIDGE_SIM_CMD_FIRST (PVRSRV_BRIDGE_CORE_CMD_LAST+1)
91#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0)
92#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1)
93#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
94#define PVRSRV_BRIDGE_SIM_CMD_LAST (PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
95
96#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST (PVRSRV_BRIDGE_SIM_CMD_LAST+1)
97#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0)
98#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1)
99#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
100#define PVRSRV_BRIDGE_MAPPING_CMD_LAST (PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
101
102#define PVRSRV_BRIDGE_STATS_CMD_FIRST (PVRSRV_BRIDGE_MAPPING_CMD_LAST+1)
103#define PVRSRV_BRIDGE_GET_FB_STATS PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
104#define PVRSRV_BRIDGE_STATS_CMD_LAST (PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
105
106#define PVRSRV_BRIDGE_MISC_CMD_FIRST (PVRSRV_BRIDGE_STATS_CMD_LAST+1)
107#define PVRSRV_BRIDGE_GET_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0)
108#define PVRSRV_BRIDGE_RELEASE_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
109#define PVRSRV_BRIDGE_MISC_CMD_LAST (PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
110
111#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
112#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST (PVRSRV_BRIDGE_MISC_CMD_LAST+1)
113#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0)
114#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
115#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
116#else
117#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST PVRSRV_BRIDGE_MISC_CMD_LAST
118#endif
119
120#if defined(PDUMP)
121#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST (PVRSRV_BRIDGE_OVERLAY_CMD_LAST+1)
122#define PVRSRV_BRIDGE_PDUMP_INIT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0)
123#define PVRSRV_BRIDGE_PDUMP_MEMPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1)
124#define PVRSRV_BRIDGE_PDUMP_DUMPMEM PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2)
125#define PVRSRV_BRIDGE_PDUMP_REG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3)
126#define PVRSRV_BRIDGE_PDUMP_REGPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4)
127#define PVRSRV_BRIDGE_PDUMP_COMMENT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5)
128#define PVRSRV_BRIDGE_PDUMP_SETFRAME PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6)
129#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7)
130#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8)
131#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9)
132#define PVRSRV_BRIDGE_PDUMP_SYNCPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10)
133#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11)
134#define PVRSRV_BRIDGE_PDUMP_MEMPAGES PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12)
135#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13)
136#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15)
137#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16)
138#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17)
139#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
140#define PVRSRV_BRIDGE_PDUMP_CMD_LAST (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
141#else
142#define PVRSRV_BRIDGE_PDUMP_CMD_LAST PVRSRV_BRIDGE_OVERLAY_CMD_LAST
143#endif
144
145#define PVRSRV_BRIDGE_OEM_CMD_FIRST (PVRSRV_BRIDGE_PDUMP_CMD_LAST+1)
146#define PVRSRV_BRIDGE_GET_OEMJTABLE PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
147#define PVRSRV_BRIDGE_OEM_CMD_LAST (PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
148
149#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST (PVRSRV_BRIDGE_OEM_CMD_LAST+1)
150#define PVRSRV_BRIDGE_ENUM_CLASS PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
151#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST (PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
152
153#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST (PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1)
154#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0)
155#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1)
156#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2)
157#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3)
158#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4)
159#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5)
160#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6)
161#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7)
162#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8)
163#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9)
164#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10)
165#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11)
166#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12)
167#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13)
168#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
169#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
170
171
172#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST (PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1)
173#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0)
174#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1)
175#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2)
176#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
177#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST (PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
178
179#define PVRSRV_BRIDGE_WRAP_CMD_FIRST (PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1)
180#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0)
181#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
182#define PVRSRV_BRIDGE_WRAP_CMD_LAST (PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
183
184#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST (PVRSRV_BRIDGE_WRAP_CMD_LAST+1)
185#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0)
186#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1)
187#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2)
188#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
189#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
190
191#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
192#define PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
193#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
194
195#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST+1)
196#define PVRSRV_BRIDGE_INITSRV_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0)
197#define PVRSRV_BRIDGE_INITSRV_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
198#define PVRSRV_BRIDGE_INITSRV_CMD_LAST (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
199
200#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1)
201#define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0)
202#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1)
203#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
204#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
205
206#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1)
207#define PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0)
208#define PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
209#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+2)
210#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+3)
211#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+4)
212#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+5)
213#define PVRSRV_BRIDGE_ALLOC_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+6)
214#define PVRSRV_BRIDGE_FREE_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7)
215#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7)
216
217#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1)
218
219
220#define PVRSRV_KERNEL_MODE_CLIENT 1
221
222typedef struct PVRSRV_BRIDGE_RETURN_TAG
223{
224 PVRSRV_ERROR eError;
225 IMG_VOID *pvData;
226
227}PVRSRV_BRIDGE_RETURN;
228
229
230typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
231{
232 IMG_UINT32 ui32BridgeID;
233 IMG_UINT32 ui32Size;
234 IMG_VOID *pvParamIn;
235 IMG_UINT32 ui32InBufferSize;
236 IMG_VOID *pvParamOut;
237 IMG_UINT32 ui32OutBufferSize;
238
239 IMG_HANDLE hKernelServices;
240}PVRSRV_BRIDGE_PACKAGE;
241
242
243
244
245
246
247typedef struct PVRSRV_BRIDGE_IN_CONNECT_SERVICES_TAG
248{
249 IMG_UINT32 ui32Flags;
250} PVRSRV_BRIDGE_IN_CONNECT_SERVICES;
251
252typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG
253{
254 IMG_UINT32 ui32BridgeFlags;
255 IMG_UINT32 uiDevIndex;
256 PVRSRV_DEVICE_TYPE eDeviceType;
257
258} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO;
259
260
261typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG
262{
263 IMG_UINT32 ui32BridgeFlags;
264 PVRSRV_DEVICE_CLASS sDeviceClass;
265} PVRSRV_BRIDGE_IN_ENUMCLASS;
266
267
268typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG
269{
270 IMG_UINT32 ui32BridgeFlags;
271 IMG_HANDLE hDeviceKM;
272} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE;
273
274
275typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG
276{
277 IMG_UINT32 ui32BridgeFlags;
278 IMG_HANDLE hDeviceKM;
279} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS;
280
281
282typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG
283{
284 IMG_UINT32 ui32BridgeFlags;
285 IMG_HANDLE hDeviceKM;
286} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER;
287
288
289typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG
290{
291 IMG_UINT32 ui32BridgeFlags;
292 IMG_HANDLE hDeviceKM;
293} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO;
294
295
296typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG
297{
298 IMG_UINT32 ui32BridgeFlags;
299 IMG_HANDLE hDeviceKM;
300} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE;
301
302
303typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG
304{
305 IMG_UINT32 ui32BridgeFlags;
306 IMG_HANDLE hDeviceKM;
307} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO;
308
309
310
311typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG
312{
313 IMG_UINT32 ui32BridgeFlags;
314 IMG_HANDLE hDevCookie;
315
316} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO;
317
318
319
320typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG
321{
322 IMG_UINT32 ui32BridgeFlags;
323 PVRSRV_DEVICE_CLASS DeviceClass;
324 IMG_VOID* pvDevInfo;
325
326}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO;
327
328
329
330typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG
331{
332 IMG_UINT32 ui32BridgeFlags;
333 IMG_HANDLE hDevCookie;
334 IMG_HANDLE hDevMemContext;
335
336}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO;
337
338
339
340typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG
341{
342 IMG_UINT32 ui32BridgeFlags;
343 IMG_HANDLE hDevCookie;
344
345}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT;
346
347
348
349typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG
350{
351 IMG_UINT32 ui32BridgeFlags;
352 IMG_HANDLE hDevCookie;
353 IMG_HANDLE hDevMemContext;
354
355}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT;
356
357
358
359typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG
360{
361 IMG_UINT32 ui32BridgeFlags;
362 IMG_HANDLE hDevCookie;
363 IMG_HANDLE hDevMemHeap;
364 IMG_UINT32 ui32Attribs;
365 IMG_SIZE_T ui32Size;
366 IMG_SIZE_T ui32Alignment;
367
368}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM;
369
370
371typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG
372{
373 IMG_UINT32 ui32BridgeFlags;
374 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
375
376}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER;
377
378
379typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG
380{
381 IMG_UINT32 ui32BridgeFlags;
382 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
383 IMG_PVOID pvLinAddr;
384 IMG_HANDLE hMappingInfo;
385
386}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER;
387
388
389typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG
390{
391 IMG_UINT32 ui32BridgeFlags;
392 IMG_HANDLE hDevCookie;
393 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
394 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
395
396}PVRSRV_BRIDGE_IN_FREEDEVICEMEM;
397
398
399typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG
400{
401 IMG_UINT32 ui32BridgeFlags;
402 IMG_HANDLE hDevCookie;
403 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
404
405}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM;
406
407
408typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG
409{
410 IMG_UINT32 ui32BridgeFlags;
411 IMG_UINT32 ui32Flags;
412
413} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM;
414
415
416typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG
417{
418 IMG_UINT32 ui32BridgeFlags;
419 IMG_HANDLE hDevCookie;
420 IMG_SIZE_T ui32QueueSize;
421
422}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE;
423
424
425
426typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG
427{
428 IMG_UINT32 ui32BridgeFlags;
429 IMG_HANDLE hDevCookie;
430 PVRSRV_QUEUE_INFO *psQueueInfo;
431
432}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE;
433
434
435
436typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG
437{
438 IMG_UINT32 ui32BridgeFlags;
439 IMG_HANDLE hMHandle;
440} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA;
441
442
443
444typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG
445{
446 IMG_UINT32 ui32BridgeFlags;
447 IMG_HANDLE hMHandle;
448} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA;
449
450
451
452typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG
453{
454 IMG_UINT32 ui32BridgeFlags;
455 IMG_HANDLE hDevMemHeap;
456 IMG_DEV_VIRTADDR *psDevVAddr;
457 IMG_SIZE_T ui32Size;
458 IMG_SIZE_T ui32Alignment;
459
460}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM;
461
462
463typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG
464{
465 PVRSRV_ERROR eError;
466 IMG_HANDLE hKernelServices;
467}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES;
468
469
470typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG
471{
472 PVRSRV_ERROR eError;
473 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
474 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
475 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
476 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
477
478}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM;
479
480
481
482typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG
483{
484 IMG_UINT32 ui32BridgeFlags;
485 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
486 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
487 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
488
489}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM;
490
491
492
493typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG
494{
495 IMG_UINT32 ui32BridgeFlags;
496 IMG_HANDLE hKernelMemInfo;
497 IMG_HANDLE hDstDevMemHeap;
498
499}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY;
500
501
502
503typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG
504{
505 PVRSRV_ERROR eError;
506 PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo;
507 PVRSRV_CLIENT_MEM_INFO sDstClientMemInfo;
508 PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo;
509
510}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY;
511
512
513
514typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG
515{
516 IMG_UINT32 ui32BridgeFlags;
517 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
518 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
519 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
520
521}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY;
522
523
524
525typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG
526{
527 IMG_UINT32 ui32BridgeFlags;
528 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
529 IMG_SYS_PHYADDR *psSysPAddr;
530 IMG_UINT32 ui32Flags;
531
532}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY;
533
534
535typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG
536{
537 IMG_UINT32 ui32BridgeFlags;
538 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
539 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
540 IMG_UINT32 ui32Flags;
541
542}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY;
543
544
545typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG
546{
547 IMG_UINT32 ui32BridgeFlags;
548 IMG_HANDLE hDeviceClassBuffer;
549 IMG_HANDLE hDevMemContext;
550
551}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY;
552
553
554
555typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG
556{
557 PVRSRV_ERROR eError;
558 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
559 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
560 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
561 IMG_HANDLE hMappingInfo;
562
563}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY;
564
565
566
567typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG
568{
569 IMG_UINT32 ui32BridgeFlags;
570 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
571 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
572 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
573
574}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY;
575
576
577
578typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG
579{
580 IMG_UINT32 ui32BridgeFlags;
581 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
582 IMG_UINT32 ui32Offset;
583 IMG_UINT32 ui32Value;
584 IMG_UINT32 ui32Mask;
585 PDUMP_POLL_OPERATOR eOperator;
586 IMG_UINT32 ui32Flags;
587
588}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL;
589
590
591typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG
592{
593 IMG_UINT32 ui32BridgeFlags;
594 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
595 IMG_BOOL bIsRead;
596 IMG_UINT32 ui32Value;
597 IMG_UINT32 ui32Mask;
598
599}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL;
600
601
602
603typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG
604{
605 IMG_UINT32 ui32BridgeFlags;
606 IMG_PVOID pvLinAddr;
607 IMG_PVOID pvAltLinAddr;
608 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
609 IMG_UINT32 ui32Offset;
610 IMG_UINT32 ui32Bytes;
611 IMG_UINT32 ui32Flags;
612
613}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM;
614
615
616
617typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG
618{
619 IMG_UINT32 ui32BridgeFlags;
620 IMG_PVOID pvAltLinAddr;
621 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
622 IMG_UINT32 ui32Offset;
623 IMG_UINT32 ui32Bytes;
624
625}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC;
626
627
628
629typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG
630{
631 IMG_UINT32 ui32BridgeFlags;
632 IMG_HANDLE hDevCookie;
633 PVRSRV_HWREG sHWReg;
634 IMG_UINT32 ui32Flags;
635 IMG_CHAR szRegRegion[32];
636
637}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG;
638
639
640typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG
641{
642 IMG_UINT32 ui32BridgeFlags;
643 IMG_HANDLE hDevCookie;
644 PVRSRV_HWREG sHWReg;
645 IMG_UINT32 ui32Mask;
646 IMG_UINT32 ui32Flags;
647 IMG_CHAR szRegRegion[32];
648}PVRSRV_BRIDGE_IN_PDUMP_REGPOL;
649
650
651typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG
652{
653 IMG_UINT32 ui32BridgeFlags;
654 PVRSRV_HWREG sHWReg;
655 IMG_UINT32 ui32Flags;
656
657}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG;
658
659
660typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG
661{
662 IMG_UINT32 ui32BridgeFlags;
663 IMG_HANDLE hKernelMemInfo;
664 IMG_DEV_PHYADDR *pPages;
665 IMG_UINT32 ui32NumPages;
666 IMG_DEV_VIRTADDR sDevAddr;
667 IMG_UINT32 ui32Start;
668 IMG_UINT32 ui32Length;
669 IMG_BOOL bContinuous;
670
671}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES;
672
673
674typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG
675{
676 IMG_UINT32 ui32BridgeFlags;
677 IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
678 IMG_UINT32 ui32Flags;
679
680}PVRSRV_BRIDGE_IN_PDUMP_COMMENT;
681
682
683
684typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG
685{
686 IMG_UINT32 ui32BridgeFlags;
687 IMG_UINT32 ui32Frame;
688
689}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME;
690
691
692
693
694typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG
695{
696 IMG_UINT32 ui32BridgeFlags;
697 IMG_HANDLE hDevCookie;
698 IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
699 IMG_UINT32 ui32FileOffset;
700 IMG_UINT32 ui32Width;
701 IMG_UINT32 ui32Height;
702 IMG_UINT32 ui32StrideInBytes;
703 IMG_DEV_VIRTADDR sDevBaseAddr;
704 IMG_HANDLE hDevMemContext;
705 IMG_UINT32 ui32Size;
706 PDUMP_PIXEL_FORMAT ePixelFormat;
707 PDUMP_MEM_FORMAT eMemFormat;
708 IMG_UINT32 ui32Flags;
709
710}PVRSRV_BRIDGE_IN_PDUMP_BITMAP;
711
712
713
714typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG
715{
716 IMG_UINT32 ui32BridgeFlags;
717 IMG_HANDLE hDevCookie;
718 IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
719 IMG_UINT32 ui32FileOffset;
720 IMG_UINT32 ui32Address;
721 IMG_UINT32 ui32Size;
722 IMG_UINT32 ui32Flags;
723 IMG_CHAR szRegRegion[32];
724
725}PVRSRV_BRIDGE_IN_PDUMP_READREG;
726
727
728typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG
729{
730 IMG_UINT32 ui32BridgeFlags;
731 IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
732 IMG_BOOL bContinuous;
733
734}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO;
735
736typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG
737{
738 IMG_UINT32 ui32BridgeFlags;
739 IMG_HANDLE hKernelMemInfo;
740 IMG_UINT32 ui32Offset;
741 IMG_DEV_PHYADDR sPDDevPAddr;
742}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR;
743
744
745typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG
746{
747 IMG_UINT32 ui32BridgeFlags;
748 IMG_HANDLE hDevCookie;
749 IMG_UINT32 ui32RegOffset;
750 IMG_BOOL bLastFrame;
751}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ;
752
753
754typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG
755{
756 PVRSRV_ERROR eError;
757 IMG_UINT32 ui32NumDevices;
758 PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES];
759
760}PVRSRV_BRIDGE_OUT_ENUMDEVICE;
761
762
763
764typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG
765{
766
767 PVRSRV_ERROR eError;
768 IMG_HANDLE hDevCookie;
769
770} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO;
771
772
773
774typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG
775{
776 PVRSRV_ERROR eError;
777 IMG_UINT32 ui32NumDevices;
778 IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES];
779
780}PVRSRV_BRIDGE_OUT_ENUMCLASS;
781
782
783
784typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG
785{
786 IMG_UINT32 ui32BridgeFlags;
787 IMG_UINT32 ui32DeviceID;
788 IMG_HANDLE hDevCookie;
789
790}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE;
791
792
793typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG
794{
795 PVRSRV_ERROR eError;
796 IMG_HANDLE hDeviceKM;
797
798}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE;
799
800
801
802typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG
803{
804 IMG_UINT32 ui32BridgeFlags;
805 IMG_HANDLE hDevCookie;
806 IMG_HANDLE hDevMemContext;
807 IMG_VOID *pvLinAddr;
808 IMG_SIZE_T ui32ByteSize;
809 IMG_SIZE_T ui32PageOffset;
810 IMG_BOOL bPhysContig;
811 IMG_UINT32 ui32NumPageTableEntries;
812 IMG_SYS_PHYADDR *psSysPAddr;
813 IMG_UINT32 ui32Flags;
814
815}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY;
816
817
818typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG
819{
820 PVRSRV_ERROR eError;
821 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
822 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
823
824}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY;
825
826
827typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG
828{
829 IMG_UINT32 ui32BridgeFlags;
830 IMG_HANDLE hKernelMemInfo;
831 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
832 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
833
834}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY;
835
836
837#define PVRSRV_MAX_DC_DISPLAY_FORMATS 10
838#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS 10
839#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS 4
840#define PVRSRV_MAX_DC_CLIP_RECTS 32
841
842
843typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG
844{
845 PVRSRV_ERROR eError;
846 IMG_UINT32 ui32Count;
847 DISPLAY_FORMAT asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS];
848
849}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS;
850
851
852
853typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG
854{
855 IMG_UINT32 ui32BridgeFlags;
856 IMG_HANDLE hDeviceKM;
857 DISPLAY_FORMAT sFormat;
858
859}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS;
860
861
862
863typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG
864{
865 PVRSRV_ERROR eError;
866 IMG_UINT32 ui32Count;
867 DISPLAY_DIMS asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS];
868
869}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS;
870
871
872
873typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG
874{
875 PVRSRV_ERROR eError;
876 DISPLAY_INFO sDisplayInfo;
877
878}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO;
879
880
881
882typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG
883{
884 PVRSRV_ERROR eError;
885 IMG_HANDLE hBuffer;
886
887}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER;
888
889
890
891typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG
892{
893 IMG_UINT32 ui32BridgeFlags;
894 IMG_HANDLE hDeviceKM;
895 IMG_UINT32 ui32Flags;
896 DISPLAY_SURF_ATTRIBUTES sDstSurfAttrib;
897 DISPLAY_SURF_ATTRIBUTES sSrcSurfAttrib;
898 IMG_UINT32 ui32BufferCount;
899 IMG_UINT32 ui32OEMFlags;
900 IMG_UINT32 ui32SwapChainID;
901
902} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN;
903
904
905
906typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG
907{
908 PVRSRV_ERROR eError;
909 IMG_HANDLE hSwapChain;
910 IMG_UINT32 ui32SwapChainID;
911
912} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN;
913
914
915
916typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG
917{
918 IMG_UINT32 ui32BridgeFlags;
919 IMG_HANDLE hDeviceKM;
920 IMG_HANDLE hSwapChain;
921
922} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN;
923
924
925
926typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG
927{
928 IMG_UINT32 ui32BridgeFlags;
929 IMG_HANDLE hDeviceKM;
930 IMG_HANDLE hSwapChain;
931 IMG_RECT sRect;
932
933} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT;
934
935
936
937typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG
938{
939 IMG_UINT32 ui32BridgeFlags;
940 IMG_HANDLE hDeviceKM;
941 IMG_HANDLE hSwapChain;
942 IMG_UINT32 ui32CKColour;
943
944} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY;
945
946
947
948typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG
949{
950 IMG_UINT32 ui32BridgeFlags;
951 IMG_HANDLE hDeviceKM;
952 IMG_HANDLE hSwapChain;
953
954} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS;
955
956
957
958typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG
959{
960 PVRSRV_ERROR eError;
961 IMG_UINT32 ui32BufferCount;
962 IMG_HANDLE ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
963
964} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS;
965
966
967
968typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG
969{
970 IMG_UINT32 ui32BridgeFlags;
971 IMG_HANDLE hDeviceKM;
972 IMG_HANDLE hBuffer;
973 IMG_UINT32 ui32SwapInterval;
974 IMG_HANDLE hPrivateTag;
975 IMG_UINT32 ui32ClipRectCount;
976 IMG_RECT sClipRect[PVRSRV_MAX_DC_CLIP_RECTS];
977
978} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER;
979
980
981
982typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG
983{
984 IMG_UINT32 ui32BridgeFlags;
985 IMG_HANDLE hDeviceKM;
986 IMG_HANDLE hSwapChain;
987
988} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM;
989
990
991
992typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG
993{
994 IMG_UINT32 ui32BridgeFlags;
995 IMG_UINT32 ui32DeviceID;
996 IMG_HANDLE hDevCookie;
997
998} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE;
999
1000
1001
1002typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG
1003{
1004 PVRSRV_ERROR eError;
1005 IMG_HANDLE hDeviceKM;
1006
1007} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE;
1008
1009
1010
1011typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG
1012{
1013 PVRSRV_ERROR eError;
1014 BUFFER_INFO sBufferInfo;
1015
1016} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO;
1017
1018
1019
1020typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG
1021{
1022 IMG_UINT32 ui32BridgeFlags;
1023 IMG_HANDLE hDeviceKM;
1024 IMG_UINT32 ui32BufferIndex;
1025
1026} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER;
1027
1028
1029
1030typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG
1031{
1032 PVRSRV_ERROR eError;
1033 IMG_HANDLE hBuffer;
1034
1035} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER;
1036
1037
1038
1039typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG
1040{
1041 PVRSRV_ERROR eError;
1042 IMG_UINT32 ui32ClientHeapCount;
1043 PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
1044
1045} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO;
1046
1047
1048
1049typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG
1050{
1051 PVRSRV_ERROR eError;
1052 IMG_HANDLE hDevMemContext;
1053 IMG_UINT32 ui32ClientHeapCount;
1054 PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
1055
1056} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT;
1057
1058
1059
1060typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG
1061{
1062 PVRSRV_ERROR eError;
1063 IMG_HANDLE hDevMemHeap;
1064
1065} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP;
1066
1067
1068
1069typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG
1070{
1071 PVRSRV_ERROR eError;
1072 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1073 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
1074 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
1075
1076} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM;
1077
1078
1079
1080typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG
1081{
1082 PVRSRV_ERROR eError;
1083 IMG_HANDLE hMemInfo;
1084#if defined(SUPPORT_MEMINFO_IDS)
1085 IMG_UINT64 ui64Stamp;
1086#endif
1087
1088} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM;
1089
1090
1091typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG
1092{
1093 PVRSRV_ERROR eError;
1094 IMG_PVOID pvLinAddr;
1095 IMG_HANDLE hMappingInfo;
1096
1097}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER;
1098
1099
1100
1101typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG
1102{
1103 PVRSRV_ERROR eError;
1104 IMG_SIZE_T ui32Total;
1105 IMG_SIZE_T ui32Free;
1106 IMG_SIZE_T ui32LargestBlock;
1107
1108} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM;
1109
1110
1111#include "pvrmmap.h"
1112typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG
1113{
1114 PVRSRV_ERROR eError;
1115
1116
1117 IMG_UINT32 ui32MMapOffset;
1118
1119
1120 IMG_UINT32 ui32ByteOffset;
1121
1122
1123 IMG_UINT32 ui32RealByteSize;
1124
1125
1126 IMG_UINT32 ui32UserVAddr;
1127
1128} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA;
1129
1130typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG
1131{
1132 PVRSRV_ERROR eError;
1133
1134
1135 IMG_BOOL bMUnmap;
1136
1137
1138 IMG_UINT32 ui32UserVAddr;
1139
1140
1141 IMG_UINT32 ui32RealByteSize;
1142} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA;
1143
1144typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG
1145{
1146 IMG_UINT32 ui32BridgeFlags;
1147 PVRSRV_MISC_INFO sMiscInfo;
1148
1149}PVRSRV_BRIDGE_IN_GET_MISC_INFO;
1150
1151
1152
1153typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG
1154{
1155 PVRSRV_ERROR eError;
1156 PVRSRV_MISC_INFO sMiscInfo;
1157
1158}PVRSRV_BRIDGE_OUT_GET_MISC_INFO;
1159
1160
1161
1162typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG
1163{
1164 IMG_UINT32 ui32BridgeFlags;
1165 PVRSRV_MISC_INFO sMiscInfo;
1166
1167}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO;
1168
1169
1170
1171typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG
1172{
1173 PVRSRV_ERROR eError;
1174 PVRSRV_MISC_INFO sMiscInfo;
1175
1176}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO;
1177
1178
1179
1180
1181typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG
1182{
1183 PVRSRV_ERROR eError;
1184 IMG_BOOL bIsCapturing;
1185
1186} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING;
1187
1188
1189typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG
1190{
1191 IMG_UINT32 ui32BridgeFlags;
1192 IMG_SIZE_T ui32Total;
1193 IMG_SIZE_T ui32Available;
1194
1195} PVRSRV_BRIDGE_IN_GET_FB_STATS;
1196
1197
1198
1199typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG
1200{
1201 IMG_UINT32 ui32BridgeFlags;
1202 IMG_HANDLE hDevCookie;
1203 IMG_SYS_PHYADDR sSysPhysAddr;
1204 IMG_UINT32 uiSizeInBytes;
1205
1206} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE;
1207
1208
1209
1210typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG
1211{
1212 IMG_PVOID pvUserAddr;
1213 IMG_UINT32 uiActualSize;
1214 IMG_PVOID pvProcess;
1215
1216} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE;
1217
1218
1219
1220typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG
1221{
1222 IMG_UINT32 ui32BridgeFlags;
1223 IMG_HANDLE hDevCookie;
1224 IMG_PVOID pvUserAddr;
1225 IMG_PVOID pvProcess;
1226
1227} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE;
1228
1229
1230
1231typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG
1232{
1233 IMG_PVOID *ppvTbl;
1234 IMG_UINT32 uiTblSize;
1235
1236} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP;
1237
1238
1239
1240typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG
1241{
1242 IMG_UINT32 ui32BridgeFlags;
1243 IMG_HANDLE hDevCookie;
1244 IMG_PVOID pvProcess;
1245
1246} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS;
1247
1248
1249typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG
1250{
1251 IMG_SYS_PHYADDR sRegsPhysBase;
1252 IMG_VOID *pvRegsBase;
1253 IMG_PVOID pvProcess;
1254 IMG_UINT32 ulNoOfEntries;
1255 IMG_PVOID pvTblLinAddr;
1256
1257} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS;
1258
1259
1260typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG
1261{
1262 IMG_UINT32 ui32BridgeFlags;
1263 IMG_HANDLE hDevCookie;
1264 IMG_PVOID pvProcess;
1265 IMG_VOID *pvRegsBase;
1266
1267} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS;
1268
1269typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG
1270{
1271 IMG_UINT32 ui32BridgeFlags;
1272 IMG_HANDLE hDevCookie;
1273 IMG_UINT32 ui32StatusAndMask;
1274 PVRSRV_ERROR eError;
1275
1276} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT;
1277
1278typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG
1279{
1280 IMG_UINT32 ui32BridgeFlags;
1281 IMG_BOOL bInitSuccesful;
1282} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT;
1283
1284
1285typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG
1286{
1287 IMG_UINT32 ui32BridgeFlags;
1288 IMG_UINT32 ui32Flags;
1289 IMG_SIZE_T ui32Size;
1290}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM;
1291
1292typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG
1293{
1294 PVRSRV_ERROR eError;
1295 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1296 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
1297}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM;
1298
1299typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG
1300{
1301 IMG_UINT32 ui32BridgeFlags;
1302 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1303 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
1304}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM;
1305
1306typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG
1307{
1308 PVRSRV_ERROR eError;
1309}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM;
1310
1311typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG
1312{
1313 IMG_UINT32 ui32BridgeFlags;
1314 IMG_HANDLE hKernelMemInfo;
1315}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM;
1316
1317typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG
1318{
1319 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
1320 PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
1321 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1322 PVRSRV_ERROR eError;
1323}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM;
1324
1325typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG
1326{
1327 IMG_UINT32 ui32BridgeFlags;
1328 PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
1329}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM;
1330
1331typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG
1332{
1333 PVRSRV_ERROR eError;
1334}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM;
1335
1336typedef struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR_TAG
1337{
1338 IMG_UINT32 ui32BridgeFlags;
1339 IMG_HANDLE hDevMemContext;
1340}PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR;
1341
1342typedef struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR_TAG
1343{
1344 IMG_DEV_PHYADDR sPDDevPAddr;
1345 PVRSRV_ERROR eError;
1346}PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR;
1347
1348typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG
1349{
1350 IMG_UINT32 ui32BridgeFlags;
1351 IMG_HANDLE hOSEventKM;
1352} PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT;
1353
1354typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG
1355{
1356 PVRSRV_EVENTOBJECT sEventObject;
1357} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN;
1358
1359typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG
1360{
1361 IMG_HANDLE hOSEvent;
1362 PVRSRV_ERROR eError;
1363} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN;
1364
1365typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG
1366{
1367 PVRSRV_EVENTOBJECT sEventObject;
1368 IMG_HANDLE hOSEventKM;
1369} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE;
1370
1371typedef struct PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ_TAG
1372{
1373 PVRSRV_ERROR eError;
1374
1375 IMG_HANDLE hKernelSyncInfoModObj;
1376
1377} PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ;
1378
1379typedef struct PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ
1380{
1381 IMG_UINT32 ui32BridgeFlags;
1382 IMG_HANDLE hKernelSyncInfoModObj;
1383} PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ;
1384
1385typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG
1386{
1387 IMG_UINT32 ui32BridgeFlags;
1388 IMG_HANDLE hKernelSyncInfoModObj;
1389 IMG_HANDLE hKernelSyncInfo;
1390 IMG_UINT32 ui32ModifyFlags;
1391
1392} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS;
1393
1394typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG
1395{
1396 IMG_UINT32 ui32BridgeFlags;
1397 IMG_HANDLE hKernelSyncInfoModObj;
1398} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS;
1399
1400typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG
1401{
1402 PVRSRV_ERROR eError;
1403
1404
1405 IMG_UINT32 ui32ReadOpsPending;
1406 IMG_UINT32 ui32WriteOpsPending;
1407
1408} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS;
1409
1410typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ_TAG
1411{
1412 IMG_UINT32 ui32BridgeFlags;
1413 IMG_HANDLE hKernelSyncInfoModObj;
1414} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ;
1415
1416typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA_TAG
1417{
1418 IMG_UINT32 ui32BridgeFlags;
1419 IMG_HANDLE hKernelSyncInfo;
1420 IMG_UINT32 ui32Delta;
1421} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA;
1422
1423typedef struct PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO_TAG
1424{
1425 IMG_UINT32 ui32BridgeFlags;
1426
1427 IMG_HANDLE hDevCookie;
1428} PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO;
1429
1430typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO_TAG
1431{
1432 PVRSRV_ERROR eError;
1433
1434 IMG_HANDLE hKernelSyncInfo;
1435} PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO;
1436
1437typedef struct PVRSRV_BRIDGE_IN_FREE_SYNC_INFO_TAG
1438{
1439 IMG_UINT32 ui32BridgeFlags;
1440
1441 IMG_HANDLE hKernelSyncInfo;
1442} PVRSRV_BRIDGE_IN_FREE_SYNC_INFO;
1443
1444
1445#if defined (__cplusplus)
1446}
1447#endif
1448
1449#endif
1450
diff --git a/drivers/gpu/pvr/pvr_bridge_k.c b/drivers/gpu/pvr/pvr_bridge_k.c
new file mode 100644
index 00000000000..81a0201113b
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge_k.c
@@ -0,0 +1,570 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "img_defs.h"
28#include "services.h"
29#include "pvr_bridge.h"
30#include "perproc.h"
31#include "mutex.h"
32#include "syscommon.h"
33#include "pvr_debug.h"
34#include "proc.h"
35#include "private_data.h"
36#include "linkage.h"
37#include "pvr_bridge_km.h"
38
39#if defined(SUPPORT_DRI_DRM)
40#include <drm/drmP.h>
41#include "pvr_drm.h"
42#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
43#include "env_perproc.h"
44#endif
45#endif
46
47#if defined(SUPPORT_VGX)
48#include "vgx_bridge.h"
49#endif
50
51#if defined(SUPPORT_SGX)
52#include "sgx_bridge.h"
53#endif
54
55#include "bridged_pvr_bridge.h"
56
57#ifdef MODULE_TEST
58#include "pvr_test_bridge.h"
59#include "kern_test.h"
60#endif
61
62
63#if defined(SUPPORT_DRI_DRM)
64#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
65#else
66#define PRIVATE_DATA(pFile) ((pFile)->private_data)
67#endif
68
69#if defined(DEBUG_BRIDGE_KM)
70
71static struct proc_dir_entry *g_ProcBridgeStats =0;
72static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off);
73static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el);
74static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off);
75static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start);
76
77#endif
78
79extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
80
81#if defined(SUPPORT_MEMINFO_IDS)
82static IMG_UINT64 ui64Stamp;
83#endif
84
85PVRSRV_ERROR
86LinuxBridgeInit(IMG_VOID)
87{
88#if defined(DEBUG_BRIDGE_KM)
89 {
90 g_ProcBridgeStats = CreateProcReadEntrySeq(
91 "bridge_stats",
92 NULL,
93 ProcSeqNextBridgeStats,
94 ProcSeqShowBridgeStats,
95 ProcSeqOff2ElementBridgeStats,
96 ProcSeqStartstopBridgeStats
97 );
98 if(!g_ProcBridgeStats)
99 {
100 return PVRSRV_ERROR_OUT_OF_MEMORY;
101 }
102 }
103#endif
104 return CommonBridgeInit();
105}
106
107IMG_VOID
108LinuxBridgeDeInit(IMG_VOID)
109{
110#if defined(DEBUG_BRIDGE_KM)
111 RemoveProcEntrySeq(g_ProcBridgeStats);
112#endif
113}
114
115#if defined(DEBUG_BRIDGE_KM)
116
117static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start)
118{
119 if(start)
120 {
121 LinuxLockMutex(&gPVRSRVLock);
122 }
123 else
124 {
125 LinuxUnLockMutex(&gPVRSRVLock);
126 }
127}
128
129
130static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off)
131{
132 if(!off)
133 {
134 return PVR_PROC_SEQ_START_TOKEN;
135 }
136
137 if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
138 {
139 return (void*)0;
140 }
141
142
143 return (void*)&g_BridgeDispatchTable[off-1];
144}
145
146static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off)
147{
148 return ProcSeqOff2ElementBridgeStats(sfile,off);
149}
150
151
152static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el)
153{
154 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el;
155
156 if(el == PVR_PROC_SEQ_START_TOKEN)
157 {
158 seq_printf(sfile,
159 "Total ioctl call count = %u\n"
160 "Total number of bytes copied via copy_from_user = %u\n"
161 "Total number of bytes copied via copy_to_user = %u\n"
162 "Total number of bytes copied via copy_*_user = %u\n\n"
163 "%-45s | %-40s | %10s | %20s | %10s\n",
164 g_BridgeGlobalStats.ui32IOCTLCount,
165 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
166 g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
167 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
168 "Bridge Name",
169 "Wrapper Function",
170 "Call Count",
171 "copy_from_user Bytes",
172 "copy_to_user Bytes"
173 );
174 return;
175 }
176
177 seq_printf(sfile,
178 "%-45s %-40s %-10u %-20u %-10u\n",
179 psEntry->pszIOCName,
180 psEntry->pszFunctionName,
181 psEntry->ui32CallCount,
182 psEntry->ui32CopyFromUserTotalBytes,
183 psEntry->ui32CopyToUserTotalBytes);
184}
185
186#endif
187
188
189#if defined(SUPPORT_DRI_DRM)
190IMG_INT
191PVRSRV_BridgeDispatchKM(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
192#else
193IMG_INT32
194PVRSRV_BridgeDispatchKM(struct file *pFile, IMG_UINT unref__ ioctlCmd, IMG_UINT32 arg)
195#endif
196{
197 IMG_UINT32 cmd;
198#if !defined(SUPPORT_DRI_DRM)
199 PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
200 PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
201#endif
202 PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
203 IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
204 PVRSRV_PER_PROCESS_DATA *psPerProc;
205 IMG_INT err = -EFAULT;
206
207 LinuxLockMutex(&gPVRSRVLock);
208
209#if defined(SUPPORT_DRI_DRM)
210 PVR_UNREFERENCED_PARAMETER(dev);
211
212 psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
213 PVR_ASSERT(psBridgePackageKM != IMG_NULL);
214#else
215 PVR_UNREFERENCED_PARAMETER(ioctlCmd);
216
217 psBridgePackageKM = &sBridgePackageKM;
218
219 if(!OSAccessOK(PVR_VERIFY_WRITE,
220 psBridgePackageUM,
221 sizeof(PVRSRV_BRIDGE_PACKAGE)))
222 {
223 PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
224 __FUNCTION__));
225
226 goto unlock_and_return;
227 }
228
229
230 if(OSCopyFromUser(IMG_NULL,
231 psBridgePackageKM,
232 psBridgePackageUM,
233 sizeof(PVRSRV_BRIDGE_PACKAGE))
234 != PVRSRV_OK)
235 {
236 goto unlock_and_return;
237 }
238#endif
239
240 cmd = psBridgePackageKM->ui32BridgeID;
241
242#if defined(MODULE_TEST)
243 switch (cmd)
244 {
245 case PVRSRV_BRIDGE_SERVICES_TEST_MEM1:
246 {
247 PVRSRV_ERROR eError = MemTest1();
248 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
249 {
250 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
251 pReturn->eError = eError;
252 }
253 }
254 err = 0;
255 goto unlock_and_return;
256 case PVRSRV_BRIDGE_SERVICES_TEST_MEM2:
257 {
258 PVRSRV_ERROR eError = MemTest2();
259 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
260 {
261 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
262 pReturn->eError = eError;
263 }
264 }
265 err = 0;
266 goto unlock_and_return;
267
268 case PVRSRV_BRIDGE_SERVICES_TEST_RESOURCE:
269 {
270 PVRSRV_ERROR eError = ResourceTest();
271 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
272 {
273 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
274 pReturn->eError = eError;
275 }
276 }
277 err = 0;
278 goto unlock_and_return;
279
280 case PVRSRV_BRIDGE_SERVICES_TEST_EVENTOBJECT:
281 {
282 PVRSRV_ERROR eError = EventObjectTest();
283 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
284 {
285 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
286 pReturn->eError = eError;
287 }
288 }
289 err = 0;
290 goto unlock_and_return;
291
292 case PVRSRV_BRIDGE_SERVICES_TEST_MEMMAPPING:
293 {
294 PVRSRV_ERROR eError = MemMappingTest();
295 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
296 {
297 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
298 pReturn->eError = eError;
299 }
300 }
301 err = 0;
302 goto unlock_and_return;
303
304 case PVRSRV_BRIDGE_SERVICES_TEST_PROCESSID:
305 {
306 PVRSRV_ERROR eError = ProcessIDTest();
307 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
308 {
309 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
310 pReturn->eError = eError;
311 }
312 }
313 err = 0;
314 goto unlock_and_return;
315
316 case PVRSRV_BRIDGE_SERVICES_TEST_CLOCKUSWAITUS:
317 {
318 PVRSRV_ERROR eError = ClockusWaitusTest();
319 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
320 {
321 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
322 pReturn->eError = eError;
323 }
324 }
325 err = 0;
326 goto unlock_and_return;
327
328 case PVRSRV_BRIDGE_SERVICES_TEST_TIMER:
329 {
330 PVRSRV_ERROR eError = TimerTest();
331 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
332 {
333 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
334 pReturn->eError = eError;
335 }
336 }
337 err = 0;
338 goto unlock_and_return;
339
340 case PVRSRV_BRIDGE_SERVICES_TEST_PRIVSRV:
341 {
342 PVRSRV_ERROR eError = PrivSrvTest();
343 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
344 {
345 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
346 pReturn->eError = eError;
347 }
348 }
349 err = 0;
350 goto unlock_and_return;
351 case PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA:
352 {
353 IMG_UINT32 ui32PID;
354 PVRSRV_PER_PROCESS_DATA *psPerProc;
355 PVRSRV_ERROR eError;
356
357 ui32PID = OSGetCurrentProcessIDKM();
358
359 PVRSRVTrace("PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA %d", ui32PID);
360
361 psPerProc = PVRSRVPerProcessData(ui32PID);
362
363 eError = CopyDataTest(psBridgePackageKM->pvParamIn, psBridgePackageKM->pvParamOut, psPerProc);
364
365 *(PVRSRV_ERROR*)psBridgePackageKM->pvParamOut = eError;
366 err = 0;
367 goto unlock_and_return;
368 }
369
370
371 case PVRSRV_BRIDGE_SERVICES_TEST_POWERMGMT:
372 {
373 PVRSRV_ERROR eError = PowerMgmtTest();
374 if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
375 {
376 PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
377 pReturn->eError = eError;
378 }
379 }
380 err = 0;
381 goto unlock_and_return;
382
383 }
384#endif
385
386 if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
387 {
388 PVRSRV_ERROR eError;
389
390 eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
391 (IMG_PVOID *)&psPerProc,
392 psBridgePackageKM->hKernelServices,
393 PVRSRV_HANDLE_TYPE_PERPROC_DATA);
394 if(eError != PVRSRV_OK)
395 {
396 PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)",
397 __FUNCTION__, eError));
398 goto unlock_and_return;
399 }
400
401 if(psPerProc->ui32PID != ui32PID)
402 {
403 PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data "
404 "belonging to process %d", __FUNCTION__, ui32PID,
405 psPerProc->ui32PID));
406 goto unlock_and_return;
407 }
408 }
409 else
410 {
411
412 psPerProc = PVRSRVPerProcessData(ui32PID);
413 if(psPerProc == IMG_NULL)
414 {
415 PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: "
416 "Couldn't create per-process data area"));
417 goto unlock_and_return;
418 }
419 }
420
421 psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
422
423#if defined(PVR_SECURE_FD_EXPORT)
424 switch(cmd)
425 {
426 case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
427 {
428 PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
429
430 if(psPrivateData->hKernelMemInfo)
431 {
432 PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo "
433 "per file descriptor", __FUNCTION__));
434 err = -EINVAL;
435 goto unlock_and_return;
436 }
437 break;
438 }
439
440 case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
441 {
442 PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
443 (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
444 PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
445
446 if(!psPrivateData->hKernelMemInfo)
447 {
448 PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
449 "associated MemInfo handle", __FUNCTION__));
450 err = -EINVAL;
451 goto unlock_and_return;
452 }
453
454 psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo;
455 break;
456 }
457
458 default:
459 {
460 PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
461
462 if(psPrivateData->hKernelMemInfo)
463 {
464 PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
465 "to use privileged service", __FUNCTION__));
466 goto unlock_and_return;
467 }
468 break;
469 }
470 }
471#endif
472#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
473 switch(cmd)
474 {
475 case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
476 case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
477 {
478 PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
479 int authenticated = pFile->authenticated;
480 PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
481
482 if (authenticated)
483 {
484 break;
485 }
486
487
488 psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
489 if (psEnvPerProc == IMG_NULL)
490 {
491 PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__));
492 err = -EFAULT;
493 goto unlock_and_return;
494 }
495
496 list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem)
497 {
498 struct drm_file *psDRMFile = psPrivateData->psDRMFile;
499
500 if (pFile->master == psDRMFile->master)
501 {
502 authenticated |= psDRMFile->authenticated;
503 if (authenticated)
504 {
505 break;
506 }
507 }
508 }
509
510 if (!authenticated)
511 {
512 PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__));
513 err = -EPERM;
514 goto unlock_and_return;
515 }
516 break;
517 }
518 default:
519 break;
520 }
521#endif
522
523 err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
524 if(err != PVRSRV_OK)
525 goto unlock_and_return;
526
527 switch(cmd)
528 {
529#if defined(PVR_SECURE_FD_EXPORT)
530 case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
531 {
532 PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
533 (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
534 PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
535
536 psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo;
537#if defined(SUPPORT_MEMINFO_IDS)
538 psExportDeviceMemOUT->ui64Stamp = psPrivateData->ui64Stamp = ++ui64Stamp;
539#endif
540 break;
541 }
542#endif
543
544#if defined(SUPPORT_MEMINFO_IDS)
545 case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
546 {
547 PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
548 (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
549 PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
550 psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp = psPrivateData->ui64Stamp;
551 break;
552 }
553
554 case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
555 {
556 PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
557 (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
558 psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp = ++ui64Stamp;
559 break;
560 }
561#endif
562
563 default:
564 break;
565 }
566
567unlock_and_return:
568 LinuxUnLockMutex(&gPVRSRVLock);
569 return err;
570}
diff --git a/drivers/gpu/pvr/pvr_bridge_km.h b/drivers/gpu/pvr/pvr_bridge_km.h
new file mode 100644
index 00000000000..d5592c2ecf5
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_bridge_km.h
@@ -0,0 +1,285 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PVR_BRIDGE_KM_H_
28#define __PVR_BRIDGE_KM_H_
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "pvr_bridge.h"
35#include "perproc.h"
36
37#if defined(__linux__)
38PVRSRV_ERROR LinuxBridgeInit(IMG_VOID);
39IMG_VOID LinuxBridgeDeInit(IMG_VOID);
40#endif
41
42IMG_IMPORT
43PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
44 PVRSRV_DEVICE_IDENTIFIER *psDevIdList);
45
46IMG_IMPORT
47PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32 uiDevIndex,
48 PVRSRV_DEVICE_TYPE eDeviceType,
49 IMG_HANDLE *phDevCookie);
50
51IMG_IMPORT
52PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
53 PVRSRV_QUEUE_INFO **ppsQueueInfo);
54
55IMG_IMPORT
56PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
57
58IMG_IMPORT
59PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
60 PVRSRV_HEAP_INFO *psHeapInfo);
61
62IMG_IMPORT
63PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
64 PVRSRV_PER_PROCESS_DATA *psPerProc,
65 IMG_HANDLE *phDevMemContext,
66 IMG_UINT32 *pui32ClientHeapCount,
67 PVRSRV_HEAP_INFO *psHeapInfo,
68 IMG_BOOL *pbCreated,
69 IMG_BOOL *pbShared);
70
71
72IMG_IMPORT
73PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
74 IMG_HANDLE hDevMemContext,
75 IMG_BOOL *pbDestroyed);
76
77
78IMG_IMPORT
79PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
80 IMG_HANDLE hDevMemContext,
81 IMG_UINT32 *pui32ClientHeapCount,
82 PVRSRV_HEAP_INFO *psHeapInfo,
83 IMG_BOOL *pbShared
84 );
85
86
87IMG_IMPORT
88PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
89 PVRSRV_PER_PROCESS_DATA *psPerProc,
90 IMG_HANDLE hDevMemHeap,
91 IMG_UINT32 ui32Flags,
92 IMG_SIZE_T ui32Size,
93 IMG_SIZE_T ui32Alignment,
94 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
95
96
97#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
98 #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
99 (PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \
100 ", " #alignment "," #memInfo "): " logStr " (size = 0x%;x)", size)),\
101 _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo))
102#else
103 #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
104 _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo)
105#endif
106
107
108IMG_IMPORT
109PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
110 PVRSRV_KERNEL_MEM_INFO *psMemInfo);
111
112IMG_IMPORT
113PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
114 PVRSRV_KERNEL_MEM_INFO *psMemInfo);
115
116IMG_IMPORT
117PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE hDevMemHeap,
118 IMG_DEV_VIRTADDR *psDevVAddr,
119 IMG_SIZE_T ui32Size,
120 IMG_SIZE_T ui32Alignment,
121 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
122
123IMG_IMPORT
124PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
125
126IMG_IMPORT
127PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
128 PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
129 IMG_HANDLE hDstDevMemHeap,
130 PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo);
131
132IMG_IMPORT
133PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
134
135IMG_IMPORT
136PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
137 PVRSRV_PER_PROCESS_DATA *psPerProc,
138 IMG_HANDLE hDevMemContext,
139 IMG_SIZE_T ui32ByteSize,
140 IMG_SIZE_T ui32PageOffset,
141 IMG_BOOL bPhysContig,
142 IMG_SYS_PHYADDR *psSysAddr,
143 IMG_VOID *pvLinAddr,
144 IMG_UINT32 ui32Flags,
145 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
146
147IMG_IMPORT
148PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
149
150IMG_IMPORT
151PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass,
152 IMG_UINT32 *pui32DevCount,
153 IMG_UINT32 *pui32DevID );
154
155IMG_IMPORT
156PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
157 IMG_UINT32 ui32DeviceID,
158 IMG_HANDLE hDevCookie,
159 IMG_HANDLE *phDeviceKM);
160
161IMG_IMPORT
162PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
163
164IMG_IMPORT
165PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM,
166 IMG_UINT32 *pui32Count,
167 DISPLAY_FORMAT *psFormat);
168
169IMG_IMPORT
170PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM,
171 DISPLAY_FORMAT *psFormat,
172 IMG_UINT32 *pui32Count,
173 DISPLAY_DIMS *psDim);
174
175IMG_IMPORT
176PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM,
177 IMG_HANDLE *phBuffer);
178
179IMG_IMPORT
180PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM,
181 DISPLAY_INFO *psDisplayInfo);
182IMG_IMPORT
183PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
184 IMG_HANDLE hDeviceKM,
185 IMG_UINT32 ui32Flags,
186 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
187 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
188 IMG_UINT32 ui32BufferCount,
189 IMG_UINT32 ui32OEMFlags,
190 IMG_HANDLE *phSwapChain,
191 IMG_UINT32 *pui32SwapChainID);
192IMG_IMPORT
193PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain);
194IMG_IMPORT
195PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
196 IMG_HANDLE hSwapChain,
197 IMG_RECT *psRect);
198IMG_IMPORT
199PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
200 IMG_HANDLE hSwapChain,
201 IMG_RECT *psRect);
202IMG_IMPORT
203PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
204 IMG_HANDLE hSwapChain,
205 IMG_UINT32 ui32CKColour);
206IMG_IMPORT
207PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
208 IMG_HANDLE hSwapChain,
209 IMG_UINT32 ui32CKColour);
210IMG_IMPORT
211PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
212 IMG_HANDLE hSwapChain,
213 IMG_UINT32 *pui32BufferCount,
214 IMG_HANDLE *phBuffer);
215IMG_IMPORT
216PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
217 IMG_HANDLE hBuffer,
218 IMG_UINT32 ui32SwapInterval,
219 IMG_HANDLE hPrivateTag,
220 IMG_UINT32 ui32ClipRectCount,
221 IMG_RECT *psClipRect);
222IMG_IMPORT
223PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
224 IMG_HANDLE hSwapChain);
225
226IMG_IMPORT
227PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
228 IMG_UINT32 ui32DeviceID,
229 IMG_HANDLE hDevCookie,
230 IMG_HANDLE *phDeviceKM);
231IMG_IMPORT
232PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
233
234IMG_IMPORT
235PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE hDeviceKM,
236 BUFFER_INFO *psBufferInfo);
237IMG_IMPORT
238PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE hDeviceKM,
239 IMG_UINT32 ui32BufferIndex,
240 IMG_HANDLE *phBuffer);
241
242
243IMG_IMPORT
244PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
245 IMG_HANDLE hDevMemContext,
246 IMG_HANDLE hDeviceClassBuffer,
247 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
248 IMG_HANDLE *phOSMapInfo);
249
250IMG_IMPORT
251PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
252
253IMG_IMPORT
254PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
255 IMG_SIZE_T *pui32Total,
256 IMG_SIZE_T *pui32Free,
257 IMG_SIZE_T *pui32LargestBlock);
258IMG_IMPORT
259PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
260 IMG_HANDLE hDevMemContext,
261 PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo);
262IMG_IMPORT
263PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
264
265IMG_IMPORT
266PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo);
267
268IMG_IMPORT PVRSRV_ERROR
269PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
270 IMG_UINT32 ui32Flags,
271 IMG_SIZE_T ui32Size,
272 PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
273
274IMG_IMPORT PVRSRV_ERROR
275PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
276
277IMG_IMPORT PVRSRV_ERROR
278PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
279
280#if defined (__cplusplus)
281}
282#endif
283
284#endif
285
diff --git a/drivers/gpu/pvr/pvr_debug.c b/drivers/gpu/pvr/pvr_debug.c
new file mode 100644
index 00000000000..091f6590e70
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_debug.c
@@ -0,0 +1,420 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <asm/io.h>
32#include <asm/uaccess.h>
33#include <linux/kernel.h>
34#include <linux/hardirq.h>
35#include <linux/module.h>
36#include <linux/spinlock.h>
37#include <linux/string.h>
38#include <stdarg.h>
39#include "img_types.h"
40#include "servicesext.h"
41#include "pvr_debug.h"
42#include "srvkm.h"
43#include "proc.h"
44#include "mutex.h"
45#include "linkage.h"
46#include "pvr_uaccess.h"
47
48static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
49 const IMG_CHAR* pszFormat, va_list VArgs)
50 IMG_FORMAT_PRINTF(3, 0);
51
52
53#if defined(PVRSRV_NEED_PVR_DPF)
54
55#define PVR_MAX_FILEPATH_LEN 256
56
57static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
58 const IMG_CHAR *pszFormat, ...)
59 IMG_FORMAT_PRINTF(3, 4);
60
61IMG_UINT32 gPVRDebugLevel =
62 (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
63
64#endif
65
66#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
67
68static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
69
70static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
71
72static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
73
74
75static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
76
77#if !defined (USE_SPIN_LOCK)
78#define USE_SPIN_LOCK (in_interrupt() || !preemptible())
79#endif
80
81static inline void GetBufferLock(unsigned long *pulLockFlags)
82{
83 if (USE_SPIN_LOCK)
84 {
85 spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
86 }
87 else
88 {
89 LinuxLockMutex(&gsDebugMutexNonIRQ);
90 }
91}
92
93static inline void ReleaseBufferLock(unsigned long ulLockFlags)
94{
95 if (USE_SPIN_LOCK)
96 {
97 spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
98 }
99 else
100 {
101 LinuxUnLockMutex(&gsDebugMutexNonIRQ);
102 }
103}
104
105static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
106{
107 if (USE_SPIN_LOCK)
108 {
109 *ppszBuf = gszBufferIRQ;
110 *pui32BufSiz = sizeof(gszBufferIRQ);
111 }
112 else
113 {
114 *ppszBuf = gszBufferNonIRQ;
115 *pui32BufSiz = sizeof(gszBufferNonIRQ);
116 }
117}
118
119static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
120{
121 IMG_UINT32 ui32Used;
122 IMG_UINT32 ui32Space;
123 IMG_INT32 i32Len;
124
125 ui32Used = strlen(pszBuf);
126 BUG_ON(ui32Used >= ui32BufSiz);
127 ui32Space = ui32BufSiz - ui32Used;
128
129 i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
130 pszBuf[ui32BufSiz - 1] = 0;
131
132
133 return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
134}
135
136IMG_VOID PVRDPFInit(IMG_VOID)
137{
138 LinuxInitMutex(&gsDebugMutexNonIRQ);
139}
140
141IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
142{
143 va_list vaArgs;
144 unsigned long ulLockFlags = 0;
145 IMG_CHAR *pszBuf;
146 IMG_UINT32 ui32BufSiz;
147
148 SelectBuffer(&pszBuf, &ui32BufSiz);
149
150 va_start(vaArgs, pszFormat);
151
152 GetBufferLock(&ulLockFlags);
153 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
154
155 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
156 {
157 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
158 }
159 else
160 {
161 printk(KERN_INFO "%s\n", pszBuf);
162 }
163
164 ReleaseBufferLock(ulLockFlags);
165 va_end(vaArgs);
166
167}
168
169#if defined(PVRSRV_NEED_PVR_ASSERT)
170
171IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
172{
173 PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
174 BUG();
175}
176
177#endif
178
179#if defined(PVRSRV_NEED_PVR_TRACE)
180
181IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
182{
183 va_list VArgs;
184 unsigned long ulLockFlags = 0;
185 IMG_CHAR *pszBuf;
186 IMG_UINT32 ui32BufSiz;
187
188 SelectBuffer(&pszBuf, &ui32BufSiz);
189
190 va_start(VArgs, pszFormat);
191
192 GetBufferLock(&ulLockFlags);
193
194 strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
195
196 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
197 {
198 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
199 }
200 else
201 {
202 printk(KERN_INFO "%s\n", pszBuf);
203 }
204
205 ReleaseBufferLock(ulLockFlags);
206
207 va_end(VArgs);
208}
209
210#endif
211
212#if defined(PVRSRV_NEED_PVR_DPF)
213
214static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
215{
216 va_list VArgs;
217 IMG_BOOL bTrunc;
218
219 va_start (VArgs, pszFormat);
220
221 bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
222
223 va_end (VArgs);
224
225 return bTrunc;
226}
227
228IMG_VOID PVRSRVDebugPrintf (
229 IMG_UINT32 ui32DebugLevel,
230 const IMG_CHAR* pszFullFileName,
231 IMG_UINT32 ui32Line,
232 const IMG_CHAR* pszFormat,
233 ...
234 )
235{
236 IMG_BOOL bTrace;
237 const IMG_CHAR *pszFileName = pszFullFileName;
238 IMG_CHAR *pszLeafName;
239
240
241 bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
242
243 if (gPVRDebugLevel & ui32DebugLevel)
244 {
245 va_list vaArgs;
246 unsigned long ulLockFlags = 0;
247 IMG_CHAR *pszBuf;
248 IMG_UINT32 ui32BufSiz;
249
250 SelectBuffer(&pszBuf, &ui32BufSiz);
251
252 va_start(vaArgs, pszFormat);
253
254 GetBufferLock(&ulLockFlags);
255
256
257 if (bTrace == IMG_FALSE)
258 {
259 switch(ui32DebugLevel)
260 {
261 case DBGPRIV_FATAL:
262 {
263 strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
264 break;
265 }
266 case DBGPRIV_ERROR:
267 {
268 strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
269 break;
270 }
271 case DBGPRIV_WARNING:
272 {
273 strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
274 break;
275 }
276 case DBGPRIV_MESSAGE:
277 {
278 strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
279 break;
280 }
281 case DBGPRIV_VERBOSE:
282 {
283 strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
284 break;
285 }
286 default:
287 {
288 strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
289 break;
290 }
291 }
292 }
293 else
294 {
295 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
296 }
297
298 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
299 {
300 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
301 }
302 else
303 {
304
305 if (bTrace == IMG_FALSE)
306 {
307#ifdef DEBUG_LOG_PATH_TRUNCATE
308
309 static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
310
311 IMG_CHAR* pszTruncIter;
312 IMG_CHAR* pszTruncBackInter;
313
314
315 pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
316
317
318 strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
319
320 if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
321 IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
322 strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
323 }
324
325 pszTruncIter = szFileNameRewrite;
326 while(*pszTruncIter++ != 0)
327 {
328 IMG_CHAR* pszNextStartPoint;
329
330 if(
331 !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
332 ( *(pszTruncIter-1) == '.') &&
333 ( *(pszTruncIter-2) == '.') &&
334 ( *(pszTruncIter-3) == '/') )
335 ) continue;
336
337
338 pszTruncBackInter = pszTruncIter - 3;
339 while(*(--pszTruncBackInter) != '/')
340 {
341 if(pszTruncBackInter <= szFileNameRewrite) break;
342 }
343 pszNextStartPoint = pszTruncBackInter;
344
345
346 while(*pszTruncIter != 0)
347 {
348 *pszTruncBackInter++ = *pszTruncIter++;
349 }
350 *pszTruncBackInter = 0;
351
352
353 pszTruncIter = pszNextStartPoint;
354 }
355
356 pszFileName = szFileNameRewrite;
357
358 if(*pszFileName == '/') pszFileName++;
359#endif
360
361#if !defined(__sh__)
362 pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
363
364 if (pszLeafName)
365 {
366 pszFileName = pszLeafName;
367 }
368#endif
369
370 if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
371 {
372 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
373 }
374 else
375 {
376 printk(KERN_INFO "%s\n", pszBuf);
377 }
378 }
379 else
380 {
381 printk(KERN_INFO "%s\n", pszBuf);
382 }
383 }
384
385 ReleaseBufferLock(ulLockFlags);
386
387 va_end (vaArgs);
388 }
389}
390
391#endif
392
393#if defined(DEBUG)
394
395IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
396{
397#define _PROC_SET_BUFFER_SZ 2
398 IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
399
400 if (count != _PROC_SET_BUFFER_SZ)
401 {
402 return -EINVAL;
403 }
404 else
405 {
406 if (pvr_copy_from_user(data_buffer, buffer, count))
407 return -EINVAL;
408 if (data_buffer[count - 1] != '\n')
409 return -EINVAL;
410 gPVRDebugLevel = data_buffer[0] - '0';
411 }
412 return (count);
413}
414
415void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
416{
417 seq_printf(sfile, "%u\n", gPVRDebugLevel);
418}
419
420#endif
diff --git a/drivers/gpu/pvr/pvr_debug.h b/drivers/gpu/pvr/pvr_debug.h
new file mode 100644
index 00000000000..21fa2cdfbe3
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_debug.h
@@ -0,0 +1,133 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PVR_DEBUG_H__
28#define __PVR_DEBUG_H__
29
30
31#include "img_types.h"
32
33#if defined (__cplusplus)
34extern "C" {
35#endif
36
37#define PVR_MAX_DEBUG_MESSAGE_LEN (512)
38
39#define DBGPRIV_FATAL 0x01UL
40#define DBGPRIV_ERROR 0x02UL
41#define DBGPRIV_WARNING 0x04UL
42#define DBGPRIV_MESSAGE 0x08UL
43#define DBGPRIV_VERBOSE 0x10UL
44#define DBGPRIV_CALLTRACE 0x20UL
45#define DBGPRIV_ALLOC 0x40UL
46
47#define DBGPRIV_DBGDRV_MESSAGE 0x1000UL
48
49#define DBGPRIV_ALLLEVELS (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING | DBGPRIV_MESSAGE | DBGPRIV_VERBOSE)
50
51
52
53#define PVR_DBG_FATAL DBGPRIV_FATAL,__FILE__, __LINE__
54#define PVR_DBG_ERROR DBGPRIV_ERROR,__FILE__, __LINE__
55#define PVR_DBG_WARNING DBGPRIV_WARNING,__FILE__, __LINE__
56#define PVR_DBG_MESSAGE DBGPRIV_MESSAGE,__FILE__, __LINE__
57#define PVR_DBG_VERBOSE DBGPRIV_VERBOSE,__FILE__, __LINE__
58#define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE,__FILE__, __LINE__
59#define PVR_DBG_ALLOC DBGPRIV_ALLOC,__FILE__, __LINE__
60
61#define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE, "", 0
62
63#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
64#define PVRSRV_NEED_PVR_ASSERT
65#endif
66
67#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
68#define PVRSRV_NEED_PVR_DPF
69#endif
70
71#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
72#define PVRSRV_NEED_PVR_TRACE
73#endif
74
75
76#if defined(PVRSRV_NEED_PVR_ASSERT)
77
78 #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__);
79
80IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
81 IMG_UINT32 ui32Line);
82
83 #if defined(PVR_DBG_BREAK_ASSERT_FAIL)
84 #define PVR_DBG_BREAK PVRSRVDebugAssertFail("PVR_DBG_BREAK", 0)
85 #else
86 #define PVR_DBG_BREAK
87 #endif
88
89#else
90
91 #define PVR_ASSERT(EXPR)
92 #define PVR_DBG_BREAK
93
94#endif
95
96
97#if defined(PVRSRV_NEED_PVR_DPF)
98
99 #define PVR_DPF(X) PVRSRVDebugPrintf X
100
101IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
102 const IMG_CHAR *pszFileName,
103 IMG_UINT32 ui32Line,
104 const IMG_CHAR *pszFormat,
105 ...) IMG_FORMAT_PRINTF(4, 5);
106
107#else
108
109 #define PVR_DPF(X)
110
111#endif
112
113
114#if defined(PVRSRV_NEED_PVR_TRACE)
115
116 #define PVR_TRACE(X) PVRSRVTrace X
117
118IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
119 IMG_FORMAT_PRINTF(1, 2);
120
121#else
122
123 #define PVR_TRACE(X)
124
125#endif
126
127
128#if defined (__cplusplus)
129}
130#endif
131
132#endif
133
diff --git a/drivers/gpu/pvr/pvr_uaccess.h b/drivers/gpu/pvr/pvr_uaccess.h
new file mode 100644
index 00000000000..04fdcc2211a
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_uaccess.h
@@ -0,0 +1,65 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PVR_UACCESS_H__
28#define __PVR_UACCESS_H__
29
30#ifndef AUTOCONF_INCLUDED
31 #include <linux/config.h>
32#endif
33
34#include <linux/version.h>
35#include <asm/uaccess.h>
36
37static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes)
38{
39#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
40 if (access_ok(VERIFY_WRITE, pvTo, ulBytes))
41 {
42 return __copy_to_user(pvTo, pvFrom, ulBytes);
43 }
44 return ulBytes;
45#else
46 return copy_to_user(pvTo, pvFrom, ulBytes);
47#endif
48}
49
50static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes)
51{
52#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
53
54 if (access_ok(VERIFY_READ, pvFrom, ulBytes))
55 {
56 return __copy_from_user(pvTo, pvFrom, ulBytes);
57 }
58 return ulBytes;
59#else
60 return copy_from_user(pvTo, pvFrom, ulBytes);
61#endif
62}
63
64#endif
65
diff --git a/drivers/gpu/pvr/pvrmmap.h b/drivers/gpu/pvr/pvrmmap.h
new file mode 100644
index 00000000000..4404d8852af
--- /dev/null
+++ b/drivers/gpu/pvr/pvrmmap.h
@@ -0,0 +1,36 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __PVRMMAP_H__
28#define __PVRMMAP_H__
29
30PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle);
31
32
33IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle);
34
35#endif
36
diff --git a/drivers/gpu/pvr/pvrmodule.h b/drivers/gpu/pvr/pvrmodule.h
new file mode 100644
index 00000000000..30cb2c3b5aa
--- /dev/null
+++ b/drivers/gpu/pvr/pvrmodule.h
@@ -0,0 +1,31 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _PVRMODULE_H_
28#define _PVRMODULE_H_
29MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
30MODULE_LICENSE("GPL");
31#endif
diff --git a/drivers/gpu/pvr/pvrsrv.c b/drivers/gpu/pvr/pvrsrv.c
new file mode 100644
index 00000000000..98aeb23d745
--- /dev/null
+++ b/drivers/gpu/pvr/pvrsrv.c
@@ -0,0 +1,1253 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "buffer_manager.h"
29#include "pvr_bridge_km.h"
30#include "handle.h"
31#include "perproc.h"
32#include "pdump_km.h"
33#include "deviceid.h"
34#include "ra.h"
35
36#include "pvrversion.h"
37
38#include "lists.h"
39
40IMG_UINT32 g_ui32InitFlags;
41
42#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
43
44PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
45{
46 SYS_DEVICE_ID* psDeviceWalker;
47 SYS_DEVICE_ID* psDeviceEnd;
48
49 psDeviceWalker = &psSysData->sDeviceID[0];
50 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
51
52
53 while (psDeviceWalker < psDeviceEnd)
54 {
55 if (!psDeviceWalker->bInUse)
56 {
57 psDeviceWalker->bInUse = IMG_TRUE;
58 *pui32DevID = psDeviceWalker->uiID;
59 return PVRSRV_OK;
60 }
61 psDeviceWalker++;
62 }
63
64 PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
65
66
67 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
68
69 return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
70}
71
72
73PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
74{
75 SYS_DEVICE_ID* psDeviceWalker;
76 SYS_DEVICE_ID* psDeviceEnd;
77
78 psDeviceWalker = &psSysData->sDeviceID[0];
79 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
80
81
82 while (psDeviceWalker < psDeviceEnd)
83 {
84
85 if (
86 (psDeviceWalker->uiID == ui32DevID) &&
87 (psDeviceWalker->bInUse)
88 )
89 {
90 psDeviceWalker->bInUse = IMG_FALSE;
91 return PVRSRV_OK;
92 }
93 psDeviceWalker++;
94 }
95
96 PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
97
98
99 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
100
101 return PVRSRV_ERROR_INVALID_DEVICEID;
102}
103
104
105#ifndef ReadHWReg
106IMG_EXPORT
107IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
108{
109 return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
110}
111#endif
112
113
114#ifndef WriteHWReg
115IMG_EXPORT
116IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
117{
118 PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
119 (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
120
121 *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
122}
123#endif
124
125
126#ifndef WriteHWRegs
127IMG_EXPORT
128IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
129{
130 while (ui32Count)
131 {
132 WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
133 psHWRegs++;
134 ui32Count--;
135 }
136}
137#endif
138
139static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
140{
141 IMG_UINT *pui32DevCount;
142 PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
143
144 pui32DevCount = va_arg(va, IMG_UINT*);
145 ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
146
147 if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
148 {
149 *(*ppsDevIdList) = psDeviceNode->sDevId;
150 (*ppsDevIdList)++;
151 (*pui32DevCount)++;
152 }
153}
154
155
156
157IMG_EXPORT
158PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
159 PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
160{
161 SYS_DATA *psSysData;
162 IMG_UINT32 i;
163
164 if (!pui32NumDevices || !psDevIdList)
165 {
166 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
167 return PVRSRV_ERROR_INVALID_PARAMS;
168 }
169
170 SysAcquireData(&psSysData);
171
172
173
174 for (i=0; i<PVRSRV_MAX_DEVICES; i++)
175 {
176 psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
177 }
178
179
180 *pui32NumDevices = 0;
181
182
183
184
185
186 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
187 &PVRSRVEnumerateDevicesKM_ForEachVaCb,
188 pui32NumDevices,
189 &psDevIdList);
190
191
192 return PVRSRV_OK;
193}
194
195
196PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
197{
198 PVRSRV_ERROR eError;
199
200
201 eError = ResManInit();
202 if (eError != PVRSRV_OK)
203 {
204 goto Error;
205 }
206
207 eError = PVRSRVPerProcessDataInit();
208 if(eError != PVRSRV_OK)
209 {
210 goto Error;
211 }
212
213
214 eError = PVRSRVHandleInit();
215 if(eError != PVRSRV_OK)
216 {
217 goto Error;
218 }
219
220
221 eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
222 if (eError != PVRSRV_OK)
223 {
224 goto Error;
225 }
226
227
228 psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
229 psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
230
231
232 if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
233 sizeof(PVRSRV_EVENTOBJECT) ,
234 (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
235 "Event Object") != PVRSRV_OK)
236 {
237
238 goto Error;
239 }
240
241 if(OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
242 {
243 goto Error;
244 }
245
246
247 PDUMPINIT();
248 g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
249
250 return eError;
251
252Error:
253 PVRSRVDeInit(psSysData);
254 return eError;
255}
256
257
258
259IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
260{
261 PVRSRV_ERROR eError;
262
263 PVR_UNREFERENCED_PARAMETER(psSysData);
264
265 if (psSysData == IMG_NULL)
266 {
267 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
268 return;
269 }
270
271
272 if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
273 {
274 PDUMPDEINIT();
275 }
276
277
278 if(psSysData->psGlobalEventObject)
279 {
280 OSEventObjectDestroy(psSysData->psGlobalEventObject);
281 OSFreeMem( PVRSRV_PAGEABLE_SELECT,
282 sizeof(PVRSRV_EVENTOBJECT),
283 psSysData->psGlobalEventObject,
284 0);
285 psSysData->psGlobalEventObject = IMG_NULL;
286 }
287
288 eError = PVRSRVHandleDeInit();
289 if (eError != PVRSRV_OK)
290 {
291 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
292 }
293
294 eError = PVRSRVPerProcessDataDeInit();
295 if (eError != PVRSRV_OK)
296 {
297 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
298 }
299
300 ResManDeInit();
301}
302
303
304PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
305 PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
306 IMG_UINT32 ui32SOCInterruptBit,
307 IMG_UINT32 *pui32DeviceIndex)
308{
309 PVRSRV_ERROR eError;
310 PVRSRV_DEVICE_NODE *psDeviceNode;
311
312
313 if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
314 sizeof(PVRSRV_DEVICE_NODE),
315 (IMG_VOID **)&psDeviceNode, IMG_NULL,
316 "Device Node") != PVRSRV_OK)
317 {
318 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
319 return (PVRSRV_ERROR_OUT_OF_MEMORY);
320 }
321 OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
322
323 eError = pfnRegisterDevice(psDeviceNode);
324 if (eError != PVRSRV_OK)
325 {
326 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
327 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
328
329 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
330 return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
331 }
332
333
334
335
336
337
338 psDeviceNode->ui32RefCount = 1;
339 psDeviceNode->psSysData = psSysData;
340 psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
341
342
343 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
344
345
346 List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
347
348
349 *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
350
351 return PVRSRV_OK;
352}
353
354
355PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
356{
357 PVRSRV_DEVICE_NODE *psDeviceNode;
358 SYS_DATA *psSysData;
359 PVRSRV_ERROR eError;
360
361 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
362
363 SysAcquireData(&psSysData);
364
365
366 psDeviceNode = (PVRSRV_DEVICE_NODE*)
367 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
368 &MatchDeviceKM_AnyVaCb,
369 ui32DevIndex,
370 IMG_TRUE);
371 if(!psDeviceNode)
372 {
373
374 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
375 return PVRSRV_ERROR_INIT_FAILURE;
376 }
377 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
378
379
380
381 eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
382 if (eError != PVRSRV_OK)
383 {
384 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
385 return eError;
386 }
387
388
389 if(psDeviceNode->pfnInitDevice != IMG_NULL)
390 {
391 eError = psDeviceNode->pfnInitDevice(psDeviceNode);
392 if (eError != PVRSRV_OK)
393 {
394 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
395 return eError;
396 }
397 }
398
399 return PVRSRV_OK;
400}
401
402
403static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
404{
405 PVRSRV_ERROR eError;
406 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
407 PVRSRV_DEV_POWER_STATE_DEFAULT,
408 KERNEL_ID, IMG_FALSE);
409 if (eError != PVRSRV_OK)
410 {
411 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
412 }
413 return eError;
414}
415
416static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
417{
418 PVRSRV_ERROR eError;
419 eError = PVRSRVDevInitCompatCheck(psDeviceNode);
420 if (eError != PVRSRV_OK)
421 {
422 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
423 }
424 return eError;
425}
426
427
428PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
429{
430 SYS_DATA *psSysData;
431 PVRSRV_ERROR eError;
432
433 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
434
435 SysAcquireData(&psSysData);
436
437 if (bInitSuccessful)
438 {
439 eError = SysFinalise();
440 if (eError != PVRSRV_OK)
441 {
442 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
443 return eError;
444 }
445
446
447 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
448 &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
449 if (eError != PVRSRV_OK)
450 {
451 return eError;
452 }
453
454
455 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
456 &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
457 if (eError != PVRSRV_OK)
458 {
459 return eError;
460 }
461 }
462
463
464
465
466
467 PDUMPENDINITPHASE();
468
469 return PVRSRV_OK;
470}
471
472
473PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
474{
475
476 if (psDeviceNode->pfnInitDeviceCompatCheck)
477 return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
478 else
479 return PVRSRV_OK;
480}
481
482static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
483{
484 PVRSRV_DEVICE_TYPE eDeviceType;
485 IMG_UINT32 ui32DevIndex;
486
487 eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
488 ui32DevIndex = va_arg(va, IMG_UINT32);
489
490 if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
491 psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
492 (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
493 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
494 {
495 return psDeviceNode;
496 }
497 else
498 {
499 return IMG_NULL;
500 }
501}
502
503IMG_EXPORT
504PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
505 PVRSRV_DEVICE_TYPE eDeviceType,
506 IMG_HANDLE *phDevCookie)
507{
508 PVRSRV_DEVICE_NODE *psDeviceNode;
509 SYS_DATA *psSysData;
510
511 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
512
513 SysAcquireData(&psSysData);
514
515
516 psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
517 &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
518 eDeviceType,
519 ui32DevIndex);
520
521
522 if (!psDeviceNode)
523 {
524
525 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
526 return PVRSRV_ERROR_INIT_FAILURE;
527 }
528
529 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
530
531
532 if (phDevCookie)
533 {
534 *phDevCookie = (IMG_HANDLE)psDeviceNode;
535 }
536
537 return PVRSRV_OK;
538}
539
540
541PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
542{
543 PVRSRV_DEVICE_NODE *psDeviceNode;
544 SYS_DATA *psSysData;
545 PVRSRV_ERROR eError;
546
547 SysAcquireData(&psSysData);
548
549 psDeviceNode = (PVRSRV_DEVICE_NODE*)
550 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
551 &MatchDeviceKM_AnyVaCb,
552 ui32DevIndex,
553 IMG_TRUE);
554
555 if (!psDeviceNode)
556 {
557 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
558 return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
559 }
560
561
562
563 eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
564 PVRSRV_DEV_POWER_STATE_OFF,
565 KERNEL_ID,
566 IMG_FALSE);
567 if (eError != PVRSRV_OK)
568 {
569 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
570 return eError;
571 }
572
573
574
575 eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
576 RESMAN_CRITERIA_RESTYPE,
577 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
578 IMG_NULL, 0);
579 if (eError != PVRSRV_OK)
580 {
581 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
582 return eError;
583 }
584
585
586
587 if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
588 {
589 eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
590 if (eError != PVRSRV_OK)
591 {
592 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
593 return eError;
594 }
595 }
596
597
598
599 PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
600 psDeviceNode->hResManContext = IMG_NULL;
601
602
603 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
604
605
606 (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
607 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
608 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
609
610
611 return (PVRSRV_OK);
612}
613
614
615IMG_EXPORT
616PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
617 IMG_UINT32 ui32Value,
618 IMG_UINT32 ui32Mask,
619 IMG_UINT32 ui32Waitus,
620 IMG_UINT32 ui32Tries)
621{
622 {
623 IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU;
624 IMG_UINT32 uiMaxTime = ui32Tries * ui32Waitus;
625
626
627 LOOP_UNTIL_TIMEOUT(uiMaxTime)
628 {
629 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
630 if(ui32ActualValue == ui32Value)
631 {
632 return PVRSRV_OK;
633 }
634 OSWaitus(ui32Waitus);
635 } END_LOOP_UNTIL_TIMEOUT();
636
637 PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
638 ui32Value, ui32ActualValue, ui32Mask));
639 }
640
641
642 return PVRSRV_ERROR_TIMEOUT;
643}
644
645
646static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
647{
648 IMG_CHAR **ppszStr;
649 IMG_UINT32 *pui32StrLen;
650 IMG_UINT32 ui32Mode;
651 PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
652
653 ppszStr = va_arg(va, IMG_CHAR**);
654 pui32StrLen = va_arg(va, IMG_UINT32*);
655 ui32Mode = va_arg(va, IMG_UINT32);
656
657
658 switch(ui32Mode)
659 {
660 case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
661 pfnGetStats = &RA_GetStats;
662 break;
663 case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
664 pfnGetStats = &RA_GetStatsFreeMem;
665 break;
666 default:
667 return;
668 }
669
670 if(psBMHeap->pImportArena)
671 {
672 pfnGetStats(psBMHeap->pImportArena,
673 ppszStr,
674 pui32StrLen);
675 }
676
677 if(psBMHeap->pVMArena)
678 {
679 pfnGetStats(psBMHeap->pVMArena,
680 ppszStr,
681 pui32StrLen);
682 }
683}
684
685static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
686{
687
688 IMG_UINT32 *pui32StrLen;
689 IMG_INT32 *pi32Count;
690 IMG_CHAR **ppszStr;
691 IMG_UINT32 ui32Mode;
692
693 pui32StrLen = va_arg(va, IMG_UINT32*);
694 pi32Count = va_arg(va, IMG_INT32*);
695 ppszStr = va_arg(va, IMG_CHAR**);
696 ui32Mode = va_arg(va, IMG_UINT32);
697
698 CHECK_SPACE(*pui32StrLen);
699 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
700 (IMG_HANDLE)psBMContext);
701 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
702
703 List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
704 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
705 ppszStr,
706 pui32StrLen,
707 ui32Mode);
708 return PVRSRV_OK;
709}
710
711
712static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
713{
714 IMG_UINT32 *pui32StrLen;
715 IMG_INT32 *pi32Count;
716 IMG_CHAR **ppszStr;
717 IMG_UINT32 ui32Mode;
718
719 pui32StrLen = va_arg(va, IMG_UINT32*);
720 pi32Count = va_arg(va, IMG_INT32*);
721 ppszStr = va_arg(va, IMG_CHAR**);
722 ui32Mode = va_arg(va, IMG_UINT32);
723
724 CHECK_SPACE(*pui32StrLen);
725 *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
726 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
727
728
729 if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
730 {
731 CHECK_SPACE(*pui32StrLen);
732 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
733 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
734
735 List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
736 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
737 ppszStr,
738 pui32StrLen,
739 ui32Mode);
740 }
741
742
743 return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
744 &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
745 pui32StrLen,
746 pi32Count,
747 ppszStr,
748 ui32Mode);
749}
750
751
752IMG_EXPORT
753PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
754{
755 SYS_DATA *psSysData;
756
757 if(!psMiscInfo)
758 {
759 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
760 return PVRSRV_ERROR_INVALID_PARAMS;
761 }
762
763 psMiscInfo->ui32StatePresent = 0;
764
765
766 if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
767 |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
768 |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
769 |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
770 |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
771 |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
772 |PVRSRV_MISC_INFO_RESET_PRESENT
773 |PVRSRV_MISC_INFO_FREEMEM_PRESENT))
774 {
775 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
776 return PVRSRV_ERROR_INVALID_PARAMS;
777 }
778
779 SysAcquireData(&psSysData);
780
781
782 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
783 (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
784 {
785 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
786 psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
787 psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
788 }
789 else
790 {
791 psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
792 psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
793 }
794
795
796 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
797 (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
798 {
799 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
800 psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
801 psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
802 }
803
804
805 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
806 (psMiscInfo->pszMemoryStr != IMG_NULL))
807 {
808 RA_ARENA **ppArena;
809 IMG_CHAR *pszStr;
810 IMG_UINT32 ui32StrLen;
811 IMG_INT32 i32Count;
812
813 pszStr = psMiscInfo->pszMemoryStr;
814 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
815
816 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
817
818
819 ppArena = &psSysData->apsLocalDevMemArena[0];
820 while(*ppArena)
821 {
822 CHECK_SPACE(ui32StrLen);
823 i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
824 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
825
826 RA_GetStats(*ppArena,
827 &pszStr,
828 &ui32StrLen);
829
830 ppArena++;
831 }
832
833
834
835 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
836 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
837 &ui32StrLen,
838 &i32Count,
839 &pszStr,
840 PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
841
842
843 i32Count = OSSNPrintf(pszStr, 100, "\n");
844 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
845 }
846
847
848 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT)
849 && psMiscInfo->pszMemoryStr)
850 {
851 IMG_CHAR *pszStr;
852 IMG_UINT32 ui32StrLen;
853 IMG_INT32 i32Count;
854
855 pszStr = psMiscInfo->pszMemoryStr;
856 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
857
858 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
859
860
861 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
862 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
863 &ui32StrLen,
864 &i32Count,
865 &pszStr,
866 PVRSRV_MISC_INFO_FREEMEM_PRESENT);
867
868 i32Count = OSSNPrintf(pszStr, 100, "\n");
869 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
870 }
871
872 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
873 (psSysData->psGlobalEventObject != IMG_NULL))
874 {
875 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
876 psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
877 }
878
879
880
881 if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
882 && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
883 && (psMiscInfo->pszMemoryStr != IMG_NULL))
884 {
885 IMG_CHAR *pszStr;
886 IMG_UINT32 ui32StrLen;
887 IMG_UINT32 ui32LenStrPerNum = 12;
888 IMG_INT32 i32Count;
889 IMG_INT i;
890 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
891
892
893 psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
894 psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
895 psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
896 psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
897
898 pszStr = psMiscInfo->pszMemoryStr;
899 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
900
901 for (i=0; i<4; i++)
902 {
903 if (ui32StrLen < ui32LenStrPerNum)
904 {
905 return PVRSRV_ERROR_INVALID_PARAMS;
906 }
907
908 i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
909 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
910 if (i != 3)
911 {
912 i32Count = OSSNPrintf(pszStr, 2, ".");
913 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
914 }
915 }
916 }
917
918 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
919 {
920 if(psMiscInfo->sCacheOpCtl.bDeferOp)
921 {
922
923 psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
924 }
925 else
926 {
927 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
928 PVRSRV_PER_PROCESS_DATA *psPerProc;
929
930 if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
931 {
932 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
933 "Ignoring non-deferred cache op with no meminfo"));
934 return PVRSRV_ERROR_INVALID_PARAMS;
935 }
936
937 if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
938 {
939 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
940 "Deferred cache op is pending. It is unlikely you want "
941 "to combine deferred cache ops with immediate ones"));
942 }
943
944
945 psPerProc = PVRSRVFindPerProcessData();
946
947 if(PVRSRVLookupHandle(psPerProc->psHandleBase,
948 (IMG_PVOID *)&psKernelMemInfo,
949 psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
950 PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
951 {
952 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
953 "Can't find kernel meminfo"));
954 return PVRSRV_ERROR_INVALID_PARAMS;
955 }
956
957 if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
958 {
959 if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
960 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
961 psMiscInfo->sCacheOpCtl.ui32Length))
962 {
963 return PVRSRV_ERROR_CACHEOP_FAILED;
964 }
965 }
966 else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
967 {
968 if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
969 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
970 psMiscInfo->sCacheOpCtl.ui32Length))
971 {
972 return PVRSRV_ERROR_CACHEOP_FAILED;
973 }
974 }
975 }
976 }
977
978#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
979 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
980 {
981 PVR_LOG(("User requested OS reset"));
982 OSPanic();
983 }
984#endif
985
986 return PVRSRV_OK;
987}
988
989
990IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
991{
992 SYS_DATA *psSysData;
993 IMG_BOOL bStatus = IMG_FALSE;
994 IMG_UINT32 ui32InterruptSource;
995
996 if(!psDeviceNode)
997 {
998 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
999 goto out;
1000 }
1001 psSysData = psDeviceNode->psSysData;
1002
1003
1004 ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
1005 if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1006 {
1007 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1008 {
1009 bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
1010 }
1011
1012 SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
1013 }
1014
1015out:
1016 return bStatus;
1017}
1018
1019static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1020{
1021
1022 IMG_BOOL *pbStatus;
1023 IMG_UINT32 *pui32InterruptSource;
1024 IMG_UINT32 *pui32ClearInterrupts;
1025
1026 pbStatus = va_arg(va, IMG_BOOL*);
1027 pui32InterruptSource = va_arg(va, IMG_UINT32*);
1028 pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
1029
1030
1031 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1032 {
1033 if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1034 {
1035 if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
1036 {
1037
1038 *pbStatus = IMG_TRUE;
1039 }
1040
1041 *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
1042 }
1043 }
1044}
1045
1046IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
1047{
1048 SYS_DATA *psSysData = pvSysData;
1049 IMG_BOOL bStatus = IMG_FALSE;
1050 IMG_UINT32 ui32InterruptSource;
1051 IMG_UINT32 ui32ClearInterrupts = 0;
1052 if(!psSysData)
1053 {
1054 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
1055 }
1056 else
1057 {
1058
1059 ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
1060
1061
1062 if(ui32InterruptSource)
1063 {
1064
1065 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1066 &PVRSRVSystemLISR_ForEachVaCb,
1067 &bStatus,
1068 &ui32InterruptSource,
1069 &ui32ClearInterrupts);
1070
1071 SysClearInterrupts(psSysData, ui32ClearInterrupts);
1072 }
1073 }
1074 return bStatus;
1075}
1076
1077
1078static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1079{
1080 if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
1081 {
1082 (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
1083 }
1084}
1085
1086IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
1087{
1088 SYS_DATA *psSysData = pvSysData;
1089 if(!psSysData)
1090 {
1091 PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
1092 return;
1093 }
1094
1095
1096 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1097 &PVRSRVMISR_ForEachCb);
1098
1099
1100 if (PVRSRVProcessQueues(ISR_ID, IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
1101 {
1102 PVRSRVProcessQueues(ISR_ID, IMG_FALSE);
1103 }
1104
1105
1106 if (psSysData->psGlobalEventObject)
1107 {
1108 IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
1109 if(hOSEventKM)
1110 {
1111 OSEventObjectSignal(hOSEventKM);
1112 }
1113 }
1114}
1115
1116
1117IMG_EXPORT
1118PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID)
1119{
1120 return PVRSRVPerProcessDataConnect(ui32PID);
1121}
1122
1123
1124IMG_EXPORT
1125IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
1126{
1127 PVRSRVPerProcessDataDisconnect(ui32PID);
1128}
1129
1130
1131PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
1132 IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
1133{
1134 IMG_SIZE_T uiBytesSaved = 0;
1135 IMG_PVOID pvLocalMemCPUVAddr;
1136 RA_SEGMENT_DETAILS sSegDetails;
1137
1138 if (hArena == IMG_NULL)
1139 {
1140 return (PVRSRV_ERROR_INVALID_PARAMS);
1141 }
1142
1143 sSegDetails.uiSize = 0;
1144 sSegDetails.sCpuPhyAddr.uiAddr = 0;
1145 sSegDetails.hSegment = 0;
1146
1147
1148 while (RA_GetNextLiveSegment(hArena, &sSegDetails))
1149 {
1150 if (pbyBuffer == IMG_NULL)
1151 {
1152
1153 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1154 }
1155 else
1156 {
1157 if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
1158 {
1159 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1160 }
1161
1162 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
1163
1164
1165 pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
1166 sSegDetails.uiSize,
1167 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1168 IMG_NULL);
1169 if (pvLocalMemCPUVAddr == IMG_NULL)
1170 {
1171 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
1172 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1173 }
1174
1175 if (bSave)
1176 {
1177
1178 OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
1179 pbyBuffer += sizeof(sSegDetails.uiSize);
1180
1181 OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
1182 pbyBuffer += sSegDetails.uiSize;
1183 }
1184 else
1185 {
1186 IMG_UINT32 uiSize;
1187
1188 OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
1189
1190 if (uiSize != sSegDetails.uiSize)
1191 {
1192 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
1193 }
1194 else
1195 {
1196 pbyBuffer += sizeof(sSegDetails.uiSize);
1197
1198 OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
1199 pbyBuffer += sSegDetails.uiSize;
1200 }
1201 }
1202
1203
1204 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1205
1206 OSUnMapPhysToLin(pvLocalMemCPUVAddr,
1207 sSegDetails.uiSize,
1208 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1209 IMG_NULL);
1210 }
1211 }
1212
1213 if (pbyBuffer == IMG_NULL)
1214 {
1215 *puiBufSize = uiBytesSaved;
1216 }
1217
1218 return (PVRSRV_OK);
1219}
1220
1221
1222IMG_EXPORT
1223const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
1224{
1225
1226#include "pvrsrv_errors.h"
1227}
1228
1229static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1230{
1231 if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
1232 {
1233
1234 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
1235 }
1236}
1237
1238IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
1239{
1240 SYS_DATA *psSysData;
1241 SysAcquireData(&psSysData);
1242
1243
1244 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1245 &PVRSRVCommandCompleteCallbacks_ForEachCb);
1246}
1247
1248IMG_EXPORT
1249IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
1250{
1251 PVRSRVScheduleDeviceCallbacks();
1252}
1253
diff --git a/drivers/gpu/pvr/pvrsrv_errors.h b/drivers/gpu/pvr/pvrsrv_errors.h
new file mode 100644
index 00000000000..56c7184fe2c
--- /dev/null
+++ b/drivers/gpu/pvr/pvrsrv_errors.h
@@ -0,0 +1,264 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__PVRSRV_ERRORS_H__)
28#define __PVRSRV_ERRORS_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34 switch (eError)
35 {
36 case PVRSRV_OK: return "No Errors";
37 case PVRSRV_ERROR_OUT_OF_MEMORY: return "PVRSRV_ERROR_OUT_OF_MEMORY - Unable to allocate required memory";
38 case PVRSRV_ERROR_TOO_FEW_BUFFERS: return "PVRSRV_ERROR_TOO_FEW_BUFFERS";
39 case PVRSRV_ERROR_INVALID_PARAMS: return "PVRSRV_ERROR_INVALID_PARAMS";
40 case PVRSRV_ERROR_INIT_FAILURE: return "PVRSRV_ERROR_INIT_FAILURE";
41 case PVRSRV_ERROR_CANT_REGISTER_CALLBACK: return "PVRSRV_ERROR_CANT_REGISTER_CALLBACK";
42 case PVRSRV_ERROR_INVALID_DEVICE: return "PVRSRV_ERROR_INVALID_DEVICE";
43 case PVRSRV_ERROR_NOT_OWNER: return "PVRSRV_ERROR_NOT_OWNER";
44 case PVRSRV_ERROR_BAD_MAPPING: return "PVRSRV_ERROR_BAD_MAPPING";
45 case PVRSRV_ERROR_TIMEOUT: return "PVRSRV_ERROR_TIMEOUT";
46 case PVRSRV_ERROR_FLIP_CHAIN_EXISTS: return "PVRSRV_ERROR_FLIP_CHAIN_EXISTS";
47 case PVRSRV_ERROR_INVALID_SWAPINTERVAL: return "PVRSRV_ERROR_INVALID_SWAPINTERVAL";
48 case PVRSRV_ERROR_SCENE_INVALID: return "PVRSRV_ERROR_SCENE_INVALID";
49 case PVRSRV_ERROR_STREAM_ERROR: return "PVRSRV_ERROR_STREAM_ERROR";
50 case PVRSRV_ERROR_FAILED_DEPENDENCIES: return "PVRSRV_ERROR_FAILED_DEPENDENCIES";
51 case PVRSRV_ERROR_CMD_NOT_PROCESSED: return "PVRSRV_ERROR_CMD_NOT_PROCESSED";
52 case PVRSRV_ERROR_CMD_TOO_BIG: return "PVRSRV_ERROR_CMD_TOO_BIG";
53 case PVRSRV_ERROR_DEVICE_REGISTER_FAILED: return "PVRSRV_ERROR_DEVICE_REGISTER_FAILED";
54 case PVRSRV_ERROR_TOOMANYBUFFERS: return "PVRSRV_ERROR_TOOMANYBUFFERS";
55 case PVRSRV_ERROR_NOT_SUPPORTED: return "PVRSRV_ERROR_NOT_SUPPORTED - fix";
56 case PVRSRV_ERROR_PROCESSING_BLOCKED: return "PVRSRV_ERROR_PROCESSING_BLOCKED";
57
58 case PVRSRV_ERROR_CANNOT_FLUSH_QUEUE: return "PVRSRV_ERROR_CANNOT_FLUSH_QUEUE";
59 case PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE: return "PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE";
60 case PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS: return "PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS";
61 case PVRSRV_ERROR_RETRY: return "PVRSRV_ERROR_RETRY";
62
63 case PVRSRV_ERROR_DDK_VERSION_MISMATCH: return "PVRSRV_ERROR_DDK_VERSION_MISMATCH";
64 case PVRSRV_ERROR_BUILD_MISMATCH: return "PVRSRV_ERROR_BUILD_MISMATCH";
65 case PVRSRV_ERROR_CORE_REVISION_MISMATCH: return "PVRSRV_ERROR_CORE_REVISION_MISMATCH";
66
67 case PVRSRV_ERROR_UPLOAD_TOO_BIG: return "PVRSRV_ERROR_UPLOAD_TOO_BIG";
68
69 case PVRSRV_ERROR_INVALID_FLAGS: return "PVRSRV_ERROR_INVALID_FLAGS";
70 case PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS: return "PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS";
71
72 case PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY: return "PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY";
73 case PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR: return "PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR";
74 case PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED: return "PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED";
75
76 case PVRSRV_ERROR_BRIDGE_CALL_FAILED: return "PVRSRV_ERROR_BRIDGE_CALL_FAILED";
77 case PVRSRV_ERROR_IOCTL_CALL_FAILED: return "PVRSRV_ERROR_IOCTL_CALL_FAILED";
78
79 case PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND: return "PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND";
80 case PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND";
81 case PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT:return "PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT";
82
83 case PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND";
84 case PVRSRV_ERROR_PCI_CALL_FAILED: return "PVRSRV_ERROR_PCI_CALL_FAILED";
85 case PVRSRV_ERROR_PCI_REGION_TOO_SMALL: return "PVRSRV_ERROR_PCI_REGION_TOO_SMALL";
86 case PVRSRV_ERROR_PCI_REGION_UNAVAILABLE: return "PVRSRV_ERROR_PCI_REGION_UNAVAILABLE";
87 case PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH: return "PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH";
88
89 case PVRSRV_ERROR_REGISTER_BASE_NOT_SET: return "PVRSRV_ERROR_REGISTER_BASE_NOT_SET";
90
91 case PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM: return "PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM";
92 case PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY";
93 case PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC: return "PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC";
94 case PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR: return "PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR";
95
96 case PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY";
97 case PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY";
98
99 case PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES: return "PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES";
100 case PVRSRV_ERROR_FAILED_TO_FREE_PAGES: return "PVRSRV_ERROR_FAILED_TO_FREE_PAGES";
101 case PVRSRV_ERROR_FAILED_TO_COPY_PAGES: return "PVRSRV_ERROR_FAILED_TO_COPY_PAGES";
102 case PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES";
103 case PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES";
104 case PVRSRV_ERROR_STILL_MAPPED: return "PVRSRV_ERROR_STILL_MAPPED";
105 case PVRSRV_ERROR_MAPPING_NOT_FOUND: return "PVRSRV_ERROR_MAPPING_NOT_FOUND";
106 case PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT: return "PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT";
107 case PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE: return "PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE";
108
109 case PVRSRV_ERROR_INVALID_SEGMENT_BLOCK: return "PVRSRV_ERROR_INVALID_SEGMENT_BLOCK";
110 case PVRSRV_ERROR_INVALID_SGXDEVDATA: return "PVRSRV_ERROR_INVALID_SGXDEVDATA";
111 case PVRSRV_ERROR_INVALID_DEVINFO: return "PVRSRV_ERROR_INVALID_DEVINFO";
112 case PVRSRV_ERROR_INVALID_MEMINFO: return "PVRSRV_ERROR_INVALID_MEMINFO";
113 case PVRSRV_ERROR_INVALID_MISCINFO: return "PVRSRV_ERROR_INVALID_MISCINFO";
114 case PVRSRV_ERROR_UNKNOWN_IOCTL: return "PVRSRV_ERROR_UNKNOWN_IOCTL";
115 case PVRSRV_ERROR_INVALID_CONTEXT: return "PVRSRV_ERROR_INVALID_CONTEXT";
116 case PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT";
117 case PVRSRV_ERROR_INVALID_HEAP: return "PVRSRV_ERROR_INVALID_HEAP";
118 case PVRSRV_ERROR_INVALID_KERNELINFO: return "PVRSRV_ERROR_INVALID_KERNELINFO";
119 case PVRSRV_ERROR_UNKNOWN_POWER_STATE: return "PVRSRV_ERROR_UNKNOWN_POWER_STATE";
120 case PVRSRV_ERROR_INVALID_HANDLE_TYPE: return "PVRSRV_ERROR_INVALID_HANDLE_TYPE";
121 case PVRSRV_ERROR_INVALID_WRAP_TYPE: return "PVRSRV_ERROR_INVALID_WRAP_TYPE";
122 case PVRSRV_ERROR_INVALID_PHYS_ADDR: return "PVRSRV_ERROR_INVALID_PHYS_ADDR";
123 case PVRSRV_ERROR_INVALID_CPU_ADDR: return "PVRSRV_ERROR_INVALID_CPU_ADDR";
124 case PVRSRV_ERROR_INVALID_HEAPINFO: return "PVRSRV_ERROR_INVALID_HEAPINFO";
125 case PVRSRV_ERROR_INVALID_PERPROC: return "PVRSRV_ERROR_INVALID_PERPROC";
126 case PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO: return "PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO";
127 case PVRSRV_ERROR_INVALID_MAP_REQUEST: return "PVRSRV_ERROR_INVALID_MAP_REQUEST";
128 case PVRSRV_ERROR_INVALID_UNMAP_REQUEST: return "PVRSRV_ERROR_INVALID_UNMAP_REQUEST";
129 case PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP: return "PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP";
130 case PVRSRV_ERROR_MAPPING_STILL_IN_USE: return "PVRSRV_ERROR_MAPPING_STILL_IN_USE";
131
132 case PVRSRV_ERROR_EXCEEDED_HW_LIMITS: return "PVRSRV_ERROR_EXCEEDED_HW_LIMITS";
133 case PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED: return "PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED";
134
135 case PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA:return "PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA";
136 case PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT";
137 case PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT";
138 case PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT";
139 case PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT";
140 case PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD";
141 case PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD";
142 case PVRSRV_ERROR_THREAD_READ_ERROR: return "PVRSRV_ERROR_THREAD_READ_ERROR";
143 case PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER:return "PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER";
144 case PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR";
145 case PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR";
146 case PVRSRV_ERROR_ISR_ALREADY_INSTALLED: return "PVRSRV_ERROR_ISR_ALREADY_INSTALLED";
147 case PVRSRV_ERROR_ISR_NOT_INSTALLED: return "PVRSRV_ERROR_ISR_NOT_INSTALLED";
148 case PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT:return "PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT";
149 case PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO: return "PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO";
150 case PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT: return "PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT";
151 case PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES";
152 case PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT";
153 case PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE";
154
155 case PVRSRV_ERROR_INVALID_CCB_COMMAND: return "PVRSRV_ERROR_INVALID_CCB_COMMAND";
156
157 case PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE";
158 case PVRSRV_ERROR_INVALID_LOCK_ID: return "PVRSRV_ERROR_INVALID_LOCK_ID";
159 case PVRSRV_ERROR_RESOURCE_NOT_LOCKED: return "PVRSRV_ERROR_RESOURCE_NOT_LOCKED";
160
161 case PVRSRV_ERROR_FLIP_FAILED: return "PVRSRV_ERROR_FLIP_FAILED";
162 case PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED: return "PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED";
163
164 case PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE: return "PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE";
165
166 case PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED: return "PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED";
167 case PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG: return "PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG";
168 case PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG";
169 case PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG";
170
171 case PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID: return "PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID";
172
173 case PVRSRV_ERROR_BLIT_SETUP_FAILED: return "PVRSRV_ERROR_BLIT_SETUP_FAILED";
174
175 case PVRSRV_ERROR_PDUMP_NOT_AVAILABLE: return "PVRSRV_ERROR_PDUMP_NOT_AVAILABLE";
176 case PVRSRV_ERROR_PDUMP_BUFFER_FULL: return "PVRSRV_ERROR_PDUMP_BUFFER_FULL";
177 case PVRSRV_ERROR_PDUMP_BUF_OVERFLOW: return "PVRSRV_ERROR_PDUMP_BUF_OVERFLOW";
178 case PVRSRV_ERROR_PDUMP_NOT_ACTIVE: return "PVRSRV_ERROR_PDUMP_NOT_ACTIVE";
179 case PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES:return "PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES";
180
181 case PVRSRV_ERROR_MUTEX_DESTROY_FAILED: return "PVRSRV_ERROR_MUTEX_DESTROY_FAILED";
182 case PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR: return "PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR";
183
184 case PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE: return "PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE";
185 case PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND:return "PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND";
186
187 case PVRSRV_ERROR_PROCESS_NOT_INITIALISED: return "PVRSRV_ERROR_PROCESS_NOT_INITIALISED";
188 case PVRSRV_ERROR_PROCESS_NOT_FOUND: return "PVRSRV_ERROR_PROCESS_NOT_FOUND";
189 case PVRSRV_ERROR_SRV_CONNECT_FAILED: return "PVRSRV_ERROR_SRV_CONNECT_FAILED";
190 case PVRSRV_ERROR_SRV_DISCONNECT_FAILED: return "PVRSRV_ERROR_SRV_DISCONNECT_FAILED";
191 case PVRSRV_ERROR_DEINT_PHASE_FAILED: return "PVRSRV_ERROR_DEINT_PHASE_FAILED";
192 case PVRSRV_ERROR_INIT2_PHASE_FAILED: return "PVRSRV_ERROR_INIT2_PHASE_FAILED";
193
194 case PVRSRV_ERROR_NO_DC_DEVICES_FOUND: return "PVRSRV_ERROR_NO_DC_DEVICES_FOUND";
195 case PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE";
196 case PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE";
197 case PVRSRV_ERROR_NO_DEVICEDATA_FOUND: return "PVRSRV_ERROR_NO_DEVICEDATA_FOUND";
198 case PVRSRV_ERROR_NO_DEVICENODE_FOUND: return "PVRSRV_ERROR_NO_DEVICENODE_FOUND";
199 case PVRSRV_ERROR_NO_CLIENTNODE_FOUND: return "PVRSRV_ERROR_NO_CLIENTNODE_FOUND";
200 case PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE: return "PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE";
201
202 case PVRSRV_ERROR_UNABLE_TO_INIT_TASK: return "PVRSRV_ERROR_UNABLE_TO_INIT_TASK";
203 case PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK: return "PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK";
204 case PVRSRV_ERROR_UNABLE_TO_KILL_TASK: return "PVRSRV_ERROR_UNABLE_TO_KILL_TASK";
205
206 case PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER";
207 case PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER";
208 case PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER";
209
210 case PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT: return "PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT";
211 case PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION: return "PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION";
212
213 case PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE: return "PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE";
214 case PVRSRV_ERROR_HANDLE_NOT_ALLOCATED: return "PVRSRV_ERROR_HANDLE_NOT_ALLOCATED";
215 case PVRSRV_ERROR_HANDLE_TYPE_MISMATCH: return "PVRSRV_ERROR_HANDLE_TYPE_MISMATCH";
216 case PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE: return "PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE";
217 case PVRSRV_ERROR_HANDLE_NOT_SHAREABLE: return "PVRSRV_ERROR_HANDLE_NOT_SHAREABLE";
218 case PVRSRV_ERROR_HANDLE_NOT_FOUND: return "PVRSRV_ERROR_HANDLE_NOT_FOUND";
219 case PVRSRV_ERROR_INVALID_SUBHANDLE: return "PVRSRV_ERROR_INVALID_SUBHANDLE";
220 case PVRSRV_ERROR_HANDLE_BATCH_IN_USE: return "PVRSRV_ERROR_HANDLE_BATCH_IN_USE";
221 case PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE: return "PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE";
222
223 case PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE: return "PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE";
224 case PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED:return "PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED";
225
226 case PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE: return "PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE";
227 case PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP";
228
229 case PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE: return "PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE";
230
231 case PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE: return "PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE";
232 case PVRSRV_ERROR_INVALID_DEVICEID: return "PVRSRV_ERROR_INVALID_DEVICEID";
233 case PVRSRV_ERROR_DEVICEID_NOT_FOUND: return "PVRSRV_ERROR_DEVICEID_NOT_FOUND";
234
235 case PVRSRV_ERROR_MEMORY_TEST_FAILED: return "PVRSRV_ERROR_MEMORY_TEST_FAILED";
236 case PVRSRV_ERROR_CPUPADDR_TEST_FAILED: return "PVRSRV_ERROR_CPUPADDR_TEST_FAILED";
237 case PVRSRV_ERROR_COPY_TEST_FAILED: return "PVRSRV_ERROR_COPY_TEST_FAILED";
238
239 case PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED: return "PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED";
240
241 case PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK";
242 case PVRSRV_ERROR_CLOCK_REQUEST_FAILED: return "PVRSRV_ERROR_CLOCK_REQUEST_FAILED";
243 case PVRSRV_ERROR_DISABLE_CLOCK_FAILURE: return "PVRSRV_ERROR_DISABLE_CLOCK_FAILURE";
244 case PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE";
245 case PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE";
246 case PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK";
247 case PVRSRV_ERROR_UNABLE_TO_GET_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_CLOCK";
248 case PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK";
249 case PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK";
250
251 case PVRSRV_ERROR_UNKNOWN_SGL_ERROR: return "PVRSRV_ERROR_UNKNOWN_SGL_ERROR";
252 case PVRSRV_ERROR_BAD_SYNC_STATE: return "PVRSRV_ERROR_BAD_SYNC_STATE";
253
254 case PVRSRV_ERROR_FORCE_I32: return "PVRSRV_ERROR_FORCE_I32";
255
256 default:
257 return "Unknown PVRSRV error number";
258 }
259
260#if defined (__cplusplus)
261}
262#endif
263#endif
264
diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h
new file mode 100644
index 00000000000..d7c06c21402
--- /dev/null
+++ b/drivers/gpu/pvr/pvrversion.h
@@ -0,0 +1,38 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _PVRVERSION_H_
28#define _PVRVERSION_H_
29
30#define PVRVERSION_MAJ 1
31#define PVRVERSION_MIN 6
32#define PVRVERSION_BRANCH 16
33#define PVRVERSION_BUILD 3421
34#define PVRVERSION_STRING "1.6.16.3421"
35#define PVRVERSION_FILE "eurasiacon.pj"
36
37#endif
38
diff --git a/drivers/gpu/pvr/queue.c b/drivers/gpu/pvr/queue.c
new file mode 100644
index 00000000000..5340571d64c
--- /dev/null
+++ b/drivers/gpu/pvr/queue.c
@@ -0,0 +1,1154 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28
29#include "lists.h"
30
31#if defined(__linux__) && defined(__KERNEL__)
32
33#include "proc.h"
34
35static IMG_INT
36QueuePrintCommands (PVRSRV_QUEUE_INFO * psQueue, IMG_CHAR * buffer, size_t size)
37{
38 off_t off = 0;
39 IMG_INT cmds = 0;
40 IMG_SIZE_T ui32ReadOffset = psQueue->ui32ReadOffset;
41 IMG_SIZE_T ui32WriteOffset = psQueue->ui32WriteOffset;
42 PVRSRV_COMMAND * psCmd;
43
44 while (ui32ReadOffset != ui32WriteOffset)
45 {
46 psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
47
48 off = printAppend(buffer, size, off, "%x %x %5u %6u %3u %5u %2u %2u %3u \n",
49 (IMG_UINTPTR_T)psQueue,
50 (IMG_UINTPTR_T)psCmd,
51 psCmd->ui32ProcessID,
52 psCmd->CommandType,
53 psCmd->ui32CmdSize,
54 psCmd->ui32DevIndex,
55 psCmd->ui32DstSyncCount,
56 psCmd->ui32SrcSyncCount,
57 psCmd->ui32DataSize);
58
59 ui32ReadOffset += psCmd->ui32CmdSize;
60 ui32ReadOffset &= psQueue->ui32QueueSize - 1;
61 cmds++;
62 }
63 if (cmds == 0)
64 {
65 off = printAppend(buffer, size, off, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
66 }
67 return off;
68}
69
70
71
72void ProcSeqShowQueue(struct seq_file *sfile,void* el)
73{
74 PVRSRV_QUEUE_INFO * psQueue = (PVRSRV_QUEUE_INFO*)el;
75 IMG_INT cmds = 0;
76 IMG_SIZE_T ui32ReadOffset;
77 IMG_SIZE_T ui32WriteOffset;
78 PVRSRV_COMMAND * psCmd;
79
80 if(el == PVR_PROC_SEQ_START_TOKEN)
81 {
82 seq_printf( sfile,
83 "Command Queues\n"
84 "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
85 return;
86 }
87
88 ui32ReadOffset = psQueue->ui32ReadOffset;
89 ui32WriteOffset = psQueue->ui32WriteOffset;
90
91 while (ui32ReadOffset != ui32WriteOffset)
92 {
93 psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
94
95 seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n",
96 (IMG_UINTPTR_T)psQueue,
97 (IMG_UINTPTR_T)psCmd,
98 psCmd->ui32ProcessID,
99 psCmd->CommandType,
100 psCmd->ui32CmdSize,
101 psCmd->ui32DevIndex,
102 psCmd->ui32DstSyncCount,
103 psCmd->ui32SrcSyncCount,
104 psCmd->ui32DataSize);
105
106 ui32ReadOffset += psCmd->ui32CmdSize;
107 ui32ReadOffset &= psQueue->ui32QueueSize - 1;
108 cmds++;
109 }
110
111 if (cmds == 0)
112 {
113 seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
114 }
115}
116
117void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
118{
119 PVRSRV_QUEUE_INFO * psQueue;
120 SYS_DATA * psSysData;
121
122 PVR_UNREFERENCED_PARAMETER(sfile);
123
124 if(!off)
125 {
126 return PVR_PROC_SEQ_START_TOKEN;
127 }
128
129
130 SysAcquireData(&psSysData);
131
132 for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
133 return psQueue;
134}
135
136off_t
137QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off)
138{
139 SYS_DATA * psSysData;
140 PVRSRV_QUEUE_INFO * psQueue;
141
142 SysAcquireData(&psSysData);
143
144 if (!off)
145 return printAppend (buffer, size, 0,
146 "Command Queues\n"
147 "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
148
149
150 for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM)
151 ;
152
153 return psQueue ? QueuePrintCommands (psQueue, buffer, size) : END_OF_FILE;
154}
155#endif
156
157#define GET_SPACE_IN_CMDQ(psQueue) \
158 ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \
159 + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
160
161#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
162 (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \
163 & ((psQueue)->ui32QueueSize - 1);
164
165#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
166 ((ui32OpsComplete) >= (ui32OpsPending))
167
168
169static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
170 IMG_UINT32 i,
171 IMG_BOOL bIsSrc)
172{
173 PVRSRV_SYNC_OBJECT *psSyncObject;
174
175 psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
176
177 if (psCmdCompleteData->bInUse)
178 {
179 PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x",
180 bIsSrc ? "SRC" : "DEST", i,
181 psSyncObject[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
182 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsPending,
183 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete,
184 psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
185 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
186 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete))
187 }
188 else
189 {
190 PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
191 }
192}
193
194
195static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
196{
197 if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
198 {
199 IMG_UINT32 i;
200 SYS_DATA *psSysData;
201 COMMAND_COMPLETE_DATA **ppsCmdCompleteData;
202 COMMAND_COMPLETE_DATA *psCmdCompleteData;
203
204 SysAcquireData(&psSysData);
205
206 ppsCmdCompleteData = psSysData->ppsCmdCompleteData[psDeviceNode->sDevId.ui32DeviceIndex];
207
208 if (ppsCmdCompleteData != IMG_NULL)
209 {
210 psCmdCompleteData = ppsCmdCompleteData[DC_FLIP_COMMAND];
211
212 PVR_LOG(("Command Complete Data for display device %u:", psDeviceNode->sDevId.ui32DeviceIndex))
213
214 for (i = 0; i < psCmdCompleteData->ui32SrcSyncCount; i++)
215 {
216 QueueDumpCmdComplete(psCmdCompleteData, i, IMG_TRUE);
217 }
218
219 for (i = 0; i < psCmdCompleteData->ui32DstSyncCount; i++)
220 {
221 QueueDumpCmdComplete(psCmdCompleteData, i, IMG_FALSE);
222 }
223 }
224 else
225 {
226 PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
227 }
228 }
229}
230
231
232IMG_VOID QueueDumpDebugInfo(IMG_VOID)
233{
234 SYS_DATA *psSysData;
235 SysAcquireData(&psSysData);
236 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
237}
238
239
240static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
241{
242 IMG_SIZE_T ui32Temp, ui32Result = 1;
243
244 if(!ui32Value)
245 return 0;
246
247 ui32Temp = ui32Value - 1;
248 while(ui32Temp)
249 {
250 ui32Result <<= 1;
251 ui32Temp >>= 1;
252 }
253
254 return ui32Result;
255}
256
257
258IMG_EXPORT
259PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
260 PVRSRV_QUEUE_INFO **ppsQueueInfo)
261{
262 PVRSRV_QUEUE_INFO *psQueueInfo;
263 IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize);
264 SYS_DATA *psSysData;
265 PVRSRV_ERROR eError;
266 IMG_HANDLE hMemBlock;
267
268 SysAcquireData(&psSysData);
269
270
271 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
272 sizeof(PVRSRV_QUEUE_INFO),
273 (IMG_VOID **)&psQueueInfo, &hMemBlock,
274 "Queue Info");
275 if (eError != PVRSRV_OK)
276 {
277 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
278 goto ErrorExit;
279 }
280 OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
281
282 psQueueInfo->hMemBlock[0] = hMemBlock;
283 psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
284
285
286 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
287 ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
288 &psQueueInfo->pvLinQueueKM, &hMemBlock,
289 "Command Queue");
290 if (eError != PVRSRV_OK)
291 {
292 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
293 goto ErrorExit;
294 }
295
296 psQueueInfo->hMemBlock[1] = hMemBlock;
297 psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
298
299
300 PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
301 PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
302
303 psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
304
305
306 if (psSysData->psQueueList == IMG_NULL)
307 {
308 eError = OSCreateResource(&psSysData->sQProcessResource);
309 if (eError != PVRSRV_OK)
310 {
311 goto ErrorExit;
312 }
313 }
314
315
316 eError = OSLockResource(&psSysData->sQProcessResource,
317 KERNEL_ID);
318 if (eError != PVRSRV_OK)
319 {
320 goto ErrorExit;
321 }
322
323 psQueueInfo->psNextKM = psSysData->psQueueList;
324 psSysData->psQueueList = psQueueInfo;
325
326 eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
327 if (eError != PVRSRV_OK)
328 {
329 goto ErrorExit;
330 }
331
332 *ppsQueueInfo = psQueueInfo;
333
334 return PVRSRV_OK;
335
336ErrorExit:
337
338 if(psQueueInfo)
339 {
340 if(psQueueInfo->pvLinQueueKM)
341 {
342 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
343 psQueueInfo->ui32QueueSize,
344 psQueueInfo->pvLinQueueKM,
345 psQueueInfo->hMemBlock[1]);
346 psQueueInfo->pvLinQueueKM = IMG_NULL;
347 }
348
349 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
350 sizeof(PVRSRV_QUEUE_INFO),
351 psQueueInfo,
352 psQueueInfo->hMemBlock[0]);
353
354 }
355
356 return eError;
357}
358
359
360IMG_EXPORT
361PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
362{
363 PVRSRV_QUEUE_INFO *psQueue;
364 SYS_DATA *psSysData;
365 PVRSRV_ERROR eError;
366 IMG_BOOL bTimeout = IMG_TRUE;
367
368 SysAcquireData(&psSysData);
369
370 psQueue = psSysData->psQueueList;
371
372
373 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
374 {
375 if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
376 {
377 bTimeout = IMG_FALSE;
378 break;
379 }
380 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
381 } END_LOOP_UNTIL_TIMEOUT();
382
383 if (bTimeout)
384 {
385
386 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
387 eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
388 goto ErrorExit;
389 }
390
391
392 eError = OSLockResource(&psSysData->sQProcessResource,
393 KERNEL_ID);
394 if (eError != PVRSRV_OK)
395 {
396 goto ErrorExit;
397 }
398
399 if(psQueue == psQueueInfo)
400 {
401 psSysData->psQueueList = psQueueInfo->psNextKM;
402
403 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
404 NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
405 psQueueInfo->pvLinQueueKM,
406 psQueueInfo->hMemBlock[1]);
407 psQueueInfo->pvLinQueueKM = IMG_NULL;
408 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
409 sizeof(PVRSRV_QUEUE_INFO),
410 psQueueInfo,
411 psQueueInfo->hMemBlock[0]);
412
413 psQueueInfo = IMG_NULL;
414 }
415 else
416 {
417 while(psQueue)
418 {
419 if(psQueue->psNextKM == psQueueInfo)
420 {
421 psQueue->psNextKM = psQueueInfo->psNextKM;
422
423 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
424 psQueueInfo->ui32QueueSize,
425 psQueueInfo->pvLinQueueKM,
426 psQueueInfo->hMemBlock[1]);
427 psQueueInfo->pvLinQueueKM = IMG_NULL;
428 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
429 sizeof(PVRSRV_QUEUE_INFO),
430 psQueueInfo,
431 psQueueInfo->hMemBlock[0]);
432
433 psQueueInfo = IMG_NULL;
434 break;
435 }
436 psQueue = psQueue->psNextKM;
437 }
438
439 if(!psQueue)
440 {
441 eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
442 if (eError != PVRSRV_OK)
443 {
444 goto ErrorExit;
445 }
446 eError = PVRSRV_ERROR_INVALID_PARAMS;
447 goto ErrorExit;
448 }
449 }
450
451
452 eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
453 if (eError != PVRSRV_OK)
454 {
455 goto ErrorExit;
456 }
457
458
459 if (psSysData->psQueueList == IMG_NULL)
460 {
461 eError = OSDestroyResource(&psSysData->sQProcessResource);
462 if (eError != PVRSRV_OK)
463 {
464 goto ErrorExit;
465 }
466 }
467
468ErrorExit:
469
470 return eError;
471}
472
473
474IMG_EXPORT
475PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
476 IMG_SIZE_T ui32ParamSize,
477 IMG_VOID **ppvSpace)
478{
479 IMG_BOOL bTimeout = IMG_TRUE;
480
481
482 ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC;
483
484 if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
485 {
486 PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
487 return PVRSRV_ERROR_CMD_TOO_BIG;
488 }
489
490
491 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
492 {
493 if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
494 {
495 bTimeout = IMG_FALSE;
496 break;
497 }
498 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
499 } END_LOOP_UNTIL_TIMEOUT();
500
501 if (bTimeout == IMG_TRUE)
502 {
503 *ppvSpace = IMG_NULL;
504
505 return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
506 }
507 else
508 {
509 *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
510 }
511
512 return PVRSRV_OK;
513}
514
515
516IMG_EXPORT
517PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
518 PVRSRV_COMMAND **ppsCommand,
519 IMG_UINT32 ui32DevIndex,
520 IMG_UINT16 CommandType,
521 IMG_UINT32 ui32DstSyncCount,
522 PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
523 IMG_UINT32 ui32SrcSyncCount,
524 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
525 IMG_SIZE_T ui32DataByteSize )
526{
527 PVRSRV_ERROR eError;
528 PVRSRV_COMMAND *psCommand;
529 IMG_SIZE_T ui32CommandSize;
530 IMG_UINT32 i;
531
532
533 ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
534
535
536 ui32CommandSize = sizeof(PVRSRV_COMMAND)
537 + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
538 + ui32DataByteSize;
539
540
541 eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
542 if(eError != PVRSRV_OK)
543 {
544 return eError;
545 }
546
547 psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
548
549
550 psCommand->ui32CmdSize = ui32CommandSize;
551 psCommand->ui32DevIndex = ui32DevIndex;
552 psCommand->CommandType = CommandType;
553 psCommand->ui32DstSyncCount = ui32DstSyncCount;
554 psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
555
556
557 psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
558
559
560 psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
561 + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
562
563 psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
564 + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
565 psCommand->ui32DataSize = ui32DataByteSize;
566
567
568 for (i=0; i<ui32DstSyncCount; i++)
569 {
570 psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
571 psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
572 psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
573
574 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
575 i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
576 psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
577 psCommand->psDstSync[i].ui32ReadOpsPending,
578 psCommand->psDstSync[i].ui32WriteOpsPending));
579 }
580
581
582 for (i=0; i<ui32SrcSyncCount; i++)
583 {
584 psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
585 psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
586 psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
587
588 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
589 i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
590 psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
591 psCommand->psSrcSync[i].ui32ReadOpsPending,
592 psCommand->psSrcSync[i].ui32WriteOpsPending));
593 }
594
595
596 *ppsCommand = psCommand;
597
598 return PVRSRV_OK;
599}
600
601
602IMG_EXPORT
603PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
604 PVRSRV_COMMAND *psCommand)
605{
606
607
608
609 if (psCommand->ui32DstSyncCount > 0)
610 {
611 psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
612 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
613 }
614
615 if (psCommand->ui32SrcSyncCount > 0)
616 {
617 psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
618 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
619 + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
620 }
621
622 psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
623 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
624 + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
625 + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
626
627
628 UPDATE_QUEUE_WOFF(psQueue, psCommand->ui32CmdSize);
629
630 return PVRSRV_OK;
631}
632
633
634
635static
636PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData,
637 PVRSRV_COMMAND *psCommand,
638 IMG_BOOL bFlush)
639{
640 PVRSRV_SYNC_OBJECT *psWalkerObj;
641 PVRSRV_SYNC_OBJECT *psEndObj;
642 IMG_UINT32 i;
643 COMMAND_COMPLETE_DATA *psCmdCompleteData;
644 PVRSRV_ERROR eError = PVRSRV_OK;
645 IMG_UINT32 ui32WriteOpsComplete;
646 IMG_UINT32 ui32ReadOpsComplete;
647
648
649 psWalkerObj = psCommand->psDstSync;
650 psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
651 while (psWalkerObj < psEndObj)
652 {
653 PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
654
655 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
656 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
657
658 if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
659 || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
660 {
661 if (!bFlush ||
662 !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
663 !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
664 {
665 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
666 }
667 }
668
669 psWalkerObj++;
670 }
671
672
673 psWalkerObj = psCommand->psSrcSync;
674 psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
675 while (psWalkerObj < psEndObj)
676 {
677 PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
678
679 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
680 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
681
682 if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
683 || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
684 {
685 if (!bFlush &&
686 SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
687 SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
688 {
689 PVR_DPF((PVR_DBG_WARNING,
690 "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
691 (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
692 }
693
694 if (!bFlush ||
695 !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
696 !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
697 {
698 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
699 }
700 }
701 psWalkerObj++;
702 }
703
704
705 if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
706 {
707 PVR_DPF((PVR_DBG_ERROR,
708 "PVRSRVProcessCommand: invalid DeviceType 0x%x",
709 psCommand->ui32DevIndex));
710 return PVRSRV_ERROR_INVALID_PARAMS;
711 }
712
713
714 psCmdCompleteData = psSysData->ppsCmdCompleteData[psCommand->ui32DevIndex][psCommand->CommandType];
715 if (psCmdCompleteData->bInUse)
716 {
717
718 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
719 }
720
721
722 psCmdCompleteData->bInUse = IMG_TRUE;
723
724
725 psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
726 for (i=0; i<psCommand->ui32DstSyncCount; i++)
727 {
728 psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
729
730 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
731 i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
732 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
733 psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
734 psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
735 }
736
737
738
739 psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
740 for (i=0; i<psCommand->ui32SrcSyncCount; i++)
741 {
742 psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
743
744 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
745 i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
746 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
747 psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
748 psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
749 }
750
751
752
753
754
755
756
757
758
759
760
761 if (psSysData->ppfnCmdProcList[psCommand->ui32DevIndex][psCommand->CommandType]((IMG_HANDLE)psCmdCompleteData,
762 psCommand->ui32DataSize,
763 psCommand->pvData) == IMG_FALSE)
764 {
765
766
767
768 psCmdCompleteData->bInUse = IMG_FALSE;
769 eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
770 }
771
772 return eError;
773}
774
775
776static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
777{
778 if (psDeviceNode->bReProcessDeviceCommandComplete &&
779 psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
780 {
781 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
782 }
783}
784
785IMG_EXPORT
786PVRSRV_ERROR PVRSRVProcessQueues(IMG_UINT32 ui32CallerID,
787 IMG_BOOL bFlush)
788{
789 PVRSRV_QUEUE_INFO *psQueue;
790 SYS_DATA *psSysData;
791 PVRSRV_COMMAND *psCommand;
792 PVRSRV_ERROR eError;
793
794 SysAcquireData(&psSysData);
795
796
797 psSysData->bReProcessQueues = IMG_FALSE;
798
799
800 eError = OSLockResource(&psSysData->sQProcessResource,
801 ui32CallerID);
802 if(eError != PVRSRV_OK)
803 {
804
805 psSysData->bReProcessQueues = IMG_TRUE;
806
807
808 if(ui32CallerID == ISR_ID)
809 {
810 if (bFlush)
811 {
812 PVR_DPF((PVR_DBG_ERROR,"PVRSRVProcessQueues: Couldn't acquire queue processing lock for FLUSH"));
813 }
814 else
815 {
816 PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Couldn't acquire queue processing lock"));
817 }
818 }
819 else
820 {
821 PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Queue processing lock-acquire failed when called from the Services driver."));
822 PVR_DPF((PVR_DBG_MESSAGE," This is due to MISR queue processing being interrupted by the Services driver."));
823 }
824
825 return PVRSRV_OK;
826 }
827
828 psQueue = psSysData->psQueueList;
829
830 if(!psQueue)
831 {
832 PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
833 }
834
835 if (bFlush)
836 {
837 PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
838 }
839
840 while (psQueue)
841 {
842 while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
843 {
844 psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
845
846 if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
847 {
848
849 UPDATE_QUEUE_ROFF(psQueue, psCommand->ui32CmdSize)
850
851 if (bFlush)
852 {
853 continue;
854 }
855 }
856
857 break;
858 }
859 psQueue = psQueue->psNextKM;
860 }
861
862 if (bFlush)
863 {
864 PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
865 }
866
867
868 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
869 &PVRSRVProcessQueues_ForEachCb);
870
871
872
873 OSUnlockResource(&psSysData->sQProcessResource, ui32CallerID);
874
875
876 if(psSysData->bReProcessQueues)
877 {
878 return PVRSRV_ERROR_PROCESSING_BLOCKED;
879 }
880
881 return PVRSRV_OK;
882}
883
884#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
885IMG_INTERNAL
886IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
887 IMG_BOOL bScheduleMISR)
888{
889 COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
890 SYS_DATA *psSysData;
891
892 SysAcquireData(&psSysData);
893
894
895 psCmdCompleteData->bInUse = IMG_FALSE;
896
897
898 PVRSRVScheduleDeviceCallbacks();
899
900#if defined(SYS_USING_INTERRUPTS)
901 if(bScheduleMISR)
902 {
903 OSScheduleMISR(psSysData);
904 }
905#else
906 PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
907#endif
908}
909
910#endif
911
912
913IMG_EXPORT
914IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
915 IMG_BOOL bScheduleMISR)
916{
917 IMG_UINT32 i;
918 COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
919 SYS_DATA *psSysData;
920
921 SysAcquireData(&psSysData);
922
923
924 for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
925 {
926 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
927
928 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
929 i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
930 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
931 psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
932 psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
933 }
934
935
936 for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
937 {
938 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
939
940 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
941 i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
942 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
943 psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
944 psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
945 }
946
947
948 psCmdCompleteData->bInUse = IMG_FALSE;
949
950
951 PVRSRVScheduleDeviceCallbacks();
952
953#if defined(SYS_USING_INTERRUPTS)
954 if(bScheduleMISR)
955 {
956 OSScheduleMISR(psSysData);
957 }
958#else
959 PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
960#endif
961}
962
963
964
965
966IMG_EXPORT
967PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
968 PFN_CMD_PROC *ppfnCmdProcList,
969 IMG_UINT32 ui32MaxSyncsPerCmd[][2],
970 IMG_UINT32 ui32CmdCount)
971{
972 SYS_DATA *psSysData;
973 PVRSRV_ERROR eError;
974 IMG_UINT32 i;
975 IMG_SIZE_T ui32AllocSize;
976 PFN_CMD_PROC *ppfnCmdProc;
977 COMMAND_COMPLETE_DATA *psCmdCompleteData;
978
979
980 if(ui32DevIndex >= SYS_DEVICE_COUNT)
981 {
982 PVR_DPF((PVR_DBG_ERROR,
983 "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
984 ui32DevIndex));
985 return PVRSRV_ERROR_INVALID_PARAMS;
986 }
987
988
989 SysAcquireData(&psSysData);
990
991
992 eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
993 ui32CmdCount * sizeof(PFN_CMD_PROC),
994 (IMG_VOID **)&psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL,
995 "Internal Queue Info structure");
996 if (eError != PVRSRV_OK)
997 {
998 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc queue"));
999 return eError;
1000 }
1001
1002
1003 ppfnCmdProc = psSysData->ppfnCmdProcList[ui32DevIndex];
1004
1005
1006 for (i=0; i<ui32CmdCount; i++)
1007 {
1008 ppfnCmdProc[i] = ppfnCmdProcList[i];
1009 }
1010
1011
1012 ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
1013 eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
1014 ui32AllocSize,
1015 (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL,
1016 "Array of Pointers for Command Store");
1017 if (eError != PVRSRV_OK)
1018 {
1019 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
1020 goto ErrorExit;
1021 }
1022
1023 for (i=0; i<ui32CmdCount; i++)
1024 {
1025
1026
1027 ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
1028 + ((ui32MaxSyncsPerCmd[i][0]
1029 + ui32MaxSyncsPerCmd[i][1])
1030 * sizeof(PVRSRV_SYNC_OBJECT));
1031
1032 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1033 ui32AllocSize,
1034 (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex][i],
1035 IMG_NULL,
1036 "Command Complete Data");
1037 if (eError != PVRSRV_OK)
1038 {
1039 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d",i));
1040 goto ErrorExit;
1041 }
1042
1043
1044 OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex][i], 0x00, ui32AllocSize);
1045
1046 psCmdCompleteData = psSysData->ppsCmdCompleteData[ui32DevIndex][i];
1047
1048
1049 psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
1050 (((IMG_UINTPTR_T)psCmdCompleteData)
1051 + sizeof(COMMAND_COMPLETE_DATA));
1052 psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
1053 (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
1054 + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[i][0]));
1055
1056 psCmdCompleteData->ui32AllocSize = ui32AllocSize;
1057 }
1058
1059 return PVRSRV_OK;
1060
1061ErrorExit:
1062
1063
1064
1065 if(psSysData->ppsCmdCompleteData[ui32DevIndex] != IMG_NULL)
1066 {
1067 for (i=0; i<ui32CmdCount; i++)
1068 {
1069 if (psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
1070 {
1071 ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
1072 + ((ui32MaxSyncsPerCmd[i][0]
1073 + ui32MaxSyncsPerCmd[i][1])
1074 * sizeof(PVRSRV_SYNC_OBJECT));
1075 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex][i], IMG_NULL);
1076 psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
1077 }
1078 }
1079 ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
1080 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL);
1081 psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
1082 }
1083
1084 if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
1085 {
1086 ui32AllocSize = ui32CmdCount * sizeof(PFN_CMD_PROC);
1087 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL);
1088 psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;
1089 }
1090
1091 return eError;
1092}
1093
1094
1095IMG_EXPORT
1096PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
1097 IMG_UINT32 ui32CmdCount)
1098{
1099 SYS_DATA *psSysData;
1100 IMG_UINT32 i;
1101
1102
1103 if(ui32DevIndex >= SYS_DEVICE_COUNT)
1104 {
1105 PVR_DPF((PVR_DBG_ERROR,
1106 "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
1107 ui32DevIndex));
1108 return PVRSRV_ERROR_INVALID_PARAMS;
1109 }
1110
1111
1112 SysAcquireData(&psSysData);
1113
1114 if(psSysData->ppsCmdCompleteData[ui32DevIndex] == IMG_NULL)
1115 {
1116 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveCmdProcListKM: Invalid command array"));
1117 return PVRSRV_ERROR_INVALID_PARAMS;
1118 }
1119 else
1120 {
1121 for(i=0; i<ui32CmdCount; i++)
1122 {
1123
1124 if(psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
1125 {
1126 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1127 psSysData->ppsCmdCompleteData[ui32DevIndex][i]->ui32AllocSize,
1128 psSysData->ppsCmdCompleteData[ui32DevIndex][i],
1129 IMG_NULL);
1130 psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
1131 }
1132 }
1133
1134
1135 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1136 ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*),
1137 psSysData->ppsCmdCompleteData[ui32DevIndex],
1138 IMG_NULL);
1139 psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
1140 }
1141
1142
1143 if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
1144 {
1145 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1146 ui32CmdCount * sizeof(PFN_CMD_PROC),
1147 psSysData->ppfnCmdProcList[ui32DevIndex],
1148 IMG_NULL);
1149 psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;
1150 }
1151
1152 return PVRSRV_OK;
1153}
1154
diff --git a/drivers/gpu/pvr/queue.h b/drivers/gpu/pvr/queue.h
new file mode 100644
index 00000000000..06aa200140f
--- /dev/null
+++ b/drivers/gpu/pvr/queue.h
@@ -0,0 +1,114 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef QUEUE_H
28#define QUEUE_H
29
30
31#if defined(__cplusplus)
32extern "C" {
33#endif
34
35#define UPDATE_QUEUE_ROFF(psQueue, ui32Size) \
36 (psQueue)->ui32ReadOffset = ((psQueue)->ui32ReadOffset + (ui32Size)) \
37 & ((psQueue)->ui32QueueSize - 1);
38
39 typedef struct _COMMAND_COMPLETE_DATA_
40 {
41 IMG_BOOL bInUse;
42
43 IMG_UINT32 ui32DstSyncCount;
44 IMG_UINT32 ui32SrcSyncCount;
45 PVRSRV_SYNC_OBJECT *psDstSync;
46 PVRSRV_SYNC_OBJECT *psSrcSync;
47 IMG_UINT32 ui32AllocSize;
48 }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA;
49
50#if !defined(USE_CODE)
51IMG_VOID QueueDumpDebugInfo(IMG_VOID);
52
53IMG_IMPORT
54PVRSRV_ERROR PVRSRVProcessQueues (IMG_UINT32 ui32CallerID,
55 IMG_BOOL bFlush);
56
57#if defined(__linux__) && defined(__KERNEL__)
58#include <linux/types.h>
59#include <linux/seq_file.h>
60off_t
61QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off);
62
63void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off);
64void ProcSeqShowQueue(struct seq_file *sfile,void* el);
65#endif
66
67
68IMG_IMPORT
69PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
70 PVRSRV_QUEUE_INFO **ppsQueueInfo);
71IMG_IMPORT
72PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
73
74IMG_IMPORT
75PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
76 PVRSRV_COMMAND **ppsCommand,
77 IMG_UINT32 ui32DevIndex,
78 IMG_UINT16 CommandType,
79 IMG_UINT32 ui32DstSyncCount,
80 PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
81 IMG_UINT32 ui32SrcSyncCount,
82 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
83 IMG_SIZE_T ui32DataByteSize );
84
85IMG_IMPORT
86PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
87 IMG_SIZE_T ui32ParamSize,
88 IMG_VOID **ppvSpace);
89
90IMG_IMPORT
91PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
92 PVRSRV_COMMAND *psCommand);
93
94IMG_IMPORT
95IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR);
96
97IMG_IMPORT
98PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
99 PFN_CMD_PROC *ppfnCmdProcList,
100 IMG_UINT32 ui32MaxSyncsPerCmd[][2],
101 IMG_UINT32 ui32CmdCount);
102IMG_IMPORT
103PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
104 IMG_UINT32 ui32CmdCount);
105
106#endif
107
108
109#if defined (__cplusplus)
110}
111#endif
112
113#endif
114
diff --git a/drivers/gpu/pvr/ra.c b/drivers/gpu/pvr/ra.c
new file mode 100644
index 00000000000..191be844004
--- /dev/null
+++ b/drivers/gpu/pvr/ra.c
@@ -0,0 +1,1725 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "hash.h"
29#include "ra.h"
30#include "buffer_manager.h"
31#include "osfunc.h"
32
33#ifdef __linux__
34#include <linux/kernel.h>
35#include "proc.h"
36#endif
37
38#ifdef USE_BM_FREESPACE_CHECK
39#include <stdio.h>
40#endif
41
42#define MINIMUM_HASH_SIZE (64)
43
44#if defined(VALIDATE_ARENA_TEST)
45
46typedef enum RESOURCE_DESCRIPTOR_TAG {
47
48 RESOURCE_SPAN_LIVE = 10,
49 RESOURCE_SPAN_FREE,
50 IMPORTED_RESOURCE_SPAN_START,
51 IMPORTED_RESOURCE_SPAN_LIVE,
52 IMPORTED_RESOURCE_SPAN_FREE,
53 IMPORTED_RESOURCE_SPAN_END,
54
55} RESOURCE_DESCRIPTOR;
56
57typedef enum RESOURCE_TYPE_TAG {
58
59 IMPORTED_RESOURCE_TYPE = 20,
60 NON_IMPORTED_RESOURCE_TYPE
61
62} RESOURCE_TYPE;
63
64
65static IMG_UINT32 ui32BoundaryTagID = 0;
66
67IMG_UINT32 ValidateArena(RA_ARENA *pArena);
68#endif
69
70struct _BT_
71{
72 enum bt_type
73 {
74 btt_span,
75 btt_free,
76 btt_live
77 } type;
78
79
80 IMG_UINTPTR_T base;
81 IMG_SIZE_T uSize;
82
83
84 struct _BT_ *pNextSegment;
85 struct _BT_ *pPrevSegment;
86
87 struct _BT_ *pNextFree;
88 struct _BT_ *pPrevFree;
89
90 BM_MAPPING *psMapping;
91
92#if defined(VALIDATE_ARENA_TEST)
93 RESOURCE_DESCRIPTOR eResourceSpan;
94 RESOURCE_TYPE eResourceType;
95
96
97 IMG_UINT32 ui32BoundaryTagID;
98#endif
99
100};
101typedef struct _BT_ BT;
102
103
104struct _RA_ARENA_
105{
106
107 IMG_CHAR *name;
108
109
110 IMG_SIZE_T uQuantum;
111
112
113 IMG_BOOL (*pImportAlloc)(IMG_VOID *,
114 IMG_SIZE_T uSize,
115 IMG_SIZE_T *pActualSize,
116 BM_MAPPING **ppsMapping,
117 IMG_UINT32 uFlags,
118 IMG_UINTPTR_T *pBase);
119 IMG_VOID (*pImportFree) (IMG_VOID *,
120 IMG_UINTPTR_T,
121 BM_MAPPING *psMapping);
122 IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE);
123
124
125 IMG_VOID *pImportHandle;
126
127
128#define FREE_TABLE_LIMIT 32
129
130
131 BT *aHeadFree [FREE_TABLE_LIMIT];
132
133
134 BT *pHeadSegment;
135 BT *pTailSegment;
136
137
138 HASH_TABLE *pSegmentHash;
139
140#ifdef RA_STATS
141 RA_STATISTICS sStatistics;
142#endif
143
144#if defined(CONFIG_PROC_FS) && defined(DEBUG)
145#define PROC_NAME_SIZE 32
146
147 struct proc_dir_entry* pProcInfo;
148 struct proc_dir_entry* pProcSegs;
149
150 IMG_BOOL bInitProcEntry;
151#endif
152};
153#if defined(ENABLE_RA_DUMP)
154IMG_VOID RA_Dump (RA_ARENA *pArena);
155#endif
156
157#if defined(CONFIG_PROC_FS) && defined(DEBUG)
158
159static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el);
160static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off);
161
162static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el);
163static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off);
164
165#endif
166
167#ifdef USE_BM_FREESPACE_CHECK
168IMG_VOID CheckBMFreespace(IMG_VOID);
169#endif
170
171#if defined(CONFIG_PROC_FS) && defined(DEBUG)
172static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS)
173{
174 IMG_CHAR *pT;
175
176 for(pT = pS; *pT != 0; pT++)
177 {
178 if (*pT == ' ' || *pT == '\t')
179 {
180 *pT = '_';
181 }
182 }
183
184 return pS;
185}
186#endif
187
188static IMG_BOOL
189_RequestAllocFail (IMG_VOID *_h,
190 IMG_SIZE_T _uSize,
191 IMG_SIZE_T *_pActualSize,
192 BM_MAPPING **_ppsMapping,
193 IMG_UINT32 _uFlags,
194 IMG_UINTPTR_T *_pBase)
195{
196 PVR_UNREFERENCED_PARAMETER (_h);
197 PVR_UNREFERENCED_PARAMETER (_uSize);
198 PVR_UNREFERENCED_PARAMETER (_pActualSize);
199 PVR_UNREFERENCED_PARAMETER (_ppsMapping);
200 PVR_UNREFERENCED_PARAMETER (_uFlags);
201 PVR_UNREFERENCED_PARAMETER (_pBase);
202
203 return IMG_FALSE;
204}
205
206static IMG_UINT32
207pvr_log2 (IMG_SIZE_T n)
208{
209 IMG_UINT32 l = 0;
210 n>>=1;
211 while (n>0)
212 {
213 n>>=1;
214 l++;
215 }
216 return l;
217}
218
219static PVRSRV_ERROR
220_SegmentListInsertAfter (RA_ARENA *pArena,
221 BT *pInsertionPoint,
222 BT *pBT)
223{
224 PVR_ASSERT (pArena != IMG_NULL);
225 PVR_ASSERT (pInsertionPoint != IMG_NULL);
226
227 if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL))
228 {
229 PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters"));
230 return PVRSRV_ERROR_INVALID_PARAMS;
231 }
232
233 pBT->pNextSegment = pInsertionPoint->pNextSegment;
234 pBT->pPrevSegment = pInsertionPoint;
235 if (pInsertionPoint->pNextSegment == IMG_NULL)
236 pArena->pTailSegment = pBT;
237 else
238 pInsertionPoint->pNextSegment->pPrevSegment = pBT;
239 pInsertionPoint->pNextSegment = pBT;
240
241 return PVRSRV_OK;
242}
243
244static PVRSRV_ERROR
245_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
246{
247 PVRSRV_ERROR eError = PVRSRV_OK;
248
249
250 if (pArena->pHeadSegment == IMG_NULL)
251 {
252 pArena->pHeadSegment = pArena->pTailSegment = pBT;
253 pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL;
254 }
255 else
256 {
257 BT *pBTScan;
258
259 if (pBT->base < pArena->pHeadSegment->base)
260 {
261
262 pBT->pNextSegment = pArena->pHeadSegment;
263 pArena->pHeadSegment->pPrevSegment = pBT;
264 pArena->pHeadSegment = pBT;
265 pBT->pPrevSegment = IMG_NULL;
266 }
267 else
268 {
269
270
271
272
273 pBTScan = pArena->pHeadSegment;
274
275 while ((pBTScan->pNextSegment != IMG_NULL) && (pBT->base >= pBTScan->pNextSegment->base))
276 {
277 pBTScan = pBTScan->pNextSegment;
278 }
279
280 eError = _SegmentListInsertAfter (pArena, pBTScan, pBT);
281 if (eError != PVRSRV_OK)
282 {
283 return eError;
284 }
285 }
286 }
287 return eError;
288}
289
290static IMG_VOID
291_SegmentListRemove (RA_ARENA *pArena, BT *pBT)
292{
293 if (pBT->pPrevSegment == IMG_NULL)
294 pArena->pHeadSegment = pBT->pNextSegment;
295 else
296 pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
297
298 if (pBT->pNextSegment == IMG_NULL)
299 pArena->pTailSegment = pBT->pPrevSegment;
300 else
301 pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
302}
303
304static BT *
305_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize)
306{
307 BT *pNeighbour;
308
309 PVR_ASSERT (pArena != IMG_NULL);
310
311 if (pArena == IMG_NULL)
312 {
313 PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena"));
314 return IMG_NULL;
315 }
316
317 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
318 sizeof(BT),
319 (IMG_VOID **)&pNeighbour, IMG_NULL,
320 "Boundary Tag") != PVRSRV_OK)
321 {
322 return IMG_NULL;
323 }
324
325 OSMemSet(pNeighbour, 0, sizeof(BT));
326
327#if defined(VALIDATE_ARENA_TEST)
328 pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID;
329#endif
330
331 pNeighbour->pPrevSegment = pBT;
332 pNeighbour->pNextSegment = pBT->pNextSegment;
333 if (pBT->pNextSegment == IMG_NULL)
334 pArena->pTailSegment = pNeighbour;
335 else
336 pBT->pNextSegment->pPrevSegment = pNeighbour;
337 pBT->pNextSegment = pNeighbour;
338
339 pNeighbour->type = btt_free;
340 pNeighbour->uSize = pBT->uSize - uSize;
341 pNeighbour->base = pBT->base + uSize;
342 pNeighbour->psMapping = pBT->psMapping;
343 pBT->uSize = uSize;
344
345#if defined(VALIDATE_ARENA_TEST)
346 if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
347 {
348 pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE;
349 pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
350 }
351 else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
352 {
353 pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
354 pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE;
355 }
356 else
357 {
358 PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized"));
359 PVR_DBG_BREAK;
360 }
361#endif
362
363 return pNeighbour;
364}
365
366static IMG_VOID
367_FreeListInsert (RA_ARENA *pArena, BT *pBT)
368{
369 IMG_UINT32 uIndex;
370 uIndex = pvr_log2 (pBT->uSize);
371 pBT->type = btt_free;
372 pBT->pNextFree = pArena->aHeadFree [uIndex];
373 pBT->pPrevFree = IMG_NULL;
374 if (pArena->aHeadFree[uIndex] != IMG_NULL)
375 pArena->aHeadFree[uIndex]->pPrevFree = pBT;
376 pArena->aHeadFree [uIndex] = pBT;
377}
378
379static IMG_VOID
380_FreeListRemove (RA_ARENA *pArena, BT *pBT)
381{
382 IMG_UINT32 uIndex;
383 uIndex = pvr_log2 (pBT->uSize);
384 if (pBT->pNextFree != IMG_NULL)
385 pBT->pNextFree->pPrevFree = pBT->pPrevFree;
386 if (pBT->pPrevFree == IMG_NULL)
387 pArena->aHeadFree[uIndex] = pBT->pNextFree;
388 else
389 pBT->pPrevFree->pNextFree = pBT->pNextFree;
390}
391
392static BT *
393_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
394{
395 BT *pBT;
396
397 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
398 sizeof(BT),
399 (IMG_VOID **)&pBT, IMG_NULL,
400 "Boundary Tag") != PVRSRV_OK)
401 {
402 return IMG_NULL;
403 }
404
405 OSMemSet(pBT, 0, sizeof(BT));
406
407#if defined(VALIDATE_ARENA_TEST)
408 pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
409#endif
410
411 pBT->type = btt_span;
412 pBT->base = base;
413 pBT->uSize = uSize;
414 pBT->psMapping = IMG_NULL;
415
416 return pBT;
417}
418
419static BT *
420_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
421{
422 BT *pBT;
423
424 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
425 sizeof(BT),
426 (IMG_VOID **)&pBT, IMG_NULL,
427 "Boundary Tag") != PVRSRV_OK)
428 {
429 return IMG_NULL;
430 }
431
432 OSMemSet(pBT, 0, sizeof(BT));
433
434#if defined(VALIDATE_ARENA_TEST)
435 pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
436#endif
437
438 pBT->type = btt_free;
439 pBT->base = base;
440 pBT->uSize = uSize;
441
442 return pBT;
443}
444
445static BT *
446_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
447{
448 BT *pBT;
449 PVR_ASSERT (pArena!=IMG_NULL);
450 if (pArena == IMG_NULL)
451 {
452 PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena"));
453 return IMG_NULL;
454 }
455
456 pBT = _BuildBT (base, uSize);
457 if (pBT != IMG_NULL)
458 {
459
460#if defined(VALIDATE_ARENA_TEST)
461 pBT->eResourceSpan = RESOURCE_SPAN_FREE;
462 pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
463#endif
464
465 if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK)
466 {
467 PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed"));
468 return IMG_NULL;
469 }
470 _FreeListInsert (pArena, pBT);
471#ifdef RA_STATS
472 pArena->sStatistics.uTotalResourceCount+=uSize;
473 pArena->sStatistics.uFreeResourceCount+=uSize;
474 pArena->sStatistics.uSpanCount++;
475#endif
476 }
477 return pBT;
478}
479
480static BT *
481_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
482{
483 PVRSRV_ERROR eError;
484 BT *pSpanStart;
485 BT *pSpanEnd;
486 BT *pBT;
487
488 PVR_ASSERT (pArena != IMG_NULL);
489 if (pArena == IMG_NULL)
490 {
491 PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena"));
492 return IMG_NULL;
493 }
494
495 PVR_DPF ((PVR_DBG_MESSAGE,
496 "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
497 pArena->name, base, uSize));
498
499 pSpanStart = _BuildSpanMarker (base, uSize);
500 if (pSpanStart == IMG_NULL)
501 {
502 goto fail_start;
503 }
504
505#if defined(VALIDATE_ARENA_TEST)
506 pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
507 pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
508#endif
509
510 pSpanEnd = _BuildSpanMarker (base + uSize, 0);
511 if (pSpanEnd == IMG_NULL)
512 {
513 goto fail_end;
514 }
515
516#if defined(VALIDATE_ARENA_TEST)
517 pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
518 pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
519#endif
520
521 pBT = _BuildBT (base, uSize);
522 if (pBT == IMG_NULL)
523 {
524 goto fail_bt;
525 }
526
527#if defined(VALIDATE_ARENA_TEST)
528 pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
529 pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
530#endif
531
532 eError = _SegmentListInsert (pArena, pSpanStart);
533 if (eError != PVRSRV_OK)
534 {
535 goto fail_SegListInsert;
536 }
537
538 eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT);
539 if (eError != PVRSRV_OK)
540 {
541 goto fail_SegListInsert;
542 }
543
544 _FreeListInsert (pArena, pBT);
545
546 eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd);
547 if (eError != PVRSRV_OK)
548 {
549 goto fail_SegListInsert;
550 }
551
552#ifdef RA_STATS
553 pArena->sStatistics.uTotalResourceCount+=uSize;
554#endif
555 return pBT;
556
557 fail_SegListInsert:
558 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
559
560 fail_bt:
561 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
562
563 fail_end:
564 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
565
566 fail_start:
567 return IMG_NULL;
568}
569
570static IMG_VOID
571_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore)
572{
573 BT *pNeighbour;
574 IMG_UINTPTR_T uOrigBase;
575 IMG_SIZE_T uOrigSize;
576
577 PVR_ASSERT (pArena!=IMG_NULL);
578 PVR_ASSERT (pBT!=IMG_NULL);
579
580 if ((pArena == IMG_NULL) || (pBT == IMG_NULL))
581 {
582 PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter"));
583 return;
584 }
585
586#ifdef RA_STATS
587 pArena->sStatistics.uLiveSegmentCount--;
588 pArena->sStatistics.uFreeSegmentCount++;
589 pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
590#endif
591
592 uOrigBase = pBT->base;
593 uOrigSize = pBT->uSize;
594
595
596 pNeighbour = pBT->pPrevSegment;
597 if (pNeighbour!=IMG_NULL
598 && pNeighbour->type == btt_free
599 && pNeighbour->base + pNeighbour->uSize == pBT->base)
600 {
601 _FreeListRemove (pArena, pNeighbour);
602 _SegmentListRemove (pArena, pNeighbour);
603 pBT->base = pNeighbour->base;
604 pBT->uSize += pNeighbour->uSize;
605 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
606
607#ifdef RA_STATS
608 pArena->sStatistics.uFreeSegmentCount--;
609#endif
610 }
611
612
613 pNeighbour = pBT->pNextSegment;
614 if (pNeighbour!=IMG_NULL
615 && pNeighbour->type == btt_free
616 && pBT->base + pBT->uSize == pNeighbour->base)
617 {
618 _FreeListRemove (pArena, pNeighbour);
619 _SegmentListRemove (pArena, pNeighbour);
620 pBT->uSize += pNeighbour->uSize;
621 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
622
623#ifdef RA_STATS
624 pArena->sStatistics.uFreeSegmentCount--;
625#endif
626 }
627
628
629 if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore)
630 {
631 IMG_UINTPTR_T uRoundedStart, uRoundedEnd;
632
633
634 uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
635
636 if (uRoundedStart < pBT->base)
637 {
638 uRoundedStart += pArena->uQuantum;
639 }
640
641
642 uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum;
643
644 if (uRoundedEnd > (pBT->base + pBT->uSize))
645 {
646 uRoundedEnd -= pArena->uQuantum;
647 }
648
649 if (uRoundedStart < uRoundedEnd)
650 {
651 pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)uRoundedEnd, (IMG_HANDLE)0);
652 }
653 }
654
655 if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span
656 && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span)
657 {
658 BT *next = pBT->pNextSegment;
659 BT *prev = pBT->pPrevSegment;
660 _SegmentListRemove (pArena, next);
661 _SegmentListRemove (pArena, prev);
662 _SegmentListRemove (pArena, pBT);
663 pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping);
664#ifdef RA_STATS
665 pArena->sStatistics.uSpanCount--;
666 pArena->sStatistics.uExportCount++;
667 pArena->sStatistics.uFreeSegmentCount--;
668 pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
669 pArena->sStatistics.uTotalResourceCount-=pBT->uSize;
670#endif
671 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL);
672
673 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
674
675 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
676
677 }
678 else
679 _FreeListInsert (pArena, pBT);
680}
681
682
683static IMG_BOOL
684_AttemptAllocAligned (RA_ARENA *pArena,
685 IMG_SIZE_T uSize,
686 BM_MAPPING **ppsMapping,
687 IMG_UINT32 uFlags,
688 IMG_UINT32 uAlignment,
689 IMG_UINT32 uAlignmentOffset,
690 IMG_UINTPTR_T *base)
691{
692 IMG_UINT32 uIndex;
693 PVR_ASSERT (pArena!=IMG_NULL);
694 if (pArena == IMG_NULL)
695 {
696 PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
697 return IMG_FALSE;
698 }
699
700 if (uAlignment>1)
701 uAlignmentOffset %= uAlignment;
702
703
704
705 uIndex = pvr_log2 (uSize);
706
707#if 0
708
709 if (1u<<uIndex < uSize)
710 uIndex++;
711#endif
712
713 while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
714 uIndex++;
715
716 while (uIndex < FREE_TABLE_LIMIT)
717 {
718 if (pArena->aHeadFree[uIndex]!=IMG_NULL)
719 {
720
721 BT *pBT;
722
723 pBT = pArena->aHeadFree [uIndex];
724 while (pBT!=IMG_NULL)
725 {
726 IMG_UINTPTR_T aligned_base;
727
728 if (uAlignment>1)
729 aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
730 else
731 aligned_base = pBT->base;
732 PVR_DPF ((PVR_DBG_MESSAGE,
733 "RA_AttemptAllocAligned: pBT-base=0x%x "
734 "pBT-size=0x%x alignedbase=0x%x size=0x%x",
735 pBT->base, pBT->uSize, aligned_base, uSize));
736
737 if (pBT->base + pBT->uSize >= aligned_base + uSize)
738 {
739 if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
740 {
741 _FreeListRemove (pArena, pBT);
742
743 PVR_ASSERT (pBT->type == btt_free);
744
745#ifdef RA_STATS
746 pArena->sStatistics.uLiveSegmentCount++;
747 pArena->sStatistics.uFreeSegmentCount--;
748 pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
749#endif
750
751
752 if (aligned_base > pBT->base)
753 {
754 BT *pNeighbour;
755 pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
756
757 if (pNeighbour==IMG_NULL)
758 {
759 PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
760
761 _FreeListInsert (pArena, pBT);
762 return IMG_FALSE;
763 }
764
765 _FreeListInsert (pArena, pBT);
766 #ifdef RA_STATS
767 pArena->sStatistics.uFreeSegmentCount++;
768 pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
769 #endif
770 pBT = pNeighbour;
771 }
772
773
774 if (pBT->uSize > uSize)
775 {
776 BT *pNeighbour;
777 pNeighbour = _SegmentSplit (pArena, pBT, uSize);
778
779 if (pNeighbour==IMG_NULL)
780 {
781 PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
782
783 _FreeListInsert (pArena, pBT);
784 return IMG_FALSE;
785 }
786
787 _FreeListInsert (pArena, pNeighbour);
788 #ifdef RA_STATS
789 pArena->sStatistics.uFreeSegmentCount++;
790 pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
791 #endif
792 }
793
794 pBT->type = btt_live;
795
796#if defined(VALIDATE_ARENA_TEST)
797 if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
798 {
799 pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
800 }
801 else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
802 {
803 pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
804 }
805 else
806 {
807 PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
808 PVR_DBG_BREAK;
809 }
810#endif
811 if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
812 {
813 _FreeBT (pArena, pBT, IMG_FALSE);
814 return IMG_FALSE;
815 }
816
817 if (ppsMapping!=IMG_NULL)
818 *ppsMapping = pBT->psMapping;
819
820 *base = pBT->base;
821
822 return IMG_TRUE;
823 }
824 else
825 {
826 PVR_DPF ((PVR_DBG_MESSAGE,
827 "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));
828
829 }
830 }
831 pBT = pBT->pNextFree;
832 }
833
834 }
835 uIndex++;
836 }
837
838 return IMG_FALSE;
839}
840
841
842
843RA_ARENA *
844RA_Create (IMG_CHAR *name,
845 IMG_UINTPTR_T base,
846 IMG_SIZE_T uSize,
847 BM_MAPPING *psMapping,
848 IMG_SIZE_T uQuantum,
849 IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize,
850 BM_MAPPING **ppsMapping, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase),
851 IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *),
852 IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE),
853 IMG_VOID *pImportHandle)
854{
855 RA_ARENA *pArena;
856 BT *pBT;
857 IMG_INT i;
858
859 PVR_DPF ((PVR_DBG_MESSAGE,
860 "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x",
861 name, base, uSize, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free));
862
863
864 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
865 sizeof (*pArena),
866 (IMG_VOID **)&pArena, IMG_NULL,
867 "Resource Arena") != PVRSRV_OK)
868 {
869 goto arena_fail;
870 }
871
872 pArena->name = name;
873 pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail;
874 pArena->pImportFree = imp_free;
875 pArena->pBackingStoreFree = backingstore_free;
876 pArena->pImportHandle = pImportHandle;
877 for (i=0; i<FREE_TABLE_LIMIT; i++)
878 pArena->aHeadFree[i] = IMG_NULL;
879 pArena->pHeadSegment = IMG_NULL;
880 pArena->pTailSegment = IMG_NULL;
881 pArena->uQuantum = uQuantum;
882
883#ifdef RA_STATS
884 pArena->sStatistics.uSpanCount = 0;
885 pArena->sStatistics.uLiveSegmentCount = 0;
886 pArena->sStatistics.uFreeSegmentCount = 0;
887 pArena->sStatistics.uFreeResourceCount = 0;
888 pArena->sStatistics.uTotalResourceCount = 0;
889 pArena->sStatistics.uCumulativeAllocs = 0;
890 pArena->sStatistics.uCumulativeFrees = 0;
891 pArena->sStatistics.uImportCount = 0;
892 pArena->sStatistics.uExportCount = 0;
893#endif
894
895#if defined(CONFIG_PROC_FS) && defined(DEBUG)
896 if(strcmp(pArena->name,"") != 0)
897 {
898 IMG_INT ret;
899 IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
900 IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
901 struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *,
902 IMG_VOID*,
903 pvr_next_proc_seq_t,
904 pvr_show_proc_seq_t,
905 pvr_off2element_proc_seq_t,
906 pvr_startstop_proc_seq_t,
907 write_proc_t);
908
909 pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
910
911
912 pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq;
913
914 ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name);
915 if (ret > 0 && ret < sizeof(szProcInfoName))
916 {
917 pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL,
918 RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL);
919 }
920 else
921 {
922 pArena->pProcInfo = 0;
923 PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
924 }
925
926 ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name);
927 if (ret > 0 && ret < sizeof(szProcInfoName))
928 {
929 pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
930 RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL);
931 }
932 else
933 {
934 pArena->pProcSegs = 0;
935 PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
936 }
937 }
938#endif
939
940 pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE);
941 if (pArena->pSegmentHash==IMG_NULL)
942 {
943 goto hash_fail;
944 }
945 if (uSize>0)
946 {
947 uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
948 pBT = _InsertResource (pArena, base, uSize);
949 if (pBT == IMG_NULL)
950 {
951 goto insert_fail;
952 }
953 pBT->psMapping = psMapping;
954
955 }
956 return pArena;
957
958insert_fail:
959 HASH_Delete (pArena->pSegmentHash);
960hash_fail:
961 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
962
963arena_fail:
964 return IMG_NULL;
965}
966
967IMG_VOID
968RA_Delete (RA_ARENA *pArena)
969{
970 IMG_UINT32 uIndex;
971
972 PVR_ASSERT(pArena != IMG_NULL);
973
974 if (pArena == IMG_NULL)
975 {
976 PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena"));
977 return;
978 }
979
980 PVR_DPF ((PVR_DBG_MESSAGE,
981 "RA_Delete: name='%s'", pArena->name));
982
983 for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
984 pArena->aHeadFree[uIndex] = IMG_NULL;
985
986 while (pArena->pHeadSegment != IMG_NULL)
987 {
988 BT *pBT = pArena->pHeadSegment;
989
990 if (pBT->type != btt_free)
991 {
992 PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed"));
993 PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
994 PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
995 }
996
997 _SegmentListRemove (pArena, pBT);
998 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
999
1000#ifdef RA_STATS
1001 pArena->sStatistics.uSpanCount--;
1002#endif
1003 }
1004#if defined(CONFIG_PROC_FS) && defined(DEBUG)
1005 {
1006 IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*);
1007
1008 pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq;
1009
1010 if (pArena->pProcInfo != 0)
1011 {
1012 pfnRemoveProcEntrySeq( pArena->pProcInfo );
1013 }
1014
1015 if (pArena->pProcSegs != 0)
1016 {
1017 pfnRemoveProcEntrySeq( pArena->pProcSegs );
1018 }
1019 }
1020#endif
1021 HASH_Delete (pArena->pSegmentHash);
1022 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
1023
1024}
1025
1026IMG_BOOL
1027RA_TestDelete (RA_ARENA *pArena)
1028{
1029 PVR_ASSERT(pArena != IMG_NULL);
1030
1031 if (pArena != IMG_NULL)
1032 {
1033 while (pArena->pHeadSegment != IMG_NULL)
1034 {
1035 BT *pBT = pArena->pHeadSegment;
1036 if (pBT->type != btt_free)
1037 {
1038 PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!"));
1039 PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
1040 return IMG_FALSE;
1041 }
1042 }
1043 }
1044
1045 return IMG_TRUE;
1046}
1047
1048IMG_BOOL
1049RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
1050{
1051 PVR_ASSERT (pArena != IMG_NULL);
1052
1053 if (pArena == IMG_NULL)
1054 {
1055 PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena"));
1056 return IMG_FALSE;
1057 }
1058
1059 PVR_DPF ((PVR_DBG_MESSAGE,
1060 "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize));
1061
1062 uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum;
1063 return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL));
1064}
1065
1066IMG_BOOL
1067RA_Alloc (RA_ARENA *pArena,
1068 IMG_SIZE_T uRequestSize,
1069 IMG_SIZE_T *pActualSize,
1070 BM_MAPPING **ppsMapping,
1071 IMG_UINT32 uFlags,
1072 IMG_UINT32 uAlignment,
1073 IMG_UINT32 uAlignmentOffset,
1074 IMG_UINTPTR_T *base)
1075{
1076 IMG_BOOL bResult;
1077 IMG_SIZE_T uSize = uRequestSize;
1078
1079 PVR_ASSERT (pArena!=IMG_NULL);
1080
1081 if (pArena == IMG_NULL)
1082 {
1083 PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena"));
1084 return IMG_FALSE;
1085 }
1086
1087#if defined(VALIDATE_ARENA_TEST)
1088 ValidateArena(pArena);
1089#endif
1090
1091#ifdef USE_BM_FREESPACE_CHECK
1092 CheckBMFreespace();
1093#endif
1094
1095 if (pActualSize != IMG_NULL)
1096 {
1097 *pActualSize = uSize;
1098 }
1099
1100 PVR_DPF ((PVR_DBG_MESSAGE,
1101 "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x",
1102 pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset));
1103
1104
1105
1106 bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags,
1107 uAlignment, uAlignmentOffset, base);
1108 if (!bResult)
1109 {
1110 BM_MAPPING *psImportMapping;
1111 IMG_UINTPTR_T import_base;
1112 IMG_SIZE_T uImportSize = uSize;
1113
1114
1115
1116
1117 if (uAlignment > pArena->uQuantum)
1118 {
1119 uImportSize += (uAlignment - 1);
1120 }
1121
1122
1123 uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
1124
1125 bResult =
1126 pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
1127 &psImportMapping, uFlags, &import_base);
1128 if (bResult)
1129 {
1130 BT *pBT;
1131 pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
1132
1133 if (pBT == IMG_NULL)
1134 {
1135
1136 pArena->pImportFree(pArena->pImportHandle, import_base,
1137 psImportMapping);
1138 PVR_DPF ((PVR_DBG_MESSAGE,
1139 "RA_Alloc: name='%s', size=0x%x failed!",
1140 pArena->name, uSize));
1141
1142 return IMG_FALSE;
1143 }
1144 pBT->psMapping = psImportMapping;
1145#ifdef RA_STATS
1146 pArena->sStatistics.uFreeSegmentCount++;
1147 pArena->sStatistics.uFreeResourceCount += uImportSize;
1148 pArena->sStatistics.uImportCount++;
1149 pArena->sStatistics.uSpanCount++;
1150#endif
1151 bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags,
1152 uAlignment, uAlignmentOffset,
1153 base);
1154 if (!bResult)
1155 {
1156 PVR_DPF ((PVR_DBG_MESSAGE,
1157 "RA_Alloc: name='%s' uAlignment failed!",
1158 pArena->name));
1159 }
1160 }
1161 }
1162#ifdef RA_STATS
1163 if (bResult)
1164 pArena->sStatistics.uCumulativeAllocs++;
1165#endif
1166
1167 PVR_DPF ((PVR_DBG_MESSAGE,
1168 "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d",
1169 pArena->name, uSize, *base, bResult));
1170
1171
1172
1173#if defined(VALIDATE_ARENA_TEST)
1174 ValidateArena(pArena);
1175#endif
1176
1177 return bResult;
1178}
1179
1180
1181#if defined(VALIDATE_ARENA_TEST)
1182
1183IMG_UINT32 ValidateArena(RA_ARENA *pArena)
1184{
1185 BT* pSegment;
1186 RESOURCE_DESCRIPTOR eNextSpan;
1187
1188 pSegment = pArena->pHeadSegment;
1189
1190 if (pSegment == IMG_NULL)
1191 {
1192 return 0;
1193 }
1194
1195 if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
1196 {
1197 PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START);
1198
1199 while (pSegment->pNextSegment)
1200 {
1201 eNextSpan = pSegment->pNextSegment->eResourceSpan;
1202
1203 switch (pSegment->eResourceSpan)
1204 {
1205 case IMPORTED_RESOURCE_SPAN_LIVE:
1206
1207 if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
1208 (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
1209 (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
1210 {
1211
1212 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1213 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1214
1215 PVR_DBG_BREAK;
1216 }
1217 break;
1218
1219 case IMPORTED_RESOURCE_SPAN_FREE:
1220
1221 if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
1222 (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
1223 {
1224
1225 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1226 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1227
1228 PVR_DBG_BREAK;
1229 }
1230 break;
1231
1232 case IMPORTED_RESOURCE_SPAN_END:
1233
1234 if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
1235 (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
1236 (eNextSpan == IMPORTED_RESOURCE_SPAN_END))
1237 {
1238
1239 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1240 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1241
1242 PVR_DBG_BREAK;
1243 }
1244 break;
1245
1246
1247 case IMPORTED_RESOURCE_SPAN_START:
1248
1249 if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
1250 (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE)))
1251 {
1252
1253 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1254 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1255
1256 PVR_DBG_BREAK;
1257 }
1258 break;
1259
1260 default:
1261 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1262 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1263
1264 PVR_DBG_BREAK;
1265 break;
1266 }
1267 pSegment = pSegment->pNextSegment;
1268 }
1269 }
1270 else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
1271 {
1272 PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE));
1273
1274 while (pSegment->pNextSegment)
1275 {
1276 eNextSpan = pSegment->pNextSegment->eResourceSpan;
1277
1278 switch (pSegment->eResourceSpan)
1279 {
1280 case RESOURCE_SPAN_LIVE:
1281
1282 if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
1283 (eNextSpan == RESOURCE_SPAN_LIVE)))
1284 {
1285
1286 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1287 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1288
1289 PVR_DBG_BREAK;
1290 }
1291 break;
1292
1293 case RESOURCE_SPAN_FREE:
1294
1295 if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
1296 (eNextSpan == RESOURCE_SPAN_LIVE)))
1297 {
1298
1299 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1300 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1301
1302 PVR_DBG_BREAK;
1303 }
1304 break;
1305
1306 default:
1307 PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
1308 pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
1309
1310 PVR_DBG_BREAK;
1311 break;
1312 }
1313 pSegment = pSegment->pNextSegment;
1314 }
1315
1316 }
1317 else
1318 {
1319 PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized"));
1320
1321 PVR_DBG_BREAK;
1322 }
1323
1324 return 0;
1325}
1326
1327#endif
1328
1329
1330IMG_VOID
1331RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore)
1332{
1333 BT *pBT;
1334
1335 PVR_ASSERT (pArena != IMG_NULL);
1336
1337 if (pArena == IMG_NULL)
1338 {
1339 PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena"));
1340 return;
1341 }
1342
1343#ifdef USE_BM_FREESPACE_CHECK
1344 CheckBMFreespace();
1345#endif
1346
1347 PVR_DPF ((PVR_DBG_MESSAGE,
1348 "RA_Free: name='%s', base=0x%x", pArena->name, base));
1349
1350 pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base);
1351 PVR_ASSERT (pBT != IMG_NULL);
1352
1353 if (pBT)
1354 {
1355 PVR_ASSERT (pBT->base == base);
1356
1357#ifdef RA_STATS
1358 pArena->sStatistics.uCumulativeFrees++;
1359#endif
1360
1361#ifdef USE_BM_FREESPACE_CHECK
1362{
1363 IMG_BYTE* p;
1364 IMG_BYTE* endp;
1365
1366 p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
1367 endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize));
1368 while ((IMG_UINT32)p & 3)
1369 {
1370 *p++ = 0xAA;
1371 }
1372 while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc))
1373 {
1374 *(IMG_UINT32*)p = 0xAAAAAAAA;
1375 p += sizeof(IMG_UINT32);
1376 }
1377 while (p < endp)
1378 {
1379 *p++ = 0xAA;
1380 }
1381 PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize));
1382}
1383#endif
1384 _FreeBT (pArena, pBT, bFreeBackingStore);
1385 }
1386}
1387
1388
1389IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails)
1390{
1391 BT *pBT;
1392
1393 if (psSegDetails->hSegment)
1394 {
1395 pBT = (BT *)psSegDetails->hSegment;
1396 }
1397 else
1398 {
1399 RA_ARENA *pArena = (RA_ARENA *)hArena;
1400
1401 pBT = pArena->pHeadSegment;
1402 }
1403
1404 while (pBT != IMG_NULL)
1405 {
1406 if (pBT->type == btt_live)
1407 {
1408 psSegDetails->uiSize = pBT->uSize;
1409 psSegDetails->sCpuPhyAddr.uiAddr = pBT->base;
1410 psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment;
1411
1412 return IMG_TRUE;
1413 }
1414
1415 pBT = pBT->pNextSegment;
1416 }
1417
1418 psSegDetails->uiSize = 0;
1419 psSegDetails->sCpuPhyAddr.uiAddr = 0;
1420 psSegDetails->hSegment = (IMG_HANDLE)IMG_UNDEF;
1421
1422 return IMG_FALSE;
1423}
1424
1425
1426#ifdef USE_BM_FREESPACE_CHECK
1427RA_ARENA* pJFSavedArena = IMG_NULL;
1428
1429IMG_VOID CheckBMFreespace(IMG_VOID)
1430{
1431 BT *pBT;
1432 IMG_BYTE* p;
1433 IMG_BYTE* endp;
1434
1435 if (pJFSavedArena != IMG_NULL)
1436 {
1437 for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
1438 {
1439 if (pBT->type == btt_free)
1440 {
1441 p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
1442 endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc);
1443
1444 while ((IMG_UINT32)p & 3)
1445 {
1446 if (*p++ != 0xAA)
1447 {
1448 fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
1449 for (;;);
1450 break;
1451 }
1452 }
1453 while (p < endp)
1454 {
1455 if (*(IMG_UINT32*)p != 0xAAAAAAAA)
1456 {
1457 fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
1458 for (;;);
1459 break;
1460 }
1461 p += 4;
1462 }
1463 }
1464 }
1465 }
1466}
1467#endif
1468
1469
1470#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS)
1471static IMG_CHAR *
1472_BTType (IMG_INT eType)
1473{
1474 switch (eType)
1475 {
1476 case btt_span: return "span";
1477 case btt_free: return "free";
1478 case btt_live: return "live";
1479 }
1480 return "junk";
1481}
1482#endif
1483
1484#if defined(ENABLE_RA_DUMP)
1485IMG_VOID
1486RA_Dump (RA_ARENA *pArena)
1487{
1488 BT *pBT;
1489 PVR_ASSERT (pArena != IMG_NULL);
1490 PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name));
1491 PVR_DPF ((PVR_DBG_MESSAGE," alloc=%08X free=%08X handle=%08X quantum=%d",
1492 pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle,
1493 pArena->uQuantum));
1494 PVR_DPF ((PVR_DBG_MESSAGE," segment Chain:"));
1495 if (pArena->pHeadSegment != IMG_NULL &&
1496 pArena->pHeadSegment->pPrevSegment != IMG_NULL)
1497 PVR_DPF ((PVR_DBG_MESSAGE," error: head boundary tag has invalid pPrevSegment"));
1498 if (pArena->pTailSegment != IMG_NULL &&
1499 pArena->pTailSegment->pNextSegment != IMG_NULL)
1500 PVR_DPF ((PVR_DBG_MESSAGE," error: tail boundary tag has invalid pNextSegment"));
1501
1502 for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
1503 {
1504 PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s ref=%08X",
1505 (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type),
1506 pBT->pRef));
1507 }
1508
1509#ifdef HASH_TRACE
1510 HASH_Dump (pArena->pSegmentHash);
1511#endif
1512}
1513#endif
1514
1515
1516#if defined(CONFIG_PROC_FS) && defined(DEBUG)
1517
1518
1519static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el)
1520{
1521 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
1522 RA_ARENA *pArena = (RA_ARENA *)handlers->data;
1523 IMG_INT off = (IMG_INT)el;
1524
1525 switch (off)
1526 {
1527 case 1:
1528 seq_printf(sfile, "quantum\t\t\t%u\n", pArena->uQuantum);
1529 break;
1530 case 2:
1531 seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
1532 break;
1533#ifdef RA_STATS
1534 case 3:
1535 seq_printf(sfile,"span count\t\t%u\n", pArena->sStatistics.uSpanCount);
1536 break;
1537 case 4:
1538 seq_printf(sfile, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
1539 break;
1540 case 5:
1541 seq_printf(sfile, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
1542 break;
1543 case 6:
1544 seq_printf(sfile, "free resource count\t%u (0x%x)\n",
1545 pArena->sStatistics.uFreeResourceCount,
1546 (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
1547 break;
1548 case 7:
1549 seq_printf(sfile, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
1550 break;
1551 case 8:
1552 seq_printf(sfile, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
1553 break;
1554 case 9:
1555 seq_printf(sfile, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
1556 break;
1557 case 10:
1558 seq_printf(sfile, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
1559 break;
1560#endif
1561 }
1562
1563}
1564
1565static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off)
1566{
1567#ifdef RA_STATS
1568 if(off <= 9)
1569#else
1570 if(off <= 1)
1571#endif
1572 return (void*)(IMG_INT)(off+1);
1573 return 0;
1574}
1575
1576static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el)
1577{
1578 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
1579 RA_ARENA *pArena = (RA_ARENA *)handlers->data;
1580 BT *pBT = (BT*)el;
1581
1582 if (el == PVR_PROC_SEQ_START_TOKEN)
1583 {
1584 seq_printf(sfile, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name);
1585 return;
1586 }
1587
1588 if (pBT)
1589 {
1590 seq_printf(sfile, "%08x %8x %4s %08x\n",
1591 (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
1592 (IMG_UINT)pBT->psMapping);
1593 }
1594}
1595
1596static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off)
1597{
1598 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
1599 RA_ARENA *pArena = (RA_ARENA *)handlers->data;
1600 BT *pBT = 0;
1601
1602 if(off == 0)
1603 return PVR_PROC_SEQ_START_TOKEN;
1604
1605 for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment);
1606
1607 return (void*)pBT;
1608}
1609
1610#endif
1611
1612
1613#ifdef RA_STATS
1614PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
1615 IMG_CHAR **ppszStr,
1616 IMG_UINT32 *pui32StrLen)
1617{
1618 IMG_CHAR *pszStr = *ppszStr;
1619 IMG_UINT32 ui32StrLen = *pui32StrLen;
1620 IMG_INT32 i32Count;
1621 BT *pBT;
1622
1623 CHECK_SPACE(ui32StrLen);
1624 i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name);
1625 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1626
1627
1628 CHECK_SPACE(ui32StrLen);
1629 i32Count = OSSNPrintf(pszStr, 100, " allocCB=%p freeCB=%p handle=%p quantum=%d\n",
1630 pArena->pImportAlloc,
1631 pArena->pImportFree,
1632 pArena->pImportHandle,
1633 pArena->uQuantum);
1634 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1635
1636 CHECK_SPACE(ui32StrLen);
1637 i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%u\n", pArena->sStatistics.uSpanCount);
1638 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1639
1640 CHECK_SPACE(ui32StrLen);
1641 i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
1642 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1643
1644 CHECK_SPACE(ui32StrLen);
1645 i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
1646 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1647
1648 CHECK_SPACE(ui32StrLen);
1649 i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%u (0x%x)\n",
1650 pArena->sStatistics.uFreeResourceCount,
1651 (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
1652 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1653
1654 CHECK_SPACE(ui32StrLen);
1655 i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
1656 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1657
1658 CHECK_SPACE(ui32StrLen);
1659 i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
1660 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1661
1662 CHECK_SPACE(ui32StrLen);
1663 i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
1664 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1665
1666 CHECK_SPACE(ui32StrLen);
1667 i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
1668 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1669
1670 CHECK_SPACE(ui32StrLen);
1671 i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n");
1672 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1673
1674 if (pArena->pHeadSegment != IMG_NULL &&
1675 pArena->pHeadSegment->pPrevSegment != IMG_NULL)
1676 {
1677 CHECK_SPACE(ui32StrLen);
1678 i32Count = OSSNPrintf(pszStr, 100, " error: head boundary tag has invalid pPrevSegment\n");
1679 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1680 }
1681
1682 if (pArena->pTailSegment != IMG_NULL &&
1683 pArena->pTailSegment->pNextSegment != IMG_NULL)
1684 {
1685 CHECK_SPACE(ui32StrLen);
1686 i32Count = OSSNPrintf(pszStr, 100, " error: tail boundary tag has invalid pNextSegment\n");
1687 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1688 }
1689
1690 for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
1691 {
1692 CHECK_SPACE(ui32StrLen);
1693 i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%p\n",
1694 (IMG_UINT32) pBT->base,
1695 pBT->uSize,
1696 _BTType(pBT->type),
1697 pBT->psMapping);
1698 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1699 }
1700
1701 *ppszStr = pszStr;
1702 *pui32StrLen = ui32StrLen;
1703
1704 return PVRSRV_OK;
1705}
1706
1707PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
1708 IMG_CHAR **ppszStr,
1709 IMG_UINT32 *pui32StrLen)
1710{
1711 IMG_CHAR *pszStr = *ppszStr;
1712 IMG_UINT32 ui32StrLen = *pui32StrLen;
1713 IMG_INT32 i32Count;
1714 CHECK_SPACE(ui32StrLen);
1715 i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %u (0x%x)\n", pArena->name,
1716 pArena->sStatistics.uFreeResourceCount,
1717 pArena->sStatistics.uFreeResourceCount);
1718 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
1719 *ppszStr = pszStr;
1720 *pui32StrLen = ui32StrLen;
1721
1722 return PVRSRV_OK;
1723}
1724#endif
1725
diff --git a/drivers/gpu/pvr/ra.h b/drivers/gpu/pvr/ra.h
new file mode 100644
index 00000000000..f28ce4cd755
--- /dev/null
+++ b/drivers/gpu/pvr/ra.h
@@ -0,0 +1,159 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _RA_H_
28#define _RA_H_
29
30#include "img_types.h"
31#include "hash.h"
32#include "osfunc.h"
33
34typedef struct _RA_ARENA_ RA_ARENA;
35typedef struct _BM_MAPPING_ BM_MAPPING;
36
37
38
39#define RA_STATS
40
41
42struct _RA_STATISTICS_
43{
44
45 IMG_SIZE_T uSpanCount;
46
47
48 IMG_SIZE_T uLiveSegmentCount;
49
50
51 IMG_SIZE_T uFreeSegmentCount;
52
53
54 IMG_SIZE_T uTotalResourceCount;
55
56
57 IMG_SIZE_T uFreeResourceCount;
58
59
60 IMG_SIZE_T uCumulativeAllocs;
61
62
63 IMG_SIZE_T uCumulativeFrees;
64
65
66 IMG_SIZE_T uImportCount;
67
68
69 IMG_SIZE_T uExportCount;
70};
71typedef struct _RA_STATISTICS_ RA_STATISTICS;
72
73struct _RA_SEGMENT_DETAILS_
74{
75 IMG_SIZE_T uiSize;
76 IMG_CPU_PHYADDR sCpuPhyAddr;
77 IMG_HANDLE hSegment;
78};
79typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
80
81RA_ARENA *
82RA_Create (IMG_CHAR *name,
83 IMG_UINTPTR_T base,
84 IMG_SIZE_T uSize,
85 BM_MAPPING *psMapping,
86 IMG_SIZE_T uQuantum,
87 IMG_BOOL (*imp_alloc)(IMG_VOID *_h,
88 IMG_SIZE_T uSize,
89 IMG_SIZE_T *pActualSize,
90 BM_MAPPING **ppsMapping,
91 IMG_UINT32 uFlags,
92 IMG_UINTPTR_T *pBase),
93 IMG_VOID (*imp_free) (IMG_VOID *,
94 IMG_UINTPTR_T,
95 BM_MAPPING *),
96 IMG_VOID (*backingstore_free) (IMG_VOID *,
97 IMG_SIZE_T,
98 IMG_SIZE_T,
99 IMG_HANDLE),
100 IMG_VOID *import_handle);
101
102IMG_VOID
103RA_Delete (RA_ARENA *pArena);
104
105IMG_BOOL
106RA_TestDelete (RA_ARENA *pArena);
107
108IMG_BOOL
109RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize);
110
111IMG_BOOL
112RA_Alloc (RA_ARENA *pArena,
113 IMG_SIZE_T uSize,
114 IMG_SIZE_T *pActualSize,
115 BM_MAPPING **ppsMapping,
116 IMG_UINT32 uFlags,
117 IMG_UINT32 uAlignment,
118 IMG_UINT32 uAlignmentOffset,
119 IMG_UINTPTR_T *pBase);
120
121IMG_VOID
122RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore);
123
124
125#ifdef RA_STATS
126
127#define CHECK_SPACE(total) \
128{ \
129 if((total)<100) \
130 return PVRSRV_ERROR_INVALID_PARAMS; \
131}
132
133#define UPDATE_SPACE(str, count, total) \
134{ \
135 if((count) == -1) \
136 return PVRSRV_ERROR_INVALID_PARAMS; \
137 else \
138 { \
139 (str) += (count); \
140 (total) -= (count); \
141 } \
142}
143
144
145IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails);
146
147
148PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
149 IMG_CHAR **ppszStr,
150 IMG_UINT32 *pui32StrLen);
151
152PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
153 IMG_CHAR **ppszStr,
154 IMG_UINT32 *pui32StrLen);
155
156#endif
157
158#endif
159
diff --git a/drivers/gpu/pvr/regpaths.h b/drivers/gpu/pvr/regpaths.h
new file mode 100644
index 00000000000..a551eff4e76
--- /dev/null
+++ b/drivers/gpu/pvr/regpaths.h
@@ -0,0 +1,43 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __REGPATHS_H__
28#define __REGPATHS_H__
29
30#define POWERVR_REG_ROOT "Drivers\\Display\\PowerVR"
31#define POWERVR_CHIP_KEY "\\SGX1\\"
32
33#define POWERVR_EURASIA_KEY "PowerVREurasia\\"
34
35#define POWERVR_SERVICES_KEY "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\PowerVR\\"
36
37#define PVRSRV_REGISTRY_ROOT POWERVR_EURASIA_KEY "HWSettings\\PVRSRVKM"
38
39
40#define MAX_REG_STRING_SIZE 128
41
42
43#endif
diff --git a/drivers/gpu/pvr/resman.c b/drivers/gpu/pvr/resman.c
new file mode 100644
index 00000000000..5d865a7d2c1
--- /dev/null
+++ b/drivers/gpu/pvr/resman.c
@@ -0,0 +1,736 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "resman.h"
29
30#ifdef __linux__
31#ifndef AUTOCONF_INCLUDED
32 #include <linux/config.h>
33#endif
34
35#include <linux/version.h>
36#include <linux/sched.h>
37#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
38#include <linux/hardirq.h>
39#else
40#include <asm/hardirq.h>
41#endif
42
43#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
44#include <linux/semaphore.h>
45#else
46#include <asm/semaphore.h>
47#endif
48
49static DECLARE_MUTEX(lock);
50
51#define ACQUIRE_SYNC_OBJ do { \
52 if (in_interrupt()) { \
53 printk ("ISR cannot take RESMAN mutex\n"); \
54 BUG(); \
55 } \
56 else down (&lock); \
57} while (0)
58#define RELEASE_SYNC_OBJ up (&lock)
59
60#else
61
62#define ACQUIRE_SYNC_OBJ
63#define RELEASE_SYNC_OBJ
64
65#endif
66
67#define RESMAN_SIGNATURE 0x12345678
68
69typedef struct _RESMAN_ITEM_
70{
71#ifdef DEBUG
72 IMG_UINT32 ui32Signature;
73#endif
74 struct _RESMAN_ITEM_ **ppsThis;
75 struct _RESMAN_ITEM_ *psNext;
76
77 IMG_UINT32 ui32Flags;
78 IMG_UINT32 ui32ResType;
79
80 IMG_PVOID pvParam;
81 IMG_UINT32 ui32Param;
82
83 RESMAN_FREE_FN pfnFreeResource;
84} RESMAN_ITEM;
85
86
87typedef struct _RESMAN_CONTEXT_
88{
89#ifdef DEBUG
90 IMG_UINT32 ui32Signature;
91#endif
92 struct _RESMAN_CONTEXT_ **ppsThis;
93 struct _RESMAN_CONTEXT_ *psNext;
94
95 PVRSRV_PER_PROCESS_DATA *psPerProc;
96
97 RESMAN_ITEM *psResItemList;
98
99} RESMAN_CONTEXT;
100
101
102typedef struct
103{
104 RESMAN_CONTEXT *psContextList;
105
106} RESMAN_LIST, *PRESMAN_LIST;
107
108
109PRESMAN_LIST gpsResList = IMG_NULL;
110
111#include "lists.h"
112
113static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
114static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
115static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
116static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
117static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
118
119static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
120static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
121
122
123#define PRINT_RESLIST(x, y, z)
124
125static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback);
126
127static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext,
128 IMG_UINT32 ui32SearchCriteria,
129 IMG_UINT32 ui32ResType,
130 IMG_PVOID pvParam,
131 IMG_UINT32 ui32Param,
132 IMG_BOOL bExecuteCallback);
133
134
135#ifdef DEBUG
136 static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
137 #define VALIDATERESLIST() ValidateResList(gpsResList)
138#else
139 #define VALIDATERESLIST()
140#endif
141
142
143
144
145
146
147PVRSRV_ERROR ResManInit(IMG_VOID)
148{
149 if (gpsResList == IMG_NULL)
150 {
151
152 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
153 sizeof(*gpsResList),
154 (IMG_VOID **)&gpsResList, IMG_NULL,
155 "Resource Manager List") != PVRSRV_OK)
156 {
157 return PVRSRV_ERROR_OUT_OF_MEMORY;
158 }
159
160
161 gpsResList->psContextList = IMG_NULL;
162
163
164 VALIDATERESLIST();
165 }
166
167 return PVRSRV_OK;
168}
169
170
171IMG_VOID ResManDeInit(IMG_VOID)
172{
173 if (gpsResList != IMG_NULL)
174 {
175
176 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
177 gpsResList = IMG_NULL;
178 }
179}
180
181
182PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
183 PRESMAN_CONTEXT *phResManContext)
184{
185 PVRSRV_ERROR eError;
186 PRESMAN_CONTEXT psResManContext;
187
188
189 ACQUIRE_SYNC_OBJ;
190
191
192 VALIDATERESLIST();
193
194
195 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
196 (IMG_VOID **)&psResManContext, IMG_NULL,
197 "Resource Manager Context");
198 if (eError != PVRSRV_OK)
199 {
200 PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
201
202
203 VALIDATERESLIST();
204
205
206 RELEASE_SYNC_OBJ;
207
208 return eError;
209 }
210
211#ifdef DEBUG
212 psResManContext->ui32Signature = RESMAN_SIGNATURE;
213#endif
214 psResManContext->psResItemList = IMG_NULL;
215 psResManContext->psPerProc = hPerProc;
216
217
218 List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
219
220
221 VALIDATERESLIST();
222
223
224 RELEASE_SYNC_OBJ;
225
226 *phResManContext = psResManContext;
227
228 return PVRSRV_OK;
229}
230
231
232IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
233 IMG_BOOL bKernelContext)
234{
235
236 ACQUIRE_SYNC_OBJ;
237
238
239 VALIDATERESLIST();
240
241
242 PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
243
244
245
246 if (!bKernelContext)
247 {
248
249 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
250
251
252 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
253
254
255
256 List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
257 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
258 List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
259
260
261 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
262 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
263 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
264 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
265 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
266 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
267
268
269
270
271 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
272 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
273
274
275 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
276
277
278 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE);
279 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
280 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
281 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
282 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
283 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
284 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
285 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
286 }
287
288
289 PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
290
291
292 List_RESMAN_CONTEXT_Remove(psResManContext);
293
294
295 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
296
297
298
299
300 VALIDATERESLIST();
301
302
303 PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
304
305
306 RELEASE_SYNC_OBJ;
307}
308
309
310PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext,
311 IMG_UINT32 ui32ResType,
312 IMG_PVOID pvParam,
313 IMG_UINT32 ui32Param,
314 RESMAN_FREE_FN pfnFreeResource)
315{
316 PRESMAN_ITEM psNewResItem;
317
318 PVR_ASSERT(psResManContext != IMG_NULL);
319 PVR_ASSERT(ui32ResType != 0);
320
321 if (psResManContext == IMG_NULL)
322 {
323 PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
324 return (PRESMAN_ITEM) IMG_NULL;
325 }
326
327
328 ACQUIRE_SYNC_OBJ;
329
330
331 VALIDATERESLIST();
332
333 PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
334 "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
335 "FreeFunc %08X",
336 (IMG_UINTPTR_T)psResManContext,
337 ui32ResType,
338 (IMG_UINTPTR_T)pvParam,
339 ui32Param,
340 (IMG_UINTPTR_T)pfnFreeResource));
341
342
343 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
344 sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
345 IMG_NULL,
346 "Resource Manager Item") != PVRSRV_OK)
347 {
348 PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
349 "ERROR allocating new resource item"));
350
351
352 RELEASE_SYNC_OBJ;
353
354 return((PRESMAN_ITEM)IMG_NULL);
355 }
356
357
358#ifdef DEBUG
359 psNewResItem->ui32Signature = RESMAN_SIGNATURE;
360#endif
361 psNewResItem->ui32ResType = ui32ResType;
362 psNewResItem->pvParam = pvParam;
363 psNewResItem->ui32Param = ui32Param;
364 psNewResItem->pfnFreeResource = pfnFreeResource;
365 psNewResItem->ui32Flags = 0;
366
367
368 List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
369
370
371 VALIDATERESLIST();
372
373
374 RELEASE_SYNC_OBJ;
375
376 return(psNewResItem);
377}
378
379PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem)
380{
381 PVRSRV_ERROR eError;
382
383 PVR_ASSERT(psResItem != IMG_NULL);
384
385 if (psResItem == IMG_NULL)
386 {
387 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
388 return PVRSRV_OK;
389 }
390
391 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X",
392 (IMG_UINTPTR_T)psResItem));
393
394
395 ACQUIRE_SYNC_OBJ;
396
397
398 VALIDATERESLIST();
399
400
401 eError = FreeResourceByPtr(psResItem, IMG_TRUE);
402
403
404 VALIDATERESLIST();
405
406
407 RELEASE_SYNC_OBJ;
408
409 return(eError);
410}
411
412
413PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext,
414 IMG_UINT32 ui32SearchCriteria,
415 IMG_UINT32 ui32ResType,
416 IMG_PVOID pvParam,
417 IMG_UINT32 ui32Param)
418{
419 PVRSRV_ERROR eError;
420
421 PVR_ASSERT(psResManContext != IMG_NULL);
422
423
424 ACQUIRE_SYNC_OBJ;
425
426
427 VALIDATERESLIST();
428
429 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
430 "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
431 (IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType,
432 (IMG_UINTPTR_T)pvParam, ui32Param));
433
434
435 eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
436 ui32ResType, pvParam, ui32Param,
437 IMG_TRUE);
438
439
440 VALIDATERESLIST();
441
442
443 RELEASE_SYNC_OBJ;
444
445 return eError;
446}
447
448
449PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem,
450 PRESMAN_CONTEXT psNewResManContext)
451{
452 PVRSRV_ERROR eError = PVRSRV_OK;
453
454 PVR_ASSERT(psResItem != IMG_NULL);
455
456 if (psResItem == IMG_NULL)
457 {
458 PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
459 PVR_DBG_BREAK;
460 return PVRSRV_ERROR_INVALID_PARAMS;
461 }
462
463#ifdef DEBUG
464 PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
465#endif
466
467 if (psNewResManContext != IMG_NULL)
468 {
469
470 List_RESMAN_ITEM_Remove(psResItem);
471
472
473 List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
474
475 }
476 else
477 {
478 eError = FreeResourceByPtr(psResItem, IMG_FALSE);
479 if(eError != PVRSRV_OK)
480 {
481 PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
482 return eError;
483 }
484 }
485
486 return eError;
487}
488
489static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
490{
491 RESMAN_ITEM *psItem;
492
493 psItem = va_arg(va, RESMAN_ITEM*);
494
495 return (IMG_BOOL)(psCurItem == psItem);
496}
497
498
499IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext,
500 RESMAN_ITEM *psItem)
501{
502 PVRSRV_ERROR eResult;
503
504 PVR_ASSERT(psResManContext != IMG_NULL);
505 PVR_ASSERT(psItem != IMG_NULL);
506
507 if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
508 {
509 PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
510 PVR_DBG_BREAK;
511 return PVRSRV_ERROR_INVALID_PARAMS;
512 }
513
514#ifdef DEBUG
515 PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
516#endif
517
518
519 ACQUIRE_SYNC_OBJ;
520
521 PVR_DPF((PVR_DBG_MESSAGE,
522 "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
523 (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
524
525 PVR_DPF((PVR_DBG_MESSAGE,
526 "FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, "
527 "Param 0x%x, FnCall %08X, Flags 0x%x",
528 (IMG_UINTPTR_T)psResManContext,
529 psItem->ui32ResType,
530 (IMG_UINTPTR_T)psItem->pvParam,
531 psItem->ui32Param,
532 (IMG_UINTPTR_T)psItem->pfnFreeResource,
533 psItem->ui32Flags));
534
535
536 if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
537 &ResManFindResourceByPtr_AnyVaCb,
538 psItem))
539 {
540 eResult = PVRSRV_OK;
541 }
542 else
543 {
544 eResult = PVRSRV_ERROR_NOT_OWNER;
545 }
546
547
548 RELEASE_SYNC_OBJ;
549
550 return eResult;
551}
552
553static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
554 IMG_BOOL bExecuteCallback)
555{
556 PVRSRV_ERROR eError;
557
558 PVR_ASSERT(psItem != IMG_NULL);
559
560 if (psItem == IMG_NULL)
561 {
562 PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
563 return PVRSRV_ERROR_INVALID_PARAMS;
564 }
565
566#ifdef DEBUG
567 PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
568#endif
569
570 PVR_DPF((PVR_DBG_MESSAGE,
571 "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
572 (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext));
573
574 PVR_DPF((PVR_DBG_MESSAGE,
575 "FreeResourceByPtr: Type 0x%x, Addr 0x%x, "
576 "Param 0x%x, FnCall %08X, Flags 0x%x",
577 psItem->ui32ResType,
578 (IMG_UINTPTR_T)psItem->pvParam, psItem->ui32Param,
579 (IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
580
581
582 List_RESMAN_ITEM_Remove(psItem);
583
584
585
586 RELEASE_SYNC_OBJ;
587
588
589 if (bExecuteCallback)
590 {
591 eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param);
592 if (eError != PVRSRV_OK)
593 {
594 PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
595 }
596 }
597
598
599 ACQUIRE_SYNC_OBJ;
600
601
602 eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
603 if (eError != PVRSRV_OK)
604 {
605 PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR freeing resource list item memory"));
606 }
607
608 return(eError);
609}
610
611static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
612{
613 IMG_UINT32 ui32SearchCriteria;
614 IMG_UINT32 ui32ResType;
615 IMG_PVOID pvParam;
616 IMG_UINT32 ui32Param;
617
618 ui32SearchCriteria = va_arg(va, IMG_UINT32);
619 ui32ResType = va_arg(va, IMG_UINT32);
620 pvParam = va_arg(va, IMG_PVOID);
621 ui32Param = va_arg(va, IMG_UINT32);
622
623
624 if(
625
626 (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
627 (psCurItem->ui32ResType == ui32ResType))
628 &&
629
630 (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
631 (psCurItem->pvParam == pvParam))
632 &&
633
634 (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
635 (psCurItem->ui32Param == ui32Param))
636 )
637 {
638 return psCurItem;
639 }
640 else
641 {
642 return IMG_NULL;
643 }
644}
645
646static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext,
647 IMG_UINT32 ui32SearchCriteria,
648 IMG_UINT32 ui32ResType,
649 IMG_PVOID pvParam,
650 IMG_UINT32 ui32Param,
651 IMG_BOOL bExecuteCallback)
652{
653 PRESMAN_ITEM psCurItem;
654 PVRSRV_ERROR eError = PVRSRV_OK;
655
656
657
658 while((psCurItem = (PRESMAN_ITEM)
659 List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
660 &FreeResourceByCriteria_AnyVaCb,
661 ui32SearchCriteria,
662 ui32ResType,
663 pvParam,
664 ui32Param)) != IMG_NULL
665 && eError == PVRSRV_OK)
666 {
667 eError = FreeResourceByPtr(psCurItem, bExecuteCallback);
668 }
669
670 return eError;
671}
672
673
674#ifdef DEBUG
675static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
676{
677 PRESMAN_ITEM psCurItem, *ppsThisItem;
678 PRESMAN_CONTEXT psCurContext, *ppsThisContext;
679
680
681 if (psResList == IMG_NULL)
682 {
683 PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
684 return;
685 }
686
687 psCurContext = psResList->psContextList;
688 ppsThisContext = &psResList->psContextList;
689
690
691 while(psCurContext != IMG_NULL)
692 {
693
694 PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
695 if (psCurContext->ppsThis != ppsThisContext)
696 {
697 PVR_DPF((PVR_DBG_WARNING,
698 "psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X",
699 (IMG_UINTPTR_T)psCurContext,
700 (IMG_UINTPTR_T)psCurContext->ppsThis,
701 (IMG_UINTPTR_T)psCurContext->psNext,
702 (IMG_UINTPTR_T)ppsThisContext));
703 PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
704 }
705
706
707 psCurItem = psCurContext->psResItemList;
708 ppsThisItem = &psCurContext->psResItemList;
709 while(psCurItem != IMG_NULL)
710 {
711
712 PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
713 if (psCurItem->ppsThis != ppsThisItem)
714 {
715 PVR_DPF((PVR_DBG_WARNING,
716 "psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X",
717 (IMG_UINTPTR_T)psCurItem,
718 (IMG_UINTPTR_T)psCurItem->ppsThis,
719 (IMG_UINTPTR_T)psCurItem->psNext,
720 (IMG_UINTPTR_T)ppsThisItem));
721 PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
722 }
723
724
725 ppsThisItem = &psCurItem->psNext;
726 psCurItem = psCurItem->psNext;
727 }
728
729
730 ppsThisContext = &psCurContext->psNext;
731 psCurContext = psCurContext->psNext;
732 }
733}
734#endif
735
736
diff --git a/drivers/gpu/pvr/resman.h b/drivers/gpu/pvr/resman.h
new file mode 100644
index 00000000000..eebec57c9d6
--- /dev/null
+++ b/drivers/gpu/pvr/resman.h
@@ -0,0 +1,114 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __RESMAN_H__
28#define __RESMAN_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34enum {
35
36 RESMAN_TYPE_SHARED_PB_DESC = 1,
37 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
38 RESMAN_TYPE_HW_RENDER_CONTEXT,
39 RESMAN_TYPE_HW_TRANSFER_CONTEXT,
40 RESMAN_TYPE_HW_2D_CONTEXT,
41 RESMAN_TYPE_TRANSFER_CONTEXT,
42
43
44
45
46
47 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
48 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
49
50
51 RESMAN_TYPE_BUFFERCLASS_DEVICE,
52
53
54 RESMAN_TYPE_OS_USERMODE_MAPPING,
55
56
57 RESMAN_TYPE_DEVICEMEM_CONTEXT,
58 RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
59 RESMAN_TYPE_DEVICEMEM_MAPPING,
60 RESMAN_TYPE_DEVICEMEM_WRAP,
61 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
62 RESMAN_TYPE_EVENT_OBJECT,
63 RESMAN_TYPE_SHARED_MEM_INFO,
64 RESMAN_TYPE_MODIFY_SYNC_OPS,
65 RESMAN_TYPE_SYNC_INFO,
66
67
68 RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION
69};
70
71#define RESMAN_CRITERIA_ALL 0x00000000
72#define RESMAN_CRITERIA_RESTYPE 0x00000001
73#define RESMAN_CRITERIA_PVOID_PARAM 0x00000002
74#define RESMAN_CRITERIA_UI32_PARAM 0x00000004
75
76typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
77
78typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM;
79typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT;
80
81PVRSRV_ERROR ResManInit(IMG_VOID);
82IMG_VOID ResManDeInit(IMG_VOID);
83
84PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT hResManContext,
85 IMG_UINT32 ui32ResType,
86 IMG_PVOID pvParam,
87 IMG_UINT32 ui32Param,
88 RESMAN_FREE_FN pfnFreeResource);
89
90PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM psResItem);
91
92PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT hResManContext,
93 IMG_UINT32 ui32SearchCriteria,
94 IMG_UINT32 ui32ResType,
95 IMG_PVOID pvParam,
96 IMG_UINT32 ui32Param);
97
98PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM psResItem,
99 PRESMAN_CONTEXT psNewResManContext);
100
101PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT hResManContext,
102 PRESMAN_ITEM psItem);
103
104PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
105 PRESMAN_CONTEXT *phResManContext);
106IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext,
107 IMG_BOOL bKernelContext);
108
109#if defined (__cplusplus)
110}
111#endif
112
113#endif
114
diff --git a/drivers/gpu/pvr/services.h b/drivers/gpu/pvr/services.h
new file mode 100644
index 00000000000..71fb4efb7fc
--- /dev/null
+++ b/drivers/gpu/pvr/services.h
@@ -0,0 +1,991 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SERVICES_H__
28#define __SERVICES_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "img_defs.h"
35#include "servicesext.h"
36#include "pdumpdefs.h"
37
38
39#define PVRSRV_4K_PAGE_SIZE 4096UL
40
41#define PVRSRV_MAX_CMD_SIZE 1024
42
43#define PVRSRV_MAX_DEVICES 16
44
45#define EVENTOBJNAME_MAXLENGTH (50)
46
47#define PVRSRV_MEM_READ (1U<<0)
48#define PVRSRV_MEM_WRITE (1U<<1)
49#define PVRSRV_MEM_CACHE_CONSISTENT (1U<<2)
50#define PVRSRV_MEM_NO_SYNCOBJ (1U<<3)
51#define PVRSRV_MEM_INTERLEAVED (1U<<4)
52#define PVRSRV_MEM_DUMMY (1U<<5)
53#define PVRSRV_MEM_EDM_PROTECT (1U<<6)
54#define PVRSRV_MEM_ZERO (1U<<7)
55#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR (1U<<8)
56#define PVRSRV_MEM_RAM_BACKED_ALLOCATION (1U<<9)
57#define PVRSRV_MEM_NO_RESMAN (1U<<10)
58#define PVRSRV_MEM_EXPORTED (1U<<11)
59
60
61#define PVRSRV_HAP_CACHED (1U<<12)
62#define PVRSRV_HAP_UNCACHED (1U<<13)
63#define PVRSRV_HAP_WRITECOMBINE (1U<<14)
64#define PVRSRV_HAP_CACHETYPE_MASK (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE)
65#define PVRSRV_HAP_KERNEL_ONLY (1U<<15)
66#define PVRSRV_HAP_SINGLE_PROCESS (1U<<16)
67#define PVRSRV_HAP_MULTI_PROCESS (1U<<17)
68#define PVRSRV_HAP_FROM_EXISTING_PROCESS (1U<<18)
69#define PVRSRV_HAP_NO_CPU_VIRTUAL (1U<<19)
70#define PVRSRV_HAP_MAPTYPE_MASK (PVRSRV_HAP_KERNEL_ONLY \
71 |PVRSRV_HAP_SINGLE_PROCESS \
72 |PVRSRV_HAP_MULTI_PROCESS \
73 |PVRSRV_HAP_FROM_EXISTING_PROCESS \
74 |PVRSRV_HAP_NO_CPU_VIRTUAL)
75
76#define PVRSRV_MEM_CACHED PVRSRV_HAP_CACHED
77#define PVRSRV_MEM_UNCACHED PVRSRV_HAP_UNCACHED
78#define PVRSRV_MEM_WRITECOMBINE PVRSRV_HAP_WRITECOMBINE
79
80#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT (24)
81
82#define PVRSRV_MAP_NOUSERVIRTUAL (1UL<<27)
83
84#define PVRSRV_NO_CONTEXT_LOSS 0
85#define PVRSRV_SEVERE_LOSS_OF_CONTEXT 1
86#define PVRSRV_PRE_STATE_CHANGE_MASK 0x80
87
88
89#define PVRSRV_DEFAULT_DEV_COOKIE (1)
90
91
92#define PVRSRV_MISC_INFO_TIMER_PRESENT (1U<<0)
93#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1U<<1)
94#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1U<<2)
95#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1U<<3)
96#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT (1U<<4)
97#define PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT (1U<<5)
98#define PVRSRV_MISC_INFO_FREEMEM_PRESENT (1U<<6)
99
100#define PVRSRV_MISC_INFO_RESET_PRESENT (1U<<31)
101
102#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20
103#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200
104
105
106#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT 0x00000001
107
108#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001
109#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002
110
111#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC 0x00000001
112#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC 0x00000002
113
114#define SRV_FLAGS_PERSIST 0x1
115
116typedef enum _PVRSRV_DEVICE_TYPE_
117{
118 PVRSRV_DEVICE_TYPE_UNKNOWN = 0 ,
119 PVRSRV_DEVICE_TYPE_MBX1 = 1 ,
120 PVRSRV_DEVICE_TYPE_MBX1_LITE = 2 ,
121
122 PVRSRV_DEVICE_TYPE_M24VA = 3,
123 PVRSRV_DEVICE_TYPE_MVDA2 = 4,
124 PVRSRV_DEVICE_TYPE_MVED1 = 5,
125 PVRSRV_DEVICE_TYPE_MSVDX = 6,
126
127 PVRSRV_DEVICE_TYPE_SGX = 7,
128
129 PVRSRV_DEVICE_TYPE_VGX = 8,
130
131
132 PVRSRV_DEVICE_TYPE_EXT = 9,
133
134 PVRSRV_DEVICE_TYPE_LAST = 9,
135
136 PVRSRV_DEVICE_TYPE_FORCE_I32 = 0x7fffffff
137
138} PVRSRV_DEVICE_TYPE;
139
140#define HEAP_ID( _dev_ , _dev_heap_idx_ ) ( ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1)) )
141#define HEAP_IDX( _heap_id_ ) ( (_heap_id_)&((1<<24) - 1 ) )
142#define HEAP_DEV( _heap_id_ ) ( (_heap_id_)>>24 )
143
144#define PVRSRV_UNDEFINED_HEAP_ID (~0LU)
145
146typedef enum
147{
148 IMG_EGL = 0x00000001,
149 IMG_OPENGLES1 = 0x00000002,
150 IMG_OPENGLES2 = 0x00000003,
151 IMG_D3DM = 0x00000004,
152 IMG_SRV_UM = 0x00000005,
153 IMG_OPENVG = 0x00000006,
154 IMG_SRVCLIENT = 0x00000007,
155 IMG_VISTAKMD = 0x00000008,
156 IMG_VISTA3DNODE = 0x00000009,
157 IMG_VISTAMVIDEONODE = 0x0000000A,
158 IMG_VISTAVPBNODE = 0x0000000B,
159 IMG_OPENGL = 0x0000000C,
160 IMG_D3D = 0x0000000D,
161#if defined(SUPPORT_GRAPHICS_HAL)
162 IMG_GRAPHICS_HAL = 0x0000000E
163#endif
164
165} IMG_MODULE_ID;
166
167
168#define APPHINT_MAX_STRING_SIZE 256
169
170typedef enum
171{
172 IMG_STRING_TYPE = 1,
173 IMG_FLOAT_TYPE ,
174 IMG_UINT_TYPE ,
175 IMG_INT_TYPE ,
176 IMG_FLAG_TYPE
177}IMG_DATA_TYPE;
178
179
180typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
181
182typedef struct _PVRSRV_DEVICE_IDENTIFIER_
183{
184 PVRSRV_DEVICE_TYPE eDeviceType;
185 PVRSRV_DEVICE_CLASS eDeviceClass;
186 IMG_UINT32 ui32DeviceIndex;
187 IMG_CHAR *pszPDumpDevName;
188 IMG_CHAR *pszPDumpRegName;
189
190} PVRSRV_DEVICE_IDENTIFIER;
191
192
193typedef struct _PVRSRV_CLIENT_DEV_DATA_
194{
195 IMG_UINT32 ui32NumDevices;
196 PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES];
197 PVRSRV_ERROR (*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);
198 PVRSRV_ERROR (*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);
199
200} PVRSRV_CLIENT_DEV_DATA;
201
202
203typedef struct _PVRSRV_CONNECTION_
204{
205 IMG_HANDLE hServices;
206 IMG_UINTPTR_T ui32ProcessID;
207 PVRSRV_CLIENT_DEV_DATA sClientDevData;
208 IMG_UINT32 ui32SrvFlags;
209}PVRSRV_CONNECTION;
210
211
212typedef struct _PVRSRV_DEV_DATA_
213{
214 IMG_CONST PVRSRV_CONNECTION *psConnection;
215 IMG_HANDLE hDevCookie;
216
217} PVRSRV_DEV_DATA;
218
219typedef struct _PVRSRV_MEMUPDATE_
220{
221 IMG_UINTPTR_T ui32UpdateAddr;
222 IMG_UINT32 ui32UpdateVal;
223} PVRSRV_MEMUPDATE;
224
225typedef struct _PVRSRV_HWREG_
226{
227 IMG_UINT32 ui32RegAddr;
228 IMG_UINT32 ui32RegVal;
229} PVRSRV_HWREG;
230
231typedef struct _PVRSRV_MEMBLK_
232{
233 IMG_DEV_VIRTADDR sDevVirtAddr;
234 IMG_HANDLE hOSMemHandle;
235 IMG_HANDLE hOSWrapMem;
236 IMG_HANDLE hBuffer;
237 IMG_HANDLE hResItem;
238 IMG_SYS_PHYADDR *psIntSysPAddr;
239
240} PVRSRV_MEMBLK;
241
242typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO;
243
244typedef struct _PVRSRV_CLIENT_MEM_INFO_
245{
246
247 IMG_PVOID pvLinAddr;
248
249
250 IMG_PVOID pvLinAddrKM;
251
252
253 IMG_DEV_VIRTADDR sDevVAddr;
254
255
256
257
258
259
260 IMG_CPU_PHYADDR sCpuPAddr;
261
262
263 IMG_UINT32 ui32Flags;
264
265
266
267
268 IMG_UINT32 ui32ClientFlags;
269
270
271 IMG_SIZE_T ui32AllocSize;
272
273
274
275 struct _PVRSRV_CLIENT_SYNC_INFO_ *psClientSyncInfo;
276
277
278 IMG_HANDLE hMappingInfo;
279
280
281 IMG_HANDLE hKernelMemInfo;
282
283
284 IMG_HANDLE hResItem;
285
286#if defined(SUPPORT_MEMINFO_IDS)
287 #if !defined(USE_CODE)
288
289 IMG_UINT64 ui64Stamp;
290 #else
291 IMG_UINT32 dummy1;
292 IMG_UINT32 dummy2;
293 #endif
294#endif
295
296
297
298
299 struct _PVRSRV_CLIENT_MEM_INFO_ *psNext;
300
301} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO;
302
303
304#define PVRSRV_MAX_CLIENT_HEAPS (32)
305typedef struct _PVRSRV_HEAP_INFO_
306{
307 IMG_UINT32 ui32HeapID;
308 IMG_HANDLE hDevMemHeap;
309 IMG_DEV_VIRTADDR sDevVAddrBase;
310 IMG_UINT32 ui32HeapByteSize;
311 IMG_UINT32 ui32Attribs;
312 IMG_UINT32 ui32XTileStride;
313}PVRSRV_HEAP_INFO;
314
315
316
317
318typedef struct _PVRSRV_EVENTOBJECT_
319{
320
321 IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH];
322
323 IMG_HANDLE hOSEventKM;
324
325} PVRSRV_EVENTOBJECT;
326
327typedef enum
328{
329 PVRSRV_MISC_INFO_CPUCACHEOP_NONE = 0,
330 PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN,
331 PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH
332} PVRSRV_MISC_INFO_CPUCACHEOP_TYPE;
333
334typedef struct _PVRSRV_MISC_INFO_
335{
336 IMG_UINT32 ui32StateRequest;
337 IMG_UINT32 ui32StatePresent;
338
339
340 IMG_VOID *pvSOCTimerRegisterKM;
341 IMG_VOID *pvSOCTimerRegisterUM;
342 IMG_HANDLE hSOCTimerRegisterOSMemHandle;
343 IMG_HANDLE hSOCTimerRegisterMappingInfo;
344
345
346 IMG_VOID *pvSOCClockGateRegs;
347 IMG_UINT32 ui32SOCClockGateRegsSize;
348
349
350 IMG_CHAR *pszMemoryStr;
351 IMG_UINT32 ui32MemoryStrLen;
352
353
354 PVRSRV_EVENTOBJECT sGlobalEventObject;
355 IMG_HANDLE hOSGlobalEvent;
356
357
358 IMG_UINT32 aui32DDKVersion[4];
359
360
361 struct
362 {
363
364 IMG_BOOL bDeferOp;
365
366
367 PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
368
369
370 union
371 {
372
373 PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
374
375
376 struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
377 } u;
378
379
380 IMG_VOID *pvBaseVAddr;
381
382
383 IMG_UINT32 ui32Length;
384 } sCacheOpCtl;
385} PVRSRV_MISC_INFO;
386
387
388typedef enum _PVRSRV_CLIENT_EVENT_
389{
390 PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,
391} PVRSRV_CLIENT_EVENT;
392
393IMG_IMPORT
394PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent,
395 PVRSRV_DEV_DATA *psDevData,
396 IMG_PVOID pvData);
397
398IMG_IMPORT
399PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection, IMG_UINT32 ui32SrvFlags);
400
401IMG_IMPORT
402PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(IMG_CONST PVRSRV_CONNECTION *psConnection);
403
404IMG_IMPORT
405PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION *psConnection,
406 IMG_UINT32 *puiNumDevices,
407 PVRSRV_DEVICE_IDENTIFIER *puiDevIDs);
408IMG_IMPORT
409PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION *psConnection,
410 IMG_UINT32 uiDevIndex,
411 PVRSRV_DEV_DATA *psDevData,
412 PVRSRV_DEVICE_TYPE eDeviceType);
413IMG_IMPORT
414PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
415
416IMG_IMPORT
417PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
418
419#if 1
420IMG_IMPORT
421IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
422
423IMG_IMPORT
424IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
425
426IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs);
427#endif
428
429IMG_IMPORT
430PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection,
431 IMG_HANDLE hOSEvent,
432 volatile IMG_UINT32 *pui32LinMemAddr,
433 IMG_UINT32 ui32Value,
434 IMG_UINT32 ui32Mask,
435 IMG_UINT32 ui32Waitus,
436 IMG_UINT32 ui32Tries);
437
438IMG_IMPORT
439PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
440 IMG_HANDLE *phDevMemContext,
441 IMG_UINT32 *pui32SharedHeapCount,
442 PVRSRV_HEAP_INFO *psHeapInfo);
443
444IMG_IMPORT
445PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
446 IMG_HANDLE hDevMemContext);
447
448IMG_IMPORT
449PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
450 IMG_HANDLE hDevMemContext,
451 IMG_UINT32 *pui32SharedHeapCount,
452 PVRSRV_HEAP_INFO *psHeapInfo);
453
454#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
455 #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
456 (PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \
457 ": " logStr " (size = 0x%lx)", ui32Size)), \
458 PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo))
459#else
460 #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
461 PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)
462#endif
463
464
465IMG_IMPORT
466PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
467 IMG_HANDLE hDevMemHeap,
468 IMG_UINT32 ui32Attribs,
469 IMG_SIZE_T ui32Size,
470 IMG_SIZE_T ui32Alignment,
471 PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
472
473IMG_IMPORT
474PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
475 PVRSRV_CLIENT_MEM_INFO *psMemInfo);
476
477IMG_IMPORT
478PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
479 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
480 IMG_HANDLE *phMemInfo);
481
482IMG_IMPORT
483PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
484 IMG_HANDLE hDevMemHeap,
485 IMG_DEV_VIRTADDR *psDevVAddr,
486 IMG_SIZE_T ui32Size,
487 IMG_SIZE_T ui32Alignment,
488 PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
489IMG_IMPORT
490PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
491 PVRSRV_CLIENT_MEM_INFO *psMemInfo);
492
493IMG_IMPORT
494PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
495 IMG_HANDLE hKernelMemInfo,
496 IMG_HANDLE hDstDevMemHeap,
497 PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
498
499IMG_IMPORT
500PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
501 PVRSRV_CLIENT_MEM_INFO *psMemInfo);
502
503IMG_IMPORT
504PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
505 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
506 IMG_SYS_PHYADDR *psSysPAddr,
507 IMG_UINT32 ui32Flags);
508IMG_IMPORT
509PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
510 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
511 IMG_UINT32 ui32Flags);
512
513IMG_IMPORT
514PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData,
515 IMG_HANDLE hDevMemContext,
516 IMG_SIZE_T ui32ByteSize,
517 IMG_SIZE_T ui32PageOffset,
518 IMG_BOOL bPhysContig,
519 IMG_SYS_PHYADDR *psSysPAddr,
520 IMG_VOID *pvLinAddr,
521 IMG_UINT32 ui32Flags,
522 PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
523IMG_IMPORT
524PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
525 PVRSRV_CLIENT_MEM_INFO *psMemInfo);
526
527PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA *psDevData,
528 PVRSRV_CLIENT_MEM_INFO *psClientMemInfo,
529 IMG_UINT32 ui32Attribs);
530
531IMG_IMPORT
532PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
533 IMG_HANDLE hDevMemContext,
534 IMG_HANDLE hDeviceClassBuffer,
535 PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
536IMG_IMPORT
537PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
538 PVRSRV_CLIENT_MEM_INFO *psMemInfo);
539
540IMG_IMPORT
541PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
542 IMG_SYS_PHYADDR sSysPhysAddr,
543 IMG_UINT32 uiSizeInBytes,
544 IMG_PVOID *ppvUserAddr,
545 IMG_UINT32 *puiActualSize,
546 IMG_PVOID *ppvProcess);
547
548IMG_IMPORT
549PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
550 IMG_PVOID pvUserAddr,
551 IMG_PVOID pvProcess);
552
553typedef enum _PVRSRV_SYNCVAL_MODE_
554{
555 PVRSRV_SYNCVAL_READ = IMG_TRUE,
556 PVRSRV_SYNCVAL_WRITE = IMG_FALSE,
557
558} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE;
559
560typedef IMG_UINT32 PVRSRV_SYNCVAL;
561
562IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
563 PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
564
565IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
566 PVRSRV_SYNCVAL_MODE eMode);
567
568IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
569 PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
570
571IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
572 PVRSRV_SYNCVAL_MODE eMode);
573
574IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
575 PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
576
577IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
578 PVRSRV_SYNCVAL_MODE eMode);
579
580IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
581 PVRSRV_SYNCVAL_MODE eMode);
582
583
584IMG_IMPORT
585PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection,
586 PVRSRV_DEVICE_CLASS DeviceClass,
587 IMG_UINT32 *pui32DevCount,
588 IMG_UINT32 *pui32DevID);
589
590IMG_IMPORT
591IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
592 IMG_UINT32 ui32DeviceID);
593
594IMG_IMPORT
595PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, IMG_HANDLE hDevice);
596
597IMG_IMPORT
598PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice,
599 IMG_UINT32 *pui32Count,
600 DISPLAY_FORMAT *psFormat);
601
602IMG_IMPORT
603PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice,
604 IMG_UINT32 *pui32Count,
605 DISPLAY_FORMAT *psFormat,
606 DISPLAY_DIMS *psDims);
607
608IMG_IMPORT
609PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice,
610 IMG_HANDLE *phBuffer);
611
612IMG_IMPORT
613PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice,
614 DISPLAY_INFO* psDisplayInfo);
615
616IMG_IMPORT
617PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE hDevice,
618 IMG_UINT32 ui32Flags,
619 DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
620 DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
621 IMG_UINT32 ui32BufferCount,
622 IMG_UINT32 ui32OEMFlags,
623 IMG_UINT32 *pui32SwapChainID,
624 IMG_HANDLE *phSwapChain);
625
626IMG_IMPORT
627PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice,
628 IMG_HANDLE hSwapChain);
629
630IMG_IMPORT
631PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice,
632 IMG_HANDLE hSwapChain,
633 IMG_RECT *psDstRect);
634
635IMG_IMPORT
636PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice,
637 IMG_HANDLE hSwapChain,
638 IMG_RECT *psSrcRect);
639
640IMG_IMPORT
641PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice,
642 IMG_HANDLE hSwapChain,
643 IMG_UINT32 ui32CKColour);
644
645IMG_IMPORT
646PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice,
647 IMG_HANDLE hSwapChain,
648 IMG_UINT32 ui32CKColour);
649
650IMG_IMPORT
651PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice,
652 IMG_HANDLE hSwapChain,
653 IMG_HANDLE *phBuffer);
654
655IMG_IMPORT
656PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice,
657 IMG_HANDLE hBuffer,
658 IMG_UINT32 ui32ClipRectCount,
659 IMG_RECT *psClipRect,
660 IMG_UINT32 ui32SwapInterval,
661 IMG_HANDLE hPrivateTag);
662
663IMG_IMPORT
664PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice,
665 IMG_HANDLE hSwapChain);
666
667
668IMG_IMPORT
669IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
670 IMG_UINT32 ui32DeviceID);
671
672IMG_IMPORT
673PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection,
674 IMG_HANDLE hDevice);
675
676IMG_IMPORT
677PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice,
678 BUFFER_INFO *psBuffer);
679
680IMG_IMPORT
681PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice,
682 IMG_UINT32 ui32BufferIndex,
683 IMG_HANDLE *phBuffer);
684
685
686IMG_IMPORT
687PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection);
688
689IMG_IMPORT
690PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
691
692IMG_IMPORT
693PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
694
695IMG_IMPORT
696PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
697 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
698 IMG_UINT32 ui32Offset,
699 IMG_UINT32 ui32Value,
700 IMG_UINT32 ui32Mask,
701 PDUMP_POLL_OPERATOR eOperator,
702 IMG_UINT32 ui32Flags);
703
704IMG_IMPORT
705PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
706 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
707 IMG_BOOL bIsRead,
708 IMG_UINT32 ui32Value,
709 IMG_UINT32 ui32Mask);
710
711IMG_IMPORT
712PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection,
713 IMG_PVOID pvAltLinAddr,
714 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
715 IMG_UINT32 ui32Offset,
716 IMG_UINT32 ui32Bytes,
717 IMG_UINT32 ui32Flags);
718
719IMG_IMPORT
720PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection,
721 IMG_PVOID pvAltLinAddr,
722 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
723 IMG_UINT32 ui32Offset,
724 IMG_UINT32 ui32Bytes);
725
726IMG_IMPORT
727PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_DEV_DATA *psDevData,
728 IMG_CHAR *pszRegRegion,
729 IMG_UINT32 ui32RegAddr,
730 IMG_UINT32 ui32RegValue,
731 IMG_UINT32 ui32Flags);
732
733IMG_IMPORT
734PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(const PVRSRV_DEV_DATA *psDevData,
735 IMG_CHAR *pszRegRegion,
736 IMG_UINT32 ui32RegAddr,
737 IMG_UINT32 ui32RegValue,
738 IMG_UINT32 ui32Mask,
739 IMG_UINT32 ui32Flags);
740IMG_IMPORT
741PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(const PVRSRV_DEV_DATA *psDevData,
742 IMG_CHAR *pszRegRegion,
743 IMG_UINT32 ui32RegAddr,
744 IMG_UINT32 ui32RegValue,
745 IMG_UINT32 ui32Mask);
746
747IMG_IMPORT
748PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection,
749 IMG_UINT32 ui32RegAddr,
750 IMG_UINT32 ui32RegValue);
751IMG_IMPORT
752PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection,
753 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
754 IMG_UINT32 ui32Offset,
755 IMG_DEV_PHYADDR sPDDevPAddr);
756
757IMG_IMPORT
758PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_CONNECTION *psConnection,
759 IMG_HANDLE hKernelMemInfo,
760 IMG_DEV_PHYADDR *pPages,
761 IMG_UINT32 ui32NumPages,
762 IMG_DEV_VIRTADDR sDevAddr,
763 IMG_UINT32 ui32Start,
764 IMG_UINT32 ui32Length,
765 IMG_BOOL bContinuous);
766
767IMG_IMPORT
768PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection,
769 IMG_UINT32 ui32Frame);
770
771IMG_IMPORT
772PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection,
773 IMG_CONST IMG_CHAR *pszComment,
774 IMG_BOOL bContinuous);
775
776IMG_IMPORT
777PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection,
778 IMG_BOOL bContinuous,
779 IMG_CONST IMG_CHAR *pszFormat, ...)
780#if !defined(USE_CODE)
781 IMG_FORMAT_PRINTF(3, 4)
782#endif
783;
784
785IMG_IMPORT
786PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection,
787 IMG_UINT32 ui32Flags,
788 IMG_CONST IMG_CHAR *pszFormat, ...)
789#if !defined(USE_CODE)
790 IMG_FORMAT_PRINTF(3, 4)
791#endif
792;
793
794IMG_IMPORT
795PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection,
796 IMG_CHAR *pszString,
797 IMG_BOOL bContinuous);
798
799IMG_IMPORT
800PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection,
801 IMG_BOOL *pbIsCapturing);
802
803IMG_IMPORT
804PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_DEV_DATA *psDevData,
805 IMG_CHAR *pszFileName,
806 IMG_UINT32 ui32FileOffset,
807 IMG_UINT32 ui32Width,
808 IMG_UINT32 ui32Height,
809 IMG_UINT32 ui32StrideInBytes,
810 IMG_DEV_VIRTADDR sDevBaseAddr,
811 IMG_HANDLE hDevMemContext,
812 IMG_UINT32 ui32Size,
813 PDUMP_PIXEL_FORMAT ePixelFormat,
814 PDUMP_MEM_FORMAT eMemFormat,
815 IMG_UINT32 ui32PDumpFlags);
816
817IMG_IMPORT
818PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
819 IMG_CONST IMG_CHAR *pszRegRegion,
820 IMG_CONST IMG_CHAR *pszFileName,
821 IMG_UINT32 ui32FileOffset,
822 IMG_UINT32 ui32Address,
823 IMG_UINT32 ui32Size,
824 IMG_UINT32 ui32PDumpFlags);
825
826
827IMG_IMPORT
828IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection);
829
830IMG_IMPORT
831PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
832 IMG_UINT32 ui32RegOffset,
833 IMG_BOOL bLastFrame);
834
835IMG_IMPORT IMG_HANDLE PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName);
836IMG_IMPORT PVRSRV_ERROR PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv);
837IMG_IMPORT PVRSRV_ERROR PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr);
838
839IMG_IMPORT IMG_UINT32 PVRSRVClockus (void);
840IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus);
841IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void);
842IMG_IMPORT IMG_UINTPTR_T IMG_CALLCONV PVRSRVGetCurrentProcessID(void);
843IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale);
844
845
846
847
848
849IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID,
850 const IMG_CHAR *pszAppName,
851 IMG_VOID **ppvState);
852IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID,
853 IMG_VOID *pvHintState);
854
855IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID *pvHintState,
856 const IMG_CHAR *pszHintName,
857 IMG_DATA_TYPE eDataType,
858 const IMG_VOID *pvDefault,
859 IMG_VOID *pvReturn);
860
861IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
862IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T ui32Size);
863IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize);
864IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem);
865IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
866IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
867
868struct _PVRSRV_MUTEX_OPAQUE_STRUCT_;
869typedef struct _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE;
870
871IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex);
872IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex);
873IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex);
874IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex);
875
876struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_;
877typedef struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE;
878
879
880 #define IMG_SEMAPHORE_WAIT_INFINITE ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull)
881
882
883#if !defined(USE_CODE)
884
885#ifdef INLINE_IS_PRAGMA
886#pragma inline(PVRSRVCreateSemaphore)
887#endif
888static INLINE PVRSRV_ERROR PVRSRVCreateSemaphore(PVRSRV_SEMAPHORE_HANDLE *phSemaphore, IMG_INT iInitialCount)
889{
890 PVR_UNREFERENCED_PARAMETER(iInitialCount);
891 *phSemaphore = 0;
892 return PVRSRV_OK;
893}
894
895#ifdef INLINE_IS_PRAGMA
896#pragma inline(PVRSRVDestroySemaphore)
897#endif
898static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore)
899{
900 PVR_UNREFERENCED_PARAMETER(hSemaphore);
901 return PVRSRV_OK;
902}
903
904#ifdef INLINE_IS_PRAGMA
905#pragma inline(PVRSRVWaitSemaphore)
906#endif
907static INLINE PVRSRV_ERROR PVRSRVWaitSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_UINT64 ui64TimeoutMicroSeconds)
908{
909 PVR_UNREFERENCED_PARAMETER(hSemaphore);
910 PVR_UNREFERENCED_PARAMETER(ui64TimeoutMicroSeconds);
911 return PVRSRV_ERROR_INVALID_PARAMS;
912}
913
914#ifdef INLINE_IS_PRAGMA
915#pragma inline(PVRSRVPostSemaphore)
916#endif
917static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount)
918{
919 PVR_UNREFERENCED_PARAMETER(hSemaphore);
920 PVR_UNREFERENCED_PARAMETER(iPostCount);
921}
922
923#endif
924
925
926#if (defined(DEBUG) && defined(__linux__))
927IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
928
929IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
930
931IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
932
933IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize,
934 IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
935#endif
936
937IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
938 IMG_HANDLE hOSEvent);
939
940IMG_IMPORT
941PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateSyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
942 IMG_HANDLE *phKernelSyncInfoModObj);
943
944IMG_IMPORT
945PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroySyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
946 IMG_HANDLE hKernelSyncInfoModObj);
947
948
949
950IMG_IMPORT
951PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(const PVRSRV_CONNECTION *psConnection,
952 IMG_HANDLE hKernelSyncInfoModObj,
953 PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
954 IMG_UINT32 ui32ModifyFlags,
955 IMG_UINT32 *pui32ReadOpsPending,
956 IMG_UINT32 *pui32WriteOpsPending);
957
958IMG_IMPORT
959PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(const PVRSRV_CONNECTION *psConnection,
960 IMG_HANDLE hKernelSyncInfoModObj);
961
962IMG_IMPORT
963PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToModObj(const PVRSRV_CONNECTION *psConnection,
964 IMG_HANDLE hKernelSyncInfoModObj,
965 IMG_BOOL bWait);
966
967IMG_IMPORT
968PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToDelta(const PVRSRV_CONNECTION *psConnection,
969 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
970 IMG_UINT32 ui32Delta,
971 IMG_BOOL bWait);
972
973IMG_IMPORT
974PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
975 PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfo);
976
977IMG_IMPORT
978PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
979 PVRSRV_CLIENT_SYNC_INFO *psSyncInfo);
980
981IMG_IMPORT
982const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
983
984
985#define TIME_NOT_PASSED_UINT32(a,b,c) (((a) - (b)) < (c))
986
987#if defined (__cplusplus)
988}
989#endif
990#endif
991
diff --git a/drivers/gpu/pvr/services_headers.h b/drivers/gpu/pvr/services_headers.h
new file mode 100644
index 00000000000..eb00dbb30f3
--- /dev/null
+++ b/drivers/gpu/pvr/services_headers.h
@@ -0,0 +1,49 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef SERVICES_HEADERS_H
28#define SERVICES_HEADERS_H
29
30#ifdef DEBUG_RELEASE_BUILD
31#pragma optimize( "", off )
32#define DEBUG 1
33#endif
34
35#include "img_defs.h"
36#include "services.h"
37#include "servicesint.h"
38#include "power.h"
39#include "resman.h"
40#include "queue.h"
41#include "srvkm.h"
42#include "kerneldisplay.h"
43#include "syscommon.h"
44#include "pvr_debug.h"
45#include "metrics.h"
46#include "osfunc.h"
47
48#endif
49
diff --git a/drivers/gpu/pvr/servicesext.h b/drivers/gpu/pvr/servicesext.h
new file mode 100644
index 00000000000..759cffe2e15
--- /dev/null
+++ b/drivers/gpu/pvr/servicesext.h
@@ -0,0 +1,850 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__SERVICESEXT_H__)
28#define __SERVICESEXT_H__
29
30#define PVRSRV_LOCKFLG_READONLY (1)
31
32typedef enum _PVRSRV_ERROR_
33{
34 PVRSRV_OK = 0,
35 PVRSRV_ERROR_OUT_OF_MEMORY,
36 PVRSRV_ERROR_TOO_FEW_BUFFERS,
37 PVRSRV_ERROR_INVALID_PARAMS,
38 PVRSRV_ERROR_INIT_FAILURE,
39 PVRSRV_ERROR_CANT_REGISTER_CALLBACK,
40 PVRSRV_ERROR_INVALID_DEVICE,
41 PVRSRV_ERROR_NOT_OWNER,
42 PVRSRV_ERROR_BAD_MAPPING,
43 PVRSRV_ERROR_TIMEOUT,
44 PVRSRV_ERROR_FLIP_CHAIN_EXISTS,
45 PVRSRV_ERROR_INVALID_SWAPINTERVAL,
46 PVRSRV_ERROR_SCENE_INVALID,
47 PVRSRV_ERROR_STREAM_ERROR,
48 PVRSRV_ERROR_FAILED_DEPENDENCIES,
49 PVRSRV_ERROR_CMD_NOT_PROCESSED,
50 PVRSRV_ERROR_CMD_TOO_BIG,
51 PVRSRV_ERROR_DEVICE_REGISTER_FAILED,
52 PVRSRV_ERROR_TOOMANYBUFFERS,
53 PVRSRV_ERROR_NOT_SUPPORTED,
54 PVRSRV_ERROR_PROCESSING_BLOCKED,
55
56 PVRSRV_ERROR_CANNOT_FLUSH_QUEUE,
57 PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE,
58 PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS,
59 PVRSRV_ERROR_RETRY,
60
61 PVRSRV_ERROR_DDK_VERSION_MISMATCH,
62 PVRSRV_ERROR_BUILD_MISMATCH,
63 PVRSRV_ERROR_CORE_REVISION_MISMATCH,
64
65 PVRSRV_ERROR_UPLOAD_TOO_BIG,
66
67 PVRSRV_ERROR_INVALID_FLAGS,
68 PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS,
69
70 PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY,
71 PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR,
72 PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED,
73
74 PVRSRV_ERROR_BRIDGE_CALL_FAILED,
75 PVRSRV_ERROR_IOCTL_CALL_FAILED,
76
77 PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND,
78 PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND,
79 PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT,
80
81 PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND,
82 PVRSRV_ERROR_PCI_CALL_FAILED,
83 PVRSRV_ERROR_PCI_REGION_TOO_SMALL,
84 PVRSRV_ERROR_PCI_REGION_UNAVAILABLE,
85 PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH,
86
87 PVRSRV_ERROR_REGISTER_BASE_NOT_SET,
88
89 PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM,
90 PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY,
91 PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC,
92 PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR,
93
94 PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY,
95 PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY,
96
97 PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES,
98 PVRSRV_ERROR_FAILED_TO_FREE_PAGES,
99 PVRSRV_ERROR_FAILED_TO_COPY_PAGES,
100 PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES,
101 PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES,
102 PVRSRV_ERROR_STILL_MAPPED,
103 PVRSRV_ERROR_MAPPING_NOT_FOUND,
104 PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT,
105 PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE,
106
107 PVRSRV_ERROR_INVALID_SEGMENT_BLOCK,
108 PVRSRV_ERROR_INVALID_SGXDEVDATA,
109 PVRSRV_ERROR_INVALID_DEVINFO,
110 PVRSRV_ERROR_INVALID_MEMINFO,
111 PVRSRV_ERROR_INVALID_MISCINFO,
112 PVRSRV_ERROR_UNKNOWN_IOCTL,
113 PVRSRV_ERROR_INVALID_CONTEXT,
114 PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT,
115 PVRSRV_ERROR_INVALID_HEAP,
116 PVRSRV_ERROR_INVALID_KERNELINFO,
117 PVRSRV_ERROR_UNKNOWN_POWER_STATE,
118 PVRSRV_ERROR_INVALID_HANDLE_TYPE,
119 PVRSRV_ERROR_INVALID_WRAP_TYPE,
120 PVRSRV_ERROR_INVALID_PHYS_ADDR,
121 PVRSRV_ERROR_INVALID_CPU_ADDR,
122 PVRSRV_ERROR_INVALID_HEAPINFO,
123 PVRSRV_ERROR_INVALID_PERPROC,
124 PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO,
125 PVRSRV_ERROR_INVALID_MAP_REQUEST,
126 PVRSRV_ERROR_INVALID_UNMAP_REQUEST,
127 PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP,
128 PVRSRV_ERROR_MAPPING_STILL_IN_USE,
129
130 PVRSRV_ERROR_EXCEEDED_HW_LIMITS,
131 PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED,
132
133 PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA,
134 PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT,
135 PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT,
136 PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT,
137 PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT,
138 PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD,
139 PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD,
140 PVRSRV_ERROR_THREAD_READ_ERROR,
141 PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER,
142 PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR,
143 PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR,
144 PVRSRV_ERROR_ISR_ALREADY_INSTALLED,
145 PVRSRV_ERROR_ISR_NOT_INSTALLED,
146 PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT,
147 PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO,
148 PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT,
149 PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES,
150 PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT,
151 PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE,
152
153 PVRSRV_ERROR_INVALID_CCB_COMMAND,
154
155 PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE,
156 PVRSRV_ERROR_INVALID_LOCK_ID,
157 PVRSRV_ERROR_RESOURCE_NOT_LOCKED,
158
159 PVRSRV_ERROR_FLIP_FAILED,
160 PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED,
161
162 PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE,
163
164 PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED,
165 PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG,
166 PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG,
167 PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG,
168
169 PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID,
170
171 PVRSRV_ERROR_BLIT_SETUP_FAILED,
172
173 PVRSRV_ERROR_PDUMP_NOT_AVAILABLE,
174 PVRSRV_ERROR_PDUMP_BUFFER_FULL,
175 PVRSRV_ERROR_PDUMP_BUF_OVERFLOW,
176 PVRSRV_ERROR_PDUMP_NOT_ACTIVE,
177 PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES,
178
179 PVRSRV_ERROR_MUTEX_DESTROY_FAILED,
180 PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR,
181
182 PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE,
183 PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND,
184
185 PVRSRV_ERROR_PROCESS_NOT_INITIALISED,
186 PVRSRV_ERROR_PROCESS_NOT_FOUND,
187 PVRSRV_ERROR_SRV_CONNECT_FAILED,
188 PVRSRV_ERROR_SRV_DISCONNECT_FAILED,
189 PVRSRV_ERROR_DEINT_PHASE_FAILED,
190 PVRSRV_ERROR_INIT2_PHASE_FAILED,
191
192 PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE,
193
194 PVRSRV_ERROR_NO_DC_DEVICES_FOUND,
195 PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE,
196 PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE,
197 PVRSRV_ERROR_NO_DEVICEDATA_FOUND,
198 PVRSRV_ERROR_NO_DEVICENODE_FOUND,
199 PVRSRV_ERROR_NO_CLIENTNODE_FOUND,
200 PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE,
201
202 PVRSRV_ERROR_UNABLE_TO_INIT_TASK,
203 PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK,
204 PVRSRV_ERROR_UNABLE_TO_KILL_TASK,
205
206 PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER,
207 PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER,
208 PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER,
209
210 PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT,
211 PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION,
212
213 PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE,
214 PVRSRV_ERROR_HANDLE_NOT_ALLOCATED,
215 PVRSRV_ERROR_HANDLE_TYPE_MISMATCH,
216 PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE,
217 PVRSRV_ERROR_HANDLE_NOT_SHAREABLE,
218 PVRSRV_ERROR_HANDLE_NOT_FOUND,
219 PVRSRV_ERROR_INVALID_SUBHANDLE,
220 PVRSRV_ERROR_HANDLE_BATCH_IN_USE,
221 PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE,
222
223 PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE,
224 PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED,
225
226 PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE,
227 PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP,
228
229 PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE,
230
231 PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE,
232 PVRSRV_ERROR_INVALID_DEVICEID,
233 PVRSRV_ERROR_DEVICEID_NOT_FOUND,
234
235 PVRSRV_ERROR_MEMORY_TEST_FAILED,
236 PVRSRV_ERROR_CPUPADDR_TEST_FAILED,
237 PVRSRV_ERROR_COPY_TEST_FAILED,
238
239 PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED,
240
241 PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK,
242 PVRSRV_ERROR_CLOCK_REQUEST_FAILED,
243 PVRSRV_ERROR_DISABLE_CLOCK_FAILURE,
244 PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE,
245 PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE,
246 PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK,
247 PVRSRV_ERROR_UNABLE_TO_GET_CLOCK,
248 PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK,
249 PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK,
250
251 PVRSRV_ERROR_UNKNOWN_SGL_ERROR,
252
253 PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE,
254 PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE,
255
256 PVRSRV_ERROR_BAD_SYNC_STATE,
257
258 PVRSRV_ERROR_CACHEOP_FAILED,
259
260 PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
261
262} PVRSRV_ERROR;
263
264
265typedef enum _PVRSRV_DEVICE_CLASS_
266{
267 PVRSRV_DEVICE_CLASS_3D = 0 ,
268 PVRSRV_DEVICE_CLASS_DISPLAY = 1 ,
269 PVRSRV_DEVICE_CLASS_BUFFER = 2 ,
270 PVRSRV_DEVICE_CLASS_VIDEO = 3 ,
271
272 PVRSRV_DEVICE_CLASS_FORCE_I32 = 0x7fffffff
273
274} PVRSRV_DEVICE_CLASS;
275
276
277typedef enum _PVRSRV_SYS_POWER_STATE_
278{
279 PVRSRV_SYS_POWER_STATE_Unspecified = -1,
280 PVRSRV_SYS_POWER_STATE_D0 = 0,
281 PVRSRV_SYS_POWER_STATE_D1 = 1,
282 PVRSRV_SYS_POWER_STATE_D2 = 2,
283 PVRSRV_SYS_POWER_STATE_D3 = 3,
284 PVRSRV_SYS_POWER_STATE_D4 = 4,
285
286 PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff
287
288} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE;
289
290
291typedef enum _PVRSRV_DEV_POWER_STATE_
292{
293 PVRSRV_DEV_POWER_STATE_DEFAULT = -1,
294 PVRSRV_DEV_POWER_STATE_ON = 0,
295 PVRSRV_DEV_POWER_STATE_IDLE = 1,
296 PVRSRV_DEV_POWER_STATE_OFF = 2,
297
298 PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff
299
300} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE;
301
302
303typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle,
304 PVRSRV_DEV_POWER_STATE eNewPowerState,
305 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
306typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle,
307 PVRSRV_DEV_POWER_STATE eNewPowerState,
308 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
309
310typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
311 IMG_BOOL bIdleDevice,
312 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
313typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
314 IMG_BOOL bIdleDevice,
315 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
316
317
318typedef enum _PVRSRV_PIXEL_FORMAT_ {
319
320 PVRSRV_PIXEL_FORMAT_UNKNOWN = 0,
321 PVRSRV_PIXEL_FORMAT_RGB565 = 1,
322 PVRSRV_PIXEL_FORMAT_RGB555 = 2,
323 PVRSRV_PIXEL_FORMAT_RGB888 = 3,
324 PVRSRV_PIXEL_FORMAT_BGR888 = 4,
325 PVRSRV_PIXEL_FORMAT_GREY_SCALE = 8,
326 PVRSRV_PIXEL_FORMAT_PAL12 = 13,
327 PVRSRV_PIXEL_FORMAT_PAL8 = 14,
328 PVRSRV_PIXEL_FORMAT_PAL4 = 15,
329 PVRSRV_PIXEL_FORMAT_PAL2 = 16,
330 PVRSRV_PIXEL_FORMAT_PAL1 = 17,
331 PVRSRV_PIXEL_FORMAT_ARGB1555 = 18,
332 PVRSRV_PIXEL_FORMAT_ARGB4444 = 19,
333 PVRSRV_PIXEL_FORMAT_ARGB8888 = 20,
334 PVRSRV_PIXEL_FORMAT_ABGR8888 = 21,
335 PVRSRV_PIXEL_FORMAT_YV12 = 22,
336 PVRSRV_PIXEL_FORMAT_I420 = 23,
337 PVRSRV_PIXEL_FORMAT_IMC2 = 25,
338 PVRSRV_PIXEL_FORMAT_XRGB8888 = 26,
339 PVRSRV_PIXEL_FORMAT_XBGR8888 = 27,
340 PVRSRV_PIXEL_FORMAT_BGRA8888 = 28,
341 PVRSRV_PIXEL_FORMAT_XRGB4444 = 29,
342 PVRSRV_PIXEL_FORMAT_ARGB8332 = 30,
343 PVRSRV_PIXEL_FORMAT_A2RGB10 = 31,
344 PVRSRV_PIXEL_FORMAT_A2BGR10 = 32,
345 PVRSRV_PIXEL_FORMAT_P8 = 33,
346 PVRSRV_PIXEL_FORMAT_L8 = 34,
347 PVRSRV_PIXEL_FORMAT_A8L8 = 35,
348 PVRSRV_PIXEL_FORMAT_A4L4 = 36,
349 PVRSRV_PIXEL_FORMAT_L16 = 37,
350 PVRSRV_PIXEL_FORMAT_L6V5U5 = 38,
351 PVRSRV_PIXEL_FORMAT_V8U8 = 39,
352 PVRSRV_PIXEL_FORMAT_V16U16 = 40,
353 PVRSRV_PIXEL_FORMAT_QWVU8888 = 41,
354 PVRSRV_PIXEL_FORMAT_XLVU8888 = 42,
355 PVRSRV_PIXEL_FORMAT_QWVU16 = 43,
356 PVRSRV_PIXEL_FORMAT_D16 = 44,
357 PVRSRV_PIXEL_FORMAT_D24S8 = 45,
358 PVRSRV_PIXEL_FORMAT_D24X8 = 46,
359
360
361 PVRSRV_PIXEL_FORMAT_ABGR16 = 47,
362 PVRSRV_PIXEL_FORMAT_ABGR16F = 48,
363 PVRSRV_PIXEL_FORMAT_ABGR32 = 49,
364 PVRSRV_PIXEL_FORMAT_ABGR32F = 50,
365 PVRSRV_PIXEL_FORMAT_B10GR11 = 51,
366 PVRSRV_PIXEL_FORMAT_GR88 = 52,
367 PVRSRV_PIXEL_FORMAT_BGR32 = 53,
368 PVRSRV_PIXEL_FORMAT_GR32 = 54,
369 PVRSRV_PIXEL_FORMAT_E5BGR9 = 55,
370
371
372 PVRSRV_PIXEL_FORMAT_DXT1 = 56,
373 PVRSRV_PIXEL_FORMAT_DXT2 = 57,
374 PVRSRV_PIXEL_FORMAT_DXT3 = 58,
375 PVRSRV_PIXEL_FORMAT_DXT4 = 59,
376 PVRSRV_PIXEL_FORMAT_DXT5 = 60,
377
378
379 PVRSRV_PIXEL_FORMAT_R8G8_B8G8 = 61,
380 PVRSRV_PIXEL_FORMAT_G8R8_G8B8 = 62,
381
382
383 PVRSRV_PIXEL_FORMAT_NV11 = 63,
384 PVRSRV_PIXEL_FORMAT_NV12 = 64,
385
386
387 PVRSRV_PIXEL_FORMAT_YUY2 = 65,
388 PVRSRV_PIXEL_FORMAT_YUV420 = 66,
389 PVRSRV_PIXEL_FORMAT_YUV444 = 67,
390 PVRSRV_PIXEL_FORMAT_VUY444 = 68,
391 PVRSRV_PIXEL_FORMAT_YUYV = 69,
392 PVRSRV_PIXEL_FORMAT_YVYU = 70,
393 PVRSRV_PIXEL_FORMAT_UYVY = 71,
394 PVRSRV_PIXEL_FORMAT_VYUY = 72,
395
396 PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY = 73,
397 PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV = 74,
398 PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU = 75,
399 PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY = 76,
400 PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV = 77,
401
402
403 PVRSRV_PIXEL_FORMAT_A32B32G32R32 = 78,
404 PVRSRV_PIXEL_FORMAT_A32B32G32R32F = 79,
405 PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT = 80,
406 PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT = 81,
407
408
409 PVRSRV_PIXEL_FORMAT_B32G32R32 = 82,
410 PVRSRV_PIXEL_FORMAT_B32G32R32F = 83,
411 PVRSRV_PIXEL_FORMAT_B32G32R32_UINT = 84,
412 PVRSRV_PIXEL_FORMAT_B32G32R32_SINT = 85,
413
414
415 PVRSRV_PIXEL_FORMAT_G32R32 = 86,
416 PVRSRV_PIXEL_FORMAT_G32R32F = 87,
417 PVRSRV_PIXEL_FORMAT_G32R32_UINT = 88,
418 PVRSRV_PIXEL_FORMAT_G32R32_SINT = 89,
419
420
421 PVRSRV_PIXEL_FORMAT_D32F = 90,
422 PVRSRV_PIXEL_FORMAT_R32 = 91,
423 PVRSRV_PIXEL_FORMAT_R32F = 92,
424 PVRSRV_PIXEL_FORMAT_R32_UINT = 93,
425 PVRSRV_PIXEL_FORMAT_R32_SINT = 94,
426
427
428 PVRSRV_PIXEL_FORMAT_A16B16G16R16 = 95,
429 PVRSRV_PIXEL_FORMAT_A16B16G16R16F = 96,
430 PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT = 97,
431 PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM = 98,
432 PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT = 99,
433 PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM = 100,
434
435
436 PVRSRV_PIXEL_FORMAT_G16R16 = 101,
437 PVRSRV_PIXEL_FORMAT_G16R16F = 102,
438 PVRSRV_PIXEL_FORMAT_G16R16_UINT = 103,
439 PVRSRV_PIXEL_FORMAT_G16R16_UNORM = 104,
440 PVRSRV_PIXEL_FORMAT_G16R16_SINT = 105,
441 PVRSRV_PIXEL_FORMAT_G16R16_SNORM = 106,
442
443
444 PVRSRV_PIXEL_FORMAT_R16 = 107,
445 PVRSRV_PIXEL_FORMAT_R16F = 108,
446 PVRSRV_PIXEL_FORMAT_R16_UINT = 109,
447 PVRSRV_PIXEL_FORMAT_R16_UNORM = 110,
448 PVRSRV_PIXEL_FORMAT_R16_SINT = 111,
449 PVRSRV_PIXEL_FORMAT_R16_SNORM = 112,
450
451
452 PVRSRV_PIXEL_FORMAT_X8R8G8B8 = 113,
453 PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM = 114,
454 PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB = 115,
455
456 PVRSRV_PIXEL_FORMAT_A8R8G8B8 = 116,
457 PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM = 117,
458 PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB = 118,
459
460 PVRSRV_PIXEL_FORMAT_A8B8G8R8 = 119,
461 PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT = 120,
462 PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM = 121,
463 PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB = 122,
464 PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT = 123,
465 PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM = 124,
466
467
468 PVRSRV_PIXEL_FORMAT_G8R8 = 125,
469 PVRSRV_PIXEL_FORMAT_G8R8_UINT = 126,
470 PVRSRV_PIXEL_FORMAT_G8R8_UNORM = 127,
471 PVRSRV_PIXEL_FORMAT_G8R8_SINT = 128,
472 PVRSRV_PIXEL_FORMAT_G8R8_SNORM = 129,
473
474
475 PVRSRV_PIXEL_FORMAT_A8 = 130,
476 PVRSRV_PIXEL_FORMAT_R8 = 131,
477 PVRSRV_PIXEL_FORMAT_R8_UINT = 132,
478 PVRSRV_PIXEL_FORMAT_R8_UNORM = 133,
479 PVRSRV_PIXEL_FORMAT_R8_SINT = 134,
480 PVRSRV_PIXEL_FORMAT_R8_SNORM = 135,
481
482
483 PVRSRV_PIXEL_FORMAT_A2B10G10R10 = 136,
484 PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM = 137,
485 PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT = 138,
486
487
488 PVRSRV_PIXEL_FORMAT_B10G11R11 = 139,
489 PVRSRV_PIXEL_FORMAT_B10G11R11F = 140,
490
491
492 PVRSRV_PIXEL_FORMAT_X24G8R32 = 141,
493 PVRSRV_PIXEL_FORMAT_G8R24 = 142,
494 PVRSRV_PIXEL_FORMAT_X8R24 = 143,
495 PVRSRV_PIXEL_FORMAT_E5B9G9R9 = 144,
496 PVRSRV_PIXEL_FORMAT_R1 = 145,
497
498 PVRSRV_PIXEL_FORMAT_BC1 = 146,
499 PVRSRV_PIXEL_FORMAT_BC1_UNORM = 147,
500 PVRSRV_PIXEL_FORMAT_BC1_SRGB = 148,
501 PVRSRV_PIXEL_FORMAT_BC2 = 149,
502 PVRSRV_PIXEL_FORMAT_BC2_UNORM = 150,
503 PVRSRV_PIXEL_FORMAT_BC2_SRGB = 151,
504 PVRSRV_PIXEL_FORMAT_BC3 = 152,
505 PVRSRV_PIXEL_FORMAT_BC3_UNORM = 153,
506 PVRSRV_PIXEL_FORMAT_BC3_SRGB = 154,
507 PVRSRV_PIXEL_FORMAT_BC4 = 155,
508 PVRSRV_PIXEL_FORMAT_BC4_UNORM = 156,
509 PVRSRV_PIXEL_FORMAT_BC4_SNORM = 157,
510 PVRSRV_PIXEL_FORMAT_BC5 = 158,
511 PVRSRV_PIXEL_FORMAT_BC5_UNORM = 159,
512 PVRSRV_PIXEL_FORMAT_BC5_SNORM = 160,
513
514
515 PVRSRV_PIXEL_FORMAT_UBYTE4 = 161,
516 PVRSRV_PIXEL_FORMAT_SHORT4 = 162,
517 PVRSRV_PIXEL_FORMAT_SHORT4N = 163,
518 PVRSRV_PIXEL_FORMAT_USHORT4N = 164,
519 PVRSRV_PIXEL_FORMAT_SHORT2N = 165,
520 PVRSRV_PIXEL_FORMAT_SHORT2 = 166,
521 PVRSRV_PIXEL_FORMAT_USHORT2N = 167,
522 PVRSRV_PIXEL_FORMAT_UDEC3 = 168,
523 PVRSRV_PIXEL_FORMAT_DEC3N = 169,
524 PVRSRV_PIXEL_FORMAT_F16_2 = 170,
525 PVRSRV_PIXEL_FORMAT_F16_4 = 171,
526
527
528 PVRSRV_PIXEL_FORMAT_L_F16 = 172,
529 PVRSRV_PIXEL_FORMAT_L_F16_REP = 173,
530 PVRSRV_PIXEL_FORMAT_L_F16_A_F16 = 174,
531 PVRSRV_PIXEL_FORMAT_A_F16 = 175,
532 PVRSRV_PIXEL_FORMAT_B16G16R16F = 176,
533
534 PVRSRV_PIXEL_FORMAT_L_F32 = 177,
535 PVRSRV_PIXEL_FORMAT_A_F32 = 178,
536 PVRSRV_PIXEL_FORMAT_L_F32_A_F32 = 179,
537
538
539 PVRSRV_PIXEL_FORMAT_PVRTC2 = 180,
540 PVRSRV_PIXEL_FORMAT_PVRTC4 = 181,
541 PVRSRV_PIXEL_FORMAT_PVRTCII2 = 182,
542 PVRSRV_PIXEL_FORMAT_PVRTCII4 = 183,
543 PVRSRV_PIXEL_FORMAT_PVRTCIII = 184,
544 PVRSRV_PIXEL_FORMAT_PVRO8 = 185,
545 PVRSRV_PIXEL_FORMAT_PVRO88 = 186,
546 PVRSRV_PIXEL_FORMAT_PT1 = 187,
547 PVRSRV_PIXEL_FORMAT_PT2 = 188,
548 PVRSRV_PIXEL_FORMAT_PT4 = 189,
549 PVRSRV_PIXEL_FORMAT_PT8 = 190,
550 PVRSRV_PIXEL_FORMAT_PTW = 191,
551 PVRSRV_PIXEL_FORMAT_PTB = 192,
552 PVRSRV_PIXEL_FORMAT_MONO8 = 193,
553 PVRSRV_PIXEL_FORMAT_MONO16 = 194,
554
555
556 PVRSRV_PIXEL_FORMAT_C0_YUYV = 195,
557 PVRSRV_PIXEL_FORMAT_C0_UYVY = 196,
558 PVRSRV_PIXEL_FORMAT_C0_YVYU = 197,
559 PVRSRV_PIXEL_FORMAT_C0_VYUY = 198,
560 PVRSRV_PIXEL_FORMAT_C1_YUYV = 199,
561 PVRSRV_PIXEL_FORMAT_C1_UYVY = 200,
562 PVRSRV_PIXEL_FORMAT_C1_YVYU = 201,
563 PVRSRV_PIXEL_FORMAT_C1_VYUY = 202,
564
565
566 PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV = 203,
567 PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU = 204,
568 PVRSRV_PIXEL_FORMAT_C0_YUV420_3P = 205,
569 PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV = 206,
570 PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU = 207,
571 PVRSRV_PIXEL_FORMAT_C1_YUV420_3P = 208,
572
573 PVRSRV_PIXEL_FORMAT_A2B10G10R10F = 209,
574 PVRSRV_PIXEL_FORMAT_B8G8R8_SINT = 210,
575 PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK = 211,
576
577 PVRSRV_PIXEL_FORMAT_ABGR4444 = 212,
578 PVRSRV_PIXEL_FORMAT_ABGR1555 = 213,
579 PVRSRV_PIXEL_FORMAT_BGR565 = 214,
580
581 PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
582
583} PVRSRV_PIXEL_FORMAT;
584
585typedef enum _PVRSRV_ALPHA_FORMAT_ {
586 PVRSRV_ALPHA_FORMAT_UNKNOWN = 0x00000000,
587 PVRSRV_ALPHA_FORMAT_PRE = 0x00000001,
588 PVRSRV_ALPHA_FORMAT_NONPRE = 0x00000002,
589 PVRSRV_ALPHA_FORMAT_MASK = 0x0000000F,
590} PVRSRV_ALPHA_FORMAT;
591
592typedef enum _PVRSRV_COLOURSPACE_FORMAT_ {
593 PVRSRV_COLOURSPACE_FORMAT_UNKNOWN = 0x00000000,
594 PVRSRV_COLOURSPACE_FORMAT_LINEAR = 0x00010000,
595 PVRSRV_COLOURSPACE_FORMAT_NONLINEAR = 0x00020000,
596 PVRSRV_COLOURSPACE_FORMAT_MASK = 0x000F0000,
597} PVRSRV_COLOURSPACE_FORMAT;
598
599
600typedef enum _PVRSRV_ROTATION_ {
601 PVRSRV_ROTATE_0 = 0,
602 PVRSRV_ROTATE_90 = 1,
603 PVRSRV_ROTATE_180 = 2,
604 PVRSRV_ROTATE_270 = 3,
605 PVRSRV_FLIP_Y
606
607} PVRSRV_ROTATION;
608
609#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0)
610#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1)
611#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2)
612
613typedef struct _PVRSRV_SYNC_DATA_
614{
615
616 IMG_UINT32 ui32WriteOpsPending;
617 volatile IMG_UINT32 ui32WriteOpsComplete;
618
619
620 IMG_UINT32 ui32ReadOpsPending;
621 volatile IMG_UINT32 ui32ReadOpsComplete;
622
623
624 IMG_UINT32 ui32LastOpDumpVal;
625 IMG_UINT32 ui32LastReadOpDumpVal;
626
627} PVRSRV_SYNC_DATA;
628
629typedef struct _PVRSRV_CLIENT_SYNC_INFO_
630{
631
632 PVRSRV_SYNC_DATA *psSyncData;
633
634
635
636
637
638 IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
639
640
641 IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
642
643
644 IMG_HANDLE hMappingInfo;
645
646
647 IMG_HANDLE hKernelSyncInfo;
648
649} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO;
650
651typedef struct PVRSRV_RESOURCE_TAG
652{
653 volatile IMG_UINT32 ui32Lock;
654 IMG_UINT32 ui32ID;
655}PVRSRV_RESOURCE;
656typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE;
657
658
659typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE);
660typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE);
661
662typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
663typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
664
665
666typedef struct _IMG_RECT_
667{
668 IMG_INT32 x0;
669 IMG_INT32 y0;
670 IMG_INT32 x1;
671 IMG_INT32 y1;
672}IMG_RECT;
673
674typedef struct _IMG_RECT_16_
675{
676 IMG_INT16 x0;
677 IMG_INT16 y0;
678 IMG_INT16 x1;
679 IMG_INT16 y1;
680}IMG_RECT_16;
681
682
683typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE,
684 IMG_HANDLE,
685 IMG_SYS_PHYADDR**,
686 IMG_SIZE_T*,
687 IMG_VOID**,
688 IMG_HANDLE*,
689 IMG_BOOL*,
690 IMG_UINT32*);
691
692
693typedef struct DISPLAY_DIMS_TAG
694{
695 IMG_UINT32 ui32ByteStride;
696 IMG_UINT32 ui32Width;
697 IMG_UINT32 ui32Height;
698} DISPLAY_DIMS;
699
700
701typedef struct DISPLAY_FORMAT_TAG
702{
703
704 PVRSRV_PIXEL_FORMAT pixelformat;
705} DISPLAY_FORMAT;
706
707typedef struct DISPLAY_SURF_ATTRIBUTES_TAG
708{
709
710 PVRSRV_PIXEL_FORMAT pixelformat;
711
712 DISPLAY_DIMS sDims;
713} DISPLAY_SURF_ATTRIBUTES;
714
715
716typedef struct DISPLAY_MODE_INFO_TAG
717{
718
719 PVRSRV_PIXEL_FORMAT pixelformat;
720
721 DISPLAY_DIMS sDims;
722
723 IMG_UINT32 ui32RefreshHZ;
724
725 IMG_UINT32 ui32OEMFlags;
726} DISPLAY_MODE_INFO;
727
728
729
730#define MAX_DISPLAY_NAME_SIZE (50)
731
732typedef struct DISPLAY_INFO_TAG
733{
734
735 IMG_UINT32 ui32MaxSwapChains;
736
737 IMG_UINT32 ui32MaxSwapChainBuffers;
738
739 IMG_UINT32 ui32MinSwapInterval;
740
741 IMG_UINT32 ui32MaxSwapInterval;
742
743 IMG_UINT32 ui32PhysicalWidthmm;
744 IMG_UINT32 ui32PhysicalHeightmm;
745
746 IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE];
747#if defined(SUPPORT_HW_CURSOR)
748
749 IMG_UINT16 ui32CursorWidth;
750 IMG_UINT16 ui32CursorHeight;
751#endif
752} DISPLAY_INFO;
753
754typedef struct ACCESS_INFO_TAG
755{
756 IMG_UINT32 ui32Size;
757 IMG_UINT32 ui32FBPhysBaseAddress;
758 IMG_UINT32 ui32FBMemAvailable;
759 IMG_UINT32 ui32SysPhysBaseAddress;
760 IMG_UINT32 ui32SysSize;
761 IMG_UINT32 ui32DevIRQ;
762}ACCESS_INFO;
763
764
765typedef struct PVRSRV_CURSOR_SHAPE_TAG
766{
767 IMG_UINT16 ui16Width;
768 IMG_UINT16 ui16Height;
769 IMG_INT16 i16XHot;
770 IMG_INT16 i16YHot;
771
772
773 IMG_VOID* pvMask;
774 IMG_INT16 i16MaskByteStride;
775
776
777 IMG_VOID* pvColour;
778 IMG_INT16 i16ColourByteStride;
779 PVRSRV_PIXEL_FORMAT eColourPixelFormat;
780} PVRSRV_CURSOR_SHAPE;
781
782#define PVRSRV_SET_CURSOR_VISIBILITY (1<<0)
783#define PVRSRV_SET_CURSOR_POSITION (1<<1)
784#define PVRSRV_SET_CURSOR_SHAPE (1<<2)
785#define PVRSRV_SET_CURSOR_ROTATION (1<<3)
786
787typedef struct PVRSRV_CURSOR_INFO_TAG
788{
789
790 IMG_UINT32 ui32Flags;
791
792
793 IMG_BOOL bVisible;
794
795
796 IMG_INT16 i16XPos;
797 IMG_INT16 i16YPos;
798
799
800 PVRSRV_CURSOR_SHAPE sCursorShape;
801
802
803 IMG_UINT32 ui32Rotation;
804
805} PVRSRV_CURSOR_INFO;
806
807
808typedef struct _PVRSRV_REGISTRY_INFO_
809{
810 IMG_UINT32 ui32DevCookie;
811 IMG_PCHAR pszKey;
812 IMG_PCHAR pszValue;
813 IMG_PCHAR pszBuf;
814 IMG_UINT32 ui32BufSize;
815} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO;
816
817
818PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
819PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
820
821
822#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE (0 << 0)
823#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE (1 << 0)
824
825#define PVRSRV_BC_FLAGS_YUVCSC_BT601 (0 << 1)
826#define PVRSRV_BC_FLAGS_YUVCSC_BT709 (1 << 1)
827
828#define MAX_BUFFER_DEVICE_NAME_SIZE (50)
829
830typedef struct BUFFER_INFO_TAG
831{
832 IMG_UINT32 ui32BufferCount;
833 IMG_UINT32 ui32BufferDeviceID;
834 PVRSRV_PIXEL_FORMAT pixelformat;
835 IMG_UINT32 ui32ByteStride;
836 IMG_UINT32 ui32Width;
837 IMG_UINT32 ui32Height;
838 IMG_UINT32 ui32Flags;
839 IMG_CHAR szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE];
840} BUFFER_INFO;
841
842typedef enum _OVERLAY_DEINTERLACE_MODE_
843{
844 WEAVE=0x0,
845 BOB_ODD,
846 BOB_EVEN,
847 BOB_EVEN_NONINTERLEAVED
848} OVERLAY_DEINTERLACE_MODE;
849
850#endif
diff --git a/drivers/gpu/pvr/servicesint.h b/drivers/gpu/pvr/servicesint.h
new file mode 100644
index 00000000000..bc5aeb8dc0b
--- /dev/null
+++ b/drivers/gpu/pvr/servicesint.h
@@ -0,0 +1,282 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__SERVICESINT_H__)
28#define __SERVICESINT_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "services.h"
35#include "sysinfo.h"
36
37#define HWREC_DEFAULT_TIMEOUT (500)
38
39#define DRIVERNAME_MAXLENGTH (100)
40
41#define ALIGNSIZE(size, alignshift) (((size) + ((1UL << (alignshift))-1)) & ~((1UL << (alignshift))-1))
42
43#ifndef MAX
44#define MAX(a,b) (((a) > (b)) ? (a) : (b))
45#endif
46#ifndef MIN
47#define MIN(a,b) (((a) < (b)) ? (a) : (b))
48#endif
49
50typedef enum _PVRSRV_MEMTYPE_
51{
52 PVRSRV_MEMTYPE_UNKNOWN = 0,
53 PVRSRV_MEMTYPE_DEVICE = 1,
54 PVRSRV_MEMTYPE_DEVICECLASS = 2,
55 PVRSRV_MEMTYPE_WRAPPED = 3,
56 PVRSRV_MEMTYPE_MAPPED = 4,
57} PVRSRV_MEMTYPE;
58
59typedef struct _PVRSRV_KERNEL_MEM_INFO_
60{
61
62 IMG_PVOID pvLinAddrKM;
63
64
65 IMG_DEV_VIRTADDR sDevVAddr;
66
67
68 IMG_UINT32 ui32Flags;
69
70
71 IMG_SIZE_T ui32AllocSize;
72
73
74 PVRSRV_MEMBLK sMemBlk;
75
76
77 IMG_PVOID pvSysBackupBuffer;
78
79
80 IMG_UINT32 ui32RefCount;
81
82
83 IMG_BOOL bPendingFree;
84
85
86#if defined(SUPPORT_MEMINFO_IDS)
87 #if !defined(USE_CODE)
88
89 IMG_UINT64 ui64Stamp;
90 #else
91 IMG_UINT32 dummy1;
92 IMG_UINT32 dummy2;
93 #endif
94#endif
95
96
97 struct _PVRSRV_KERNEL_SYNC_INFO_ *psKernelSyncInfo;
98
99 PVRSRV_MEMTYPE memType;
100} PVRSRV_KERNEL_MEM_INFO;
101
102
103typedef struct _PVRSRV_KERNEL_SYNC_INFO_
104{
105
106 PVRSRV_SYNC_DATA *psSyncData;
107
108
109 IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
110
111
112 IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
113
114
115 PVRSRV_KERNEL_MEM_INFO *psSyncDataMemInfoKM;
116
117
118
119 IMG_UINT32 ui32RefCount;
120
121
122 IMG_HANDLE hResItem;
123} PVRSRV_KERNEL_SYNC_INFO;
124
125typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_
126{
127
128 IMG_UINT32 ui32ReadOpsPendingVal;
129 IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
130 IMG_UINT32 ui32WriteOpsPendingVal;
131 IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
132} PVRSRV_DEVICE_SYNC_OBJECT;
133
134typedef struct _PVRSRV_SYNC_OBJECT
135{
136 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM;
137 IMG_UINT32 ui32WriteOpsPending;
138 IMG_UINT32 ui32ReadOpsPending;
139
140}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT;
141
142typedef struct _PVRSRV_COMMAND
143{
144 IMG_SIZE_T ui32CmdSize;
145 IMG_UINT32 ui32DevIndex;
146 IMG_UINT32 CommandType;
147 IMG_UINT32 ui32DstSyncCount;
148 IMG_UINT32 ui32SrcSyncCount;
149 PVRSRV_SYNC_OBJECT *psDstSync;
150 PVRSRV_SYNC_OBJECT *psSrcSync;
151 IMG_SIZE_T ui32DataSize;
152 IMG_UINT32 ui32ProcessID;
153 IMG_VOID *pvData;
154}PVRSRV_COMMAND, *PPVRSRV_COMMAND;
155
156
157typedef struct _PVRSRV_QUEUE_INFO_
158{
159 IMG_VOID *pvLinQueueKM;
160 IMG_VOID *pvLinQueueUM;
161 volatile IMG_SIZE_T ui32ReadOffset;
162 volatile IMG_SIZE_T ui32WriteOffset;
163 IMG_UINT32 *pui32KickerAddrKM;
164 IMG_UINT32 *pui32KickerAddrUM;
165 IMG_SIZE_T ui32QueueSize;
166
167 IMG_UINT32 ui32ProcessID;
168
169 IMG_HANDLE hMemBlock[2];
170
171 struct _PVRSRV_QUEUE_INFO_ *psNextKM;
172}PVRSRV_QUEUE_INFO;
173
174typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*,
175 PVRSRV_COMMAND**,
176 IMG_UINT32,
177 IMG_UINT16,
178 IMG_UINT32,
179 PVRSRV_KERNEL_SYNC_INFO*[],
180 IMG_UINT32,
181 PVRSRV_KERNEL_SYNC_INFO*[],
182 IMG_UINT32);
183typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL);
184
185
186typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG
187{
188 PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
189 IMG_HANDLE hDevMemContext;
190 IMG_HANDLE hExtDevice;
191 IMG_HANDLE hExtBuffer;
192 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
193
194} PVRSRV_DEVICECLASS_BUFFER;
195
196
197typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG
198{
199 IMG_HANDLE hDeviceKM;
200 IMG_HANDLE hServices;
201} PVRSRV_CLIENT_DEVICECLASS_INFO;
202
203
204#ifdef INLINE_IS_PRAGMA
205#pragma inline(PVRSRVGetWriteOpsPending)
206#endif
207static INLINE
208IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
209{
210 IMG_UINT32 ui32WriteOpsPending;
211
212 if(bIsReadOp)
213 {
214 ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
215 }
216 else
217 {
218
219
220
221 ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++;
222 }
223
224 return ui32WriteOpsPending;
225}
226
227#ifdef INLINE_IS_PRAGMA
228#pragma inline(PVRSRVGetReadOpsPending)
229#endif
230static INLINE
231IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
232{
233 IMG_UINT32 ui32ReadOpsPending;
234
235 if(bIsReadOp)
236 {
237 ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending++;
238 }
239 else
240 {
241 ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
242 }
243
244 return ui32ReadOpsPending;
245}
246
247IMG_IMPORT
248PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
249 PVRSRV_COMMAND *psCommand);
250
251
252
253IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
254PVRSRVGetMMUContextPDDevPAddr(const PVRSRV_CONNECTION *psConnection,
255 IMG_HANDLE hDevMemContext,
256 IMG_DEV_PHYADDR *sPDDevPAddr);
257
258IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
259PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
260 IMG_UINT32 ui32Flags,
261 IMG_SIZE_T ui32Size,
262 PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
263
264IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
265PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection,
266 PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
267
268IMG_IMPORT PVRSRV_ERROR
269PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection,
270 PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
271
272IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
273PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection,
274 IMG_HANDLE hKernelMemInfo,
275 PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
276
277
278#if defined (__cplusplus)
279}
280#endif
281#endif
282
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
new file mode 100644
index 00000000000..e1b73201a12
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
@@ -0,0 +1,2670 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27
28
29#include <stddef.h>
30
31#include "img_defs.h"
32
33#if defined(SUPPORT_SGX)
34
35#include "services.h"
36#include "pvr_debug.h"
37#include "pvr_bridge.h"
38#include "sgx_bridge.h"
39#include "perproc.h"
40#include "power.h"
41#include "pvr_bridge_km.h"
42#include "sgx_bridge_km.h"
43
44#if defined(SUPPORT_MSVDX)
45 #include "msvdx_bridge.h"
46#endif
47
48#include "bridged_pvr_bridge.h"
49#include "bridged_sgx_bridge.h"
50#include "sgxutils.h"
51#include "pdump_km.h"
52
53static IMG_INT
54SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID,
55 PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN,
56 PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT,
57 PVRSRV_PER_PROCESS_DATA *psPerProc)
58{
59 IMG_HANDLE hDevCookieInt;
60
61 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO);
62
63 psGetClientInfoOUT->eError =
64 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
65 psGetClientInfoIN->hDevCookie,
66 PVRSRV_HANDLE_TYPE_DEV_NODE);
67 if(psGetClientInfoOUT->eError != PVRSRV_OK)
68 {
69 return 0;
70 }
71
72 psGetClientInfoOUT->eError =
73 SGXGetClientInfoKM(hDevCookieInt,
74 &psGetClientInfoOUT->sClientInfo);
75 return 0;
76}
77
78static IMG_INT
79SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID,
80 PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN,
81 PVRSRV_BRIDGE_RETURN *psRetOUT,
82 PVRSRV_PER_PROCESS_DATA *psPerProc)
83{
84 PVRSRV_SGXDEV_INFO *psDevInfo;
85 IMG_HANDLE hDevCookieInt;
86
87 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO);
88
89 psRetOUT->eError =
90 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
91 psReleaseClientInfoIN->hDevCookie,
92 PVRSRV_HANDLE_TYPE_DEV_NODE);
93 if(psRetOUT->eError != PVRSRV_OK)
94 {
95 return 0;
96 }
97
98 psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
99
100 PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0);
101
102 psDevInfo->ui32ClientRefCount--;
103
104 psRetOUT->eError = PVRSRV_OK;
105
106 return 0;
107}
108
109
110static IMG_INT
111SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID,
112 PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN,
113 PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT,
114 PVRSRV_PER_PROCESS_DATA *psPerProc)
115{
116 IMG_HANDLE hDevCookieInt;
117
118 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO);
119
120 psSGXGetInternalDevInfoOUT->eError =
121 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
122 psSGXGetInternalDevInfoIN->hDevCookie,
123 PVRSRV_HANDLE_TYPE_DEV_NODE);
124 if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK)
125 {
126 return 0;
127 }
128
129 psSGXGetInternalDevInfoOUT->eError =
130 SGXGetInternalDevInfoKM(hDevCookieInt,
131 &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
132
133
134 psSGXGetInternalDevInfoOUT->eError =
135 PVRSRVAllocHandle(psPerProc->psHandleBase,
136 &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
137 psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
138 PVRSRV_HANDLE_TYPE_MEM_INFO,
139 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
140
141 return 0;
142}
143
144
145static IMG_INT
146SGXDoKickBW(IMG_UINT32 ui32BridgeID,
147 PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN,
148 PVRSRV_BRIDGE_RETURN *psRetOUT,
149 PVRSRV_PER_PROCESS_DATA *psPerProc)
150{
151 IMG_HANDLE hDevCookieInt;
152 IMG_UINT32 i;
153 IMG_INT ret = 0;
154 IMG_UINT32 ui32NumDstSyncs;
155 IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL;
156
157 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK);
158
159 psRetOUT->eError =
160 PVRSRVLookupHandle(psPerProc->psHandleBase,
161 &hDevCookieInt,
162 psDoKickIN->hDevCookie,
163 PVRSRV_HANDLE_TYPE_DEV_NODE);
164
165 if(psRetOUT->eError != PVRSRV_OK)
166 {
167 return 0;
168 }
169
170 psRetOUT->eError =
171 PVRSRVLookupHandle(psPerProc->psHandleBase,
172 &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
173 psDoKickIN->sCCBKick.hCCBKernelMemInfo,
174 PVRSRV_HANDLE_TYPE_MEM_INFO);
175
176 if(psRetOUT->eError != PVRSRV_OK)
177 {
178 return 0;
179 }
180
181 if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL)
182 {
183 psRetOUT->eError =
184 PVRSRVLookupHandle(psPerProc->psHandleBase,
185 &psDoKickIN->sCCBKick.hTA3DSyncInfo,
186 psDoKickIN->sCCBKick.hTA3DSyncInfo,
187 PVRSRV_HANDLE_TYPE_SYNC_INFO);
188
189 if(psRetOUT->eError != PVRSRV_OK)
190 {
191 return 0;
192 }
193 }
194
195 if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL)
196 {
197 psRetOUT->eError =
198 PVRSRVLookupHandle(psPerProc->psHandleBase,
199 &psDoKickIN->sCCBKick.hTASyncInfo,
200 psDoKickIN->sCCBKick.hTASyncInfo,
201 PVRSRV_HANDLE_TYPE_SYNC_INFO);
202
203 if(psRetOUT->eError != PVRSRV_OK)
204 {
205 return 0;
206 }
207 }
208
209 if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL)
210 {
211 psRetOUT->eError =
212 PVRSRVLookupHandle(psPerProc->psHandleBase,
213 &psDoKickIN->sCCBKick.h3DSyncInfo,
214 psDoKickIN->sCCBKick.h3DSyncInfo,
215 PVRSRV_HANDLE_TYPE_SYNC_INFO);
216
217 if(psRetOUT->eError != PVRSRV_OK)
218 {
219 return 0;
220 }
221 }
222
223
224#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
225
226 if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS)
227 {
228 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
229 return 0;
230 }
231
232 for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++)
233 {
234 psRetOUT->eError =
235 PVRSRVLookupHandle(psPerProc->psHandleBase,
236 &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
237 psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
238 PVRSRV_HANDLE_TYPE_SYNC_INFO);
239
240 if(psRetOUT->eError != PVRSRV_OK)
241 {
242 return 0;
243 }
244 }
245
246 if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS)
247 {
248 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
249 return 0;
250 }
251
252 for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++)
253 {
254 psRetOUT->eError =
255 PVRSRVLookupHandle(psPerProc->psHandleBase,
256 &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
257 psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
258 PVRSRV_HANDLE_TYPE_SYNC_INFO);
259
260 if(psRetOUT->eError != PVRSRV_OK)
261 {
262 return 0;
263 }
264 }
265
266 if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS)
267 {
268 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
269 return 0;
270 }
271
272 for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++)
273 {
274 psRetOUT->eError =
275 PVRSRVLookupHandle(psPerProc->psHandleBase,
276 &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
277 psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
278 PVRSRV_HANDLE_TYPE_SYNC_INFO);
279
280 if(psRetOUT->eError != PVRSRV_OK)
281 {
282 return 0;
283 }
284 }
285#else
286
287 if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS)
288 {
289 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
290 return 0;
291 }
292 for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++)
293 {
294 psRetOUT->eError =
295 PVRSRVLookupHandle(psPerProc->psHandleBase,
296 &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
297 psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
298 PVRSRV_HANDLE_TYPE_SYNC_INFO);
299
300 if(psRetOUT->eError != PVRSRV_OK)
301 {
302 return 0;
303 }
304 }
305#endif
306
307 if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS)
308 {
309 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
310 return 0;
311 }
312 for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++)
313 {
314 psRetOUT->eError =
315#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
316 PVRSRVLookupHandle(psPerProc->psHandleBase,
317 &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
318 psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
319 PVRSRV_HANDLE_TYPE_MEM_INFO);
320#else
321 PVRSRVLookupHandle(psPerProc->psHandleBase,
322 &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
323 psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
324 PVRSRV_HANDLE_TYPE_SYNC_INFO);
325#endif
326 if(psRetOUT->eError != PVRSRV_OK)
327 {
328 return 0;
329 }
330 }
331
332 if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS)
333 {
334 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
335 return 0;
336 }
337 for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++)
338 {
339 psRetOUT->eError =
340#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
341 PVRSRVLookupHandle(psPerProc->psHandleBase,
342 &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
343 psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
344 PVRSRV_HANDLE_TYPE_MEM_INFO);
345#else
346 PVRSRVLookupHandle(psPerProc->psHandleBase,
347 &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
348 psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
349 PVRSRV_HANDLE_TYPE_SYNC_INFO);
350#endif
351
352 if(psRetOUT->eError != PVRSRV_OK)
353 {
354 return 0;
355 }
356 }
357
358 ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
359
360 if(ui32NumDstSyncs > 0)
361 {
362 if(!OSAccessOK(PVR_VERIFY_READ,
363 psDoKickIN->sCCBKick.pahDstSyncHandles,
364 ui32NumDstSyncs * sizeof(IMG_HANDLE)))
365 {
366 PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:"
367 " Invalid pasDstSyncHandles pointer", __FUNCTION__));
368 return -EFAULT;
369 }
370
371 psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
372 ui32NumDstSyncs * sizeof(IMG_HANDLE),
373 (IMG_VOID **)&phKernelSyncInfoHandles,
374 0,
375 "Array of Synchronization Info Handles");
376 if (psRetOUT->eError != PVRSRV_OK)
377 {
378 return 0;
379 }
380
381 if(CopyFromUserWrapper(psPerProc,
382 ui32BridgeID,
383 phKernelSyncInfoHandles,
384 psDoKickIN->sCCBKick.pahDstSyncHandles,
385 ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK)
386 {
387 ret = -EFAULT;
388 goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
389 }
390
391
392 psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles;
393
394 for( i = 0; i < ui32NumDstSyncs; i++)
395 {
396 psRetOUT->eError =
397 PVRSRVLookupHandle(psPerProc->psHandleBase,
398 &psDoKickIN->sCCBKick.pahDstSyncHandles[i],
399 psDoKickIN->sCCBKick.pahDstSyncHandles[i],
400 PVRSRV_HANDLE_TYPE_SYNC_INFO);
401
402 if(psRetOUT->eError != PVRSRV_OK)
403 {
404 goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
405 }
406
407 }
408
409 psRetOUT->eError =
410 PVRSRVLookupHandle(psPerProc->psHandleBase,
411 &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
412 psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
413 PVRSRV_HANDLE_TYPE_MEM_INFO);
414
415 if(psRetOUT->eError != PVRSRV_OK)
416 {
417 goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
418 }
419 }
420
421 psRetOUT->eError =
422 SGXDoKickKM(hDevCookieInt,
423 &psDoKickIN->sCCBKick);
424
425PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT:
426
427 if(phKernelSyncInfoHandles)
428 {
429 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
430 ui32NumDstSyncs * sizeof(IMG_HANDLE),
431 (IMG_VOID *)phKernelSyncInfoHandles,
432 0);
433
434 }
435 return ret;
436}
437
438
439static IMG_INT
440SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID,
441 PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN,
442 PVRSRV_BRIDGE_RETURN *psRetOUT,
443 PVRSRV_PER_PROCESS_DATA *psPerProc)
444{
445 IMG_HANDLE hDevCookieInt;
446
447 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES);
448
449 psRetOUT->eError =
450 PVRSRVLookupHandle(psPerProc->psHandleBase,
451 &hDevCookieInt,
452 psScheduleProcQIN->hDevCookie,
453 PVRSRV_HANDLE_TYPE_DEV_NODE);
454
455 if(psRetOUT->eError != PVRSRV_OK)
456 {
457 return 0;
458 }
459
460 psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt);
461
462 return 0;
463}
464
465
466#if defined(TRANSFER_QUEUE)
467static IMG_INT
468SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID,
469 PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN,
470 PVRSRV_BRIDGE_RETURN *psRetOUT,
471 PVRSRV_PER_PROCESS_DATA *psPerProc)
472{
473 IMG_HANDLE hDevCookieInt;
474 PVRSRV_TRANSFER_SGX_KICK *psKick;
475 IMG_UINT32 i;
476
477 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
478 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
479
480 psKick = &psSubmitTransferIN->sKick;
481
482 psRetOUT->eError =
483 PVRSRVLookupHandle(psPerProc->psHandleBase,
484 &hDevCookieInt,
485 psSubmitTransferIN->hDevCookie,
486 PVRSRV_HANDLE_TYPE_DEV_NODE);
487 if(psRetOUT->eError != PVRSRV_OK)
488 {
489 return 0;
490 }
491
492 psRetOUT->eError =
493 PVRSRVLookupHandle(psPerProc->psHandleBase,
494 &psKick->hCCBMemInfo,
495 psKick->hCCBMemInfo,
496 PVRSRV_HANDLE_TYPE_MEM_INFO);
497 if(psRetOUT->eError != PVRSRV_OK)
498 {
499 return 0;
500 }
501
502 if (psKick->hTASyncInfo != IMG_NULL)
503 {
504 psRetOUT->eError =
505 PVRSRVLookupHandle(psPerProc->psHandleBase,
506 &psKick->hTASyncInfo,
507 psKick->hTASyncInfo,
508 PVRSRV_HANDLE_TYPE_SYNC_INFO);
509 if(psRetOUT->eError != PVRSRV_OK)
510 {
511 return 0;
512 }
513 }
514
515 if (psKick->h3DSyncInfo != IMG_NULL)
516 {
517 psRetOUT->eError =
518 PVRSRVLookupHandle(psPerProc->psHandleBase,
519 &psKick->h3DSyncInfo,
520 psKick->h3DSyncInfo,
521 PVRSRV_HANDLE_TYPE_SYNC_INFO);
522 if(psRetOUT->eError != PVRSRV_OK)
523 {
524 return 0;
525 }
526 }
527
528 if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS)
529 {
530 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
531 return 0;
532 }
533 for (i = 0; i < psKick->ui32NumSrcSync; i++)
534 {
535 psRetOUT->eError =
536 PVRSRVLookupHandle(psPerProc->psHandleBase,
537 &psKick->ahSrcSyncInfo[i],
538 psKick->ahSrcSyncInfo[i],
539 PVRSRV_HANDLE_TYPE_SYNC_INFO);
540 if(psRetOUT->eError != PVRSRV_OK)
541 {
542 return 0;
543 }
544 }
545
546 if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS)
547 {
548 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
549 return 0;
550 }
551 for (i = 0; i < psKick->ui32NumDstSync; i++)
552 {
553 psRetOUT->eError =
554 PVRSRVLookupHandle(psPerProc->psHandleBase,
555 &psKick->ahDstSyncInfo[i],
556 psKick->ahDstSyncInfo[i],
557 PVRSRV_HANDLE_TYPE_SYNC_INFO);
558 if(psRetOUT->eError != PVRSRV_OK)
559 {
560 return 0;
561 }
562 }
563
564 psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick);
565
566 return 0;
567}
568
569
570#if defined(SGX_FEATURE_2D_HARDWARE)
571static IMG_INT
572SGXSubmit2DBW(IMG_UINT32 ui32BridgeID,
573 PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN,
574 PVRSRV_BRIDGE_RETURN *psRetOUT,
575 PVRSRV_PER_PROCESS_DATA *psPerProc)
576{
577 IMG_HANDLE hDevCookieInt;
578 PVRSRV_2D_SGX_KICK *psKick;
579 IMG_UINT32 i;
580
581 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D);
582 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
583
584 psRetOUT->eError =
585 PVRSRVLookupHandle(psPerProc->psHandleBase,
586 &hDevCookieInt,
587 psSubmit2DIN->hDevCookie,
588 PVRSRV_HANDLE_TYPE_DEV_NODE);
589
590 if(psRetOUT->eError != PVRSRV_OK)
591 {
592 return 0;
593 }
594
595 psKick = &psSubmit2DIN->sKick;
596
597 psRetOUT->eError =
598 PVRSRVLookupHandle(psPerProc->psHandleBase,
599 &psKick->hCCBMemInfo,
600 psKick->hCCBMemInfo,
601 PVRSRV_HANDLE_TYPE_MEM_INFO);
602 if(psRetOUT->eError != PVRSRV_OK)
603 {
604 return 0;
605 }
606
607 if (psKick->hTASyncInfo != IMG_NULL)
608 {
609 psRetOUT->eError =
610 PVRSRVLookupHandle(psPerProc->psHandleBase,
611 &psKick->hTASyncInfo,
612 psKick->hTASyncInfo,
613 PVRSRV_HANDLE_TYPE_SYNC_INFO);
614 if(psRetOUT->eError != PVRSRV_OK)
615 {
616 return 0;
617 }
618 }
619
620 if (psKick->h3DSyncInfo != IMG_NULL)
621 {
622 psRetOUT->eError =
623 PVRSRVLookupHandle(psPerProc->psHandleBase,
624 &psKick->h3DSyncInfo,
625 psKick->h3DSyncInfo,
626 PVRSRV_HANDLE_TYPE_SYNC_INFO);
627 if(psRetOUT->eError != PVRSRV_OK)
628 {
629 return 0;
630 }
631 }
632
633 if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS)
634 {
635 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
636 return 0;
637 }
638 for (i = 0; i < psKick->ui32NumSrcSync; i++)
639 {
640 psRetOUT->eError =
641 PVRSRVLookupHandle(psPerProc->psHandleBase,
642 &psKick->ahSrcSyncInfo[i],
643 psKick->ahSrcSyncInfo[i],
644 PVRSRV_HANDLE_TYPE_SYNC_INFO);
645 if(psRetOUT->eError != PVRSRV_OK)
646 {
647 return 0;
648 }
649 }
650
651 if (psKick->hDstSyncInfo != IMG_NULL)
652 {
653 psRetOUT->eError =
654 PVRSRVLookupHandle(psPerProc->psHandleBase,
655 &psKick->hDstSyncInfo,
656 psKick->hDstSyncInfo,
657 PVRSRV_HANDLE_TYPE_SYNC_INFO);
658 if(psRetOUT->eError != PVRSRV_OK)
659 {
660 return 0;
661 }
662 }
663
664 psRetOUT->eError =
665 SGXSubmit2DKM(hDevCookieInt, psKick);
666
667 return 0;
668}
669#endif
670#endif
671
672
673static IMG_INT
674SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
675 PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
676 PVRSRV_BRIDGE_RETURN *psRetOUT,
677 PVRSRV_PER_PROCESS_DATA *psPerProc)
678{
679 IMG_HANDLE hDevCookieInt;
680 IMG_HANDLE hDevMemContextInt = 0;
681 PVRSRV_SGXDEV_INFO *psDevInfo;
682 SGX_MISC_INFO sMiscInfo;
683 PVRSRV_DEVICE_NODE *psDeviceNode;
684
685 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
686 PVRSRV_BRIDGE_SGX_GETMISCINFO);
687
688 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
689 &hDevCookieInt,
690 psSGXGetMiscInfoIN->hDevCookie,
691 PVRSRV_HANDLE_TYPE_DEV_NODE);
692
693 if(psRetOUT->eError != PVRSRV_OK)
694 {
695 return 0;
696 }
697
698#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
699
700 if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD)
701 {
702 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
703 &hDevMemContextInt,
704 psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext,
705 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
706
707 if(psRetOUT->eError != PVRSRV_OK)
708 {
709 return 0;
710 }
711 }
712#endif
713
714 psDeviceNode = hDevCookieInt;
715 PVR_ASSERT(psDeviceNode != IMG_NULL);
716 if (psDeviceNode == IMG_NULL)
717 {
718 return -EFAULT;
719 }
720
721 psDevInfo = psDeviceNode->pvDevice;
722
723
724 psRetOUT->eError = CopyFromUserWrapper(psPerProc,
725 ui32BridgeID,
726 &sMiscInfo,
727 psSGXGetMiscInfoIN->psMiscInfo,
728 sizeof(SGX_MISC_INFO));
729 if (psRetOUT->eError != PVRSRV_OK)
730 {
731 return -EFAULT;
732 }
733
734 {
735 psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt);
736
737 if (psRetOUT->eError != PVRSRV_OK)
738 {
739 return 0;
740 }
741 }
742
743
744 psRetOUT->eError = CopyToUserWrapper(psPerProc,
745 ui32BridgeID,
746 psSGXGetMiscInfoIN->psMiscInfo,
747 &sMiscInfo,
748 sizeof(SGX_MISC_INFO));
749 if (psRetOUT->eError != PVRSRV_OK)
750 {
751 return -EFAULT;
752 }
753 return 0;
754}
755
756
757static IMG_INT
758SGXReadHWPerfCBBW(IMG_UINT32 ui32BridgeID,
759 PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN,
760 PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT,
761 PVRSRV_PER_PROCESS_DATA *psPerProc)
762{
763 IMG_HANDLE hDevCookieInt;
764 PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated;
765 IMG_HANDLE hAllocatedHandle;
766 IMG_UINT32 ui32AllocatedSize;
767
768 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB);
769
770 psSGXReadHWPerfCBOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
771 &hDevCookieInt,
772 psSGXReadHWPerfCBIN->hDevCookie,
773 PVRSRV_HANDLE_TYPE_DEV_NODE);
774
775 if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK)
776 {
777 return 0;
778 }
779
780 ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize *
781 sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]);
782 ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError,
783 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
784 ui32AllocatedSize,
785 (IMG_VOID **)&psAllocated,
786 &hAllocatedHandle,
787 "Array of Hardware Performance Circular Buffer Data"));
788
789 psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt,
790 psSGXReadHWPerfCBIN->ui32ArraySize,
791 psAllocated,
792 &psSGXReadHWPerfCBOUT->ui32DataCount,
793 &psSGXReadHWPerfCBOUT->ui32ClockSpeed,
794 &psSGXReadHWPerfCBOUT->ui32HostTimeStamp);
795 if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK)
796 {
797 psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc,
798 ui32BridgeID,
799 psSGXReadHWPerfCBIN->psHWPerfCBData,
800 psAllocated,
801 ui32AllocatedSize);
802 }
803
804 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
805 ui32AllocatedSize,
806 psAllocated,
807 hAllocatedHandle);
808
809
810 return 0;
811}
812
813
814static IMG_INT
815SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
816 PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
817 PVRSRV_BRIDGE_RETURN *psRetOUT,
818 PVRSRV_PER_PROCESS_DATA *psPerProc)
819{
820 IMG_HANDLE hDevCookieInt;
821 PVRSRV_ERROR eError;
822 IMG_BOOL bDissociateFailed = IMG_FALSE;
823 IMG_BOOL bLookupFailed = IMG_FALSE;
824 IMG_BOOL bReleaseFailed = IMG_FALSE;
825 IMG_HANDLE hDummy;
826 IMG_UINT32 i;
827
828 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
829
830 if(!psPerProc->bInitProcess)
831 {
832 psRetOUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
833 return 0;
834 }
835
836 psRetOUT->eError =
837 PVRSRVLookupHandle(psPerProc->psHandleBase,
838 &hDevCookieInt,
839 psSGXDevInitPart2IN->hDevCookie,
840 PVRSRV_HANDLE_TYPE_DEV_NODE);
841 if(psRetOUT->eError != PVRSRV_OK)
842 {
843 return 0;
844 }
845
846
847 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
848 &hDummy,
849 psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
850 PVRSRV_HANDLE_TYPE_MEM_INFO);
851 if (eError != PVRSRV_OK)
852 {
853 bLookupFailed = IMG_TRUE;
854 }
855
856 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
857 &hDummy,
858 psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
859 PVRSRV_HANDLE_TYPE_MEM_INFO);
860 if (eError != PVRSRV_OK)
861 {
862 bLookupFailed = IMG_TRUE;
863 }
864
865 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
866 &hDummy,
867 psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
868 PVRSRV_HANDLE_TYPE_MEM_INFO);
869 if (eError != PVRSRV_OK)
870 {
871 bLookupFailed = IMG_TRUE;
872 }
873
874 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
875 &hDummy,
876 psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
877 PVRSRV_HANDLE_TYPE_MEM_INFO);
878 if (eError != PVRSRV_OK)
879 {
880 bLookupFailed = IMG_TRUE;
881 }
882
883 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
884 &hDummy,
885 psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
886 PVRSRV_HANDLE_TYPE_MEM_INFO);
887 if (eError != PVRSRV_OK)
888 {
889 bLookupFailed = IMG_TRUE;
890 }
891
892
893 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
894 &hDummy,
895 psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
896 PVRSRV_HANDLE_TYPE_MEM_INFO);
897 if (eError != PVRSRV_OK)
898 {
899 bLookupFailed = IMG_TRUE;
900 }
901
902#if defined(SGX_SUPPORT_HWPROFILING)
903 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
904 &hDummy,
905 psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
906 PVRSRV_HANDLE_TYPE_MEM_INFO);
907 if (eError != PVRSRV_OK)
908 {
909 bLookupFailed = IMG_TRUE;
910 }
911#endif
912
913#if defined(SUPPORT_SGX_HWPERF)
914 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
915 &hDummy,
916 psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
917 PVRSRV_HANDLE_TYPE_MEM_INFO);
918 if (eError != PVRSRV_OK)
919 {
920 bLookupFailed = IMG_TRUE;
921 }
922#endif
923
924 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
925 &hDummy,
926 psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
927 PVRSRV_HANDLE_TYPE_MEM_INFO);
928 if (eError != PVRSRV_OK)
929 {
930 bLookupFailed = IMG_TRUE;
931 }
932
933 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
934 &hDummy,
935 psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
936 PVRSRV_HANDLE_TYPE_MEM_INFO);
937 if (eError != PVRSRV_OK)
938 {
939 bLookupFailed = IMG_TRUE;
940 }
941
942#if defined(FIX_HW_BRN_29702)
943 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
944 &hDummy,
945 psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
946 PVRSRV_HANDLE_TYPE_MEM_INFO);
947 if (eError != PVRSRV_OK)
948 {
949 bLookupFailed = IMG_TRUE;
950 }
951#endif
952
953#if defined(FIX_HW_BRN_29823)
954 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
955 &hDummy,
956 psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
957 PVRSRV_HANDLE_TYPE_MEM_INFO);
958 if (eError != PVRSRV_OK)
959 {
960 bLookupFailed = IMG_TRUE;
961 }
962#endif
963
964#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
965 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
966 &hDummy,
967 psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
968 PVRSRV_HANDLE_TYPE_MEM_INFO);
969 if (eError != PVRSRV_OK)
970 {
971 bLookupFailed = IMG_TRUE;
972 }
973#endif
974
975#if defined(SGX_FEATURE_SPM_MODE_0)
976 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
977 &hDummy,
978 psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
979 PVRSRV_HANDLE_TYPE_MEM_INFO);
980 if (eError != PVRSRV_OK)
981 {
982 bLookupFailed = IMG_TRUE;
983 }
984#endif
985
986 for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
987 {
988 IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
989
990 if (hHandle == IMG_NULL)
991 {
992 continue;
993 }
994
995 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
996 &hDummy,
997 hHandle,
998 PVRSRV_HANDLE_TYPE_MEM_INFO);
999 if (eError != PVRSRV_OK)
1000 {
1001 bLookupFailed = IMG_TRUE;
1002 }
1003 }
1004
1005 if (bLookupFailed)
1006 {
1007 PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle lookup failed"));
1008 psRetOUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
1009 return 0;
1010 }
1011
1012
1013 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1014 &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
1015 psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
1016 PVRSRV_HANDLE_TYPE_MEM_INFO);
1017 if (eError != PVRSRV_OK)
1018 {
1019 bReleaseFailed = IMG_TRUE;
1020 }
1021
1022 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1023 &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
1024 psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
1025 PVRSRV_HANDLE_TYPE_MEM_INFO);
1026 if (eError != PVRSRV_OK)
1027 {
1028 bReleaseFailed = IMG_TRUE;
1029 }
1030
1031 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1032 &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
1033 psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
1034 PVRSRV_HANDLE_TYPE_MEM_INFO);
1035 if (eError != PVRSRV_OK)
1036 {
1037 bReleaseFailed = IMG_TRUE;
1038 }
1039
1040
1041 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1042 &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
1043 psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
1044 PVRSRV_HANDLE_TYPE_MEM_INFO);
1045 if (eError != PVRSRV_OK)
1046 {
1047 bReleaseFailed = IMG_TRUE;
1048 }
1049
1050 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1051 &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
1052 psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
1053 PVRSRV_HANDLE_TYPE_MEM_INFO);
1054 if (eError != PVRSRV_OK)
1055 {
1056 bReleaseFailed = IMG_TRUE;
1057 }
1058
1059 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1060 &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
1061 psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
1062 PVRSRV_HANDLE_TYPE_MEM_INFO);
1063 if (eError != PVRSRV_OK)
1064 {
1065 bReleaseFailed = IMG_TRUE;
1066 }
1067
1068
1069 #if defined(SGX_SUPPORT_HWPROFILING)
1070 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1071 &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
1072 psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
1073 PVRSRV_HANDLE_TYPE_MEM_INFO);
1074 if (eError != PVRSRV_OK)
1075 {
1076 bReleaseFailed = IMG_TRUE;
1077 }
1078#endif
1079
1080#if defined(SUPPORT_SGX_HWPERF)
1081 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1082 &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
1083 psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
1084 PVRSRV_HANDLE_TYPE_MEM_INFO);
1085 if (eError != PVRSRV_OK)
1086 {
1087 bReleaseFailed = IMG_TRUE;
1088 }
1089#endif
1090
1091 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1092 &psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
1093 psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
1094 PVRSRV_HANDLE_TYPE_MEM_INFO);
1095 if (eError != PVRSRV_OK)
1096 {
1097 bReleaseFailed = IMG_TRUE;
1098 }
1099
1100 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1101 &psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
1102 psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
1103 PVRSRV_HANDLE_TYPE_MEM_INFO);
1104 if (eError != PVRSRV_OK)
1105 {
1106 bReleaseFailed = IMG_TRUE;
1107 }
1108
1109#if defined(FIX_HW_BRN_29702)
1110 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1111 &psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
1112 psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
1113 PVRSRV_HANDLE_TYPE_MEM_INFO);
1114 if (eError != PVRSRV_OK)
1115 {
1116 bLookupFailed = IMG_TRUE;
1117 }
1118#endif
1119
1120#if defined(FIX_HW_BRN_29823)
1121 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1122 &psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
1123 psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
1124 PVRSRV_HANDLE_TYPE_MEM_INFO);
1125 if (eError != PVRSRV_OK)
1126 {
1127 bReleaseFailed = IMG_TRUE;
1128 }
1129#endif
1130
1131#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
1132 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1133 &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
1134 psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
1135 PVRSRV_HANDLE_TYPE_MEM_INFO);
1136 if (eError != PVRSRV_OK)
1137 {
1138 bReleaseFailed = IMG_TRUE;
1139 }
1140#endif
1141
1142#if defined(SGX_FEATURE_SPM_MODE_0)
1143 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1144 &psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
1145 psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
1146 PVRSRV_HANDLE_TYPE_MEM_INFO);
1147 if (eError != PVRSRV_OK)
1148 {
1149 bReleaseFailed = IMG_TRUE;
1150 }
1151#endif
1152
1153
1154 for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
1155 {
1156 IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
1157
1158 if (*phHandle == IMG_NULL)
1159 continue;
1160
1161 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
1162 phHandle,
1163 *phHandle,
1164 PVRSRV_HANDLE_TYPE_MEM_INFO);
1165 if (eError != PVRSRV_OK)
1166 {
1167 bReleaseFailed = IMG_TRUE;
1168 }
1169 }
1170
1171 if (bReleaseFailed)
1172 {
1173 PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle release failed"));
1174 psRetOUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
1175
1176 PVR_DBG_BREAK;
1177 return 0;
1178 }
1179
1180
1181 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
1182 if (eError != PVRSRV_OK)
1183 {
1184 bDissociateFailed = IMG_TRUE;
1185 }
1186
1187 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
1188 if (eError != PVRSRV_OK)
1189 {
1190 bDissociateFailed = IMG_TRUE;
1191 }
1192
1193 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo);
1194 if (eError != PVRSRV_OK)
1195 {
1196 bDissociateFailed = IMG_TRUE;
1197 }
1198
1199 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
1200 if (eError != PVRSRV_OK)
1201 {
1202 bDissociateFailed = IMG_TRUE;
1203 }
1204
1205 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
1206 if (eError != PVRSRV_OK)
1207 {
1208 bDissociateFailed = IMG_TRUE;
1209 }
1210
1211
1212 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
1213 if (eError != PVRSRV_OK)
1214 {
1215 bDissociateFailed = IMG_TRUE;
1216 }
1217
1218
1219#if defined(SGX_SUPPORT_HWPROFILING)
1220 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo);
1221 bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
1222#endif
1223
1224#if defined(SUPPORT_SGX_HWPERF)
1225 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo);
1226 if (eError != PVRSRV_OK)
1227 {
1228 bDissociateFailed = IMG_TRUE;
1229 }
1230#endif
1231
1232 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo);
1233 if (eError != PVRSRV_OK)
1234 {
1235 bDissociateFailed = IMG_TRUE;
1236 }
1237
1238 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo);
1239 if (eError != PVRSRV_OK)
1240 {
1241 bDissociateFailed = IMG_TRUE;
1242 }
1243
1244#if defined(FIX_HW_BRN_29702)
1245 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo);
1246 bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
1247#endif
1248
1249#if defined(FIX_HW_BRN_29823)
1250 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo);
1251 bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
1252#endif
1253
1254#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
1255 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo);
1256 bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
1257#endif
1258
1259#if defined(SGX_FEATURE_SPM_MODE_0)
1260 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo);
1261 if (eError != PVRSRV_OK)
1262 {
1263 bDissociateFailed = IMG_TRUE;
1264 }
1265#endif
1266
1267 for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
1268 {
1269 IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
1270
1271 if (hHandle == IMG_NULL)
1272 continue;
1273
1274 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
1275 if (eError != PVRSRV_OK)
1276 {
1277 bDissociateFailed = IMG_TRUE;
1278 }
1279 }
1280
1281
1282 if(bDissociateFailed)
1283 {
1284 PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
1285 PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
1286 PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
1287 PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
1288 PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
1289
1290 for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
1291 {
1292 IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
1293
1294 if (hHandle == IMG_NULL)
1295 continue;
1296
1297 PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle);
1298
1299 }
1300
1301 PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A dissociate failed"));
1302
1303 psRetOUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
1304
1305
1306 PVR_DBG_BREAK;
1307 return 0;
1308 }
1309
1310 psRetOUT->eError =
1311 DevInitSGXPart2KM(psPerProc,
1312 hDevCookieInt,
1313 &psSGXDevInitPart2IN->sInitInfo);
1314
1315 return 0;
1316}
1317
1318
1319static IMG_INT
1320SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
1321 PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN,
1322 PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT,
1323 PVRSRV_PER_PROCESS_DATA *psPerProc)
1324{
1325 IMG_HANDLE hDevCookieInt;
1326 IMG_HANDLE hHWRenderContextInt;
1327
1328 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT);
1329
1330 NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1);
1331
1332 psSGXRegHWRenderContextOUT->eError =
1333 PVRSRVLookupHandle(psPerProc->psHandleBase,
1334 &hDevCookieInt,
1335 psSGXRegHWRenderContextIN->hDevCookie,
1336 PVRSRV_HANDLE_TYPE_DEV_NODE);
1337 if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK)
1338 {
1339 return 0;
1340 }
1341
1342 hHWRenderContextInt =
1343 SGXRegisterHWRenderContextKM(hDevCookieInt,
1344 &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr,
1345 psPerProc);
1346
1347 if (hHWRenderContextInt == IMG_NULL)
1348 {
1349 psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
1350 return 0;
1351 }
1352
1353 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1354 &psSGXRegHWRenderContextOUT->hHWRenderContext,
1355 hHWRenderContextInt,
1356 PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
1357 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1358
1359 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc);
1360
1361 return 0;
1362}
1363
1364
1365static IMG_INT
1366SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
1367 PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN,
1368 PVRSRV_BRIDGE_RETURN *psRetOUT,
1369 PVRSRV_PER_PROCESS_DATA *psPerProc)
1370{
1371 IMG_HANDLE hHWRenderContextInt;
1372
1373 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT);
1374
1375 psRetOUT->eError =
1376 PVRSRVLookupHandle(psPerProc->psHandleBase,
1377 &hHWRenderContextInt,
1378 psSGXUnregHWRenderContextIN->hHWRenderContext,
1379 PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
1380 if(psRetOUT->eError != PVRSRV_OK)
1381 {
1382 return 0;
1383 }
1384
1385 psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt);
1386 if(psRetOUT->eError != PVRSRV_OK)
1387 {
1388 return 0;
1389 }
1390
1391 psRetOUT->eError =
1392 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1393 psSGXUnregHWRenderContextIN->hHWRenderContext,
1394 PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
1395
1396 return 0;
1397}
1398
1399
1400static IMG_INT
1401SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
1402 PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN,
1403 PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT,
1404 PVRSRV_PER_PROCESS_DATA *psPerProc)
1405{
1406 IMG_HANDLE hDevCookieInt;
1407 IMG_HANDLE hHWTransferContextInt;
1408
1409 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT);
1410
1411 NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1);
1412
1413 psSGXRegHWTransferContextOUT->eError =
1414 PVRSRVLookupHandle(psPerProc->psHandleBase,
1415 &hDevCookieInt,
1416 psSGXRegHWTransferContextIN->hDevCookie,
1417 PVRSRV_HANDLE_TYPE_DEV_NODE);
1418 if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK)
1419 {
1420 return 0;
1421 }
1422
1423 hHWTransferContextInt =
1424 SGXRegisterHWTransferContextKM(hDevCookieInt,
1425 &psSGXRegHWTransferContextIN->sHWTransferContextDevVAddr,
1426 psPerProc);
1427
1428 if (hHWTransferContextInt == IMG_NULL)
1429 {
1430 psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
1431 return 0;
1432 }
1433
1434 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1435 &psSGXRegHWTransferContextOUT->hHWTransferContext,
1436 hHWTransferContextInt,
1437 PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
1438 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1439
1440 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc);
1441
1442 return 0;
1443}
1444
1445
1446static IMG_INT
1447SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
1448 PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN,
1449 PVRSRV_BRIDGE_RETURN *psRetOUT,
1450 PVRSRV_PER_PROCESS_DATA *psPerProc)
1451{
1452 IMG_HANDLE hHWTransferContextInt;
1453
1454 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT);
1455
1456 psRetOUT->eError =
1457 PVRSRVLookupHandle(psPerProc->psHandleBase,
1458 &hHWTransferContextInt,
1459 psSGXUnregHWTransferContextIN->hHWTransferContext,
1460 PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
1461 if(psRetOUT->eError != PVRSRV_OK)
1462 {
1463 return 0;
1464 }
1465
1466 psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt);
1467 if(psRetOUT->eError != PVRSRV_OK)
1468 {
1469 return 0;
1470 }
1471
1472 psRetOUT->eError =
1473 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1474 psSGXUnregHWTransferContextIN->hHWTransferContext,
1475 PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
1476
1477 return 0;
1478}
1479
1480
1481#if defined(SGX_FEATURE_2D_HARDWARE)
1482static IMG_INT
1483SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
1484 PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN,
1485 PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT,
1486 PVRSRV_PER_PROCESS_DATA *psPerProc)
1487{
1488 IMG_HANDLE hDevCookieInt;
1489 IMG_HANDLE hHW2DContextInt;
1490
1491 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT);
1492
1493 NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1);
1494
1495 psSGXRegHW2DContextOUT->eError =
1496 PVRSRVLookupHandle(psPerProc->psHandleBase,
1497 &hDevCookieInt,
1498 psSGXRegHW2DContextIN->hDevCookie,
1499 PVRSRV_HANDLE_TYPE_DEV_NODE);
1500 if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK)
1501 {
1502 return 0;
1503 }
1504
1505 hHW2DContextInt =
1506 SGXRegisterHW2DContextKM(hDevCookieInt,
1507 &psSGXRegHW2DContextIN->sHW2DContextDevVAddr,
1508 psPerProc);
1509
1510 if (hHW2DContextInt == IMG_NULL)
1511 {
1512 psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
1513 return 0;
1514 }
1515
1516 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1517 &psSGXRegHW2DContextOUT->hHW2DContext,
1518 hHW2DContextInt,
1519 PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
1520 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1521
1522 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc);
1523
1524 return 0;
1525}
1526
1527
1528static IMG_INT
1529SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
1530 PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN,
1531 PVRSRV_BRIDGE_RETURN *psRetOUT,
1532 PVRSRV_PER_PROCESS_DATA *psPerProc)
1533{
1534 IMG_HANDLE hHW2DContextInt;
1535
1536 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT);
1537
1538 psRetOUT->eError =
1539 PVRSRVLookupHandle(psPerProc->psHandleBase,
1540 &hHW2DContextInt,
1541 psSGXUnregHW2DContextIN->hHW2DContext,
1542 PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
1543 if(psRetOUT->eError != PVRSRV_OK)
1544 {
1545 return 0;
1546 }
1547
1548 psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt);
1549 if(psRetOUT->eError != PVRSRV_OK)
1550 {
1551 return 0;
1552 }
1553
1554 psRetOUT->eError =
1555 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1556 psSGXUnregHW2DContextIN->hHW2DContext,
1557 PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
1558
1559 return 0;
1560}
1561#endif
1562
1563static IMG_INT
1564SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID,
1565 PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN,
1566 PVRSRV_BRIDGE_RETURN *psRetOUT,
1567 PVRSRV_PER_PROCESS_DATA *psPerProc)
1568{
1569 IMG_HANDLE hDevCookieInt;
1570 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET);
1571
1572 psRetOUT->eError =
1573 PVRSRVLookupHandle(psPerProc->psHandleBase,
1574 &hDevCookieInt,
1575 psSGXFlushHWRenderTargetIN->hDevCookie,
1576 PVRSRV_HANDLE_TYPE_DEV_NODE);
1577 if(psRetOUT->eError != PVRSRV_OK)
1578 {
1579 return 0;
1580 }
1581
1582 SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr);
1583
1584 return 0;
1585}
1586
1587
1588static IMG_INT
1589SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID,
1590 PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN,
1591 PVRSRV_BRIDGE_RETURN *psRetOUT,
1592 PVRSRV_PER_PROCESS_DATA *psPerProc)
1593{
1594 IMG_HANDLE hDevCookieInt;
1595 IMG_VOID *pvSyncInfo;
1596 PVRSRV_SGXDEV_INFO *psDevInfo;
1597
1598 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE);
1599
1600 psRetOUT->eError =
1601 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1602 ps2DQueryBltsCompleteIN->hDevCookie,
1603 PVRSRV_HANDLE_TYPE_DEV_NODE);
1604 if(psRetOUT->eError != PVRSRV_OK)
1605 {
1606 return 0;
1607 }
1608
1609 psRetOUT->eError =
1610 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1611 ps2DQueryBltsCompleteIN->hKernSyncInfo,
1612 PVRSRV_HANDLE_TYPE_SYNC_INFO);
1613 if(psRetOUT->eError != PVRSRV_OK)
1614 {
1615 return 0;
1616 }
1617
1618 psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
1619
1620 psRetOUT->eError =
1621 SGX2DQueryBlitsCompleteKM(psDevInfo,
1622 (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo,
1623 ps2DQueryBltsCompleteIN->bWaitForComplete);
1624
1625 return 0;
1626}
1627
1628
1629static IMG_INT
1630SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID,
1631 PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN,
1632 PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT,
1633 PVRSRV_PER_PROCESS_DATA *psPerProc)
1634{
1635 IMG_HANDLE hDevCookieInt;
1636 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
1637 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
1638 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
1639 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
1640 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL;
1641 IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0;
1642 IMG_UINT32 i;
1643 IMG_HANDLE hSharedPBDesc = IMG_NULL;
1644
1645 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC);
1646
1647 NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4);
1648
1649 psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
1650
1651 psSGXFindSharedPBDescOUT->eError =
1652 PVRSRVLookupHandle(psPerProc->psHandleBase,
1653 &hDevCookieInt,
1654 psSGXFindSharedPBDescIN->hDevCookie,
1655 PVRSRV_HANDLE_TYPE_DEV_NODE);
1656 if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
1657 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1658
1659 psSGXFindSharedPBDescOUT->eError =
1660 SGXFindSharedPBDescKM(psPerProc, hDevCookieInt,
1661 psSGXFindSharedPBDescIN->bLockOnFailure,
1662 psSGXFindSharedPBDescIN->ui32TotalPBSize,
1663 &hSharedPBDesc,
1664 &psSharedPBDescKernelMemInfo,
1665 &psHWPBDescKernelMemInfo,
1666 &psBlockKernelMemInfo,
1667 &psHWBlockKernelMemInfo,
1668 &ppsSharedPBDescSubKernelMemInfos,
1669 &ui32SharedPBDescSubKernelMemInfosCount);
1670 if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
1671 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1672
1673 PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount
1674 <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
1675
1676 psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount =
1677 ui32SharedPBDescSubKernelMemInfosCount;
1678
1679 if(hSharedPBDesc == IMG_NULL)
1680 {
1681 psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0;
1682
1683 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1684 }
1685
1686 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1687 &psSGXFindSharedPBDescOUT->hSharedPBDesc,
1688 hSharedPBDesc,
1689 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
1690 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1691
1692
1693 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1694 &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle,
1695 psSharedPBDescKernelMemInfo,
1696 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1697 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1698 psSGXFindSharedPBDescOUT->hSharedPBDesc);
1699
1700 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1701 &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle,
1702 psHWPBDescKernelMemInfo,
1703 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1704 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1705 psSGXFindSharedPBDescOUT->hSharedPBDesc);
1706
1707 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1708 &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle,
1709 psBlockKernelMemInfo,
1710 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1711 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1712 psSGXFindSharedPBDescOUT->hSharedPBDesc);
1713
1714 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1715 &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle,
1716 psHWBlockKernelMemInfo,
1717 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1718 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1719 psSGXFindSharedPBDescOUT->hSharedPBDesc);
1720
1721
1722 for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
1723 {
1724 PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut =
1725 psSGXFindSharedPBDescOUT;
1726
1727 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1728 &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i],
1729 ppsSharedPBDescSubKernelMemInfos[i],
1730 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1731 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1732 psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle);
1733 }
1734
1735PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT:
1736 if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL)
1737 {
1738 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1739 sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
1740 ppsSharedPBDescSubKernelMemInfos,
1741 IMG_NULL);
1742 }
1743
1744 if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
1745 {
1746 if(hSharedPBDesc != IMG_NULL)
1747 {
1748 SGXUnrefSharedPBDescKM(hSharedPBDesc);
1749 }
1750 }
1751 else
1752 {
1753 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc);
1754 }
1755
1756 return 0;
1757}
1758
1759
1760static IMG_INT
1761SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID,
1762 PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN,
1763 PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT,
1764 PVRSRV_PER_PROCESS_DATA *psPerProc)
1765{
1766 IMG_HANDLE hSharedPBDesc;
1767
1768 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC);
1769
1770 psSGXUnrefSharedPBDescOUT->eError =
1771 PVRSRVLookupHandle(psPerProc->psHandleBase,
1772 &hSharedPBDesc,
1773 psSGXUnrefSharedPBDescIN->hSharedPBDesc,
1774 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
1775 if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
1776 {
1777 return 0;
1778 }
1779
1780 psSGXUnrefSharedPBDescOUT->eError =
1781 SGXUnrefSharedPBDescKM(hSharedPBDesc);
1782
1783 if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
1784 {
1785 return 0;
1786 }
1787
1788 psSGXUnrefSharedPBDescOUT->eError =
1789 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1790 psSGXUnrefSharedPBDescIN->hSharedPBDesc,
1791 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
1792
1793 return 0;
1794}
1795
1796
1797static IMG_INT
1798SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID,
1799 PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN,
1800 PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT,
1801 PVRSRV_PER_PROCESS_DATA *psPerProc)
1802{
1803 IMG_HANDLE hDevCookieInt;
1804 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
1805 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
1806 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
1807 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
1808 IMG_UINT32 ui32KernelMemInfoHandlesCount =
1809 psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
1810 IMG_INT ret = 0;
1811 IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL;
1812 PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL;
1813 IMG_UINT32 i;
1814 PVRSRV_ERROR eError;
1815 IMG_HANDLE hSharedPBDesc = IMG_NULL;
1816
1817 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC);
1818
1819 NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1);
1820
1821 psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
1822
1823 PVR_ASSERT(ui32KernelMemInfoHandlesCount
1824 <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
1825
1826 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1827 &hDevCookieInt,
1828 psSGXAddSharedPBDescIN->hDevCookie,
1829 PVRSRV_HANDLE_TYPE_DEV_NODE);
1830 if(eError != PVRSRV_OK)
1831 {
1832 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1833 }
1834
1835 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1836 (IMG_VOID **)&psSharedPBDescKernelMemInfo,
1837 psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
1838 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1839 if(eError != PVRSRV_OK)
1840 {
1841 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1842 }
1843
1844 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1845 (IMG_VOID **)&psHWPBDescKernelMemInfo,
1846 psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
1847 PVRSRV_HANDLE_TYPE_MEM_INFO);
1848 if(eError != PVRSRV_OK)
1849 {
1850 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1851 }
1852
1853 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1854 (IMG_VOID **)&psBlockKernelMemInfo,
1855 psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
1856 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1857 if(eError != PVRSRV_OK)
1858 {
1859 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1860 }
1861
1862 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1863 (IMG_VOID **)&psHWBlockKernelMemInfo,
1864 psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
1865 PVRSRV_HANDLE_TYPE_MEM_INFO);
1866 if(eError != PVRSRV_OK)
1867 {
1868 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1869 }
1870
1871
1872 if(!OSAccessOK(PVR_VERIFY_READ,
1873 psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
1874 ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)))
1875 {
1876 PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:"
1877 " Invalid phKernelMemInfos pointer", __FUNCTION__));
1878 ret = -EFAULT;
1879 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1880 }
1881
1882 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1883 ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
1884 (IMG_VOID **)&phKernelMemInfoHandles,
1885 0,
1886 "Array of Handles");
1887 if (eError != PVRSRV_OK)
1888 {
1889 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1890 }
1891
1892 if(CopyFromUserWrapper(psPerProc,
1893 ui32BridgeID,
1894 phKernelMemInfoHandles,
1895 psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
1896 ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))
1897 != PVRSRV_OK)
1898 {
1899 ret = -EFAULT;
1900 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1901 }
1902
1903 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1904 ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
1905 (IMG_VOID **)&ppsKernelMemInfos,
1906 0,
1907 "Array of pointers to Kernel Memory Info");
1908 if (eError != PVRSRV_OK)
1909 {
1910 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1911 }
1912
1913 for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
1914 {
1915 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1916 (IMG_VOID **)&ppsKernelMemInfos[i],
1917 phKernelMemInfoHandles[i],
1918 PVRSRV_HANDLE_TYPE_MEM_INFO);
1919 if(eError != PVRSRV_OK)
1920 {
1921 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1922 }
1923 }
1924
1925
1926
1927 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1928 psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
1929 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1930 PVR_ASSERT(eError == PVRSRV_OK);
1931
1932
1933 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1934 psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
1935 PVRSRV_HANDLE_TYPE_MEM_INFO);
1936 PVR_ASSERT(eError == PVRSRV_OK);
1937
1938
1939 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1940 psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
1941 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1942 PVR_ASSERT(eError == PVRSRV_OK);
1943
1944
1945 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1946 psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
1947 PVRSRV_HANDLE_TYPE_MEM_INFO);
1948 PVR_ASSERT(eError == PVRSRV_OK);
1949
1950 for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
1951 {
1952
1953 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1954 phKernelMemInfoHandles[i],
1955 PVRSRV_HANDLE_TYPE_MEM_INFO);
1956 PVR_ASSERT(eError == PVRSRV_OK);
1957 }
1958
1959 eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
1960 psSharedPBDescKernelMemInfo,
1961 psHWPBDescKernelMemInfo,
1962 psBlockKernelMemInfo,
1963 psHWBlockKernelMemInfo,
1964 psSGXAddSharedPBDescIN->ui32TotalPBSize,
1965 &hSharedPBDesc,
1966 ppsKernelMemInfos,
1967 ui32KernelMemInfoHandlesCount);
1968
1969
1970 if (eError != PVRSRV_OK)
1971 {
1972 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1973 }
1974
1975 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1976 &psSGXAddSharedPBDescOUT->hSharedPBDesc,
1977 hSharedPBDesc,
1978 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
1979 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1980
1981PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT:
1982
1983 if(phKernelMemInfoHandles)
1984 {
1985 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1986 psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
1987 (IMG_VOID *)phKernelMemInfoHandles,
1988 0);
1989 }
1990 if(ppsKernelMemInfos)
1991 {
1992 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1993 psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
1994 (IMG_VOID *)ppsKernelMemInfos,
1995 0);
1996 }
1997
1998 if(ret == 0 && eError == PVRSRV_OK)
1999 {
2000 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc);
2001 }
2002
2003 psSGXAddSharedPBDescOUT->eError = eError;
2004
2005 return ret;
2006}
2007
2008static IMG_INT
2009SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID,
2010 PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN,
2011 PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT,
2012 PVRSRV_PER_PROCESS_DATA *psPerProc)
2013{
2014 IMG_HANDLE hDevCookieInt;
2015 IMG_UINT32 i;
2016 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT);
2017
2018 NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS);
2019
2020 if(!psPerProc->bInitProcess)
2021 {
2022 psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
2023 return 0;
2024 }
2025
2026 psSGXInfoForSrvinitOUT->eError =
2027 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
2028 psSGXInfoForSrvinitIN->hDevCookie,
2029 PVRSRV_HANDLE_TYPE_DEV_NODE);
2030
2031 if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
2032 {
2033 return 0;
2034 }
2035
2036 psSGXInfoForSrvinitOUT->eError =
2037 SGXGetInfoForSrvinitKM(hDevCookieInt,
2038 &psSGXInfoForSrvinitOUT->sInitInfo);
2039
2040 if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
2041 {
2042 return 0;
2043 }
2044
2045 for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
2046 {
2047 PVRSRV_HEAP_INFO *psHeapInfo;
2048
2049 psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i];
2050
2051 if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID)
2052 {
2053 IMG_HANDLE hDevMemHeapExt;
2054
2055 if (psHeapInfo->hDevMemHeap != IMG_NULL)
2056 {
2057
2058 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2059 &hDevMemHeapExt,
2060 psHeapInfo->hDevMemHeap,
2061 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
2062 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
2063 psHeapInfo->hDevMemHeap = hDevMemHeapExt;
2064 }
2065 }
2066 }
2067
2068 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
2069
2070 return 0;
2071}
2072
2073#if defined(PDUMP)
2074static IMG_VOID
2075DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc,
2076 PSGX_KICKTA_DUMP_BUFFER psBufferArray,
2077 IMG_UINT32 ui32BufferArrayLength,
2078 IMG_BOOL bDumpPolls)
2079{
2080 IMG_UINT32 i;
2081
2082 for (i=0; i<ui32BufferArrayLength; i++)
2083 {
2084 PSGX_KICKTA_DUMP_BUFFER psBuffer;
2085 PVRSRV_KERNEL_MEM_INFO *psCtrlMemInfoKM;
2086 IMG_CHAR * pszName;
2087 IMG_HANDLE hUniqueTag;
2088 IMG_UINT32 ui32Offset;
2089
2090 psBuffer = &psBufferArray[i];
2091 pszName = psBuffer->pszName;
2092 if (!pszName)
2093 {
2094 pszName = "Nameless buffer";
2095 }
2096
2097 hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo);
2098
2099 #if defined(SUPPORT_SGX_NEW_STATUS_VALS)
2100 psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo);
2101 ui32Offset = psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr;
2102 #else
2103 psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM;
2104 ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
2105 #endif
2106
2107 if (psBuffer->ui32Start <= psBuffer->ui32End)
2108 {
2109 if (bDumpPolls)
2110 {
2111 PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
2112 PDUMPCBP(psCtrlMemInfoKM,
2113 ui32Offset,
2114 psBuffer->ui32Start,
2115 psBuffer->ui32SpaceUsed,
2116 psBuffer->ui32BufferSize,
2117 0,
2118 MAKEUNIQUETAG(psCtrlMemInfoKM));
2119 }
2120
2121 PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName);
2122 PDUMPMEMUM(psPerProc,
2123 IMG_NULL,
2124 psBuffer->pvLinAddr,
2125 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
2126 psBuffer->ui32Start,
2127 psBuffer->ui32End - psBuffer->ui32Start,
2128 0,
2129 hUniqueTag);
2130 }
2131 else
2132 {
2133
2134
2135 if (bDumpPolls)
2136 {
2137 PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
2138 PDUMPCBP(psCtrlMemInfoKM,
2139 ui32Offset,
2140 psBuffer->ui32Start,
2141 psBuffer->ui32BackEndLength,
2142 psBuffer->ui32BufferSize,
2143 0,
2144 MAKEUNIQUETAG(psCtrlMemInfoKM));
2145 }
2146 PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
2147 PDUMPMEMUM(psPerProc,
2148 IMG_NULL,
2149 psBuffer->pvLinAddr,
2150 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
2151 psBuffer->ui32Start,
2152 psBuffer->ui32BackEndLength,
2153 0,
2154 hUniqueTag);
2155
2156 if (bDumpPolls)
2157 {
2158 PDUMPMEMPOL(psCtrlMemInfoKM,
2159 ui32Offset,
2160 0,
2161 0xFFFFFFFF,
2162 PDUMP_POLL_OPERATOR_NOTEQUAL,
2163 0,
2164 MAKEUNIQUETAG(psCtrlMemInfoKM));
2165
2166 PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
2167 PDUMPCBP(psCtrlMemInfoKM,
2168 ui32Offset,
2169 0,
2170 psBuffer->ui32End,
2171 psBuffer->ui32BufferSize,
2172 0,
2173 MAKEUNIQUETAG(psCtrlMemInfoKM));
2174 }
2175 PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
2176 PDUMPMEMUM(psPerProc,
2177 IMG_NULL,
2178 psBuffer->pvLinAddr,
2179 (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
2180 0,
2181 psBuffer->ui32End,
2182 0,
2183 hUniqueTag);
2184 }
2185 }
2186}
2187static IMG_INT
2188SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID,
2189 PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
2190 IMG_VOID *psBridgeOut,
2191 PVRSRV_PER_PROCESS_DATA *psPerProc)
2192{
2193 IMG_UINT32 i;
2194 SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
2195 IMG_UINT32 ui32BufferArrayLength =
2196 psPDumpBufferArrayIN->ui32BufferArrayLength;
2197 IMG_UINT32 ui32BufferArraySize =
2198 ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER);
2199 PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS;
2200
2201 PVR_UNREFERENCED_PARAMETER(psBridgeOut);
2202
2203 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
2204
2205 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2206 ui32BufferArraySize,
2207 (IMG_PVOID *)&psKickTADumpBuffer, 0,
2208 "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
2209 {
2210 return -ENOMEM;
2211 }
2212
2213 if(CopyFromUserWrapper(psPerProc,
2214 ui32BridgeID,
2215 psKickTADumpBuffer,
2216 psPDumpBufferArrayIN->psBufferArray,
2217 ui32BufferArraySize) != PVRSRV_OK)
2218 {
2219 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
2220
2221 return -EFAULT;
2222 }
2223
2224 for(i = 0; i < ui32BufferArrayLength; i++)
2225 {
2226 IMG_VOID *pvMemInfo;
2227
2228 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2229 &pvMemInfo,
2230 psKickTADumpBuffer[i].hKernelMemInfo,
2231 PVRSRV_HANDLE_TYPE_MEM_INFO);
2232
2233 if(eError != PVRSRV_OK)
2234 {
2235 PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
2236 "PVRSRVLookupHandle failed (%d)", eError));
2237 break;
2238 }
2239 psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
2240
2241#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
2242 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2243 &pvMemInfo,
2244 psKickTADumpBuffer[i].hCtrlKernelMemInfo,
2245 PVRSRV_HANDLE_TYPE_MEM_INFO);
2246
2247 if(eError != PVRSRV_OK)
2248 {
2249 PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
2250 "PVRSRVLookupHandle failed (%d)", eError));
2251 break;
2252 }
2253 psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo;
2254#endif
2255 }
2256
2257 if(eError == PVRSRV_OK)
2258 {
2259 DumpBufferArray(psPerProc,
2260 psKickTADumpBuffer,
2261 ui32BufferArrayLength,
2262 psPDumpBufferArrayIN->bDumpPolls);
2263 }
2264
2265 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
2266
2267
2268 return 0;
2269}
2270
2271static IMG_INT
2272SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID,
2273 PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN,
2274 PVRSRV_BRIDGE_RETURN *psRetOUT,
2275 PVRSRV_PER_PROCESS_DATA *psPerProc)
2276{
2277 IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
2278 IMG_UINT32 *pui32Registers = IMG_NULL;
2279 PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL;
2280#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2281 IMG_UINT32 ui32RegVal = 0;
2282#endif
2283 PVRSRV_DEVICE_NODE *psDeviceNode;
2284 IMG_INT ret = -EFAULT;
2285
2286 PVR_UNREFERENCED_PARAMETER(psRetOUT);
2287
2288 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
2289
2290 if (ui32RegisterArraySize == 0)
2291 {
2292 goto ExitNoError;
2293 }
2294
2295 psRetOUT->eError =
2296 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
2297 psPDump3DSignatureRegistersIN->hDevCookie,
2298 PVRSRV_HANDLE_TYPE_DEV_NODE);
2299 if(psRetOUT->eError != PVRSRV_OK)
2300 {
2301 PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
2302 goto Exit;
2303 }
2304
2305 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2306
2307#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2308
2309 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
2310 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
2311#if defined(PDUMP)
2312 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
2313 psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2314#endif
2315#endif
2316
2317 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2318 ui32RegisterArraySize,
2319 (IMG_PVOID *)&pui32Registers, 0,
2320 "Array of Registers") != PVRSRV_OK)
2321 {
2322 PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed"));
2323 goto Exit;
2324 }
2325
2326 if(CopyFromUserWrapper(psPerProc,
2327 ui32BridgeID,
2328 pui32Registers,
2329 psPDump3DSignatureRegistersIN->pui32Registers,
2330 ui32RegisterArraySize) != PVRSRV_OK)
2331 {
2332 PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed"));
2333 goto Exit;
2334 }
2335
2336 PDump3DSignatureRegisters(&psDeviceNode->sDevId,
2337 psPDump3DSignatureRegistersIN->ui32DumpFrameNum,
2338 psPDump3DSignatureRegistersIN->bLastFrame,
2339 pui32Registers,
2340 psPDump3DSignatureRegistersIN->ui32NumRegisters);
2341
2342 PDumpSignatureBuffer(&psDeviceNode->sDevId,
2343 "out.tasig", "TA", 0,
2344 psDevInfo->psKernelTASigBufferMemInfo->sDevVAddr,
2345 psDevInfo->psKernelTASigBufferMemInfo->ui32AllocSize,
2346 0 );
2347 PDumpSignatureBuffer(&psDeviceNode->sDevId,
2348 "out.3dsig", "3D", 0,
2349 psDevInfo->psKernel3DSigBufferMemInfo->sDevVAddr,
2350 psDevInfo->psKernel3DSigBufferMemInfo->ui32AllocSize,
2351 0 );
2352
2353ExitNoError:
2354 psRetOUT->eError = PVRSRV_OK;
2355 ret = 0;
2356Exit:
2357 if (pui32Registers != IMG_NULL)
2358 {
2359 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
2360 }
2361
2362#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2363 if (psDevInfo != IMG_NULL)
2364 {
2365 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
2366#if defined(PDUMP)
2367 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
2368 psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2369#endif
2370 }
2371#endif
2372
2373 return ret;
2374}
2375
2376static IMG_INT
2377SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID,
2378 PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN,
2379 IMG_VOID *psBridgeOut,
2380 PVRSRV_PER_PROCESS_DATA *psPerProc)
2381{
2382 IMG_UINT32 ui32RegisterArraySize = psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
2383 IMG_UINT32 *pui32Registers = IMG_NULL;
2384 PVRSRV_DEVICE_NODE *psDeviceNode;
2385 IMG_INT ret = -EFAULT;
2386
2387 PVR_UNREFERENCED_PARAMETER(psBridgeOut);
2388
2389 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
2390
2391 if (ui32RegisterArraySize == 0)
2392 {
2393 goto ExitNoError;
2394 }
2395
2396 if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
2397 psPDumpCounterRegistersIN->hDevCookie,
2398 PVRSRV_HANDLE_TYPE_DEV_NODE) != PVRSRV_OK)
2399 {
2400 PVR_DPF((PVR_DBG_ERROR, "SGXPDumpCounterRegistersBW: hDevCookie lookup failed"));
2401 ret = -ENOMEM;
2402 goto Exit;
2403 }
2404
2405 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2406 ui32RegisterArraySize,
2407 (IMG_PVOID *)&pui32Registers, 0,
2408 "Array of Registers") != PVRSRV_OK)
2409 {
2410 PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed"));
2411 ret = -ENOMEM;
2412 goto Exit;
2413 }
2414
2415 if(CopyFromUserWrapper(psPerProc,
2416 ui32BridgeID,
2417 pui32Registers,
2418 psPDumpCounterRegistersIN->pui32Registers,
2419 ui32RegisterArraySize) != PVRSRV_OK)
2420 {
2421 PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed"));
2422 goto Exit;
2423 }
2424
2425 PDumpCounterRegisters(&psDeviceNode->sDevId,
2426 psPDumpCounterRegistersIN->ui32DumpFrameNum,
2427 psPDumpCounterRegistersIN->bLastFrame,
2428 pui32Registers,
2429 psPDumpCounterRegistersIN->ui32NumRegisters);
2430
2431ExitNoError:
2432 ret = 0;
2433Exit:
2434 if (pui32Registers != IMG_NULL)
2435 {
2436 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
2437 }
2438
2439 return ret;
2440}
2441
2442static IMG_INT
2443SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID,
2444 PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN,
2445 PVRSRV_BRIDGE_RETURN *psRetOUT,
2446 PVRSRV_PER_PROCESS_DATA *psPerProc)
2447{
2448 IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
2449 IMG_UINT32 *pui32Registers = IMG_NULL;
2450#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2451 PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL;
2452 IMG_UINT32 ui32RegVal = 0;
2453#endif
2454 PVRSRV_DEVICE_NODE *psDeviceNode;
2455 IMG_INT ret = -EFAULT;
2456
2457 PVR_UNREFERENCED_PARAMETER(psRetOUT);
2458
2459 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
2460
2461 if (ui32RegisterArraySize == 0)
2462 {
2463 goto ExitNoError;
2464 }
2465
2466 psRetOUT->eError =
2467 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
2468 psPDumpTASignatureRegistersIN->hDevCookie,
2469 PVRSRV_HANDLE_TYPE_DEV_NODE);
2470 if(psRetOUT->eError != PVRSRV_OK)
2471 {
2472 PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
2473 goto Exit;
2474 }
2475
2476#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2477
2478 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2479
2480
2481 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
2482 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
2483#if defined(PDUMP)
2484 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
2485 psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2486#endif
2487#endif
2488
2489 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2490 ui32RegisterArraySize,
2491 (IMG_PVOID *)&pui32Registers, 0,
2492 "Array of Registers") != PVRSRV_OK)
2493 {
2494 PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed"));
2495 ret = -ENOMEM;
2496 goto Exit;
2497 }
2498
2499 if(CopyFromUserWrapper(psPerProc,
2500 ui32BridgeID,
2501 pui32Registers,
2502 psPDumpTASignatureRegistersIN->pui32Registers,
2503 ui32RegisterArraySize) != PVRSRV_OK)
2504 {
2505 PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed"));
2506 goto Exit;
2507 }
2508
2509 PDumpTASignatureRegisters(&psDeviceNode->sDevId,
2510 psPDumpTASignatureRegistersIN->ui32DumpFrameNum,
2511 psPDumpTASignatureRegistersIN->ui32TAKickCount,
2512 psPDumpTASignatureRegistersIN->bLastFrame,
2513 pui32Registers,
2514 psPDumpTASignatureRegistersIN->ui32NumRegisters);
2515
2516ExitNoError:
2517 psRetOUT->eError = PVRSRV_OK;
2518 ret = 0;
2519Exit:
2520 if (pui32Registers != IMG_NULL)
2521 {
2522 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
2523 }
2524
2525#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
2526 if (psDevInfo != IMG_NULL)
2527 {
2528 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
2529#if defined(PDUMP)
2530 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
2531 psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2532#endif
2533 }
2534#endif
2535
2536 return ret;
2537}
2538static IMG_INT
2539SGXPDumpHWPerfCBBW(IMG_UINT32 ui32BridgeID,
2540 PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN,
2541 PVRSRV_BRIDGE_RETURN *psRetOUT,
2542 PVRSRV_PER_PROCESS_DATA *psPerProc)
2543{
2544#if defined(SUPPORT_SGX_HWPERF)
2545#if defined(__linux__)
2546 PVRSRV_SGXDEV_INFO *psDevInfo;
2547 PVRSRV_DEVICE_NODE *psDeviceNode;
2548
2549 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
2550
2551 psRetOUT->eError =
2552 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
2553 psPDumpHWPerfCBIN->hDevCookie,
2554 PVRSRV_HANDLE_TYPE_DEV_NODE);
2555 if(psRetOUT->eError != PVRSRV_OK)
2556 {
2557 return 0;
2558 }
2559
2560 psDevInfo = psDeviceNode->pvDevice;
2561
2562 PDumpHWPerfCBKM(&psDeviceNode->sDevId,
2563 &psPDumpHWPerfCBIN->szFileName[0],
2564 psPDumpHWPerfCBIN->ui32FileOffset,
2565 psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
2566 psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize,
2567 psPDumpHWPerfCBIN->ui32PDumpFlags);
2568
2569 return 0;
2570#else
2571 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2572 PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
2573 PVR_UNREFERENCED_PARAMETER(psRetOUT);
2574 PVR_UNREFERENCED_PARAMETER(psPerProc);
2575 return 0;
2576#endif
2577#else
2578 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2579 PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
2580 PVR_UNREFERENCED_PARAMETER(psRetOUT);
2581 PVR_UNREFERENCED_PARAMETER(psPerProc);
2582 return -EFAULT;
2583#endif
2584}
2585
2586
2587static IMG_INT
2588SGXPDumpSaveMemBW(IMG_UINT32 ui32BridgeID,
2589 PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM *psPDumpSaveMem,
2590 PVRSRV_BRIDGE_RETURN *psRetOUT,
2591 PVRSRV_PER_PROCESS_DATA *psPerProc)
2592{
2593 PVRSRV_DEVICE_NODE *psDeviceNode;
2594
2595 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM);
2596
2597 psRetOUT->eError =
2598 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
2599 psPDumpSaveMem->hDevCookie,
2600 PVRSRV_HANDLE_TYPE_DEV_NODE);
2601 if(psRetOUT->eError != PVRSRV_OK)
2602 {
2603 return 0;
2604 }
2605
2606 PDumpSaveMemKM(&psDeviceNode->sDevId,
2607 &psPDumpSaveMem->szFileName[0],
2608 psPDumpSaveMem->ui32FileOffset,
2609 psPDumpSaveMem->sDevVAddr,
2610 psPDumpSaveMem->ui32Size,
2611 psPDumpSaveMem->ui32DataMaster,
2612 psPDumpSaveMem->ui32PDumpFlags);
2613 return 0;
2614}
2615
2616#endif
2617
2618
2619
2620IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
2621{
2622
2623 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, SGXGetClientInfoBW);
2624 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW);
2625 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW);
2626 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW);
2627 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW);
2628 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW);
2629
2630 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW);
2631
2632 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW);
2633
2634#if defined(TRANSFER_QUEUE)
2635 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW);
2636#endif
2637 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW);
2638 SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT , SGXGetInfoForSrvinitBW);
2639 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, SGXDevInitPart2BW);
2640
2641 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW);
2642 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW);
2643 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW);
2644 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW);
2645 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW);
2646 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW);
2647#if defined(SGX_FEATURE_2D_HARDWARE)
2648 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW);
2649 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW);
2650 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW);
2651#endif
2652 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW);
2653 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW);
2654
2655 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
2656
2657 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
2658
2659#if defined(PDUMP)
2660 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW);
2661 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW);
2662 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW);
2663 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW);
2664 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW);
2665 SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM, SGXPDumpSaveMemBW);
2666#endif
2667}
2668
2669
2670#endif
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h
new file mode 100644
index 00000000000..de6cfd1bc1e
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.h
@@ -0,0 +1,42 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __BRIDGED_SGX_BRIDGE_H__
28#define __BRIDGED_SGX_BRIDGE_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34
35IMG_VOID SetSGXDispatchTableEntry(IMG_VOID);
36
37#if defined (__cplusplus)
38}
39#endif
40
41#endif
42
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
new file mode 100644
index 00000000000..8cf6682c247
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -0,0 +1,2940 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "sgxdefs.h"
28#include "sgxmmu.h"
29#include "services_headers.h"
30#include "buffer_manager.h"
31#include "hash.h"
32#include "ra.h"
33#include "pdump_km.h"
34#include "sgxapi_km.h"
35#include "sgxinfo.h"
36#include "sgxinfokm.h"
37#include "mmu.h"
38#include "sgxconfig.h"
39#include "sgx_bridge_km.h"
40
41#define UINT32_MAX_VALUE 0xFFFFFFFFUL
42
43#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
44
45typedef struct _MMU_PT_INFO_
46{
47
48 IMG_VOID *hPTPageOSMemHandle;
49 IMG_CPU_VIRTADDR PTPageCpuVAddr;
50 IMG_UINT32 ui32ValidPTECount;
51} MMU_PT_INFO;
52
53struct _MMU_CONTEXT_
54{
55
56 PVRSRV_DEVICE_NODE *psDeviceNode;
57
58
59 IMG_CPU_VIRTADDR pvPDCpuVAddr;
60 IMG_DEV_PHYADDR sPDDevPAddr;
61
62 IMG_VOID *hPDOSMemHandle;
63
64
65 MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
66
67 PVRSRV_SGXDEV_INFO *psDevInfo;
68
69#if defined(PDUMP)
70 IMG_UINT32 ui32PDumpMMUContextID;
71#endif
72
73 struct _MMU_CONTEXT_ *psNext;
74};
75
76struct _MMU_HEAP_
77{
78
79 MMU_CONTEXT *psMMUContext;
80
81
82
83
84 IMG_UINT32 ui32PDBaseIndex;
85
86 IMG_UINT32 ui32PageTableCount;
87
88 IMG_UINT32 ui32PTETotal;
89
90 IMG_UINT32 ui32PDEPageSizeCtrl;
91
92
93
94
95 IMG_UINT32 ui32DataPageSize;
96
97 IMG_UINT32 ui32DataPageBitWidth;
98
99 IMG_UINT32 ui32DataPageMask;
100
101
102
103
104 IMG_UINT32 ui32PTShift;
105
106 IMG_UINT32 ui32PTBitWidth;
107
108 IMG_UINT32 ui32PTMask;
109
110 IMG_UINT32 ui32PTSize;
111
112 IMG_UINT32 ui32PTECount;
113
114
115
116
117 IMG_UINT32 ui32PDShift;
118
119 IMG_UINT32 ui32PDBitWidth;
120
121 IMG_UINT32 ui32PDMask;
122
123
124
125 RA_ARENA *psVMArena;
126 DEV_ARENA_DESCRIPTOR *psDevArena;
127#if defined(PDUMP)
128 PDUMP_MMU_ATTRIB sMMUAttrib;
129#endif
130};
131
132
133
134#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
135#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF
136#endif
137
138#if defined(PDUMP)
139static IMG_VOID
140MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
141 IMG_DEV_VIRTADDR DevVAddr,
142 IMG_SIZE_T uSize,
143 IMG_BOOL bForUnmap,
144 IMG_HANDLE hUniqueTag);
145#endif
146
147#define PAGE_TEST 0
148#if PAGE_TEST
149static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
150#endif
151
152#define PT_DEBUG 0
153#if PT_DEBUG
154static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
155{
156 IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
157 IMG_UINT32 i;
158
159
160 for(i = 0; i < 1024; i += 8)
161 {
162 PVR_DPF((PVR_DBG_WARNING,
163 "%08X %08X %08X %08X %08X %08X %08X %08X\n",
164 p[i + 0], p[i + 1], p[i + 2], p[i + 3],
165 p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
166 }
167}
168
169static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
170{
171 IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
172 IMG_UINT32 i, ui32Count = 0;
173
174
175 for(i = 0; i < 1024; i++)
176 if(p[i] & SGX_MMU_PTE_VALID)
177 ui32Count++;
178
179 if(psPTInfoList->ui32ValidPTECount != ui32Count)
180 {
181 PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %u ui32Count: %u\n",
182 psPTInfoList->ui32ValidPTECount, ui32Count));
183 DumpPT(psPTInfoList);
184 BUG();
185 }
186}
187#else
188static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
189{
190 PVR_UNREFERENCED_PARAMETER(psPTInfoList);
191}
192
193static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
194{
195 PVR_UNREFERENCED_PARAMETER(psPTInfoList);
196}
197#endif
198
199#ifdef SUPPORT_SGX_MMU_BYPASS
200IMG_VOID
201EnableHostAccess (MMU_CONTEXT *psMMUContext)
202{
203 IMG_UINT32 ui32RegVal;
204 IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
205
206
207
208
209 ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
210
211 OSWriteHWReg(pvRegsBaseKM,
212 EUR_CR_BIF_CTRL,
213 ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
214
215 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
216}
217
218IMG_VOID
219DisableHostAccess (MMU_CONTEXT *psMMUContext)
220{
221 IMG_UINT32 ui32RegVal;
222 IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
223
224
225
226
227
228 OSWriteHWReg(pvRegsBaseKM,
229 EUR_CR_BIF_CTRL,
230 ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
231
232 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, 0);
233}
234#endif
235
236
237#if defined(SGX_FEATURE_SYSTEM_CACHE)
238static IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
239{
240 #if defined(SGX_FEATURE_MP)
241 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
242 #else
243
244 PVR_UNREFERENCED_PARAMETER(psDevInfo);
245 #endif
246}
247#endif
248
249IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
250{
251 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
252 #if defined(SGX_FEATURE_SYSTEM_CACHE)
253 MMU_InvalidateSystemLevelCache(psDevInfo);
254 #endif
255}
256
257
258static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
259{
260 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT;
261 #if defined(SGX_FEATURE_SYSTEM_CACHE)
262 MMU_InvalidateSystemLevelCache(psDevInfo);
263 #endif
264}
265
266
267static IMG_BOOL
268_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
269 MMU_PT_INFO *psPTInfoList,
270 IMG_DEV_PHYADDR *psDevPAddr)
271{
272 IMG_DEV_PHYADDR sDevPAddr;
273 IMG_CPU_PHYADDR sCpuPAddr;
274
275
276
277
278 if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
279 {
280
281 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
282 pMMUHeap->ui32PTSize,
283 SGX_MMU_PAGE_SIZE,
284 (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
285 &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
286 {
287 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
288 return IMG_FALSE;
289 }
290
291
292 if(psPTInfoList->PTPageCpuVAddr)
293 {
294 sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
295 psPTInfoList->PTPageCpuVAddr);
296 }
297 else
298 {
299
300 sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
301 }
302
303 sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
304 }
305 else
306 {
307 IMG_SYS_PHYADDR sSysPAddr;
308
309
310
311
312
313 if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
314 SGX_MMU_PAGE_SIZE,
315 IMG_NULL,
316 IMG_NULL,
317 0,
318 SGX_MMU_PAGE_SIZE,
319 0,
320 &(sSysPAddr.uiAddr))!= IMG_TRUE)
321 {
322 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
323 return IMG_FALSE;
324 }
325
326
327 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
328
329 psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
330 SGX_MMU_PAGE_SIZE,
331 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
332 &psPTInfoList->hPTPageOSMemHandle);
333 if(!psPTInfoList->PTPageCpuVAddr)
334 {
335 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
336 return IMG_FALSE;
337 }
338
339
340 sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
341
342 #if PAGE_TEST
343 PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
344 #endif
345 }
346
347#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
348 {
349 IMG_UINT32 *pui32Tmp;
350 IMG_UINT32 i;
351
352 pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
353
354 for(i=0; i<pMMUHeap->ui32PTECount; i++)
355 {
356 pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
357 | SGX_MMU_PTE_VALID;
358 }
359 }
360#else
361
362 OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
363#endif
364
365
366 PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
367
368 PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
369
370
371 *psDevPAddr = sDevPAddr;
372
373 return IMG_TRUE;
374}
375
376
377static IMG_VOID
378_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
379{
380
381
382
383
384 if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
385 {
386
387 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
388 pMMUHeap->ui32PTSize,
389 psPTInfoList->PTPageCpuVAddr,
390 psPTInfoList->hPTPageOSMemHandle);
391 }
392 else
393 {
394 IMG_SYS_PHYADDR sSysPAddr;
395 IMG_CPU_PHYADDR sCpuPAddr;
396
397
398 sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
399 psPTInfoList->PTPageCpuVAddr);
400 sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
401
402
403
404 OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
405 SGX_MMU_PAGE_SIZE,
406 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
407 psPTInfoList->hPTPageOSMemHandle);
408
409
410
411
412 RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
413 }
414}
415
416
417
418static IMG_VOID
419_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
420{
421 IMG_UINT32 *pui32PDEntry;
422 IMG_UINT32 i;
423 IMG_UINT32 ui32PDIndex;
424 SYS_DATA *psSysData;
425 MMU_PT_INFO **ppsPTInfoList;
426
427 SysAcquireData(&psSysData);
428
429
430 ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
431
432
433 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
434
435 {
436#if PT_DEBUG
437 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
438 {
439 DumpPT(ppsPTInfoList[ui32PTIndex]);
440
441 }
442#endif
443
444
445 PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
446 }
447
448
449 PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
450 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
451 {
452 PDUMPFREEPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
453 }
454
455 switch(pMMUHeap->psDevArena->DevMemHeapType)
456 {
457 case DEVICE_MEMORY_HEAP_SHARED :
458 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
459 {
460
461 MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
462
463 while(psMMUContext)
464 {
465
466 pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
467 pui32PDEntry += ui32PDIndex;
468
469#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
470
471 pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
472 >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
473 | SGX_MMU_PDE_PAGE_SIZE_4K
474 | SGX_MMU_PDE_VALID;
475#else
476
477 if(bOSFreePT)
478 {
479 pui32PDEntry[ui32PTIndex] = 0;
480 }
481#endif
482
483
484 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
485
486
487 psMMUContext = psMMUContext->psNext;
488 }
489 break;
490 }
491 case DEVICE_MEMORY_HEAP_PERCONTEXT :
492 case DEVICE_MEMORY_HEAP_KERNEL :
493 {
494
495 pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
496 pui32PDEntry += ui32PDIndex;
497
498#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
499
500 pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
501 >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
502 | SGX_MMU_PDE_PAGE_SIZE_4K
503 | SGX_MMU_PDE_VALID;
504#else
505
506 if(bOSFreePT)
507 {
508 pui32PDEntry[ui32PTIndex] = 0;
509 }
510#endif
511
512
513 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
514 break;
515 }
516 default:
517 {
518 PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"));
519 return;
520 }
521 }
522
523
524 if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
525 {
526 if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
527 {
528 IMG_PUINT32 pui32Tmp;
529
530 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
531
532
533 for(i=0;
534 (i<pMMUHeap->ui32PTETotal) && (i<pMMUHeap->ui32PTECount);
535 i++)
536 {
537 pui32Tmp[i] = 0;
538 }
539
540
541
542 if(bOSFreePT)
543 {
544 _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
545 }
546
547
548
549
550 pMMUHeap->ui32PTETotal -= i;
551 }
552 else
553 {
554
555 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
556 }
557
558 if(bOSFreePT)
559 {
560
561 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
562 sizeof(MMU_PT_INFO),
563 ppsPTInfoList[ui32PTIndex],
564 IMG_NULL);
565 ppsPTInfoList[ui32PTIndex] = IMG_NULL;
566 }
567 }
568 else
569 {
570
571 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
572 }
573
574 PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
575}
576
577static IMG_VOID
578_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
579{
580 IMG_UINT32 i;
581#if defined(PDUMP)
582 PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)",
583 pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
584 pMMUHeap->ui32PDBaseIndex,
585 pMMUHeap->ui32PageTableCount);
586#endif
587 for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
588 {
589 _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
590 }
591 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
592}
593
594
595static IMG_BOOL
596_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
597{
598 IMG_UINT32 ui32PageTableCount;
599 IMG_UINT32 ui32PDIndex;
600 IMG_UINT32 i;
601 IMG_UINT32 *pui32PDEntry;
602 MMU_PT_INFO **ppsPTInfoList;
603 SYS_DATA *psSysData;
604 IMG_DEV_VIRTADDR sHighDevVAddr;
605
606
607#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
608 PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
609#endif
610
611
612 SysAcquireData(&psSysData);
613
614
615 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
616
617
618
619 if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
620 < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
621 {
622
623 sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
624 }
625 else
626 {
627 sHighDevVAddr.uiAddr = DevVAddr.uiAddr
628 + ui32Size
629 + pMMUHeap->ui32DataPageMask
630 + pMMUHeap->ui32PTMask;
631 }
632
633 ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
634
635 ui32PageTableCount -= ui32PDIndex;
636
637
638 pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
639 pui32PDEntry += ui32PDIndex;
640
641
642 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
643
644#if defined(PDUMP)
645 PDUMPCOMMENT("Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)",
646 pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
647 pMMUHeap->ui32PDBaseIndex,
648 ui32Size);
649 PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PageTableCount);
650 PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PageTableCount);
651#endif
652
653 for(i=0; i<ui32PageTableCount; i++)
654 {
655 if(ppsPTInfoList[i] == IMG_NULL)
656 {
657 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
658 sizeof (MMU_PT_INFO),
659 (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
660 "MMU Page Table Info");
661 if (ppsPTInfoList[i] == IMG_NULL)
662 {
663 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
664 return IMG_FALSE;
665 }
666 OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
667 }
668
669 if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
670 && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
671 {
672 IMG_DEV_PHYADDR sDevPAddr;
673#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
674 IMG_UINT32 *pui32Tmp;
675 IMG_UINT32 j;
676#else
677
678 PVR_ASSERT(pui32PDEntry[i] == 0);
679#endif
680
681 if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
682 {
683 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
684 return IMG_FALSE;
685 }
686
687 switch(pMMUHeap->psDevArena->DevMemHeapType)
688 {
689 case DEVICE_MEMORY_HEAP_SHARED :
690 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
691 {
692
693 MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
694
695 while(psMMUContext)
696 {
697
698 pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
699 pui32PDEntry += ui32PDIndex;
700
701
702 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
703 | pMMUHeap->ui32PDEPageSizeCtrl
704 | SGX_MMU_PDE_VALID;
705
706
707 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
708
709
710 psMMUContext = psMMUContext->psNext;
711 }
712 break;
713 }
714 case DEVICE_MEMORY_HEAP_PERCONTEXT :
715 case DEVICE_MEMORY_HEAP_KERNEL :
716 {
717
718 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
719 | pMMUHeap->ui32PDEPageSizeCtrl
720 | SGX_MMU_PDE_VALID;
721
722
723 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
724 break;
725 }
726 default:
727 {
728 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type"));
729 return IMG_FALSE;
730 }
731 }
732
733#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
734
735
736
737
738 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
739#endif
740 }
741 else
742 {
743
744 PVR_ASSERT(pui32PDEntry[i] != 0);
745 }
746 }
747
748 #if defined(SGX_FEATURE_SYSTEM_CACHE)
749 MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
750 #endif
751
752 return IMG_TRUE;
753}
754
755
756#if defined(PDUMP)
757IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext)
758{
759 BM_CONTEXT *pBMContext = hDevMemContext;
760 PVR_ASSERT(pBMContext);
761 return pBMContext->psMMUContext->ui32PDumpMMUContextID;
762}
763
764static IMG_VOID MMU_SetPDumpAttribs(PDUMP_MMU_ATTRIB *psMMUAttrib,
765 PVRSRV_DEVICE_NODE *psDeviceNode,
766 IMG_UINT32 ui32DataPageMask,
767 IMG_UINT32 ui32PTSize)
768{
769
770 psMMUAttrib->sDevId = psDeviceNode->sDevId;
771
772 psMMUAttrib->pszPDRegRegion = IMG_NULL;
773 psMMUAttrib->ui32DataPageMask = ui32DataPageMask;
774
775 psMMUAttrib->ui32PTEValid = SGX_MMU_PTE_VALID;
776 psMMUAttrib->ui32PTSize = ui32PTSize;
777 psMMUAttrib->ui32PTEAlignShift = SGX_MMU_PTE_ADDR_ALIGNSHIFT;
778
779 psMMUAttrib->ui32PDEMask = SGX_MMU_PDE_ADDR_MASK;
780 psMMUAttrib->ui32PDEAlignShift = SGX_MMU_PDE_ADDR_ALIGNSHIFT;
781}
782#endif
783
784PVRSRV_ERROR
785MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr)
786{
787 IMG_UINT32 *pui32Tmp;
788 IMG_UINT32 i;
789 IMG_CPU_VIRTADDR pvPDCpuVAddr;
790 IMG_DEV_PHYADDR sPDDevPAddr;
791 IMG_CPU_PHYADDR sCpuPAddr;
792 MMU_CONTEXT *psMMUContext;
793 IMG_HANDLE hPDOSMemHandle;
794 SYS_DATA *psSysData;
795 PVRSRV_SGXDEV_INFO *psDevInfo;
796#if defined(PDUMP)
797 PDUMP_MMU_ATTRIB sMMUAttrib;
798#endif
799 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
800
801 SysAcquireData(&psSysData);
802#if defined(PDUMP)
803
804
805 MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
806 SGX_MMU_PAGE_MASK,
807 SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
808#endif
809
810 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
811 sizeof (MMU_CONTEXT),
812 (IMG_VOID **)&psMMUContext, IMG_NULL,
813 "MMU Context");
814 if (psMMUContext == IMG_NULL)
815 {
816 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
817 return PVRSRV_ERROR_OUT_OF_MEMORY;
818 }
819 OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
820
821
822 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
823 psMMUContext->psDevInfo = psDevInfo;
824
825
826 psMMUContext->psDeviceNode = psDeviceNode;
827
828
829 if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
830 {
831 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
832 SGX_MMU_PAGE_SIZE,
833 SGX_MMU_PAGE_SIZE,
834 &pvPDCpuVAddr,
835 &hPDOSMemHandle) != PVRSRV_OK)
836 {
837 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
838 return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
839 }
840
841 if(pvPDCpuVAddr)
842 {
843 sCpuPAddr = OSMapLinToCPUPhys(hPDOSMemHandle,
844 pvPDCpuVAddr);
845 }
846 else
847 {
848
849 sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
850 }
851 sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
852
853 #if PAGE_TEST
854 PageTest(pvPDCpuVAddr, sPDDevPAddr);
855 #endif
856
857#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
858
859 if(!psDevInfo->pvMMUContextList)
860 {
861
862 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
863 SGX_MMU_PAGE_SIZE,
864 SGX_MMU_PAGE_SIZE,
865 &psDevInfo->pvDummyPTPageCpuVAddr,
866 &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
867 {
868 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
869 return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
870 }
871
872 if(psDevInfo->pvDummyPTPageCpuVAddr)
873 {
874 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
875 psDevInfo->pvDummyPTPageCpuVAddr);
876 }
877 else
878 {
879
880 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
881 }
882 psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
883
884
885 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
886 SGX_MMU_PAGE_SIZE,
887 SGX_MMU_PAGE_SIZE,
888 &psDevInfo->pvDummyDataPageCpuVAddr,
889 &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
890 {
891 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
892 return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
893 }
894
895 if(psDevInfo->pvDummyDataPageCpuVAddr)
896 {
897 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
898 psDevInfo->pvDummyDataPageCpuVAddr);
899 }
900 else
901 {
902 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
903 }
904 psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
905 }
906#endif
907 }
908 else
909 {
910 IMG_SYS_PHYADDR sSysPAddr;
911
912
913 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
914 SGX_MMU_PAGE_SIZE,
915 IMG_NULL,
916 IMG_NULL,
917 0,
918 SGX_MMU_PAGE_SIZE,
919 0,
920 &(sSysPAddr.uiAddr))!= IMG_TRUE)
921 {
922 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
923 return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
924 }
925
926
927 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
928 sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
929 pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr,
930 SGX_MMU_PAGE_SIZE,
931 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
932 &hPDOSMemHandle);
933 if(!pvPDCpuVAddr)
934 {
935 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
936 return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
937 }
938
939 #if PAGE_TEST
940 PageTest(pvPDCpuVAddr, sPDDevPAddr);
941 #endif
942
943#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
944
945 if(!psDevInfo->pvMMUContextList)
946 {
947
948 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
949 SGX_MMU_PAGE_SIZE,
950 IMG_NULL,
951 IMG_NULL,
952 0,
953 SGX_MMU_PAGE_SIZE,
954 0,
955 &(sSysPAddr.uiAddr))!= IMG_TRUE)
956 {
957 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
958 return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
959 }
960
961
962 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
963 psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
964 psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
965 SGX_MMU_PAGE_SIZE,
966 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
967 &psDevInfo->hDummyPTPageOSMemHandle);
968 if(!psDevInfo->pvDummyPTPageCpuVAddr)
969 {
970 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
971 return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
972 }
973
974
975 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
976 SGX_MMU_PAGE_SIZE,
977 IMG_NULL,
978 IMG_NULL,
979 0,
980 SGX_MMU_PAGE_SIZE,
981 0,
982 &(sSysPAddr.uiAddr))!= IMG_TRUE)
983 {
984 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
985 return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
986 }
987
988
989 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
990 psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
991 psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
992 SGX_MMU_PAGE_SIZE,
993 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
994 &psDevInfo->hDummyDataPageOSMemHandle);
995 if(!psDevInfo->pvDummyDataPageCpuVAddr)
996 {
997 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
998 return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
999 }
1000 }
1001#endif
1002 }
1003
1004#if defined(PDUMP)
1005
1006#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
1007 PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)",
1008 sPDDevPAddr.uiAddr);
1009#else
1010 PDUMPCOMMENT("Alloc page directory for new MMU context, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
1011 sPDDevPAddr.uiHighAddr, sPDDevPAddr.uiAddr);
1012#endif
1013#endif
1014#ifdef SUPPORT_SGX_MMU_BYPASS
1015 EnableHostAccess(psMMUContext);
1016#endif
1017
1018 if (pvPDCpuVAddr)
1019 {
1020 pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
1021 }
1022 else
1023 {
1024 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
1025 return PVRSRV_ERROR_INVALID_CPU_ADDR;
1026 }
1027
1028 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
1029
1030#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1031
1032 for(i=0; i<SGX_MMU_PD_SIZE; i++)
1033 {
1034 pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
1035 | SGX_MMU_PDE_PAGE_SIZE_4K
1036 | SGX_MMU_PDE_VALID;
1037 }
1038
1039 if(!psDevInfo->pvMMUContextList)
1040 {
1041
1042
1043
1044 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
1045 for(i=0; i<SGX_MMU_PT_SIZE; i++)
1046 {
1047 pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1048 | SGX_MMU_PTE_VALID;
1049 }
1050
1051 PDUMPCOMMENT("Dummy Page table contents");
1052 PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1053
1054
1055
1056 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
1057 for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
1058 {
1059 pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
1060 }
1061
1062 PDUMPCOMMENT("Dummy Data Page contents");
1063 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1064 }
1065#else
1066
1067 for(i=0; i<SGX_MMU_PD_SIZE; i++)
1068 {
1069
1070 pui32Tmp[i] = 0;
1071 }
1072#endif
1073
1074
1075 PDUMPCOMMENT("Page directory contents");
1076 PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1077
1078
1079#if defined(PDUMP)
1080 {
1081 PVRSRV_ERROR eError;
1082
1083 IMG_UINT32 ui32MMUType = 1;
1084
1085 #if defined(SGX_FEATURE_36BIT_MMU)
1086 ui32MMUType = 3;
1087 #else
1088 #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
1089 ui32MMUType = 2;
1090 #endif
1091 #endif
1092
1093 eError = PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
1094 psDeviceNode->sDevId.pszPDumpDevName,
1095 &psMMUContext->ui32PDumpMMUContextID,
1096 ui32MMUType,
1097 PDUMP_PT_UNIQUETAG,
1098 hPDOSMemHandle,
1099 pvPDCpuVAddr);
1100 if (eError != PVRSRV_OK)
1101 {
1102 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
1103 return eError;
1104 }
1105 }
1106
1107
1108 PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
1109#endif
1110
1111
1112 psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
1113 psMMUContext->sPDDevPAddr = sPDDevPAddr;
1114 psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
1115
1116
1117 *ppsMMUContext = psMMUContext;
1118
1119
1120 *psPDDevPAddr = sPDDevPAddr;
1121
1122
1123 psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
1124 psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
1125
1126#ifdef SUPPORT_SGX_MMU_BYPASS
1127 DisableHostAccess(psMMUContext);
1128#endif
1129
1130 return PVRSRV_OK;
1131}
1132
1133IMG_VOID
1134MMU_Finalise (MMU_CONTEXT *psMMUContext)
1135{
1136 IMG_UINT32 *pui32Tmp, i;
1137 SYS_DATA *psSysData;
1138 MMU_CONTEXT **ppsMMUContext;
1139#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1140 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
1141 MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
1142#endif
1143
1144 SysAcquireData(&psSysData);
1145
1146#if defined(PDUMP)
1147
1148 PDUMPCOMMENT("Clear MMU context (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
1149 PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->psDeviceNode->sDevId.pszPDumpDevName, psMMUContext->ui32PDumpMMUContextID, 2);
1150
1151
1152#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
1153 PDUMPCOMMENT("Free page directory (PDDevPAddr == 0x%08x)",
1154 psMMUContext->sPDDevPAddr.uiAddr);
1155#else
1156 PDUMPCOMMENT("Free page directory, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
1157 psMMUContext->sPDDevPAddr.uiHighAddr, psMMUContext->sPDDevPAddr.uiAddr);
1158#endif
1159#endif
1160
1161 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psMMUContext->hPDOSMemHandle, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1162#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1163 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyPTPageOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1164 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1165#endif
1166
1167 pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
1168
1169
1170 for(i=0; i<SGX_MMU_PD_SIZE; i++)
1171 {
1172
1173 pui32Tmp[i] = 0;
1174 }
1175
1176
1177
1178
1179
1180 if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
1181 {
1182 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1183 SGX_MMU_PAGE_SIZE,
1184 psMMUContext->pvPDCpuVAddr,
1185 psMMUContext->hPDOSMemHandle);
1186
1187#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1188
1189 if(!psMMUContextList->psNext)
1190 {
1191 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1192 SGX_MMU_PAGE_SIZE,
1193 psDevInfo->pvDummyPTPageCpuVAddr,
1194 psDevInfo->hDummyPTPageOSMemHandle);
1195 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1196 SGX_MMU_PAGE_SIZE,
1197 psDevInfo->pvDummyDataPageCpuVAddr,
1198 psDevInfo->hDummyDataPageOSMemHandle);
1199 }
1200#endif
1201 }
1202 else
1203 {
1204 IMG_SYS_PHYADDR sSysPAddr;
1205 IMG_CPU_PHYADDR sCpuPAddr;
1206
1207
1208 sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->hPDOSMemHandle,
1209 psMMUContext->pvPDCpuVAddr);
1210 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1211
1212
1213 OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
1214 SGX_MMU_PAGE_SIZE,
1215 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1216 psMMUContext->hPDOSMemHandle);
1217
1218 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1219
1220#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1221
1222 if(!psMMUContextList->psNext)
1223 {
1224
1225 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
1226 psDevInfo->pvDummyPTPageCpuVAddr);
1227 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1228
1229
1230 OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
1231 SGX_MMU_PAGE_SIZE,
1232 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1233 psDevInfo->hDummyPTPageOSMemHandle);
1234
1235 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1236
1237
1238 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyDataPageOSMemHandle,
1239 psDevInfo->pvDummyDataPageCpuVAddr);
1240 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1241
1242
1243 OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
1244 SGX_MMU_PAGE_SIZE,
1245 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1246 psDevInfo->hDummyDataPageOSMemHandle);
1247
1248 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1249 }
1250#endif
1251 }
1252
1253 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
1254
1255
1256 ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
1257 while(*ppsMMUContext)
1258 {
1259 if(*ppsMMUContext == psMMUContext)
1260 {
1261
1262 *ppsMMUContext = psMMUContext->psNext;
1263 break;
1264 }
1265
1266
1267 ppsMMUContext = &((*ppsMMUContext)->psNext);
1268 }
1269
1270
1271 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
1272
1273}
1274
1275
1276IMG_VOID
1277MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
1278{
1279 IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
1280 IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr;
1281 IMG_UINT32 ui32PDEntry;
1282#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1283 IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
1284#endif
1285
1286
1287 pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1288 pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1289
1290
1291
1292
1293#if defined(PDUMP)
1294 PDUMPCOMMENT("Page directory shared heap range copy");
1295 PDUMPCOMMENT(" (Source heap MMU Context ID == %u, PT count == 0x%x)",
1296 psMMUHeap->psMMUContext->ui32PDumpMMUContextID,
1297 psMMUHeap->ui32PageTableCount);
1298 PDUMPCOMMENT(" (Destination MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
1299#endif
1300#ifdef SUPPORT_SGX_MMU_BYPASS
1301 EnableHostAccess(psMMUContext);
1302#endif
1303
1304 for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
1305 {
1306#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1307
1308 PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
1309#endif
1310
1311
1312 pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
1313 if (pui32PDCpuVAddr[ui32PDEntry])
1314 {
1315 PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1316
1317#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1318 bInvalidateDirectoryCache = IMG_TRUE;
1319#endif
1320 }
1321 }
1322
1323#ifdef SUPPORT_SGX_MMU_BYPASS
1324 DisableHostAccess(psMMUContext);
1325#endif
1326
1327#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1328 if (bInvalidateDirectoryCache)
1329 {
1330
1331
1332
1333
1334 MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
1335 }
1336#endif
1337}
1338
1339
1340static IMG_VOID
1341MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
1342 IMG_DEV_VIRTADDR sDevVAddr,
1343 IMG_UINT32 ui32PageCount,
1344 IMG_HANDLE hUniqueTag)
1345{
1346 IMG_DEV_VIRTADDR sTmpDevVAddr;
1347 IMG_UINT32 i;
1348 IMG_UINT32 ui32PDIndex;
1349 IMG_UINT32 ui32PTIndex;
1350 IMG_UINT32 *pui32Tmp;
1351 IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
1352
1353#if !defined (PDUMP)
1354 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1355#endif
1356
1357 sTmpDevVAddr = sDevVAddr;
1358
1359 for(i=0; i<ui32PageCount; i++)
1360 {
1361 MMU_PT_INFO **ppsPTInfoList;
1362
1363
1364 ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1365
1366
1367 ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
1368
1369 {
1370
1371 ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
1372
1373
1374 if (!ppsPTInfoList[0])
1375 {
1376 PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
1377
1378
1379 sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
1380
1381
1382 continue;
1383 }
1384
1385
1386 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
1387
1388
1389 if (!pui32Tmp)
1390 {
1391 continue;
1392 }
1393
1394 CheckPT(ppsPTInfoList[0]);
1395
1396
1397 if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
1398 {
1399 ppsPTInfoList[0]->ui32ValidPTECount--;
1400 }
1401 else
1402 {
1403 PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
1404 }
1405
1406
1407 PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
1408
1409#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1410
1411 pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1412 | SGX_MMU_PTE_VALID;
1413#else
1414
1415 pui32Tmp[ui32PTIndex] = 0;
1416#endif
1417
1418 CheckPT(ppsPTInfoList[0]);
1419 }
1420
1421
1422
1423 if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0)
1424 {
1425 _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
1426 bInvalidateDirectoryCache = IMG_TRUE;
1427 }
1428
1429
1430 sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
1431 }
1432
1433 if(bInvalidateDirectoryCache)
1434 {
1435 MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
1436 }
1437 else
1438 {
1439 MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
1440 }
1441
1442#if defined(PDUMP)
1443 MMU_PDumpPageTables(psMMUHeap,
1444 sDevVAddr,
1445 psMMUHeap->ui32DataPageSize * ui32PageCount,
1446 IMG_TRUE,
1447 hUniqueTag);
1448#endif
1449}
1450
1451
1452static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
1453 IMG_SIZE_T ui32Start,
1454 IMG_SIZE_T ui32End,
1455 IMG_HANDLE hUniqueTag)
1456{
1457 MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
1458 IMG_DEV_VIRTADDR Start;
1459
1460 Start.uiAddr = ui32Start;
1461
1462 MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) >> pMMUHeap->ui32PTShift, hUniqueTag);
1463}
1464
1465MMU_HEAP *
1466MMU_Create (MMU_CONTEXT *psMMUContext,
1467 DEV_ARENA_DESCRIPTOR *psDevArena,
1468 RA_ARENA **ppsVMArena,
1469 PDUMP_MMU_ATTRIB **ppsMMUAttrib)
1470{
1471 MMU_HEAP *pMMUHeap;
1472 IMG_UINT32 ui32ScaleSize;
1473
1474 PVR_UNREFERENCED_PARAMETER(ppsMMUAttrib);
1475
1476 PVR_ASSERT (psDevArena != IMG_NULL);
1477
1478 if (psDevArena == IMG_NULL)
1479 {
1480 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter"));
1481 return IMG_NULL;
1482 }
1483
1484 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1485 sizeof (MMU_HEAP),
1486 (IMG_VOID **)&pMMUHeap, IMG_NULL,
1487 "MMU Heap");
1488 if (pMMUHeap == IMG_NULL)
1489 {
1490 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"));
1491 return IMG_NULL;
1492 }
1493
1494 pMMUHeap->psMMUContext = psMMUContext;
1495 pMMUHeap->psDevArena = psDevArena;
1496
1497
1498
1499
1500 switch(pMMUHeap->psDevArena->ui32DataPageSize)
1501 {
1502 case 0x1000:
1503 ui32ScaleSize = 0;
1504 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
1505 break;
1506#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
1507 case 0x4000:
1508 ui32ScaleSize = 2;
1509 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
1510 break;
1511 case 0x10000:
1512 ui32ScaleSize = 4;
1513 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
1514 break;
1515 case 0x40000:
1516 ui32ScaleSize = 6;
1517 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
1518 break;
1519 case 0x100000:
1520 ui32ScaleSize = 8;
1521 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
1522 break;
1523 case 0x400000:
1524 ui32ScaleSize = 10;
1525 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
1526 break;
1527#endif
1528 default:
1529 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
1530 goto ErrorFreeHeap;
1531 }
1532
1533
1534 pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
1535 pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
1536 pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
1537
1538 pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
1539 pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
1540 pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
1541 pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
1542
1543 if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
1544 {
1545 pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
1546 }
1547 pMMUHeap->ui32PTECount = pMMUHeap->ui32PTSize >> 2;
1548
1549
1550 pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
1551 pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
1552 pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
1553
1554
1555
1556
1557
1558 if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
1559 {
1560
1561
1562
1563 PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
1564 & (pMMUHeap->ui32DataPageMask
1565 | pMMUHeap->ui32PTMask)) == 0);
1566 }
1567
1568
1569 pMMUHeap->ui32PTETotal = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
1570
1571
1572 pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
1573
1574
1575
1576
1577 pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotal + pMMUHeap->ui32PTECount - 1)
1578 >> pMMUHeap->ui32PTBitWidth;
1579
1580
1581 pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
1582 psDevArena->BaseDevVAddr.uiAddr,
1583 psDevArena->ui32Size,
1584 IMG_NULL,
1585 MAX(HOST_PAGESIZE(), pMMUHeap->ui32DataPageSize),
1586 IMG_NULL,
1587 IMG_NULL,
1588 &MMU_FreePageTables,
1589 pMMUHeap);
1590
1591 if (pMMUHeap->psVMArena == IMG_NULL)
1592 {
1593 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
1594 goto ErrorFreePagetables;
1595 }
1596
1597#if defined(PDUMP)
1598
1599 MMU_SetPDumpAttribs(&pMMUHeap->sMMUAttrib,
1600 psMMUContext->psDeviceNode,
1601 pMMUHeap->ui32DataPageMask,
1602 pMMUHeap->ui32PTSize);
1603 *ppsMMUAttrib = &pMMUHeap->sMMUAttrib;
1604
1605 PDUMPCOMMENT("Create MMU device from arena %s (Size == 0x%x, DataPageSize == 0x%x, BaseDevVAddr == 0x%x)",
1606 psDevArena->pszName,
1607 psDevArena->ui32Size,
1608 pMMUHeap->ui32DataPageSize,
1609 psDevArena->BaseDevVAddr.uiAddr);
1610#endif
1611
1612#if 0
1613
1614 if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID)
1615 {
1616 IMG_UINT32 ui32RegVal;
1617 IMG_UINT32 ui32XTileStride;
1618
1619
1620
1621
1622
1623
1624 ui32XTileStride = 2;
1625
1626 ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK
1627 & ((psDevArena->BaseDevVAddr.uiAddr>>20)
1628 << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT))
1629 |(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK
1630 & (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20)
1631 << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT))
1632 |(EUR_CR_BIF_TILE0_CFG_MASK
1633 & (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT));
1634 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_TILE0, ui32RegVal);
1635 }
1636#endif
1637
1638
1639
1640 *ppsVMArena = pMMUHeap->psVMArena;
1641
1642 return pMMUHeap;
1643
1644
1645ErrorFreePagetables:
1646 _DeferredFreePageTables (pMMUHeap);
1647
1648ErrorFreeHeap:
1649 OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
1650
1651
1652 return IMG_NULL;
1653}
1654
1655IMG_VOID
1656MMU_Delete (MMU_HEAP *pMMUHeap)
1657{
1658 if (pMMUHeap != IMG_NULL)
1659 {
1660 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete"));
1661
1662 if(pMMUHeap->psVMArena)
1663 {
1664 RA_Delete (pMMUHeap->psVMArena);
1665 }
1666
1667#if defined(PDUMP)
1668 PDUMPCOMMENT("Delete MMU device from arena %s (BaseDevVAddr == 0x%x, PT count for deferred free == 0x%x)",
1669 pMMUHeap->psDevArena->pszName,
1670 pMMUHeap->psDevArena->BaseDevVAddr.uiAddr,
1671 pMMUHeap->ui32PageTableCount);
1672#endif
1673
1674#ifdef SUPPORT_SGX_MMU_BYPASS
1675 EnableHostAccess(pMMUHeap->psMMUContext);
1676#endif
1677 _DeferredFreePageTables (pMMUHeap);
1678#ifdef SUPPORT_SGX_MMU_BYPASS
1679 DisableHostAccess(pMMUHeap->psMMUContext);
1680#endif
1681
1682 OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
1683
1684 }
1685}
1686
1687IMG_BOOL
1688MMU_Alloc (MMU_HEAP *pMMUHeap,
1689 IMG_SIZE_T uSize,
1690 IMG_SIZE_T *pActualSize,
1691 IMG_UINT32 uFlags,
1692 IMG_UINT32 uDevVAddrAlignment,
1693 IMG_DEV_VIRTADDR *psDevVAddr)
1694{
1695 IMG_BOOL bStatus;
1696
1697 PVR_DPF ((PVR_DBG_MESSAGE,
1698 "MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x",
1699 uSize, uFlags, uDevVAddrAlignment));
1700
1701
1702
1703 if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
1704 {
1705 IMG_UINTPTR_T uiAddr;
1706
1707 bStatus = RA_Alloc (pMMUHeap->psVMArena,
1708 uSize,
1709 pActualSize,
1710 IMG_NULL,
1711 0,
1712 uDevVAddrAlignment,
1713 0,
1714 &uiAddr);
1715 if(!bStatus)
1716 {
1717 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
1718 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Alloc of DevVAddr failed from heap %s ID%d",
1719 pMMUHeap->psDevArena->pszName,
1720 pMMUHeap->psDevArena->ui32HeapID));
1721 return bStatus;
1722 }
1723
1724 psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
1725 }
1726
1727 #ifdef SUPPORT_SGX_MMU_BYPASS
1728 EnableHostAccess(pMMUHeap->psMMUContext);
1729 #endif
1730
1731
1732 bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize);
1733
1734 #ifdef SUPPORT_SGX_MMU_BYPASS
1735 DisableHostAccess(pMMUHeap->psMMUContext);
1736 #endif
1737
1738 if (!bStatus)
1739 {
1740 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
1741 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to alloc pagetable(s) for DevVAddr 0x%8.8x from heap %s ID%d",
1742 psDevVAddr->uiAddr,
1743 pMMUHeap->psDevArena->pszName,
1744 pMMUHeap->psDevArena->ui32HeapID));
1745 if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
1746 {
1747
1748 RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
1749 }
1750 }
1751
1752 return bStatus;
1753}
1754
1755IMG_VOID
1756MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
1757{
1758 PVR_ASSERT (pMMUHeap != IMG_NULL);
1759
1760 if (pMMUHeap == IMG_NULL)
1761 {
1762 PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
1763 return;
1764 }
1765
1766 PVR_DPF((PVR_DBG_MESSAGE, "MMU_Free: Freeing DevVAddr 0x%08X from heap %s ID%d",
1767 DevVAddr.uiAddr,
1768 pMMUHeap->psDevArena->pszName,
1769 pMMUHeap->psDevArena->ui32HeapID));
1770
1771 if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) &&
1772 (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size))
1773 {
1774 RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE);
1775 return;
1776 }
1777
1778 PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't free DevVAddr %08X from heap %s ID%d (not in range of heap))",
1779 DevVAddr.uiAddr,
1780 pMMUHeap->psDevArena->pszName,
1781 pMMUHeap->psDevArena->ui32HeapID));
1782}
1783
1784IMG_VOID
1785MMU_Enable (MMU_HEAP *pMMUHeap)
1786{
1787 PVR_UNREFERENCED_PARAMETER(pMMUHeap);
1788
1789}
1790
1791IMG_VOID
1792MMU_Disable (MMU_HEAP *pMMUHeap)
1793{
1794 PVR_UNREFERENCED_PARAMETER(pMMUHeap);
1795
1796}
1797
1798#if defined(PDUMP)
1799static IMG_VOID
1800MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
1801 IMG_DEV_VIRTADDR DevVAddr,
1802 IMG_SIZE_T uSize,
1803 IMG_BOOL bForUnmap,
1804 IMG_HANDLE hUniqueTag)
1805{
1806 IMG_UINT32 ui32NumPTEntries;
1807 IMG_UINT32 ui32PTIndex;
1808 IMG_UINT32 *pui32PTEntry;
1809
1810 MMU_PT_INFO **ppsPTInfoList;
1811 IMG_UINT32 ui32PDIndex;
1812 IMG_UINT32 ui32PTDumpCount;
1813
1814
1815 ui32NumPTEntries = (uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift;
1816
1817
1818 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
1819
1820
1821 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
1822
1823
1824 ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
1825
1826
1827 PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
1828
1829
1830 while(ui32NumPTEntries > 0)
1831 {
1832 MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
1833
1834 if(ui32NumPTEntries <= pMMUHeap->ui32PTECount - ui32PTIndex)
1835 {
1836 ui32PTDumpCount = ui32NumPTEntries;
1837 }
1838 else
1839 {
1840 ui32PTDumpCount = pMMUHeap->ui32PTECount - ui32PTIndex;
1841 }
1842
1843 if (psPTInfo)
1844 {
1845 pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
1846 PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
1847 }
1848
1849
1850 ui32NumPTEntries -= ui32PTDumpCount;
1851
1852
1853 ui32PTIndex = 0;
1854 }
1855
1856 PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
1857}
1858#endif
1859
1860
1861static IMG_VOID
1862MMU_MapPage (MMU_HEAP *pMMUHeap,
1863 IMG_DEV_VIRTADDR DevVAddr,
1864 IMG_DEV_PHYADDR DevPAddr,
1865 IMG_UINT32 ui32MemFlags)
1866{
1867 IMG_UINT32 ui32Index;
1868 IMG_UINT32 *pui32Tmp;
1869 IMG_UINT32 ui32MMUFlags = 0;
1870 MMU_PT_INFO **ppsPTInfoList;
1871
1872
1873 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1874
1875
1876
1877 if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
1878 {
1879
1880 ui32MMUFlags = 0;
1881 }
1882 else if(PVRSRV_MEM_READ & ui32MemFlags)
1883 {
1884
1885 ui32MMUFlags |= SGX_MMU_PTE_READONLY;
1886 }
1887 else if(PVRSRV_MEM_WRITE & ui32MemFlags)
1888 {
1889
1890 ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
1891 }
1892
1893
1894 if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
1895 {
1896 ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
1897 }
1898
1899#if !defined(FIX_HW_BRN_25503)
1900
1901 if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
1902 {
1903 ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
1904 }
1905#endif
1906
1907
1908
1909
1910
1911 ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
1912
1913
1914 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
1915
1916 CheckPT(ppsPTInfoList[0]);
1917
1918
1919 ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
1920
1921
1922 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
1923
1924#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1925 {
1926 IMG_UINT32 uTmp = pui32Tmp[ui32Index];
1927
1928
1929 if (uTmp & SGX_MMU_PTE_VALID)
1930 {
1931 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u",
1932 DevVAddr.uiAddr,
1933 DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
1934 ui32Index ));
1935 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
1936 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
1937 }
1938
1939 PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
1940 }
1941#endif
1942
1943
1944 ppsPTInfoList[0]->ui32ValidPTECount++;
1945
1946
1947 pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1948 & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
1949 | SGX_MMU_PTE_VALID
1950 | ui32MMUFlags;
1951
1952 CheckPT(ppsPTInfoList[0]);
1953}
1954
1955
1956IMG_VOID
1957MMU_MapScatter (MMU_HEAP *pMMUHeap,
1958 IMG_DEV_VIRTADDR DevVAddr,
1959 IMG_SYS_PHYADDR *psSysAddr,
1960 IMG_SIZE_T uSize,
1961 IMG_UINT32 ui32MemFlags,
1962 IMG_HANDLE hUniqueTag)
1963{
1964#if defined(PDUMP)
1965 IMG_DEV_VIRTADDR MapBaseDevVAddr;
1966#endif
1967 IMG_UINT32 uCount, i;
1968 IMG_DEV_PHYADDR DevPAddr;
1969
1970 PVR_ASSERT (pMMUHeap != IMG_NULL);
1971
1972#if defined(PDUMP)
1973 MapBaseDevVAddr = DevVAddr;
1974#else
1975 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1976#endif
1977
1978 for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
1979 {
1980 IMG_SYS_PHYADDR sSysAddr;
1981
1982 sSysAddr = psSysAddr[i];
1983
1984
1985
1986 PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1987
1988 DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
1989
1990 MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
1991 DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
1992
1993 PVR_DPF ((PVR_DBG_MESSAGE,
1994 "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
1995 DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
1996 }
1997
1998#if defined(PDUMP)
1999 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
2000#endif
2001}
2002
2003IMG_VOID
2004MMU_MapPages (MMU_HEAP *pMMUHeap,
2005 IMG_DEV_VIRTADDR DevVAddr,
2006 IMG_SYS_PHYADDR SysPAddr,
2007 IMG_SIZE_T uSize,
2008 IMG_UINT32 ui32MemFlags,
2009 IMG_HANDLE hUniqueTag)
2010{
2011 IMG_DEV_PHYADDR DevPAddr;
2012#if defined(PDUMP)
2013 IMG_DEV_VIRTADDR MapBaseDevVAddr;
2014#endif
2015 IMG_UINT32 uCount;
2016 IMG_UINT32 ui32VAdvance;
2017 IMG_UINT32 ui32PAdvance;
2018
2019 PVR_ASSERT (pMMUHeap != IMG_NULL);
2020
2021 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPages: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=%08X, size=0x%x",
2022 pMMUHeap->psDevArena->pszName,
2023 pMMUHeap->psDevArena->ui32HeapID,
2024 DevVAddr.uiAddr,
2025 SysPAddr.uiAddr,
2026 uSize));
2027
2028
2029 ui32VAdvance = pMMUHeap->ui32DataPageSize;
2030 ui32PAdvance = pMMUHeap->ui32DataPageSize;
2031
2032#if defined(PDUMP)
2033 MapBaseDevVAddr = DevVAddr;
2034#else
2035 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
2036#endif
2037
2038 DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
2039
2040
2041 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
2042
2043#if defined(FIX_HW_BRN_23281)
2044 if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
2045 {
2046 ui32VAdvance *= 2;
2047 }
2048#endif
2049
2050
2051
2052
2053 if(ui32MemFlags & PVRSRV_MEM_DUMMY)
2054 {
2055 ui32PAdvance = 0;
2056 }
2057
2058 for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
2059 {
2060 MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
2061 DevVAddr.uiAddr += ui32VAdvance;
2062 DevPAddr.uiAddr += ui32PAdvance;
2063 }
2064
2065#if defined(PDUMP)
2066 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
2067#endif
2068}
2069
2070IMG_VOID
2071MMU_MapShadow (MMU_HEAP *pMMUHeap,
2072 IMG_DEV_VIRTADDR MapBaseDevVAddr,
2073 IMG_SIZE_T uByteSize,
2074 IMG_CPU_VIRTADDR CpuVAddr,
2075 IMG_HANDLE hOSMemHandle,
2076 IMG_DEV_VIRTADDR *pDevVAddr,
2077 IMG_UINT32 ui32MemFlags,
2078 IMG_HANDLE hUniqueTag)
2079{
2080 IMG_UINT32 i;
2081 IMG_UINT32 uOffset = 0;
2082 IMG_DEV_VIRTADDR MapDevVAddr;
2083 IMG_UINT32 ui32VAdvance;
2084 IMG_UINT32 ui32PAdvance;
2085
2086#if !defined (PDUMP)
2087 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
2088#endif
2089
2090 PVR_DPF ((PVR_DBG_MESSAGE,
2091 "MMU_MapShadow: DevVAddr:%08X, Bytes:0x%x, CPUVAddr:%08X",
2092 MapBaseDevVAddr.uiAddr,
2093 uByteSize,
2094 (IMG_UINTPTR_T)CpuVAddr));
2095
2096
2097 ui32VAdvance = pMMUHeap->ui32DataPageSize;
2098 ui32PAdvance = pMMUHeap->ui32DataPageSize;
2099
2100
2101 PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
2102 PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
2103 pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
2104
2105#if defined(FIX_HW_BRN_23281)
2106 if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
2107 {
2108 ui32VAdvance *= 2;
2109 }
2110#endif
2111
2112
2113
2114
2115 if(ui32MemFlags & PVRSRV_MEM_DUMMY)
2116 {
2117 ui32PAdvance = 0;
2118 }
2119
2120
2121 MapDevVAddr = MapBaseDevVAddr;
2122 for (i=0; i<uByteSize; i+=ui32VAdvance)
2123 {
2124 IMG_CPU_PHYADDR CpuPAddr;
2125 IMG_DEV_PHYADDR DevPAddr;
2126
2127 if(CpuVAddr)
2128 {
2129 CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle,
2130 (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset));
2131 }
2132 else
2133 {
2134 CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
2135 }
2136 DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
2137
2138
2139 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
2140
2141 PVR_DPF ((PVR_DBG_MESSAGE,
2142 "Offset=0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
2143 uOffset,
2144 (IMG_UINTPTR_T)CpuVAddr + uOffset,
2145 CpuPAddr.uiAddr,
2146 MapDevVAddr.uiAddr,
2147 DevPAddr.uiAddr));
2148
2149 MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
2150
2151
2152 MapDevVAddr.uiAddr += ui32VAdvance;
2153 uOffset += ui32PAdvance;
2154 }
2155
2156#if defined(PDUMP)
2157 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
2158#endif
2159}
2160
2161
2162IMG_VOID
2163MMU_UnmapPages (MMU_HEAP *psMMUHeap,
2164 IMG_DEV_VIRTADDR sDevVAddr,
2165 IMG_UINT32 ui32PageCount,
2166 IMG_HANDLE hUniqueTag)
2167{
2168 IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize;
2169 IMG_DEV_VIRTADDR sTmpDevVAddr;
2170 IMG_UINT32 i;
2171 IMG_UINT32 ui32PDIndex;
2172 IMG_UINT32 ui32PTIndex;
2173 IMG_UINT32 *pui32Tmp;
2174
2175#if !defined (PDUMP)
2176 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
2177#endif
2178
2179
2180 sTmpDevVAddr = sDevVAddr;
2181
2182 for(i=0; i<ui32PageCount; i++)
2183 {
2184 MMU_PT_INFO **ppsPTInfoList;
2185
2186
2187 ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
2188
2189
2190 ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
2191
2192
2193 ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
2194
2195
2196 if (!ppsPTInfoList[0])
2197 {
2198 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
2199 sTmpDevVAddr.uiAddr,
2200 sDevVAddr.uiAddr,
2201 i,
2202 ui32PDIndex,
2203 ui32PTIndex));
2204
2205
2206 sTmpDevVAddr.uiAddr += uPageSize;
2207
2208
2209 continue;
2210 }
2211
2212 CheckPT(ppsPTInfoList[0]);
2213
2214
2215 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
2216
2217
2218 if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
2219 {
2220 ppsPTInfoList[0]->ui32ValidPTECount--;
2221 }
2222 else
2223 {
2224 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
2225 sTmpDevVAddr.uiAddr,
2226 sDevVAddr.uiAddr,
2227 i,
2228 ui32PDIndex,
2229 ui32PTIndex));
2230 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08X", pui32Tmp[ui32PTIndex]));
2231 }
2232
2233
2234 PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
2235
2236#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
2237
2238 pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2239 | SGX_MMU_PTE_VALID;
2240#else
2241
2242 pui32Tmp[ui32PTIndex] = 0;
2243#endif
2244
2245 CheckPT(ppsPTInfoList[0]);
2246
2247
2248 sTmpDevVAddr.uiAddr += uPageSize;
2249 }
2250
2251 MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
2252
2253#if defined(PDUMP)
2254 MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
2255#endif
2256}
2257
2258
2259IMG_DEV_PHYADDR
2260MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr)
2261{
2262 IMG_UINT32 *pui32PageTable;
2263 IMG_UINT32 ui32Index;
2264 IMG_DEV_PHYADDR sDevPAddr;
2265 MMU_PT_INFO **ppsPTInfoList;
2266
2267
2268 ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
2269
2270
2271 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
2272 if (!ppsPTInfoList[0])
2273 {
2274 PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
2275 sDevPAddr.uiAddr = 0;
2276 return sDevPAddr;
2277 }
2278
2279
2280 ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
2281
2282
2283 pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
2284
2285
2286 sDevPAddr.uiAddr = pui32PageTable[ui32Index];
2287
2288
2289 sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
2290
2291
2292 sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
2293
2294 return sDevPAddr;
2295}
2296
2297
2298IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
2299{
2300 return (pMMUContext->sPDDevPAddr);
2301}
2302
2303
2304IMG_EXPORT
2305PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap,
2306 IMG_DEV_VIRTADDR sDevVAddr,
2307 IMG_DEV_PHYADDR *pDevPAddr,
2308 IMG_CPU_PHYADDR *pCpuPAddr)
2309{
2310 MMU_HEAP *pMMUHeap;
2311 IMG_DEV_PHYADDR DevPAddr;
2312
2313
2314
2315 pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
2316
2317 DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
2318 pCpuPAddr->uiAddr = DevPAddr.uiAddr;
2319 pDevPAddr->uiAddr = DevPAddr.uiAddr;
2320
2321 return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
2322}
2323
2324
2325PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
2326 IMG_HANDLE hDevMemContext,
2327 IMG_DEV_PHYADDR *psPDDevPAddr)
2328{
2329 if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
2330 {
2331 return PVRSRV_ERROR_INVALID_PARAMS;
2332 }
2333
2334
2335 *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
2336
2337 return PVRSRV_OK;
2338}
2339
2340PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo)
2341{
2342 PVRSRV_ERROR eError;
2343 SYS_DATA *psSysData;
2344 RA_ARENA *psLocalDevMemArena;
2345 IMG_HANDLE hOSMemHandle = IMG_NULL;
2346 IMG_BYTE *pui8MemBlock = IMG_NULL;
2347 IMG_SYS_PHYADDR sMemBlockSysPAddr;
2348 IMG_CPU_PHYADDR sMemBlockCpuPAddr;
2349
2350 SysAcquireData(&psSysData);
2351
2352 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2353
2354
2355 if(psLocalDevMemArena == IMG_NULL)
2356 {
2357
2358 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2359 3 * SGX_MMU_PAGE_SIZE,
2360 SGX_MMU_PAGE_SIZE,
2361 (IMG_VOID **)&pui8MemBlock,
2362 &hOSMemHandle);
2363 if (eError != PVRSRV_OK)
2364 {
2365 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
2366 return eError;
2367 }
2368
2369
2370 if(pui8MemBlock)
2371 {
2372 sMemBlockCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle,
2373 pui8MemBlock);
2374 }
2375 else
2376 {
2377
2378 sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
2379 }
2380 }
2381 else
2382 {
2383
2384
2385 if(RA_Alloc(psLocalDevMemArena,
2386 3 * SGX_MMU_PAGE_SIZE,
2387 IMG_NULL,
2388 IMG_NULL,
2389 0,
2390 SGX_MMU_PAGE_SIZE,
2391 0,
2392 &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
2393 {
2394 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
2395 return PVRSRV_ERROR_OUT_OF_MEMORY;
2396 }
2397
2398
2399 sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr);
2400 pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr,
2401 SGX_MMU_PAGE_SIZE * 3,
2402 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2403 &hOSMemHandle);
2404 if(!pui8MemBlock)
2405 {
2406 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables"));
2407 return PVRSRV_ERROR_BAD_MAPPING;
2408 }
2409 }
2410
2411 psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle;
2412 psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr);
2413 psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
2414 psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
2415
2416
2417 psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
2418 psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
2419
2420
2421 OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
2422 OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
2423
2424 OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
2425
2426 return PVRSRV_OK;
2427}
2428
2429IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
2430{
2431 SYS_DATA *psSysData;
2432 RA_ARENA *psLocalDevMemArena;
2433 IMG_SYS_PHYADDR sPDSysPAddr;
2434
2435 SysAcquireData(&psSysData);
2436
2437 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2438
2439
2440 if(psLocalDevMemArena == IMG_NULL)
2441 {
2442 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2443 3 * SGX_MMU_PAGE_SIZE,
2444 psDevInfo->pui32BIFResetPD,
2445 psDevInfo->hBIFResetPDOSMemHandle);
2446 }
2447 else
2448 {
2449 OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD,
2450 3 * SGX_MMU_PAGE_SIZE,
2451 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2452 psDevInfo->hBIFResetPDOSMemHandle);
2453
2454 sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr);
2455 RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE);
2456 }
2457}
2458
2459
2460#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
2461PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode)
2462{
2463 PVRSRV_ERROR eError;
2464 SYS_DATA *psSysData;
2465 RA_ARENA *psLocalDevMemArena;
2466 IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
2467 IMG_HANDLE hPDPageOSMemHandle = IMG_NULL;
2468 IMG_UINT32 *pui32PD = IMG_NULL;
2469 IMG_UINT32 *pui32PT = IMG_NULL;
2470 IMG_CPU_PHYADDR sCpuPAddr;
2471 IMG_DEV_PHYADDR sPTDevPAddr;
2472 IMG_DEV_PHYADDR sPDDevPAddr;
2473 PVRSRV_SGXDEV_INFO *psDevInfo;
2474 IMG_UINT32 ui32PDOffset;
2475 IMG_UINT32 ui32PTOffset;
2476
2477 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
2478
2479 SysAcquireData(&psSysData);
2480
2481 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2482
2483
2484 if(psLocalDevMemArena == IMG_NULL)
2485 {
2486
2487 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2488 SGX_MMU_PAGE_SIZE,
2489 SGX_MMU_PAGE_SIZE,
2490 (IMG_VOID **)&pui32PT,
2491 &hPTPageOSMemHandle);
2492 if (eError != PVRSRV_OK)
2493 {
2494 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
2495 return eError;
2496 }
2497 ui32PTOffset = 0;
2498
2499 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2500 SGX_MMU_PAGE_SIZE,
2501 SGX_MMU_PAGE_SIZE,
2502 (IMG_VOID **)&pui32PD,
2503 &hPDPageOSMemHandle);
2504 if (eError != PVRSRV_OK)
2505 {
2506 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
2507 return eError;
2508 }
2509 ui32PDOffset = 0;
2510
2511
2512 if(pui32PT)
2513 {
2514 sCpuPAddr = OSMapLinToCPUPhys(hPTPageOSMemHandle,
2515 pui32PT);
2516 }
2517 else
2518 {
2519
2520 sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
2521 }
2522 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2523
2524 if(pui32PD)
2525 {
2526 sCpuPAddr = OSMapLinToCPUPhys(hPDPageOSMemHandle,
2527 pui32PD);
2528 }
2529 else
2530 {
2531
2532 sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0);
2533 }
2534 sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2535
2536 }
2537 else
2538 {
2539
2540
2541 if(RA_Alloc(psLocalDevMemArena,
2542 SGX_MMU_PAGE_SIZE * 2,
2543 IMG_NULL,
2544 IMG_NULL,
2545 0,
2546 SGX_MMU_PAGE_SIZE,
2547 0,
2548 &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE)
2549 {
2550 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed"));
2551 return PVRSRV_ERROR_OUT_OF_MEMORY;
2552 }
2553
2554
2555 sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr);
2556 pui32PT = OSMapPhysToLin(sCpuPAddr,
2557 SGX_MMU_PAGE_SIZE * 2,
2558 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2559 &hPTPageOSMemHandle);
2560 if(!pui32PT)
2561 {
2562 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables"));
2563 return PVRSRV_ERROR_BAD_MAPPING;
2564 }
2565 ui32PTOffset = 0;
2566
2567
2568 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2569
2570 pui32PD = pui32PT + SGX_MMU_PAGE_SIZE/sizeof(IMG_UINT32);
2571 ui32PDOffset = SGX_MMU_PAGE_SIZE;
2572 hPDPageOSMemHandle = hPTPageOSMemHandle;
2573 sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
2574 }
2575
2576 OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE);
2577 OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
2578
2579
2580 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDPageOSMemHandle, ui32PDOffset, pui32PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
2581 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPTPageOSMemHandle, ui32PTOffset, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2582 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2583 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2584
2585 psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle;
2586 psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle;
2587 psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr;
2588 psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr;
2589 psDevInfo->pui32BRN22997PD = pui32PD;
2590 psDevInfo->pui32BRN22997PT = pui32PT;
2591
2592 return PVRSRV_OK;
2593}
2594
2595
2596IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo)
2597{
2598 IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD;
2599 IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT;
2600 IMG_UINT32 ui32PDIndex;
2601 IMG_UINT32 ui32PTIndex;
2602 IMG_DEV_VIRTADDR sDevVAddr;
2603 volatile IMG_UINT32 *pui32HostPort;
2604 IMG_UINT32 ui32BIFCtrl;
2605
2606
2607
2608
2609 pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET);
2610
2611
2612 sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET;
2613
2614 ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2615 ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
2616
2617
2618 pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
2619 | SGX_MMU_PDE_VALID;
2620
2621 pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2622 | SGX_MMU_PTE_VALID;
2623
2624 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2625 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2626
2627
2628 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
2629 psDevInfo->sBRN22997PDDevPAddr.uiAddr);
2630 PDUMPPDREG(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG);
2631
2632
2633 ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
2634 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2635 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2636 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2637 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2638
2639
2640 if (pui32HostPort)
2641 {
2642
2643 IMG_UINT32 ui32Tmp;
2644 ui32Tmp = *pui32HostPort;
2645 }
2646 else
2647 {
2648 PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround"));
2649 }
2650
2651
2652
2653
2654
2655
2656
2657 PDUMPCOMMENT("RDW :SGXMEM:v4:%08X\r\n", sDevVAddr.uiAddr);
2658
2659 PDUMPCOMMENT("SAB :SGXMEM:v4:%08X 4 0 hostport.bin", sDevVAddr.uiAddr);
2660
2661
2662 pui32PD[ui32PDIndex] = 0;
2663 pui32PT[ui32PTIndex] = 0;
2664
2665
2666 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2667 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDevInfo->hBRN22997PTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2668
2669 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2670 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2671 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2672 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2673}
2674
2675
2676IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode)
2677{
2678 SYS_DATA *psSysData;
2679 RA_ARENA *psLocalDevMemArena;
2680 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2681
2682
2683 SysAcquireData(&psSysData);
2684
2685 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2686
2687 PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PDPageOSMemHandle, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
2688 PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN22997PTPageOSMemHandle, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2689
2690
2691 if(psLocalDevMemArena == IMG_NULL)
2692 {
2693 if (psDevInfo->pui32BRN22997PD != IMG_NULL)
2694 {
2695 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2696 SGX_MMU_PAGE_SIZE,
2697 psDevInfo->pui32BRN22997PD,
2698 psDevInfo->hBRN22997PDPageOSMemHandle);
2699 }
2700
2701 if (psDevInfo->pui32BRN22997PT != IMG_NULL)
2702 {
2703 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2704 SGX_MMU_PAGE_SIZE,
2705 psDevInfo->pui32BRN22997PT,
2706 psDevInfo->hBRN22997PTPageOSMemHandle);
2707 }
2708 }
2709 else
2710 {
2711 if (psDevInfo->pui32BRN22997PT != IMG_NULL)
2712 {
2713 OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT,
2714 SGX_MMU_PAGE_SIZE * 2,
2715 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2716 psDevInfo->hBRN22997PTPageOSMemHandle);
2717
2718
2719 RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE);
2720 }
2721 }
2722}
2723#endif
2724
2725
2726#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
2727PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
2728{
2729 PVRSRV_ERROR eError;
2730 SYS_DATA *psSysData;
2731 RA_ARENA *psLocalDevMemArena;
2732 IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
2733 IMG_UINT32 *pui32PD;
2734 IMG_UINT32 *pui32PT = IMG_NULL;
2735 IMG_CPU_PHYADDR sCpuPAddr;
2736 IMG_DEV_PHYADDR sPTDevPAddr;
2737 PVRSRV_SGXDEV_INFO *psDevInfo;
2738 IMG_UINT32 ui32PDIndex;
2739 IMG_UINT32 ui32PTIndex;
2740
2741 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2742 pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
2743
2744 SysAcquireData(&psSysData);
2745
2746 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2747
2748
2749 if(psLocalDevMemArena == IMG_NULL)
2750 {
2751
2752 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2753 SGX_MMU_PAGE_SIZE,
2754 SGX_MMU_PAGE_SIZE,
2755 (IMG_VOID **)&pui32PT,
2756 &hPTPageOSMemHandle);
2757 if (eError != PVRSRV_OK)
2758 {
2759 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to OSAllocPages failed"));
2760 return eError;
2761 }
2762
2763
2764 if(pui32PT)
2765 {
2766 sCpuPAddr = OSMapLinToCPUPhys(hPTPageOSMemHandle,
2767 pui32PT);
2768 }
2769 else
2770 {
2771
2772 sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
2773 }
2774 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2775 }
2776 else
2777 {
2778 IMG_SYS_PHYADDR sSysPAddr;
2779
2780
2781 if(RA_Alloc(psLocalDevMemArena,
2782 SGX_MMU_PAGE_SIZE,
2783 IMG_NULL,
2784 IMG_NULL,
2785 0,
2786 SGX_MMU_PAGE_SIZE,
2787 0,
2788 &(sSysPAddr.uiAddr))!= IMG_TRUE)
2789 {
2790 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to RA_Alloc failed"));
2791 return PVRSRV_ERROR_OUT_OF_MEMORY;
2792 }
2793
2794
2795 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
2796 pui32PT = OSMapPhysToLin(sCpuPAddr,
2797 SGX_MMU_PAGE_SIZE,
2798 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2799 &hPTPageOSMemHandle);
2800 if(!pui32PT)
2801 {
2802 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR failed to map page tables"));
2803 return PVRSRV_ERROR_BAD_MAPPING;
2804 }
2805
2806
2807 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2808
2809
2810 psDevInfo->sExtSystemCacheRegsPTSysPAddr = sSysPAddr;
2811 }
2812
2813 OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
2814
2815 ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2816 ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
2817
2818
2819 pui32PD[ui32PDIndex] = (sPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
2820 | SGX_MMU_PDE_VALID;
2821
2822 pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2823 | SGX_MMU_PTE_VALID;
2824
2825
2826 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevID, hPTPageOSMemHandle, 0, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2827 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, hPDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2828 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2829
2830
2831 psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT;
2832 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle = hPTPageOSMemHandle;
2833
2834 return PVRSRV_OK;
2835}
2836
2837
2838PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
2839{
2840 SYS_DATA *psSysData;
2841 RA_ARENA *psLocalDevMemArena;
2842 PVRSRV_SGXDEV_INFO *psDevInfo;
2843 IMG_UINT32 ui32PDIndex;
2844 IMG_UINT32 *pui32PD;
2845
2846 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2847 pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
2848
2849 SysAcquireData(&psSysData);
2850
2851 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2852
2853
2854 ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2855 pui32PD[ui32PDIndex] = 0;
2856
2857 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2858 PDUMPFREEPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle, psDevInfo->pui32ExtSystemCacheRegsPT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2859
2860
2861 if(psLocalDevMemArena == IMG_NULL)
2862 {
2863 if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
2864 {
2865 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2866 SGX_MMU_PAGE_SIZE,
2867 psDevInfo->pui32ExtSystemCacheRegsPT,
2868 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
2869 }
2870 }
2871 else
2872 {
2873 if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
2874 {
2875 OSUnMapPhysToLin(psDevInfo->pui32ExtSystemCacheRegsPT,
2876 SGX_MMU_PAGE_SIZE,
2877 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2878 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
2879
2880 RA_Free(psLocalDevMemArena, psDevInfo->sExtSystemCacheRegsPTSysPAddr.uiAddr, IMG_FALSE);
2881 }
2882 }
2883
2884 return PVRSRV_OK;
2885}
2886#endif
2887
2888
2889#if PAGE_TEST
2890static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr)
2891{
2892 volatile IMG_UINT32 ui32WriteData;
2893 volatile IMG_UINT32 ui32ReadData;
2894 volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem;
2895 IMG_INT n;
2896 IMG_BOOL bOK=IMG_TRUE;
2897
2898 ui32WriteData = 0xffffffff;
2899
2900 for (n=0; n<1024; n++)
2901 {
2902 pMem32[n] = ui32WriteData;
2903 ui32ReadData = pMem32[n];
2904
2905 if (ui32WriteData != ui32ReadData)
2906 {
2907
2908 PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
2909 PVR_DBG_BREAK;
2910 bOK = IMG_FALSE;
2911 }
2912 }
2913
2914 ui32WriteData = 0;
2915
2916 for (n=0; n<1024; n++)
2917 {
2918 pMem32[n] = ui32WriteData;
2919 ui32ReadData = pMem32[n];
2920
2921 if (ui32WriteData != ui32ReadData)
2922 {
2923
2924 PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
2925 PVR_DBG_BREAK;
2926 bOK = IMG_FALSE;
2927 }
2928 }
2929
2930 if (bOK)
2931 {
2932 PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr));
2933 }
2934 else
2935 {
2936 PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr));
2937 }
2938}
2939#endif
2940
diff --git a/drivers/gpu/pvr/sgx/mmu.h b/drivers/gpu/pvr/sgx/mmu.h
new file mode 100644
index 00000000000..f13fcc0d2d9
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/mmu.h
@@ -0,0 +1,144 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _MMU_H_
28#define _MMU_H_
29
30#include "sgxinfokm.h"
31
32PVRSRV_ERROR
33MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr);
34
35IMG_VOID
36MMU_Finalise (MMU_CONTEXT *psMMUContext);
37
38
39IMG_VOID
40MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap);
41
42MMU_HEAP *
43MMU_Create (MMU_CONTEXT *psMMUContext,
44 DEV_ARENA_DESCRIPTOR *psDevArena,
45 RA_ARENA **ppsVMArena,
46 PDUMP_MMU_ATTRIB **ppsMMUAttrib);
47
48IMG_VOID
49MMU_Delete (MMU_HEAP *pMMU);
50
51IMG_BOOL
52MMU_Alloc (MMU_HEAP *pMMU,
53 IMG_SIZE_T uSize,
54 IMG_SIZE_T *pActualSize,
55 IMG_UINT32 uFlags,
56 IMG_UINT32 uDevVAddrAlignment,
57 IMG_DEV_VIRTADDR *pDevVAddr);
58
59IMG_VOID
60MMU_Free (MMU_HEAP *pMMU,
61 IMG_DEV_VIRTADDR DevVAddr,
62 IMG_UINT32 ui32Size);
63
64IMG_VOID
65MMU_Enable (MMU_HEAP *pMMU);
66
67IMG_VOID
68MMU_Disable (MMU_HEAP *pMMU);
69
70IMG_VOID
71MMU_MapPages (MMU_HEAP *pMMU,
72 IMG_DEV_VIRTADDR devVAddr,
73 IMG_SYS_PHYADDR SysPAddr,
74 IMG_SIZE_T uSize,
75 IMG_UINT32 ui32MemFlags,
76 IMG_HANDLE hUniqueTag);
77
78IMG_VOID
79MMU_MapShadow (MMU_HEAP * pMMU,
80 IMG_DEV_VIRTADDR MapBaseDevVAddr,
81 IMG_SIZE_T uSize,
82 IMG_CPU_VIRTADDR CpuVAddr,
83 IMG_HANDLE hOSMemHandle,
84 IMG_DEV_VIRTADDR * pDevVAddr,
85 IMG_UINT32 ui32MemFlags,
86 IMG_HANDLE hUniqueTag);
87
88IMG_VOID
89MMU_UnmapPages (MMU_HEAP *pMMU,
90 IMG_DEV_VIRTADDR dev_vaddr,
91 IMG_UINT32 ui32PageCount,
92 IMG_HANDLE hUniqueTag);
93
94IMG_VOID
95MMU_MapScatter (MMU_HEAP *pMMU,
96 IMG_DEV_VIRTADDR DevVAddr,
97 IMG_SYS_PHYADDR *psSysAddr,
98 IMG_SIZE_T uSize,
99 IMG_UINT32 ui32MemFlags,
100 IMG_HANDLE hUniqueTag);
101
102
103IMG_DEV_PHYADDR
104MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
105
106
107IMG_DEV_PHYADDR
108MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext);
109
110
111#ifdef SUPPORT_SGX_MMU_BYPASS
112IMG_VOID
113EnableHostAccess (MMU_CONTEXT *psMMUContext);
114
115
116IMG_VOID
117DisableHostAccess (MMU_CONTEXT *psMMUContext);
118#endif
119
120IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo);
121
122PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo);
123
124IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo);
125
126#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
127PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode);
128
129IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo);
130
131IMG_VOID WorkaroundBRN22997Free(PVRSRV_DEVICE_NODE *psDeviceNode);
132#endif
133
134#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
135PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
136
137PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
138#endif
139
140#if defined(PDUMP)
141IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext);
142#endif
143
144#endif
diff --git a/drivers/gpu/pvr/sgx/pb.c b/drivers/gpu/pvr/sgx/pb.c
new file mode 100644
index 00000000000..f9e8b19a70a
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/pb.c
@@ -0,0 +1,459 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "services_headers.h"
30#include "sgx_bridge_km.h"
31#include "sgxapi_km.h"
32#include "sgxinfo.h"
33#include "sgxinfokm.h"
34#include "pvr_bridge_km.h"
35#include "pdump_km.h"
36#include "sgxutils.h"
37
38#ifndef __linux__
39#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
40#endif
41
42#include "lists.h"
43
44static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
45static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
46
47static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
48static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
49
50static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
51static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
52
53IMG_EXPORT PVRSRV_ERROR
54SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
55 IMG_HANDLE hDevCookie,
56 IMG_BOOL bLockOnFailure,
57 IMG_UINT32 ui32TotalPBSize,
58 IMG_HANDLE *phSharedPBDesc,
59 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
60 PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
61 PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
62 PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo,
63 PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
64 IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount)
65{
66 PVRSRV_STUB_PBDESC *psStubPBDesc;
67 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
68 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
69 PVRSRV_ERROR eError;
70
71 psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
72
73 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
74 if (psStubPBDesc != IMG_NULL)
75 {
76 IMG_UINT32 i;
77 PRESMAN_ITEM psResItem;
78
79 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
80 {
81 PVR_DPF((PVR_DBG_WARNING,
82 "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
83 ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
84 }
85
86 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
87 sizeof(PVRSRV_KERNEL_MEM_INFO *)
88 * psStubPBDesc->ui32SubKernelMemInfosCount,
89 (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
90 IMG_NULL,
91 "Array of Kernel Memory Info") != PVRSRV_OK)
92 {
93 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
94
95 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
96 goto ExitNotFound;
97 }
98
99 psResItem = ResManRegisterRes(psPerProc->hResManContext,
100 RESMAN_TYPE_SHARED_PB_DESC,
101 psStubPBDesc,
102 0,
103 &SGXCleanupSharedPBDescCallback);
104
105 if (psResItem == IMG_NULL)
106 {
107 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
108 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
109 ppsSharedPBDescSubKernelMemInfos,
110 0);
111
112
113 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
114
115 eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
116 goto ExitNotFound;
117 }
118
119 *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
120 *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
121 *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
122 *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
123
124 *ui32SharedPBDescSubKernelMemInfosCount =
125 psStubPBDesc->ui32SubKernelMemInfosCount;
126
127 *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
128
129 for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
130 {
131 ppsSharedPBDescSubKernelMemInfos[i] =
132 psStubPBDesc->ppsSubKernelMemInfos[i];
133 }
134
135 psStubPBDesc->ui32RefCount++;
136 *phSharedPBDesc = (IMG_HANDLE)psResItem;
137 return PVRSRV_OK;
138 }
139
140 eError = PVRSRV_OK;
141 if (bLockOnFailure)
142 {
143 if (psResItemCreateSharedPB == IMG_NULL)
144 {
145 psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
146 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
147 psPerProc,
148 0,
149 &SGXCleanupSharedPBDescCreateLockCallback);
150
151 if (psResItemCreateSharedPB == IMG_NULL)
152 {
153 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
154
155 eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
156 goto ExitNotFound;
157 }
158 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
159 psPerProcCreateSharedPB = psPerProc;
160 }
161 else
162 {
163 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
164 }
165 }
166ExitNotFound:
167 *phSharedPBDesc = IMG_NULL;
168
169 return eError;
170}
171
172
173static PVRSRV_ERROR
174SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
175{
176
177 IMG_UINT32 i;
178 PVRSRV_DEVICE_NODE *psDeviceNode;
179
180 psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
181
182
183
184
185 psStubPBDescIn->ui32RefCount--;
186 if (psStubPBDescIn->ui32RefCount == 0)
187 {
188 List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
189 for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
190 {
191
192 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
193 psStubPBDescIn->ppsSubKernelMemInfos[i]);
194 }
195
196 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
197 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
198 psStubPBDescIn->ppsSubKernelMemInfos,
199 0);
200 psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
201
202 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
203
204 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
205
206 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
207
208 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
209
210 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
211 sizeof(PVRSRV_STUB_PBDESC),
212 psStubPBDescIn,
213 0);
214
215
216
217 SGXCleanupRequest(psDeviceNode,
218 IMG_NULL,
219 PVRSRV_CLEANUPCMD_PB);
220 }
221 return PVRSRV_OK;
222
223}
224
225static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
226{
227 PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
228
229 PVR_UNREFERENCED_PARAMETER(ui32Param);
230
231 return SGXCleanupSharedPBDescKM(psStubPBDesc);
232}
233
234static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
235{
236#ifdef DEBUG
237 PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
238 PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
239#else
240 PVR_UNREFERENCED_PARAMETER(pvParam);
241#endif
242
243 PVR_UNREFERENCED_PARAMETER(ui32Param);
244
245 psPerProcCreateSharedPB = IMG_NULL;
246 psResItemCreateSharedPB = IMG_NULL;
247
248 return PVRSRV_OK;
249}
250
251
252IMG_EXPORT PVRSRV_ERROR
253SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
254{
255 PVR_ASSERT(hSharedPBDesc != IMG_NULL);
256
257 return ResManFreeResByPtr(hSharedPBDesc);
258}
259
260
261IMG_EXPORT PVRSRV_ERROR
262SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
263 IMG_HANDLE hDevCookie,
264 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
265 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
266 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
267 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
268 IMG_UINT32 ui32TotalPBSize,
269 IMG_HANDLE *phSharedPBDesc,
270 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
271 IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount)
272{
273 PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
274 PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
275 IMG_UINT32 i;
276 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
277 PRESMAN_ITEM psResItem;
278
279
280 if (psPerProcCreateSharedPB != psPerProc)
281 {
282 goto NoAdd;
283 }
284 else
285 {
286 PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
287
288 ResManFreeResByPtr(psResItemCreateSharedPB);
289
290 PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
291 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
292 }
293
294 psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
295
296 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
297 if (psStubPBDesc != IMG_NULL)
298 {
299 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
300 {
301 PVR_DPF((PVR_DBG_WARNING,
302 "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
303 ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
304
305 }
306
307
308 psResItem = ResManRegisterRes(psPerProc->hResManContext,
309 RESMAN_TYPE_SHARED_PB_DESC,
310 psStubPBDesc,
311 0,
312 &SGXCleanupSharedPBDescCallback);
313 if (psResItem == IMG_NULL)
314 {
315 PVR_DPF((PVR_DBG_ERROR,
316 "SGXAddSharedPBDescKM: "
317 "Failed to register existing shared "
318 "PBDesc with the resource manager"));
319 goto NoAddKeepPB;
320 }
321
322
323 psStubPBDesc->ui32RefCount++;
324
325 *phSharedPBDesc = (IMG_HANDLE)psResItem;
326 eRet = PVRSRV_OK;
327 goto NoAddKeepPB;
328 }
329
330 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
331 sizeof(PVRSRV_STUB_PBDESC),
332 (IMG_VOID **)&psStubPBDesc,
333 0,
334 "Stub Parameter Buffer Description") != PVRSRV_OK)
335 {
336 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
337 "StubPBDesc"));
338 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
339 goto NoAdd;
340 }
341
342
343 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
344
345 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
346 sizeof(PVRSRV_KERNEL_MEM_INFO *)
347 * ui32SharedPBDescSubKernelMemInfosCount,
348 (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
349 0,
350 "Array of Kernel Memory Info") != PVRSRV_OK)
351 {
352 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
353 "Failed to alloc "
354 "StubPBDesc->ppsSubKernelMemInfos"));
355 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
356 goto NoAdd;
357 }
358
359 if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
360 != PVRSRV_OK)
361 {
362 goto NoAdd;
363 }
364
365 if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
366 != PVRSRV_OK)
367 {
368 goto NoAdd;
369 }
370
371 if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
372 != PVRSRV_OK)
373 {
374 goto NoAdd;
375 }
376
377 if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
378 != PVRSRV_OK)
379 {
380 goto NoAdd;
381 }
382
383 psStubPBDesc->ui32RefCount = 1;
384 psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
385 psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
386 psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
387 psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
388 psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
389
390 psStubPBDesc->ui32SubKernelMemInfosCount =
391 ui32SharedPBDescSubKernelMemInfosCount;
392 for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
393 {
394 psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
395 if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
396 != PVRSRV_OK)
397 {
398 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
399 "Failed to dissociate shared PBDesc "
400 "from process"));
401 goto NoAdd;
402 }
403 }
404
405 psResItem = ResManRegisterRes(psPerProc->hResManContext,
406 RESMAN_TYPE_SHARED_PB_DESC,
407 psStubPBDesc,
408 0,
409 &SGXCleanupSharedPBDescCallback);
410 if (psResItem == IMG_NULL)
411 {
412 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
413 "Failed to register shared PBDesc "
414 " with the resource manager"));
415 goto NoAdd;
416 }
417 psStubPBDesc->hDevCookie = hDevCookie;
418
419
420 List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
421 psStubPBDesc);
422
423 *phSharedPBDesc = (IMG_HANDLE)psResItem;
424
425 return PVRSRV_OK;
426
427NoAdd:
428 if(psStubPBDesc)
429 {
430 if(psStubPBDesc->ppsSubKernelMemInfos)
431 {
432 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
433 sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
434 psStubPBDesc->ppsSubKernelMemInfos,
435 0);
436 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
437 }
438 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
439 sizeof(PVRSRV_STUB_PBDESC),
440 psStubPBDesc,
441 0);
442
443 }
444
445NoAddKeepPB:
446 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
447 {
448 PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
449 }
450
451 PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
452 PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
453
454 PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
455 PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
456
457 return eRet;
458}
459
diff --git a/drivers/gpu/pvr/sgx/sgx_bridge_km.h b/drivers/gpu/pvr/sgx/sgx_bridge_km.h
new file mode 100644
index 00000000000..7738be13f38
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgx_bridge_km.h
@@ -0,0 +1,134 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SGX_BRIDGE_KM_H__)
28#define __SGX_BRIDGE_KM_H__
29
30#include "sgxapi_km.h"
31#include "sgxinfo.h"
32#include "sgxinfokm.h"
33#include "sgx_bridge.h"
34#include "pvr_bridge.h"
35#include "perproc.h"
36
37#if defined (__cplusplus)
38extern "C" {
39#endif
40
41IMG_IMPORT
42PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick);
43
44#if defined(SGX_FEATURE_2D_HARDWARE)
45IMG_IMPORT
46PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick);
47#endif
48
49IMG_IMPORT
50PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle,
51 SGX_CCB_KICK *psCCBKick);
52
53IMG_IMPORT
54PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap,
55 IMG_DEV_VIRTADDR sDevVAddr,
56 IMG_DEV_PHYADDR *pDevPAddr,
57 IMG_CPU_PHYADDR *pCpuPAddr);
58
59IMG_IMPORT
60PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
61 IMG_HANDLE hDevMemContext,
62 IMG_DEV_PHYADDR *psPDDevPAddr);
63
64IMG_IMPORT
65PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
66 SGX_CLIENT_INFO* psClientInfo);
67
68IMG_IMPORT
69PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
70 SGX_MISC_INFO *psMiscInfo,
71 PVRSRV_DEVICE_NODE *psDeviceNode,
72 IMG_HANDLE hDevMemContext);
73
74IMG_IMPORT
75PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
76 IMG_UINT32 ui32ArraySize,
77 PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData,
78 IMG_UINT32 *pui32DataCount,
79 IMG_UINT32 *pui32ClockSpeed,
80 IMG_UINT32 *pui32HostTimeStamp);
81
82IMG_IMPORT
83PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo,
84 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
85 IMG_BOOL bWaitForComplete);
86
87IMG_IMPORT
88PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle,
89 SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo);
90
91IMG_IMPORT
92PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc,
93 IMG_HANDLE hDevHandle,
94 SGX_BRIDGE_INIT_INFO *psInitInfo);
95
96IMG_IMPORT PVRSRV_ERROR
97SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
98 IMG_HANDLE hDevCookie,
99 IMG_BOOL bLockOnFailure,
100 IMG_UINT32 ui32TotalPBSize,
101 IMG_HANDLE *phSharedPBDesc,
102 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
103 PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
104 PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
105 PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo,
106 PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
107 IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount);
108
109IMG_IMPORT PVRSRV_ERROR
110SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc);
111
112IMG_IMPORT PVRSRV_ERROR
113SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
114 IMG_HANDLE hDevCookie,
115 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
116 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
117 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
118 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
119 IMG_UINT32 ui32TotalPBSize,
120 IMG_HANDLE *phSharedPBDesc,
121 PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos,
122 IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount);
123
124
125IMG_IMPORT PVRSRV_ERROR
126SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
127 SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo);
128
129#if defined (__cplusplus)
130}
131#endif
132
133#endif
134
diff --git a/drivers/gpu/pvr/sgx/sgxconfig.h b/drivers/gpu/pvr/sgx/sgxconfig.h
new file mode 100644
index 00000000000..a0ca3e9e864
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxconfig.h
@@ -0,0 +1,227 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SGXCONFIG_H__
28#define __SGXCONFIG_H__
29
30#include "sgxdefs.h"
31
32#define DEV_DEVICE_TYPE PVRSRV_DEVICE_TYPE_SGX
33#define DEV_DEVICE_CLASS PVRSRV_DEVICE_CLASS_3D
34
35#define DEV_MAJOR_VERSION 1
36#define DEV_MINOR_VERSION 0
37
38#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
39 #if defined(SGX_FEATURE_2D_HARDWARE)
40 #define SGX_2D_HEAP_BASE 0x00100000
41 #define SGX_2D_HEAP_SIZE (0x08000000-0x00100000-0x00001000)
42 #else
43 #if defined(FIX_HW_BRN_26915)
44 #define SGX_CGBUFFER_HEAP_BASE 0x00100000
45 #define SGX_CGBUFFER_HEAP_SIZE (0x08000000-0x00100000-0x00001000)
46 #endif
47 #endif
48
49 #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
50 #define SGX_GENERAL_MAPPING_HEAP_BASE 0x08000000
51 #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x08000000-0x00001000)
52 #endif
53
54 #define SGX_GENERAL_HEAP_BASE 0x10000000
55 #define SGX_GENERAL_HEAP_SIZE (0xC2000000-0x00001000)
56
57 #define SGX_3DPARAMETERS_HEAP_BASE 0xD2000000
58 #define SGX_3DPARAMETERS_HEAP_SIZE (0x10000000-0x00001000)
59
60 #define SGX_TADATA_HEAP_BASE 0xE2000000
61 #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000)
62
63 #define SGX_SYNCINFO_HEAP_BASE 0xEF000000
64 #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000)
65
66 #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xF0000000
67 #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000)
68
69 #define SGX_KERNEL_CODE_HEAP_BASE 0xF2000000
70 #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
71
72 #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xF2400000
73 #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000)
74
75 #define SGX_KERNEL_DATA_HEAP_BASE 0xF4000000
76 #define SGX_KERNEL_DATA_HEAP_SIZE (0x05000000-0x00001000)
77
78
79 #define SGX_PIXELSHADER_HEAP_BASE 0xF9000000
80 #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000)
81
82 #define SGX_VERTEXSHADER_HEAP_BASE 0xFE000000
83 #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000)
84
85
86 #define SGX_CORE_IDENTIFIED
87#endif
88
89#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28
90 #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
91 #define SGX_GENERAL_MAPPING_HEAP_BASE 0x00001000
92 #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x01800000-0x00001000-0x00001000)
93 #endif
94
95 #define SGX_GENERAL_HEAP_BASE 0x01800000
96 #define SGX_GENERAL_HEAP_SIZE (0x07000000-0x00001000)
97
98 #define SGX_3DPARAMETERS_HEAP_BASE 0x08800000
99 #define SGX_3DPARAMETERS_HEAP_SIZE (0x04000000-0x00001000)
100
101 #define SGX_TADATA_HEAP_BASE 0x0C800000
102 #define SGX_TADATA_HEAP_SIZE (0x01000000-0x00001000)
103
104 #define SGX_SYNCINFO_HEAP_BASE 0x0D800000
105 #define SGX_SYNCINFO_HEAP_SIZE (0x00400000-0x00001000)
106
107 #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0x0DC00000
108 #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
109
110 #define SGX_KERNEL_CODE_HEAP_BASE 0x0E400000
111 #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
112
113 #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0x0E800000
114 #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
115
116 #define SGX_KERNEL_DATA_HEAP_BASE 0x0F000000
117 #define SGX_KERNEL_DATA_HEAP_SIZE (0x00400000-0x00001000)
118
119 #define SGX_PIXELSHADER_HEAP_BASE 0x0F400000
120 #define SGX_PIXELSHADER_HEAP_SIZE (0x00500000-0x00001000)
121
122 #define SGX_VERTEXSHADER_HEAP_BASE 0x0FC00000
123 #define SGX_VERTEXSHADER_HEAP_SIZE (0x00200000-0x00001000)
124
125
126 #define SGX_CORE_IDENTIFIED
127
128#endif
129
130#if !defined(SGX_CORE_IDENTIFIED)
131 #error "sgxconfig.h: ERROR: unspecified SGX Core version"
132#endif
133
134#if !defined (SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE)
135 #if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
136 #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
137 #endif
138
139 #if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
140 #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
141 #endif
142#endif
143
144#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
145 #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE - SGX_2D_HEAP_BASE) >= EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK)
146 #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP inaccessable by 2D requestor"
147 #endif
148#endif
149
150#if defined (EURASIA_USE_CODE_PAGE_SIZE)
151 #if ((SGX_KERNEL_CODE_HEAP_BASE & (EURASIA_USE_CODE_PAGE_SIZE - 1)) != 0)
152 #error "sgxconfig.h: ERROR: Kernel code heap base misalignment"
153 #endif
154#endif
155
156#if defined(SGX_FEATURE_2D_HARDWARE)
157 #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
158 #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
159 #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
160 #endif
161 #else
162 #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
163 #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_HEAP_BASE"
164 #endif
165 #endif
166#else
167 #if defined(FIX_HW_BRN_26915)
168 #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
169 #if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
170 #error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
171 #endif
172 #else
173 #if ((SGX_CGBUFFER_HEAP_BASE + SGX_CGBUFFER_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
174 #error "sgxconfig.h: ERROR: SGX_CGBUFFER_HEAP overlaps SGX_GENERAL_HEAP_BASE"
175 #endif
176 #endif
177 #endif
178#endif
179
180#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
181 #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
182 #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP overlaps SGX_GENERAL_HEAP"
183 #endif
184#endif
185
186#if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_3DPARAMETERS_HEAP_BASE)
187 #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_3DPARAMETERS_HEAP"
188#endif
189
190#if ((SGX_3DPARAMETERS_HEAP_BASE + SGX_3DPARAMETERS_HEAP_SIZE) >= SGX_TADATA_HEAP_BASE)
191 #error "sgxconfig.h: ERROR: SGX_3DPARAMETERS_HEAP overlaps SGX_TADATA_HEAP"
192#endif
193
194#if ((SGX_TADATA_HEAP_BASE + SGX_TADATA_HEAP_SIZE) >= SGX_SYNCINFO_HEAP_BASE)
195 #error "sgxconfig.h: ERROR: SGX_TADATA_HEAP overlaps SGX_SYNCINFO_HEAP"
196#endif
197
198#if ((SGX_SYNCINFO_HEAP_BASE + SGX_SYNCINFO_HEAP_SIZE) >= SGX_PDSPIXEL_CODEDATA_HEAP_BASE)
199 #error "sgxconfig.h: ERROR: SGX_SYNCINFO_HEAP overlaps SGX_PDSPIXEL_CODEDATA_HEAP"
200#endif
201
202#if ((SGX_PDSPIXEL_CODEDATA_HEAP_BASE + SGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_CODE_HEAP_BASE)
203 #error "sgxconfig.h: ERROR: SGX_PDSPIXEL_CODEDATA_HEAP overlaps SGX_KERNEL_CODE_HEAP"
204#endif
205
206#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE) >= SGX_PDSVERTEX_CODEDATA_HEAP_BASE)
207 #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP overlaps SGX_PDSVERTEX_CODEDATA_HEAP"
208#endif
209
210#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_DATA_HEAP_BASE)
211 #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP overlaps SGX_KERNEL_DATA_HEAP"
212#endif
213
214#if ((SGX_KERNEL_DATA_HEAP_BASE + SGX_KERNEL_DATA_HEAP_SIZE) >= SGX_PIXELSHADER_HEAP_BASE)
215 #error "sgxconfig.h: ERROR: SGX_KERNEL_DATA_HEAP overlaps SGX_PIXELSHADER_HEAP"
216#endif
217
218#if ((SGX_PIXELSHADER_HEAP_BASE + SGX_PIXELSHADER_HEAP_SIZE) >= SGX_VERTEXSHADER_HEAP_BASE)
219 #error "sgxconfig.h: ERROR: SGX_PIXELSHADER_HEAP overlaps SGX_VERTEXSHADER_HEAP"
220#endif
221
222#if ((SGX_VERTEXSHADER_HEAP_BASE + SGX_VERTEXSHADER_HEAP_SIZE) < SGX_VERTEXSHADER_HEAP_BASE)
223 #error "sgxconfig.h: ERROR: SGX_VERTEXSHADER_HEAP_BASE size cause wraparound"
224#endif
225
226#endif
227
diff --git a/drivers/gpu/pvr/sgx/sgxinfokm.h b/drivers/gpu/pvr/sgx/sgxinfokm.h
new file mode 100644
index 00000000000..056db35831d
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxinfokm.h
@@ -0,0 +1,369 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SGXINFOKM_H__
28#define __SGXINFOKM_H__
29
30#include "sgxdefs.h"
31#include "device.h"
32#include "power.h"
33#include "sysconfig.h"
34#include "sgxscript.h"
35#include "sgxinfo.h"
36
37#if defined (__cplusplus)
38extern "C" {
39#endif
40
41#define SGX_HOSTPORT_PRESENT 0x00000001UL
42
43
44#define SGX_PDUMPREG_NAME "SGXREG"
45
46typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
47
48
49typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO;
50
51typedef struct _PVRSRV_SGXDEV_INFO_
52{
53 PVRSRV_DEVICE_TYPE eDeviceType;
54 PVRSRV_DEVICE_CLASS eDeviceClass;
55
56 IMG_UINT8 ui8VersionMajor;
57 IMG_UINT8 ui8VersionMinor;
58 IMG_UINT32 ui32CoreConfig;
59 IMG_UINT32 ui32CoreFlags;
60
61
62 IMG_PVOID pvRegsBaseKM;
63
64#if defined(SGX_FEATURE_HOST_PORT)
65
66 IMG_PVOID pvHostPortBaseKM;
67
68 IMG_UINT32 ui32HPSize;
69
70 IMG_SYS_PHYADDR sHPSysPAddr;
71#endif
72
73
74 IMG_HANDLE hRegMapping;
75
76
77 IMG_SYS_PHYADDR sRegsPhysBase;
78
79 IMG_UINT32 ui32RegSize;
80
81#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
82
83 IMG_UINT32 ui32ExtSysCacheRegsSize;
84
85 IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase;
86
87 IMG_UINT32 *pui32ExtSystemCacheRegsPT;
88
89 IMG_HANDLE hExtSystemCacheRegsPTPageOSMemHandle;
90
91 IMG_SYS_PHYADDR sExtSystemCacheRegsPTSysPAddr;
92#endif
93
94
95 IMG_UINT32 ui32CoreClockSpeed;
96 IMG_UINT32 ui32uKernelTimerClock;
97
98 PVRSRV_STUB_PBDESC *psStubPBDescListKM;
99
100
101
102 IMG_DEV_PHYADDR sKernelPDDevPAddr;
103
104 IMG_VOID *pvDeviceMemoryHeap;
105 PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo;
106 PVRSRV_SGX_KERNEL_CCB *psKernelCCB;
107 PPVRSRV_SGX_CCB_INFO psKernelCCBInfo;
108 PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo;
109 PVRSRV_SGX_CCB_CTL *psKernelCCBCtl;
110 PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo;
111 IMG_UINT32 *pui32KernelCCBEventKicker;
112#if defined(PDUMP)
113 IMG_UINT32 ui32KernelCCBEventKickerDumpVal;
114#endif
115 PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo;
116 IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
117#if defined(SGX_SUPPORT_HWPROFILING)
118 PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo;
119#endif
120 PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo;
121 PPVRSRV_KERNEL_MEM_INFO psKernelTASigBufferMemInfo;
122 PPVRSRV_KERNEL_MEM_INFO psKernel3DSigBufferMemInfo;
123#if defined(FIX_HW_BRN_29702)
124 PPVRSRV_KERNEL_MEM_INFO psKernelCFIMemInfo;
125#endif
126#if defined(FIX_HW_BRN_29823)
127 PPVRSRV_KERNEL_MEM_INFO psKernelDummyTermStreamMemInfo;
128#endif
129#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
130 PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo;
131#endif
132#if defined(SGX_FEATURE_OVERLAPPED_SPM)
133 PPVRSRV_KERNEL_MEM_INFO psKernelTmpRgnHeaderMemInfo;
134#endif
135#if defined(SGX_FEATURE_SPM_MODE_0)
136 PPVRSRV_KERNEL_MEM_INFO psKernelTmpDPMStateMemInfo;
137#endif
138
139
140 IMG_UINT32 ui32ClientRefCount;
141
142
143 IMG_UINT32 ui32CacheControl;
144
145
146 IMG_UINT32 ui32ClientBuildOptions;
147
148
149 SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
150
151
152
153
154 IMG_VOID *pvMMUContextList;
155
156
157 IMG_BOOL bForcePTOff;
158
159 IMG_UINT32 ui32EDMTaskReg0;
160 IMG_UINT32 ui32EDMTaskReg1;
161
162 IMG_UINT32 ui32ClkGateStatusReg;
163 IMG_UINT32 ui32ClkGateStatusMask;
164#if defined(SGX_FEATURE_MP)
165 IMG_UINT32 ui32MasterClkGateStatusReg;
166 IMG_UINT32 ui32MasterClkGateStatusMask;
167 IMG_UINT32 ui32MasterClkGateStatus2Reg;
168 IMG_UINT32 ui32MasterClkGateStatus2Mask;
169#endif
170 SGX_INIT_SCRIPTS sScripts;
171
172
173 IMG_HANDLE hBIFResetPDOSMemHandle;
174 IMG_DEV_PHYADDR sBIFResetPDDevPAddr;
175 IMG_DEV_PHYADDR sBIFResetPTDevPAddr;
176 IMG_DEV_PHYADDR sBIFResetPageDevPAddr;
177 IMG_UINT32 *pui32BIFResetPD;
178 IMG_UINT32 *pui32BIFResetPT;
179
180#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
181
182 IMG_HANDLE hBRN22997PTPageOSMemHandle;
183 IMG_HANDLE hBRN22997PDPageOSMemHandle;
184 IMG_DEV_PHYADDR sBRN22997PTDevPAddr;
185 IMG_DEV_PHYADDR sBRN22997PDDevPAddr;
186 IMG_UINT32 *pui32BRN22997PT;
187 IMG_UINT32 *pui32BRN22997PD;
188 IMG_SYS_PHYADDR sBRN22997SysPAddr;
189#endif
190
191#if defined(SUPPORT_HW_RECOVERY)
192
193 IMG_HANDLE hTimer;
194
195 IMG_UINT32 ui32TimeStamp;
196#endif
197
198
199 IMG_UINT32 ui32NumResets;
200
201
202 PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo;
203 SGXMKIF_HOST_CTL *psSGXHostCtl;
204
205
206 PVRSRV_KERNEL_MEM_INFO *psKernelSGXTA3DCtlMemInfo;
207
208 IMG_UINT32 ui32Flags;
209
210
211 IMG_UINT32 ui32MemTilingUsage;
212
213 #if defined(PDUMP)
214 PVRSRV_SGX_PDUMP_CONTEXT sPDContext;
215 #endif
216
217#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
218
219 IMG_VOID *pvDummyPTPageCpuVAddr;
220 IMG_DEV_PHYADDR sDummyPTDevPAddr;
221 IMG_HANDLE hDummyPTPageOSMemHandle;
222 IMG_VOID *pvDummyDataPageCpuVAddr;
223 IMG_DEV_PHYADDR sDummyDataDevPAddr;
224 IMG_HANDLE hDummyDataPageOSMemHandle;
225#endif
226#if defined(PDUMP)
227 PDUMP_MMU_ATTRIB sMMUAttrib;
228#endif
229 IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA];
230
231} PVRSRV_SGXDEV_INFO;
232
233
234typedef struct _SGX_TIMING_INFORMATION_
235{
236 IMG_UINT32 ui32CoreClockSpeed;
237 IMG_UINT32 ui32HWRecoveryFreq;
238 IMG_BOOL bEnableActivePM;
239 IMG_UINT32 ui32ActivePowManLatencyms;
240 IMG_UINT32 ui32uKernelFreq;
241} SGX_TIMING_INFORMATION;
242
243typedef struct _SGX_DEVICE_MAP_
244{
245 IMG_UINT32 ui32Flags;
246
247
248 IMG_SYS_PHYADDR sRegsSysPBase;
249 IMG_CPU_PHYADDR sRegsCpuPBase;
250 IMG_CPU_VIRTADDR pvRegsCpuVBase;
251 IMG_UINT32 ui32RegsSize;
252
253#if defined(SGX_FEATURE_HOST_PORT)
254 IMG_SYS_PHYADDR sHPSysPBase;
255 IMG_CPU_PHYADDR sHPCpuPBase;
256 IMG_UINT32 ui32HPSize;
257#endif
258
259
260 IMG_SYS_PHYADDR sLocalMemSysPBase;
261 IMG_DEV_PHYADDR sLocalMemDevPBase;
262 IMG_CPU_PHYADDR sLocalMemCpuPBase;
263 IMG_UINT32 ui32LocalMemSize;
264
265#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
266 IMG_UINT32 ui32ExtSysCacheRegsSize;
267 IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase;
268#endif
269
270
271 IMG_UINT32 ui32IRQ;
272
273#if !defined(SGX_DYNAMIC_TIMING_INFO)
274
275 SGX_TIMING_INFORMATION sTimingInfo;
276#endif
277#if defined(PDUMP)
278
279 IMG_CHAR *pszPDumpDevName;
280#endif
281} SGX_DEVICE_MAP;
282
283
284struct _PVRSRV_STUB_PBDESC_
285{
286 IMG_UINT32 ui32RefCount;
287 IMG_UINT32 ui32TotalPBSize;
288 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
289 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
290 PVRSRV_KERNEL_MEM_INFO **ppsSubKernelMemInfos;
291 IMG_UINT32 ui32SubKernelMemInfosCount;
292 IMG_HANDLE hDevCookie;
293 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
294 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
295 PVRSRV_STUB_PBDESC *psNext;
296 PVRSRV_STUB_PBDESC **ppsThis;
297};
298
299typedef struct _PVRSRV_SGX_CCB_INFO_
300{
301 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo;
302 PVRSRV_KERNEL_MEM_INFO *psCCBCtlMemInfo;
303 SGXMKIF_COMMAND *psCommands;
304 IMG_UINT32 *pui32WriteOffset;
305 volatile IMG_UINT32 *pui32ReadOffset;
306#if defined(PDUMP)
307 IMG_UINT32 ui32CCBDumpWOff;
308#endif
309} PVRSRV_SGX_CCB_INFO;
310
311PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode);
312
313IMG_VOID SGXOSTimer(IMG_VOID *pvData);
314
315IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
316 IMG_BOOL bHardwareRecovery,
317 IMG_UINT32 ui32PDUMPFlags);
318
319PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
320 IMG_BOOL bHardwareRecovery);
321PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie);
322
323PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE hDevHandle,
324 PVRSRV_DEV_POWER_STATE eNewPowerState,
325 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
326
327PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE hDevHandle,
328 PVRSRV_DEV_POWER_STATE eNewPowerState,
329 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
330
331PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE hDevHandle,
332 IMG_BOOL bIdleDevice,
333 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
334
335PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle,
336 IMG_BOOL bIdleDevice,
337 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
338
339IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo);
340
341PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
342
343#if defined(SGX_DYNAMIC_TIMING_INFO)
344IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo);
345#endif
346
347#if defined(NO_HARDWARE)
348static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO *psDevInfo,
349 IMG_UINT32 ui32StatusRegister,
350 IMG_UINT32 ui32StatusValue,
351 IMG_UINT32 ui32StatusMask)
352{
353 IMG_UINT32 ui32RegVal;
354
355 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister);
356
357 ui32RegVal &= ~ui32StatusMask;
358 ui32RegVal |= (ui32StatusValue & ui32StatusMask);
359
360 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal);
361}
362#endif
363
364#if defined(__cplusplus)
365}
366#endif
367
368#endif
369
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c
new file mode 100644
index 00000000000..2471915d10f
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxinit.c
@@ -0,0 +1,2507 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "sgxdefs.h"
30#include "sgxmmu.h"
31#include "services_headers.h"
32#include "buffer_manager.h"
33#include "sgxapi_km.h"
34#include "sgxinfo.h"
35#include "sgx_mkif_km.h"
36#include "sgxconfig.h"
37#include "sysconfig.h"
38#include "pvr_bridge_km.h"
39
40#include "sgx_bridge_km.h"
41
42#include "pdump_km.h"
43#include "ra.h"
44#include "mmu.h"
45#include "handle.h"
46#include "perproc.h"
47
48#include "sgxutils.h"
49#include "pvrversion.h"
50#include "sgx_options.h"
51
52#include "lists.h"
53#include "srvkm.h"
54
55#define VAR(x) #x
56
57
58#define CHECK_SIZE(NAME) \
59{ \
60 if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
61 { \
62 PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
63 VAR(NAME), \
64 psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
65 psSGXStructSizes->ui32Sizeof_##NAME )); \
66 bStructSizesFailed = IMG_TRUE; \
67 } \
68}
69
70#if defined (SYS_USING_INTERRUPTS)
71IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
72#endif
73
74
75static
76PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
77 PVRSRV_DEVICE_NODE *psDeviceNode);
78#if defined(PDUMP)
79static
80PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode);
81#endif
82
83static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
84{
85#if defined(OS_SUPPORTS_IN_LISR)
86 if (OSInLISR(psDeviceNode->psSysData))
87 {
88
89 psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
90 }
91 else
92 {
93 SGXScheduleProcessQueuesKM(psDeviceNode);
94 }
95#else
96 SGXScheduleProcessQueuesKM(psDeviceNode);
97#endif
98}
99
100static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
101{
102 if (psDevInfo->psKernelCCBInfo != IMG_NULL)
103 {
104
105
106 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
107 }
108
109 return PVRSRV_OK;
110}
111
112static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
113 PVRSRV_DEVICE_NODE *psDeviceNode,
114 SGX_BRIDGE_INIT_INFO *psInitInfo)
115{
116 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
117 PVRSRV_ERROR eError;
118
119 PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL;
120
121 PVR_UNREFERENCED_PARAMETER(psPerProc);
122 psDevInfo->sScripts = psInitInfo->sScripts;
123
124 psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
125 psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
126
127 psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
128 psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
129
130 psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
131 psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
132
133 psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
134 psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
135
136 psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
137
138 psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
139
140#if defined(SGX_SUPPORT_HWPROFILING)
141 psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;
142#endif
143#if defined(SUPPORT_SGX_HWPERF)
144 psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;
145#endif
146 psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo;
147 psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo;
148#if defined(FIX_HW_BRN_29702)
149 psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo;
150#endif
151#if defined(FIX_HW_BRN_29823)
152 psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
153#endif
154#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
155 psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
156#endif
157#if defined(SGX_FEATURE_OVERLAPPED_SPM)
158 psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;
159#endif
160#if defined(SGX_FEATURE_SPM_MODE_0)
161 psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo;
162#endif
163
164 psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
165
166
167 psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
168
169
170
171 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
172 sizeof(PVRSRV_SGX_CCB_INFO),
173 (IMG_VOID **)&psKernelCCBInfo, 0,
174 "SGX Circular Command Buffer Info");
175 if (eError != PVRSRV_OK)
176 {
177 PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
178 goto failed_allockernelccb;
179 }
180
181
182 OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
183 psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo;
184 psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo;
185 psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands;
186 psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
187 psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
188 psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
189
190
191
192 OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
193 SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
194
195 psDevInfo->bForcePTOff = IMG_FALSE;
196
197 psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
198
199 psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
200 psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
201 psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
202 psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
203#if defined(SGX_FEATURE_MP)
204 psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
205 psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
206 psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg;
207 psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask;
208#endif
209
210
211
212 OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
213
214 return PVRSRV_OK;
215
216failed_allockernelccb:
217 DeinitDevInfo(psDevInfo);
218
219 return eError;
220}
221
222
223
224
225static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
226{
227 IMG_UINT32 ui32PC;
228 SGX_INIT_COMMAND *psComm;
229
230 for (ui32PC = 0, psComm = psScript;
231 ui32PC < ui32NumInitCommands;
232 ui32PC++, psComm++)
233 {
234 switch (psComm->eOp)
235 {
236 case SGX_INIT_OP_WRITE_HW_REG:
237 {
238 OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
239 PDUMPCOMMENT("SGXRunScript: Write HW reg operation");
240 PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
241 break;
242 }
243#if defined(PDUMP)
244 case SGX_INIT_OP_PDUMP_HW_REG:
245 {
246 PDUMPCOMMENT("SGXRunScript: Dump HW reg operation");
247 PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
248 break;
249 }
250#endif
251 case SGX_INIT_OP_HALT:
252 {
253 return PVRSRV_OK;
254 }
255 case SGX_INIT_OP_ILLEGAL:
256
257 default:
258 {
259 PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
260 return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
261 }
262 }
263
264 }
265
266 return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
267}
268
269PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
270 IMG_BOOL bHardwareRecovery)
271{
272 PVRSRV_ERROR eError;
273 PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
274 SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
275 static IMG_BOOL bFirstTime = IMG_TRUE;
276#if defined(PDUMP)
277 IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
278#endif
279
280
281
282 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
283 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
284 if (eError != PVRSRV_OK)
285 {
286 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
287 return eError;
288 }
289 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
290
291
292 SGXReset(psDevInfo, bFirstTime || bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS);
293
294#if defined(EUR_CR_POWER)
295#if defined(SGX531)
296
297
298
299
300
301 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
302 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1);
303#else
304
305 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
306 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0);
307#endif
308#endif
309
310
311 *psDevInfo->pui32KernelCCBEventKicker = 0;
312#if defined(PDUMP)
313 if (!bPDumpIsSuspended)
314 {
315 psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
316 PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
317 psDevInfo->psKernelCCBEventKickerMemInfo, 0,
318 sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
319 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
320 }
321#endif
322
323
324
325 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
326 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
327 if (eError != PVRSRV_OK)
328 {
329 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
330 return eError;
331 }
332 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
333
334
335 psSGXHostCtl->ui32HostClock = OSClockus();
336
337 psSGXHostCtl->ui32InitStatus = 0;
338#if defined(PDUMP)
339 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
340 "Reset the SGX microkernel initialisation status\n");
341 PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
342 offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
343 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
344 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
345 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
346 "Initialise the microkernel\n");
347#endif
348
349#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
350 OSWriteMemoryBarrier();
351 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
352 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
353 EUR_CR_EVENT_KICK2_NOW_MASK);
354#else
355 *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
356 OSWriteMemoryBarrier();
357 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
358 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
359 EUR_CR_EVENT_KICK_NOW_MASK);
360#endif
361
362 OSMemoryBarrier();
363
364#if defined(PDUMP)
365
366
367 if (!bPDumpIsSuspended)
368 {
369#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
370 PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK);
371#else
372 psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
373 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
374 "First increment of the SGX event kicker value\n");
375 PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
376 psDevInfo->psKernelCCBEventKickerMemInfo,
377 0,
378 sizeof(IMG_UINT32),
379 PDUMP_FLAGS_CONTINUOUS,
380 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
381 PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
382#endif
383 }
384#endif
385
386#if !defined(NO_HARDWARE)
387
388
389 if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
390 PVRSRV_USSE_EDM_INIT_COMPLETE,
391 PVRSRV_USSE_EDM_INIT_COMPLETE,
392 MAX_HW_TIME_US/WAIT_TRY_COUNT,
393 WAIT_TRY_COUNT) != PVRSRV_OK)
394 {
395 PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
396 PVR_DBG_BREAK;
397 return PVRSRV_ERROR_RETRY;
398 }
399#endif
400
401#if defined(PDUMP)
402 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
403 "Wait for the SGX microkernel initialisation to complete");
404 PDUMPMEMPOL(psSGXHostCtlMemInfo,
405 offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
406 PVRSRV_USSE_EDM_INIT_COMPLETE,
407 PVRSRV_USSE_EDM_INIT_COMPLETE,
408 PDUMP_POLL_OPERATOR_EQUAL,
409 PDUMP_FLAGS_CONTINUOUS,
410 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
411#endif
412
413#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
414
415
416
417 WorkaroundBRN22997ReadHostPort(psDevInfo);
418#endif
419
420 PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
421
422 bFirstTime = IMG_FALSE;
423
424 return PVRSRV_OK;
425}
426
427PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
428
429{
430 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
431 PVRSRV_ERROR eError;
432
433
434 if (psDevInfo->pvRegsBaseKM == IMG_NULL)
435 {
436 return PVRSRV_OK;
437 }
438
439 eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
440 if (eError != PVRSRV_OK)
441 {
442 PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
443 return eError;
444 }
445
446 return PVRSRV_OK;
447}
448
449
450static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
451{
452 IMG_HANDLE hDevMemHeap = IMG_NULL;
453 PVRSRV_SGXDEV_INFO *psDevInfo;
454 IMG_HANDLE hKernelDevMemContext;
455 IMG_DEV_PHYADDR sPDDevPAddr;
456 IMG_UINT32 i;
457 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
458 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
459 PVRSRV_ERROR eError;
460
461
462 PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
463
464 #if defined(SGX_FEATURE_MP)
465 PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT);
466 #endif
467
468#if (SGX_CORE_REV == 0)
469 PDUMPCOMMENT("SGX Core Revision Information: head RTL");
470#else
471 PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
472#endif
473
474 #if defined(SGX_FEATURE_SYSTEM_CACHE)
475 PDUMPCOMMENT("SGX System Level Cache is present\r\n");
476 #if defined(SGX_BYPASS_SYSTEM_CACHE)
477 PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
478 #endif
479 #endif
480
481 PDUMPCOMMENT("SGX Initialisation Part 1");
482
483
484 if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
485 sizeof(PVRSRV_SGXDEV_INFO),
486 (IMG_VOID **)&psDevInfo, IMG_NULL,
487 "SGX Device Info") != PVRSRV_OK)
488 {
489 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
490 return (PVRSRV_ERROR_OUT_OF_MEMORY);
491 }
492 OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
493
494
495 psDevInfo->eDeviceType = DEV_DEVICE_TYPE;
496 psDevInfo->eDeviceClass = DEV_DEVICE_CLASS;
497
498
499 psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
500
501
502 psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
503
504
505 hKernelDevMemContext = BM_CreateContext(psDeviceNode,
506 &sPDDevPAddr,
507 IMG_NULL,
508 IMG_NULL);
509 if (hKernelDevMemContext == IMG_NULL)
510 {
511 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
512 return PVRSRV_ERROR_OUT_OF_MEMORY;
513 }
514
515 psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
516
517
518 for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
519 {
520 switch(psDeviceMemoryHeap[i].DevMemHeapType)
521 {
522 case DEVICE_MEMORY_HEAP_KERNEL:
523 case DEVICE_MEMORY_HEAP_SHARED:
524 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
525 {
526 hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
527 &psDeviceMemoryHeap[i]);
528
529
530
531 psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
532 break;
533 }
534 }
535 }
536#if defined(PDUMP)
537 if(hDevMemHeap)
538 {
539
540 psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib;
541 }
542#endif
543 eError = MMU_BIFResetPDAlloc(psDevInfo);
544 if (eError != PVRSRV_OK)
545 {
546 PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
547 return eError;
548 }
549
550 return PVRSRV_OK;
551}
552
553IMG_EXPORT
554PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
555{
556 PVRSRV_DEVICE_NODE *psDeviceNode;
557 PVRSRV_SGXDEV_INFO *psDevInfo;
558 PVRSRV_ERROR eError;
559
560 PDUMPCOMMENT("SGXGetInfoForSrvinit");
561
562 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
563 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
564
565 psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
566
567 eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
568 if (eError != PVRSRV_OK)
569 {
570 PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
571 return eError;
572 }
573
574 return eError;
575}
576
577IMG_EXPORT
578PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
579 IMG_HANDLE hDevHandle,
580 SGX_BRIDGE_INIT_INFO *psInitInfo)
581{
582 PVRSRV_DEVICE_NODE *psDeviceNode;
583 PVRSRV_SGXDEV_INFO *psDevInfo;
584 PVRSRV_ERROR eError;
585 SGX_DEVICE_MAP *psSGXDeviceMap;
586 PVRSRV_DEV_POWER_STATE eDefaultPowerState;
587
588 PDUMPCOMMENT("SGX Initialisation Part 2");
589
590 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
591 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
592
593
594
595 eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
596 if (eError != PVRSRV_OK)
597 {
598 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
599 goto failed_init_dev_info;
600 }
601
602
603 eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
604 (IMG_VOID**)&psSGXDeviceMap);
605 if (eError != PVRSRV_OK)
606 {
607 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
608 return PVRSRV_ERROR_INIT_FAILURE;
609 }
610
611
612 if (psSGXDeviceMap->pvRegsCpuVBase)
613 {
614 psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
615 }
616 else
617 {
618
619 psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
620 psSGXDeviceMap->ui32RegsSize,
621 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
622 IMG_NULL);
623 if (!psDevInfo->pvRegsBaseKM)
624 {
625 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
626 return PVRSRV_ERROR_BAD_MAPPING;
627 }
628 }
629 psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
630 psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
631
632
633#if defined(SGX_FEATURE_HOST_PORT)
634 if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
635 {
636
637 psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
638 psSGXDeviceMap->ui32HPSize,
639 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
640 IMG_NULL);
641 if (!psDevInfo->pvHostPortBaseKM)
642 {
643 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
644 return PVRSRV_ERROR_BAD_MAPPING;
645 }
646 psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
647 psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
648 }
649#endif
650
651#if defined (SYS_USING_INTERRUPTS)
652
653
654 psDeviceNode->pvISRData = psDeviceNode;
655
656 PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
657
658#endif
659
660
661 psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
662 eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
663
664 eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
665 &SGXPrePowerState, &SGXPostPowerState,
666 &SGXPreClockSpeedChange, &SGXPostClockSpeedChange,
667 (IMG_HANDLE)psDeviceNode,
668 PVRSRV_DEV_POWER_STATE_OFF,
669 eDefaultPowerState);
670 if (eError != PVRSRV_OK)
671 {
672 PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
673 return eError;
674 }
675
676#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
677 eError = WorkaroundBRN22997Alloc(psDeviceNode);
678 if (eError != PVRSRV_OK)
679 {
680 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));
681 return eError;
682 }
683#endif
684
685#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
686
687 psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
688 psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
689 eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
690 if (eError != PVRSRV_OK)
691 {
692 PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
693 return eError;
694 }
695#endif
696
697
698
699 OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
700 OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
701 OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
702 PDUMPCOMMENT("Initialise Kernel CCB");
703 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
704 PDUMPCOMMENT("Initialise Kernel CCB Control");
705 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
706 PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
707 PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
708
709 return PVRSRV_OK;
710
711failed_init_dev_info:
712 return eError;
713}
714
715static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
716{
717 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
718 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
719 PVRSRV_ERROR eError;
720 IMG_UINT32 ui32Heap;
721 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
722 SGX_DEVICE_MAP *psSGXDeviceMap;
723
724 if (!psDevInfo)
725 {
726
727 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
728 return PVRSRV_OK;
729 }
730
731#if defined(SUPPORT_HW_RECOVERY)
732 if (psDevInfo->hTimer)
733 {
734 eError = OSRemoveTimer(psDevInfo->hTimer);
735 if (eError != PVRSRV_OK)
736 {
737 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));
738 return eError;
739 }
740 psDevInfo->hTimer = IMG_NULL;
741 }
742#endif
743
744#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
745
746 eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
747 if (eError != PVRSRV_OK)
748 {
749 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
750 return eError;
751 }
752#endif
753
754#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
755 WorkaroundBRN22997Free(psDeviceNode);
756#endif
757
758 MMU_BIFResetPDFree(psDevInfo);
759
760
761
762 DeinitDevInfo(psDevInfo);
763
764
765 psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
766 for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
767 {
768 switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
769 {
770 case DEVICE_MEMORY_HEAP_KERNEL:
771 case DEVICE_MEMORY_HEAP_SHARED:
772 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
773 {
774 if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
775 {
776 BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
777 }
778 break;
779 }
780 }
781 }
782
783
784 eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
785 if (eError != PVRSRV_OK)
786 {
787 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
788 return eError;
789 }
790
791
792 eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
793 if (eError != PVRSRV_OK)
794 {
795 return eError;
796 }
797
798 eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
799 (IMG_VOID**)&psSGXDeviceMap);
800 if (eError != PVRSRV_OK)
801 {
802 PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
803 return eError;
804 }
805
806
807 if (!psSGXDeviceMap->pvRegsCpuVBase)
808 {
809
810 if (psDevInfo->pvRegsBaseKM != IMG_NULL)
811 {
812 OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
813 psDevInfo->ui32RegSize,
814 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
815 IMG_NULL);
816 }
817 }
818
819#if defined(SGX_FEATURE_HOST_PORT)
820 if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
821 {
822
823 if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
824 {
825 OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
826 psDevInfo->ui32HPSize,
827 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
828 IMG_NULL);
829 }
830 }
831#endif
832
833
834
835 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
836 sizeof(PVRSRV_SGXDEV_INFO),
837 psDevInfo,
838 0);
839
840 psDeviceNode->pvDevice = IMG_NULL;
841
842 if (psDeviceMemoryHeap != IMG_NULL)
843 {
844
845 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
846 sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
847 psDeviceMemoryHeap,
848 0);
849 }
850
851 return PVRSRV_OK;
852}
853
854
855static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
856 IMG_UINT32 ui32CoreNum,
857 IMG_CHAR *pszName,
858 IMG_UINT32 ui32RegAddr)
859{
860 IMG_UINT32 ui32RegVal;
861 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum));
862 PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal));
863}
864
865static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
866 IMG_BOOL bDumpSGXRegs)
867{
868 IMG_UINT32 ui32CoreNum;
869
870 PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING));
871
872 if (bDumpSGXRegs)
873 {
874 PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM));
875 PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr));
876
877 for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++)
878 {
879
880 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS);
881 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2);
882 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL);
883 #if defined(EUR_CR_BIF_BANK0)
884 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0);
885 #endif
886 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT);
887 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT);
888 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT);
889 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL);
890 #if defined(EUR_CR_PDS_PC_BASE)
891 SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE);
892 #endif
893 }
894 }
895
896
897
898 QueueDumpDebugInfo();
899
900 {
901
902
903 IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psDevInfo->psSGXHostCtl;
904 IMG_UINT32 ui32LoopCounter;
905
906 PVR_LOG(("SGX Host control:"));
907
908 for (ui32LoopCounter = 0;
909 ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
910 ui32LoopCounter += 4)
911 {
912 PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
913 pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
914 pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
915 }
916 }
917
918 {
919
920
921 IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
922 IMG_UINT32 ui32LoopCounter;
923
924 PVR_LOG(("SGX TA/3D control:"));
925
926 for (ui32LoopCounter = 0;
927 ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->ui32AllocSize / sizeof(*pui32TA3DCtlBuffer);
928 ui32LoopCounter += 4)
929 {
930 PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
931 pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
932 pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
933 }
934 }
935
936 #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
937 {
938 IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
939 IMG_UINT32 ui32LastStatusCode, ui32WriteOffset;
940
941 ui32LastStatusCode = *pui32MKTraceBuffer;
942 pui32MKTraceBuffer++;
943 ui32WriteOffset = *pui32MKTraceBuffer;
944 pui32MKTraceBuffer++;
945
946 PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode));
947
948 #if defined(PVRSRV_DUMP_MK_TRACE)
949
950
951 {
952 IMG_UINT32 ui32LoopCounter;
953
954 for (ui32LoopCounter = 0;
955 ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
956 ui32LoopCounter++)
957 {
958 IMG_UINT32 *pui32BufPtr;
959 pui32BufPtr = pui32MKTraceBuffer +
960 (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
961 PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter,
962 pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
963 }
964 }
965 #endif
966 }
967 #endif
968
969 {
970
971
972 PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X",
973 psDevInfo->psKernelCCBCtl->ui32WriteOffset,
974 psDevInfo->psKernelCCBCtl->ui32ReadOffset));
975
976 #if defined(PVRSRV_DUMP_KERNEL_CCB)
977 {
978 IMG_UINT32 ui32LoopCounter;
979
980 for (ui32LoopCounter = 0;
981 ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) /
982 sizeof(psDevInfo->psKernelCCB->asCommands[0]);
983 ui32LoopCounter++)
984 {
985 SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter];
986
987 PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter,
988 psCommand->ui32ServiceAddress, psCommand->ui32CacheControl,
989 psCommand->ui32Data[0], psCommand->ui32Data[1],
990 psCommand->ui32Data[2], psCommand->ui32Data[3]));
991 }
992 }
993 #endif
994 }
995}
996
997
998#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)
999static
1000IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,
1001 IMG_UINT32 ui32Component,
1002 IMG_UINT32 ui32CallerID)
1003{
1004 PVRSRV_ERROR eError;
1005 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
1006 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1007
1008 PVR_UNREFERENCED_PARAMETER(ui32Component);
1009
1010
1011
1012 eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
1013 if(eError != PVRSRV_OK)
1014 {
1015
1016
1017
1018 PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
1019 return;
1020 }
1021
1022 psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
1023
1024 PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
1025
1026 SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
1027
1028
1029 PDUMPSUSPEND();
1030
1031
1032 eError = SGXInitialise(psDevInfo, IMG_TRUE);
1033 if (eError != PVRSRV_OK)
1034 {
1035 PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
1036 }
1037
1038
1039 PDUMPRESUME();
1040
1041 PVRSRVPowerUnlock(ui32CallerID);
1042
1043
1044 SGXScheduleProcessQueuesKM(psDeviceNode);
1045
1046
1047
1048 PVRSRVProcessQueues(ui32CallerID, IMG_TRUE);
1049}
1050#endif
1051
1052
1053#if defined(SUPPORT_HW_RECOVERY)
1054IMG_VOID SGXOSTimer(IMG_VOID *pvData)
1055{
1056 PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
1057 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1058 static IMG_UINT32 ui32EDMTasks = 0;
1059 static IMG_UINT32 ui32LockupCounter = 0;
1060 static IMG_UINT32 ui32NumResets = 0;
1061 IMG_UINT32 ui32CurrentEDMTasks;
1062 IMG_BOOL bLockup = IMG_FALSE;
1063 IMG_BOOL bPoweredDown;
1064
1065
1066 psDevInfo->ui32TimeStamp++;
1067
1068#if defined(NO_HARDWARE)
1069 bPoweredDown = IMG_TRUE;
1070#else
1071 bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE;
1072#endif
1073
1074
1075
1076 if (bPoweredDown)
1077 {
1078 ui32LockupCounter = 0;
1079 }
1080 else
1081 {
1082
1083 ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
1084 if (psDevInfo->ui32EDMTaskReg1 != 0)
1085 {
1086 ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
1087 }
1088 if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
1089 (psDevInfo->ui32NumResets == ui32NumResets))
1090 {
1091 ui32LockupCounter++;
1092 if (ui32LockupCounter == 3)
1093 {
1094 ui32LockupCounter = 0;
1095 PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
1096
1097 bLockup = IMG_TRUE;
1098 }
1099 }
1100 else
1101 {
1102 ui32LockupCounter = 0;
1103 ui32EDMTasks = ui32CurrentEDMTasks;
1104 ui32NumResets = psDevInfo->ui32NumResets;
1105 }
1106 }
1107
1108 if (bLockup)
1109 {
1110 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1111
1112
1113 psSGXHostCtl->ui32HostDetectedLockups ++;
1114
1115
1116 HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID);
1117 }
1118}
1119#endif
1120
1121
1122#if defined(SYS_USING_INTERRUPTS)
1123
1124IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
1125{
1126 IMG_BOOL bInterruptProcessed = IMG_FALSE;
1127
1128
1129
1130 {
1131 IMG_UINT32 ui32EventStatus, ui32EventEnable;
1132 IMG_UINT32 ui32EventClear = 0;
1133#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1134 IMG_UINT32 ui32EventStatus2, ui32EventEnable2;
1135#endif
1136 IMG_UINT32 ui32EventClear2 = 0;
1137 PVRSRV_DEVICE_NODE *psDeviceNode;
1138 PVRSRV_SGXDEV_INFO *psDevInfo;
1139
1140
1141 if(pvData == IMG_NULL)
1142 {
1143 PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
1144 return bInterruptProcessed;
1145 }
1146
1147 psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
1148 psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
1149
1150 ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
1151 ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
1152
1153
1154 ui32EventStatus &= ui32EventEnable;
1155
1156#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1157 ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
1158 ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2);
1159
1160
1161 ui32EventStatus2 &= ui32EventEnable2;
1162#endif
1163
1164
1165
1166 if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
1167 {
1168 ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
1169 }
1170
1171#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1172 if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK)
1173 {
1174 ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK;
1175 }
1176
1177 if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK)
1178 {
1179 ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK;
1180 }
1181#endif
1182
1183 if (ui32EventClear || ui32EventClear2)
1184 {
1185 bInterruptProcessed = IMG_TRUE;
1186
1187
1188 ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
1189
1190
1191 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
1192 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2);
1193 }
1194 }
1195
1196 return bInterruptProcessed;
1197}
1198
1199
1200static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
1201{
1202 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
1203 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
1204 SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
1205
1206 if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
1207 ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
1208 {
1209 HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
1210 }
1211
1212#if defined(OS_SUPPORTS_IN_LISR)
1213 if (psDeviceNode->bReProcessDeviceCommandComplete)
1214 {
1215 SGXScheduleProcessQueuesKM(psDeviceNode);
1216 }
1217#endif
1218
1219 SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
1220}
1221#endif
1222
1223
1224
1225#if defined(SUPPORT_MEMORY_TILING)
1226PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
1227 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1228 IMG_UINT32 ui32TilingStride,
1229 IMG_UINT32 *pui32RangeIndex)
1230{
1231#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
1232 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1233 IMG_UINT32 i;
1234 IMG_UINT32 ui32Start;
1235 IMG_UINT32 ui32End;
1236 IMG_UINT32 ui32Offset;
1237 IMG_UINT32 ui32Val;
1238
1239
1240 for(i=0; i<10; i++)
1241 {
1242 if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0)
1243 {
1244
1245 psDevInfo->ui32MemTilingUsage |= 1U << i;
1246
1247 *pui32RangeIndex = i;
1248 goto RangeAllocated;
1249 }
1250 }
1251
1252 PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use"));
1253 return PVRSRV_ERROR_EXCEEDED_HW_LIMITS;
1254
1255RangeAllocated:
1256 ui32Offset = EUR_CR_BIF_TILE0 + (i<<2);
1257
1258 ui32Start = psMemInfo->sDevVAddr.uiAddr;
1259 ui32End = ui32Start + psMemInfo->ui32AllocSize + SGX_MMU_PAGE_SIZE - 1;
1260
1261 ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK)
1262 | (((ui32End>>20) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK)
1263 | (((ui32Start>>20) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK)
1264 | (0x8 << EUR_CR_BIF_TILE0_CFG_SHIFT);
1265
1266
1267 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1268 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1269
1270 ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2);
1271
1272 ui32Val = (((ui32End>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK)
1273 | (((ui32Start>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK);
1274
1275
1276 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1277 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1278
1279 return PVRSRV_OK;
1280#else
1281 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1282 PVR_UNREFERENCED_PARAMETER(psMemInfo);
1283 PVR_UNREFERENCED_PARAMETER(ui32TilingStride);
1284 PVR_UNREFERENCED_PARAMETER(pui32RangeIndex);
1285
1286 PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: device does not support memory tiling"));
1287 return PVRSRV_ERROR_NOT_SUPPORTED;
1288#endif
1289}
1290
1291PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
1292 IMG_UINT32 ui32RangeIndex)
1293{
1294#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
1295 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1296 IMG_UINT32 ui32Offset;
1297 IMG_UINT32 ui32Val;
1298
1299 if(ui32RangeIndex >= 10)
1300 {
1301 PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index "));
1302 return PVRSRV_ERROR_INVALID_PARAMS;
1303 }
1304
1305
1306 psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex);
1307
1308
1309 ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2);
1310 ui32Val = 0;
1311
1312
1313 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
1314 PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
1315
1316 return PVRSRV_OK;
1317#else
1318 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1319 PVR_UNREFERENCED_PARAMETER(ui32RangeIndex);
1320
1321 PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: device does not support memory tiling"));
1322 return PVRSRV_ERROR_NOT_SUPPORTED;
1323#endif
1324}
1325#endif
1326
1327
1328PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
1329{
1330 DEVICE_MEMORY_INFO *psDevMemoryInfo;
1331 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
1332
1333
1334 psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE;
1335 psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS;
1336#if defined(PDUMP)
1337 {
1338
1339 SGX_DEVICE_MAP *psSGXDeviceMemMap;
1340 SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
1341 (IMG_VOID**)&psSGXDeviceMemMap);
1342
1343 psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName;
1344 PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL);
1345 }
1346
1347 psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME;
1348#endif
1349
1350 psDeviceNode->pfnInitDevice = &DevInitSGXPart1;
1351 psDeviceNode->pfnDeInitDevice = &DevDeInitSGX;
1352
1353 psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck;
1354#if defined(PDUMP)
1355 psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump;
1356 psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID;
1357#endif
1358
1359
1360 psDeviceNode->pfnMMUInitialise = &MMU_Initialise;
1361 psDeviceNode->pfnMMUFinalise = &MMU_Finalise;
1362 psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap;
1363 psDeviceNode->pfnMMUCreate = &MMU_Create;
1364 psDeviceNode->pfnMMUDelete = &MMU_Delete;
1365 psDeviceNode->pfnMMUAlloc = &MMU_Alloc;
1366 psDeviceNode->pfnMMUFree = &MMU_Free;
1367 psDeviceNode->pfnMMUMapPages = &MMU_MapPages;
1368 psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow;
1369 psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages;
1370 psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter;
1371 psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr;
1372 psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr;
1373
1374#if defined (SYS_USING_INTERRUPTS)
1375
1376
1377 psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
1378 psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
1379#endif
1380
1381#if defined(SUPPORT_MEMORY_TILING)
1382 psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange;
1383 psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange;
1384#endif
1385
1386
1387
1388 psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete;
1389
1390
1391
1392 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
1393
1394 psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
1395
1396
1397 psDevMemoryInfo->ui32Flags = 0;
1398
1399
1400 if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
1401 sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
1402 (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
1403 "Array of Device Memory Heap Info") != PVRSRV_OK)
1404 {
1405 PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
1406 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1407 }
1408 OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID);
1409
1410 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
1411
1412
1413
1414
1415
1416 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
1417 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
1418 psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
1419 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1420 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1421 | PVRSRV_HAP_SINGLE_PROCESS;
1422 psDeviceMemoryHeap->pszName = "General";
1423 psDeviceMemoryHeap->pszBSName = "General BS";
1424 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1425
1426 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1427#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
1428
1429 psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1430#endif
1431 psDeviceMemoryHeap++;
1432
1433
1434
1435 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
1436 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
1437 psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
1438 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1439 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1440 | PVRSRV_HAP_MULTI_PROCESS;
1441 psDeviceMemoryHeap->pszName = "TA Data";
1442 psDeviceMemoryHeap->pszBSName = "TA Data BS";
1443 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1444
1445 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1446 psDeviceMemoryHeap++;
1447
1448
1449
1450 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
1451 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
1452 psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
1453 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1454 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1455 | PVRSRV_HAP_MULTI_PROCESS;
1456 psDeviceMemoryHeap->pszName = "Kernel Code";
1457 psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
1458 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1459
1460 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1461 psDeviceMemoryHeap++;
1462
1463
1464
1465 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
1466 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
1467 psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
1468 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1469 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1470 | PVRSRV_HAP_MULTI_PROCESS;
1471 psDeviceMemoryHeap->pszName = "KernelData";
1472 psDeviceMemoryHeap->pszBSName = "KernelData BS";
1473 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1474
1475 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1476 psDeviceMemoryHeap++;
1477
1478
1479
1480 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
1481 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
1482
1483
1484
1485
1486
1487
1488 psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
1489 PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE);
1490 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1491 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1492 | PVRSRV_HAP_SINGLE_PROCESS;
1493 psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
1494 psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
1495 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1496
1497 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1498 psDeviceMemoryHeap++;
1499
1500
1501
1502 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
1503 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
1504
1505 psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
1506 PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE);
1507 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1508 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1509 | PVRSRV_HAP_SINGLE_PROCESS;
1510 psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
1511 psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
1512 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1513
1514 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1515 psDeviceMemoryHeap++;
1516
1517
1518
1519 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
1520 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
1521 psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
1522 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1523 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1524 | PVRSRV_HAP_SINGLE_PROCESS;
1525 psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
1526 psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
1527 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1528
1529 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1530 psDeviceMemoryHeap++;
1531
1532
1533
1534 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
1535 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
1536 psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
1537 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1538 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1539 | PVRSRV_HAP_SINGLE_PROCESS;
1540 psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
1541 psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
1542 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1543
1544 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1545 psDeviceMemoryHeap++;
1546
1547
1548
1549 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
1550 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
1551 psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
1552 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1553 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1554 | PVRSRV_HAP_MULTI_PROCESS;
1555 psDeviceMemoryHeap->pszName = "CacheCoherent";
1556 psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
1557 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1558
1559 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1560
1561 psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1562 psDeviceMemoryHeap++;
1563
1564
1565
1566 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID);
1567 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE;
1568 psDeviceMemoryHeap->ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE;
1569 psDeviceMemoryHeap->pszName = "3DParameters";
1570 psDeviceMemoryHeap->pszBSName = "3DParameters BS";
1571#if defined(SUPPORT_PERCONTEXT_PB)
1572 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1573 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1574 | PVRSRV_HAP_SINGLE_PROCESS;
1575 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1576#else
1577 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1578 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1579 | PVRSRV_HAP_MULTI_PROCESS;
1580 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1581#endif
1582
1583 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1584 psDeviceMemoryHeap++;
1585
1586
1587#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
1588
1589 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
1590 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
1591 psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
1592 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS;
1593 psDeviceMemoryHeap->pszName = "GeneralMapping";
1594 psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
1595 #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
1596
1597
1598
1599
1600
1601
1602
1603 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1604 #else
1605 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1606 #endif
1607
1608
1609 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1610
1611 psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1612 psDeviceMemoryHeap++;
1613#endif
1614
1615
1616#if defined(SGX_FEATURE_2D_HARDWARE)
1617
1618 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
1619 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
1620 psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
1621 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1622 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1623 | PVRSRV_HAP_SINGLE_PROCESS;
1624 psDeviceMemoryHeap->pszName = "2D";
1625 psDeviceMemoryHeap->pszBSName = "2D BS";
1626
1627 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
1628
1629 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1630 psDeviceMemoryHeap++;
1631#endif
1632
1633
1634#if defined(FIX_HW_BRN_26915)
1635
1636
1637 psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID);
1638 psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE;
1639 psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE;
1640 psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
1641 | PVRSRV_MEM_RAM_BACKED_ALLOCATION
1642 | PVRSRV_HAP_SINGLE_PROCESS;
1643 psDeviceMemoryHeap->pszName = "CGBuffer";
1644 psDeviceMemoryHeap->pszBSName = "CGBuffer BS";
1645
1646 psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
1647
1648 psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
1649 psDeviceMemoryHeap++;
1650#endif
1651
1652
1653 psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
1654
1655 return PVRSRV_OK;
1656}
1657
1658#if defined(PDUMP)
1659static
1660PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
1661{
1662 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice);
1663 psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
1664 PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset."));
1665
1666 return PVRSRV_OK;
1667}
1668#endif
1669
1670
1671IMG_EXPORT
1672PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
1673 SGX_CLIENT_INFO* psClientInfo)
1674{
1675 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
1676
1677
1678
1679 psDevInfo->ui32ClientRefCount++;
1680
1681
1682
1683 psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
1684
1685
1686
1687 OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
1688
1689
1690 return PVRSRV_OK;
1691}
1692
1693
1694IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo)
1695{
1696 PVR_LOG(("SGX panic"));
1697 SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
1698 OSPanic();
1699}
1700
1701
1702PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
1703{
1704 PVRSRV_ERROR eError;
1705 PVRSRV_SGXDEV_INFO *psDevInfo;
1706 IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch;
1707#if !defined(NO_HARDWARE)
1708 PPVRSRV_KERNEL_MEM_INFO psMemInfo;
1709 PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
1710 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
1711 SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
1712 IMG_BOOL bStructSizesFailed;
1713
1714
1715 IMG_BOOL bCheckCoreRev;
1716 const IMG_UINT32 aui32CoreRevExceptions[] =
1717 {
1718 0x10100, 0x10101
1719 };
1720 const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
1721 IMG_UINT i;
1722#endif
1723
1724
1725 if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
1726 {
1727 PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
1728 eError = PVRSRV_ERROR_INVALID_PARAMS;
1729 goto chk_exit;
1730 }
1731
1732 psDevInfo = psDeviceNode->pvDevice;
1733
1734
1735
1736 ui32BuildOptions = (SGX_BUILD_OPTIONS);
1737 if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
1738 {
1739 ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
1740 if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
1741 {
1742 PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
1743 "extra options present in client-side driver: (0x%x). Please check sgx_options.h",
1744 psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
1745 }
1746
1747 if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
1748 {
1749 PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
1750 "extra options present in KM: (0x%x). Please check sgx_options.h",
1751 ui32BuildOptions & ui32BuildOptionsMismatch ));
1752 }
1753 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1754 goto chk_exit;
1755 }
1756 else
1757 {
1758 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
1759 }
1760
1761#if !defined (NO_HARDWARE)
1762 psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1763
1764
1765 psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
1766 psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
1767 psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
1768 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
1769
1770
1771 if(eError != PVRSRV_OK)
1772 {
1773 PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
1774 goto chk_exit;
1775 }
1776 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
1777 if( (psSGXFeatures->ui32DDKVersion !=
1778 ((PVRVERSION_MAJ << 16) |
1779 (PVRVERSION_MIN << 8) |
1780 PVRVERSION_BRANCH) ) ||
1781 (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
1782 {
1783 PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).",
1784 PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
1785 eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
1786 PVR_DBG_BREAK;
1787 goto chk_exit;
1788 }
1789 else
1790 {
1791 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]",
1792 PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
1793 }
1794
1795
1796 if (psSGXFeatures->ui32CoreRevSW == 0)
1797 {
1798
1799
1800 PVR_LOG(("SGXInit: HW core rev (%x) check skipped.",
1801 psSGXFeatures->ui32CoreRev));
1802 }
1803 else
1804 {
1805
1806 bCheckCoreRev = IMG_TRUE;
1807 for(i=0; i<ui32NumCoreExceptions; i+=2)
1808 {
1809 if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
1810 (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) )
1811 {
1812 PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.",
1813 psSGXFeatures->ui32CoreRev,
1814 psSGXFeatures->ui32CoreRevSW));
1815 bCheckCoreRev = IMG_FALSE;
1816 }
1817 }
1818
1819 if (bCheckCoreRev)
1820 {
1821 if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
1822 {
1823 PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).",
1824 psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
1825 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1826 goto chk_exit;
1827 }
1828 else
1829 {
1830 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]",
1831 psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
1832 }
1833 }
1834 }
1835
1836
1837 psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
1838
1839 bStructSizesFailed = IMG_FALSE;
1840
1841 CHECK_SIZE(HOST_CTL);
1842 CHECK_SIZE(COMMAND);
1843#if defined(SGX_FEATURE_2D_HARDWARE)
1844 CHECK_SIZE(2DCMD);
1845 CHECK_SIZE(2DCMD_SHARED);
1846#endif
1847 CHECK_SIZE(CMDTA);
1848 CHECK_SIZE(CMDTA_SHARED);
1849 CHECK_SIZE(TRANSFERCMD);
1850 CHECK_SIZE(TRANSFERCMD_SHARED);
1851
1852 CHECK_SIZE(3DREGISTERS);
1853 CHECK_SIZE(HWPBDESC);
1854 CHECK_SIZE(HWRENDERCONTEXT);
1855 CHECK_SIZE(HWRENDERDETAILS);
1856 CHECK_SIZE(HWRTDATA);
1857 CHECK_SIZE(HWRTDATASET);
1858 CHECK_SIZE(HWTRANSFERCONTEXT);
1859
1860 if (bStructSizesFailed == IMG_TRUE)
1861 {
1862 PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
1863 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1864 goto chk_exit;
1865 }
1866 else
1867 {
1868 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
1869 }
1870
1871
1872 ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
1873 if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
1874 {
1875 ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
1876 if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
1877 {
1878 PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
1879 "extra options present in driver: (0x%x). Please check sgx_options.h",
1880 (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
1881 }
1882
1883 if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
1884 {
1885 PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
1886 "extra options present in microkernel: (0x%x). Please check sgx_options.h",
1887 ui32BuildOptions & ui32BuildOptionsMismatch ));
1888 }
1889 eError = PVRSRV_ERROR_BUILD_MISMATCH;
1890 goto chk_exit;
1891 }
1892 else
1893 {
1894 PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
1895 }
1896#endif
1897
1898 eError = PVRSRV_OK;
1899chk_exit:
1900#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
1901 return PVRSRV_OK;
1902#else
1903 return eError;
1904#endif
1905}
1906
1907static
1908PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
1909 PVRSRV_DEVICE_NODE *psDeviceNode)
1910{
1911 PVRSRV_ERROR eError;
1912 SGXMKIF_COMMAND sCommandData;
1913 PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt;
1914 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
1915 SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes;
1916
1917 PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1918
1919 if (! psMemInfo->pvLinAddrKM)
1920 {
1921 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
1922 return PVRSRV_ERROR_INVALID_PARAMS;
1923 }
1924 psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
1925 psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
1926 psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
1927
1928 psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
1929
1930
1931 OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
1932 OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
1933
1934
1935 sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr;
1936
1937 PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo");
1938 eError = SGXScheduleCCBCommandKM(psDeviceNode,
1939 SGXMKIF_CMD_GETMISCINFO,
1940 &sCommandData,
1941 KERNEL_ID,
1942 0);
1943
1944 if (eError != PVRSRV_OK)
1945 {
1946 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
1947 return eError;
1948 }
1949
1950
1951#if !defined(NO_HARDWARE)
1952 {
1953 IMG_BOOL bExit;
1954
1955 bExit = IMG_FALSE;
1956 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
1957 {
1958 if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
1959 {
1960 bExit = IMG_TRUE;
1961 break;
1962 }
1963 } END_LOOP_UNTIL_TIMEOUT();
1964
1965
1966 if (!bExit)
1967 {
1968 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
1969 return PVRSRV_ERROR_TIMEOUT;
1970 }
1971 }
1972#endif
1973
1974 return PVRSRV_OK;
1975}
1976
1977
1978
1979IMG_EXPORT
1980PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
1981 SGX_MISC_INFO *psMiscInfo,
1982 PVRSRV_DEVICE_NODE *psDeviceNode,
1983 IMG_HANDLE hDevMemContext)
1984{
1985 PVRSRV_ERROR eError;
1986 PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
1987 IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
1988
1989
1990 *pui32MiscInfoFlags = 0;
1991
1992#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
1993 PVR_UNREFERENCED_PARAMETER(hDevMemContext);
1994#endif
1995
1996 switch(psMiscInfo->eRequest)
1997 {
1998#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
1999 case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
2000 {
2001 IMG_UINT32 ui32MaskDM;
2002 IMG_UINT32 ui32CtrlWEnable;
2003 IMG_UINT32 ui32CtrlREnable;
2004 IMG_UINT32 ui32CtrlTrapEnable;
2005 IMG_UINT32 ui32RegVal;
2006 IMG_UINT32 ui32StartRegVal;
2007 IMG_UINT32 ui32EndRegVal;
2008 SGXMKIF_COMMAND sCommandData;
2009
2010
2011 if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
2012 {
2013
2014 IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
2015 IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd;
2016
2017
2018 ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK;
2019 ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK;
2020
2021 ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask;
2022 ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite;
2023 ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead;
2024 ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped;
2025
2026
2027 ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) |
2028 ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) |
2029 ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) |
2030 ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK);
2031 }
2032 else
2033 {
2034
2035 ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0;
2036 }
2037
2038
2039 sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex;
2040 sCommandData.ui32Data[1] = ui32StartRegVal;
2041 sCommandData.ui32Data[2] = ui32EndRegVal;
2042 sCommandData.ui32Data[3] = ui32RegVal;
2043
2044
2045 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2046
2047 PDUMPCOMMENT("Microkernel kick for setting a data breakpoint");
2048 eError = SGXScheduleCCBCommandKM(psDeviceNode,
2049 SGXMKIF_CMD_DATABREAKPOINT,
2050 &sCommandData,
2051 KERNEL_ID,
2052 0);
2053
2054 if (eError != PVRSRV_OK)
2055 {
2056 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));
2057 return eError;
2058 }
2059
2060#if defined(NO_HARDWARE)
2061
2062 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2063#else
2064 {
2065 IMG_BOOL bExit;
2066
2067 bExit = IMG_FALSE;
2068 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
2069 {
2070 if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0)
2071 {
2072 bExit = IMG_TRUE;
2073
2074 psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
2075 break;
2076 }
2077 } END_LOOP_UNTIL_TIMEOUT();
2078
2079
2080 if (!bExit)
2081 {
2082 PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear"));
2083 return PVRSRV_ERROR_TIMEOUT;
2084 }
2085 }
2086#endif
2087
2088 return PVRSRV_OK;
2089 }
2090
2091 case SGX_MISC_INFO_REQUEST_WAIT_FOR_BREAKPOINT:
2092 {
2093
2094
2095 PDUMPCOMMENT("Wait for data breakpoint hit");
2096
2097#if defined(NO_HARDWARE) && defined(PDUMP)
2098 {
2099 PDUMPREGPOL(SGX_PDUMPREG_NAME,
2100 EUR_CR_EVENT_STATUS2,
2101 EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK,
2102 EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK);
2103
2104 PDUMPREG(SGX_PDUMPREG_NAME,
2105 EUR_CR_EVENT_HOST_CLEAR2,
2106 EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK);
2107
2108 PDUMPCOMMENT("Breakpoint detected. Wait a bit to show that pipeline stops in simulation");
2109 PDUMPIDL(2000);
2110
2111 PDUMPCOMMENT("Now we can resume");
2112 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BREAKPOINT_TRAP, EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
2113 }
2114#else
2115 {
2116
2117 }
2118#endif
2119 return PVRSRV_OK;
2120 }
2121
2122 case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT:
2123 {
2124
2125
2126
2127
2128
2129
2130
2131#if !defined(NO_HARDWARE)
2132 IMG_BOOL bTrappedBPMaster;
2133 IMG_BOOL abTrappedBPPerCore[SGX_FEATURE_MP_CORE_COUNT];
2134 IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum;
2135 IMG_BOOL bTrappedBPAny;
2136
2137 ui32TrappedBPCoreNum = 0;
2138 bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT));
2139 bTrappedBPAny = bTrappedBPMaster;
2140 for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++)
2141 {
2142 abTrappedBPPerCore[ui32CoreNum] = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)));
2143 if (abTrappedBPPerCore[ui32CoreNum])
2144 {
2145 bTrappedBPAny = IMG_TRUE;
2146 ui32TrappedBPCoreNum = ui32CoreNum;
2147 }
2148 }
2149
2150 psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny;
2151
2152 if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP)
2153 {
2154 IMG_UINT32 ui32Info0, ui32Info1;
2155
2156 ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum));
2157 ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum));
2158
2159 psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
2160 psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
2161 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
2162 psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK);
2163 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
2164 psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
2165 psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum;
2166 }
2167#endif
2168 return PVRSRV_OK;
2169 }
2170
2171 case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT:
2172 {
2173
2174
2175
2176#if !defined(NO_HARDWARE)
2177 IMG_UINT32 ui32CoreNum;
2178 IMG_BOOL bMaster;
2179 IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum;
2180
2181 ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum;
2182 bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT;
2183 if (bMaster)
2184 {
2185
2186
2187 ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
2188 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK);
2189 do
2190 {
2191 ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
2192 }
2193 while (ui32OldSeqNum == ui32NewSeqNum);
2194 }
2195 else
2196 {
2197
2198 ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
2199 OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
2200 do
2201 {
2202 ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
2203 }
2204 while (ui32OldSeqNum == ui32NewSeqNum);
2205 }
2206#endif
2207 return PVRSRV_OK;
2208 }
2209#endif
2210
2211 case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
2212 {
2213 psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
2214 return PVRSRV_OK;
2215 }
2216
2217 case SGX_MISC_INFO_REQUEST_ACTIVEPOWER:
2218 {
2219 psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents;
2220 return PVRSRV_OK;
2221 }
2222
2223 case SGX_MISC_INFO_REQUEST_LOCKUPS:
2224 {
2225#if defined(SUPPORT_HW_RECOVERY)
2226 psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups;
2227 psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups;
2228#else
2229 psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0;
2230 psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0;
2231#endif
2232 return PVRSRV_OK;
2233 }
2234
2235 case SGX_MISC_INFO_REQUEST_SPM:
2236 {
2237
2238 return PVRSRV_OK;
2239 }
2240
2241 case SGX_MISC_INFO_REQUEST_SGXREV:
2242 {
2243 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2244 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
2245 if(eError != PVRSRV_OK)
2246 {
2247 PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
2248 eError));
2249 return eError;
2250 }
2251 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2252
2253
2254 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2255
2256
2257 PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n",
2258 psSGXFeatures->ui32CoreRev,
2259 psSGXFeatures->ui32CoreIdSW,
2260 psSGXFeatures->ui32CoreRevSW));
2261 PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n",
2262 psSGXFeatures->ui32DDKVersion,
2263 psSGXFeatures->ui32DDKBuild));
2264
2265
2266 return PVRSRV_OK;
2267 }
2268
2269 case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
2270 {
2271 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2272
2273 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2274
2275
2276 OSMemSet(psMemInfo->pvLinAddrKM, 0,
2277 sizeof(PVRSRV_SGX_MISCINFO_INFO));
2278
2279 psSGXFeatures->ui32DDKVersion =
2280 (PVRVERSION_MAJ << 16) |
2281 (PVRVERSION_MIN << 8) |
2282 PVRVERSION_BRANCH;
2283 psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
2284
2285
2286 psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
2287
2288#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
2289
2290 psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr;
2291 psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
2292#endif
2293
2294
2295 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2296 return PVRSRV_OK;
2297 }
2298
2299#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
2300 case SGX_MISC_INFO_REQUEST_MEMREAD:
2301 case SGX_MISC_INFO_REQUEST_MEMCOPY:
2302 {
2303 PVRSRV_ERROR eError;
2304 PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
2305 PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc;
2306 PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest;
2307
2308 {
2309
2310 *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
2311 psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc;
2312
2313 if(psMiscInfo->sDevVAddrSrc.uiAddr != 0)
2314 {
2315 psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc;
2316 }
2317 else
2318 {
2319 return PVRSRV_ERROR_INVALID_PARAMS;
2320 }
2321 }
2322
2323 if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY)
2324 {
2325
2326 *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE;
2327 psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest;
2328
2329 if(psMiscInfo->sDevVAddrDest.uiAddr != 0)
2330 {
2331 psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest;
2332 }
2333 else
2334 {
2335 return PVRSRV_ERROR_INVALID_PARAMS;
2336 }
2337 }
2338
2339
2340 if(psMiscInfo->hDevMemContext != IMG_NULL)
2341 {
2342 SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr);
2343
2344
2345 psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr;
2346 }
2347 else
2348 {
2349 return PVRSRV_ERROR_INVALID_PARAMS;
2350 }
2351
2352
2353 eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
2354 if(eError != PVRSRV_OK)
2355 {
2356 PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
2357 eError));
2358 return eError;
2359 }
2360 psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
2361
2362#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
2363 if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
2364 {
2365 return PVRSRV_ERROR_INVALID_MISCINFO;
2366 }
2367#endif
2368
2369 psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
2370 return PVRSRV_OK;
2371 }
2372#endif
2373
2374#if defined(SUPPORT_SGX_HWPERF)
2375 case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
2376 {
2377 PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus;
2378 const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS |
2379 PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON |
2380 PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON |
2381 PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON;
2382 SGXMKIF_COMMAND sCommandData = {0};
2383
2384
2385 if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0)
2386 {
2387 return PVRSRV_ERROR_INVALID_PARAMS;
2388 }
2389
2390 #if defined(PDUMP)
2391 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
2392 "SGX ukernel HWPerf status %u\n",
2393 psSetHWPerfStatus->ui32NewHWPerfStatus);
2394 #endif
2395
2396
2397 #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
2398 OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0],
2399 &psSetHWPerfStatus->aui32PerfGroup[0],
2400 sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup));
2401 OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0],
2402 &psSetHWPerfStatus->aui32PerfBit[0],
2403 sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit));
2404 #if defined(PDUMP)
2405 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2406 offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup),
2407 sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup),
2408 PDUMP_FLAGS_CONTINUOUS,
2409 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2410 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2411 offsetof(SGXMKIF_HOST_CTL, aui32PerfBit),
2412 sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit),
2413 PDUMP_FLAGS_CONTINUOUS,
2414 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2415 #endif
2416 #else
2417 psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup;
2418 #if defined(PDUMP)
2419 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
2420 offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup),
2421 sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup),
2422 PDUMP_FLAGS_CONTINUOUS,
2423 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
2424 #endif
2425 #endif
2426
2427
2428 sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus;
2429 eError = SGXScheduleCCBCommandKM(psDeviceNode,
2430 SGXMKIF_CMD_SETHWPERFSTATUS,
2431 &sCommandData,
2432 KERNEL_ID,
2433 0);
2434 return eError;
2435 }
2436#endif
2437
2438 case SGX_MISC_INFO_DUMP_DEBUG_INFO:
2439 {
2440 PVR_LOG(("User requested SGX debug info"));
2441
2442
2443 SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE);
2444
2445 return PVRSRV_OK;
2446 }
2447
2448 case SGX_MISC_INFO_PANIC:
2449 {
2450 PVR_LOG(("User requested SGX panic"));
2451
2452 SGXPanic(psDeviceNode->pvDevice);
2453
2454 return PVRSRV_OK;
2455 }
2456
2457 default:
2458 {
2459
2460 return PVRSRV_ERROR_INVALID_PARAMS;
2461 }
2462 }
2463}
2464
2465
2466IMG_EXPORT
2467PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
2468 IMG_UINT32 ui32ArraySize,
2469 PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry,
2470 IMG_UINT32 *pui32DataCount,
2471 IMG_UINT32 *pui32ClockSpeed,
2472 IMG_UINT32 *pui32HostTimeStamp)
2473{
2474 PVRSRV_ERROR eError = PVRSRV_OK;
2475 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
2476 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
2477 SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
2478 IMG_UINT i;
2479
2480 for (i = 0;
2481 psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
2482 i++)
2483 {
2484 SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
2485
2486 psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
2487 psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
2488 psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal;
2489 psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info;
2490 psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
2491 psMKPerfEntry->ui32TimeWraps,
2492 psMKPerfEntry->ui32Time);
2493 OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0],
2494 &psMKPerfEntry->ui32Counters[0][0],
2495 sizeof(psMKPerfEntry->ui32Counters));
2496
2497 psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
2498 }
2499
2500 *pui32DataCount = i;
2501 *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
2502 *pui32HostTimeStamp = OSClockus();
2503
2504 return eError;
2505}
2506
2507
diff --git a/drivers/gpu/pvr/sgx/sgxkick.c b/drivers/gpu/pvr/sgx/sgxkick.c
new file mode 100644
index 00000000000..8a229c9fd3c
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxkick.c
@@ -0,0 +1,713 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28#include "services_headers.h"
29#include "sgxinfo.h"
30#include "sgxinfokm.h"
31#if defined (PDUMP)
32#include "sgxapi_km.h"
33#include "pdump_km.h"
34#endif
35#include "sgx_bridge_km.h"
36#include "osfunc.h"
37#include "pvr_debug.h"
38#include "sgxutils.h"
39
40IMG_EXPORT
41PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
42{
43 PVRSRV_ERROR eError;
44 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
45 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo;
46 SGXMKIF_CMDTA_SHARED *psTACmd;
47 IMG_UINT32 i;
48
49 if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset))
50 {
51 PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
52 return PVRSRV_ERROR_INVALID_PARAMS;
53 }
54
55
56 psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset);
57
58
59 if (psCCBKick->hTA3DSyncInfo)
60 {
61 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
62 psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
63
64 psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
65
66 if (psCCBKick->bTADependency)
67 {
68 psSyncInfo->psSyncData->ui32WriteOpsPending++;
69 }
70 }
71
72 if (psCCBKick->hTASyncInfo != IMG_NULL)
73 {
74 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
75
76 psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
77 psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
78
79 psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80 psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
81 }
82
83 if (psCCBKick->h3DSyncInfo != IMG_NULL)
84 {
85 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
86
87 psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
88 psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
89
90 psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
91 psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
92 }
93
94 psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals;
95 if (psCCBKick->ui32NumTAStatusVals != 0)
96 {
97
98 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
99 {
100#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
101 psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus;
102#else
103 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
104 psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
105 psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
106#endif
107 }
108 }
109
110 psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
111 if (psCCBKick->ui32Num3DStatusVals != 0)
112 {
113
114 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
115 {
116#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
117 psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus;
118#else
119 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
120 psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
121 psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
122#endif
123 }
124 }
125
126
127#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
128
129 psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs;
130 for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
131 {
132 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
133
134 psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
135 psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
136
137
138 psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
139
140 psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
141 }
142
143 psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs;
144 for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
145 {
146 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
147
148 psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
149 psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
150
151
152 psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
153
154 psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
155 }
156
157 psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs;
158 for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
159 {
160 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
161
162 psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
163 psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
164
165
166 psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
167
168 psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
169 }
170#else
171
172 psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
173 for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
174 {
175 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
176
177 psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
178 psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
179
180
181 psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
182
183 psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
184 }
185#endif
186
187 if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
188 {
189 PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
190 (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
191 SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
192 IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
193
194 PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->ui32AllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) +
195 (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs)));
196
197 psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
198#if defined(PDUMP)
199 if (PDumpIsCaptureFrameKM())
200 {
201 PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
202 PDUMPMEM(IMG_NULL,
203 psHWDstSyncListMemInfo,
204 0,
205 sizeof(SGXMKIF_HWDEVICE_SYNC_LIST),
206 0,
207 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
208 }
209#endif
210
211 for (i=0; i<ui32NumDstSyncs; i++)
212 {
213 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
214
215 if (psSyncInfo)
216 {
217 psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
218 psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
219
220 psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
221 psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
222
223 #if defined(PDUMP)
224 if (PDumpIsCaptureFrameKM())
225 {
226 IMG_UINT32 ui32ModifiedValue;
227 IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData)
228 + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT));
229 IMG_UINT32 ui32WOpsOffset = ui32SyncOffset
230 + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal);
231 IMG_UINT32 ui32ROpsOffset = ui32SyncOffset
232 + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal);
233
234 PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i);
235
236 PDUMPMEM(IMG_NULL,
237 psHWDstSyncListMemInfo,
238 ui32SyncOffset,
239 sizeof(PVRSRV_DEVICE_SYNC_OBJECT),
240 0,
241 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
242
243 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
244 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
245 {
246
247 PDUMPCOMMENT("Init RT ROpsComplete\r\n");
248 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
249 psSyncInfo->psSyncDataMemInfoKM,
250 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
251 sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
252 0,
253 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
254
255 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
256 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
257 psSyncInfo->psSyncDataMemInfoKM,
258 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
259 sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
260 0,
261 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
262 }
263
264 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
265
266 ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
267
268 PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i);
269
270 PDUMPMEM(&ui32ModifiedValue,
271 psHWDstSyncListMemInfo,
272 ui32WOpsOffset,
273 sizeof(IMG_UINT32),
274 0,
275 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
276
277 ui32ModifiedValue = 0;
278 PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i);
279
280 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
281 psHWDstSyncListMemInfo,
282 ui32ROpsOffset,
283 sizeof(IMG_UINT32),
284 0,
285 MAKEUNIQUETAG(psHWDstSyncListMemInfo));
286 }
287 #endif
288 }
289 else
290 {
291 psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0;
292 psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0;
293
294 psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0;
295 psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0;
296 }
297 }
298 }
299
300
301
302
303 psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY;
304
305#if defined(PDUMP)
306 if (PDumpIsCaptureFrameKM())
307 {
308 PDUMPCOMMENT("Shared part of TA command\r\n");
309
310 PDUMPMEM(psTACmd,
311 psCCBMemInfo,
312 psCCBKick->ui32CCBDumpWOff,
313 sizeof(SGXMKIF_CMDTA_SHARED),
314 0,
315 MAKEUNIQUETAG(psCCBMemInfo));
316
317#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
318 for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
319 {
320 IMG_UINT32 ui32ModifiedValue;
321 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
322
323 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
324 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
325 {
326
327 PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i);
328 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
329 psSyncInfo->psSyncDataMemInfoKM,
330 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
331 sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
332 0,
333 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
334
335 PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n");
336 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
337 psSyncInfo->psSyncDataMemInfoKM,
338 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
339 sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
340 0,
341 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
342 }
343
344 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
345
346 ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
347
348 PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i);
349
350 PDUMPMEM(&ui32ModifiedValue,
351 psCCBMemInfo,
352 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
353 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
354 sizeof(IMG_UINT32),
355 0,
356 MAKEUNIQUETAG(psCCBMemInfo));
357
358 PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i);
359
360 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
361 psCCBMemInfo,
362 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
363 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
364 sizeof(IMG_UINT32),
365 0,
366 MAKEUNIQUETAG(psCCBMemInfo));
367 }
368
369 for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
370 {
371 IMG_UINT32 ui32ModifiedValue;
372 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
373
374 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
375 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
376 {
377
378 PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i);
379 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
380 psSyncInfo->psSyncDataMemInfoKM,
381 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
382 sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
383 0,
384 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
385
386 PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n");
387 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
388 psSyncInfo->psSyncDataMemInfoKM,
389 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
390 sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
391 0,
392 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
393 }
394
395 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
396
397 ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
398
399 PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i);
400
401 PDUMPMEM(&ui32ModifiedValue,
402 psCCBMemInfo,
403 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
404 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
405 sizeof(IMG_UINT32),
406 0,
407 MAKEUNIQUETAG(psCCBMemInfo));
408
409 PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i);
410
411 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
412 psCCBMemInfo,
413 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
414 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
415 sizeof(IMG_UINT32),
416 0,
417 MAKEUNIQUETAG(psCCBMemInfo));
418 }
419
420 for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
421 {
422 IMG_UINT32 ui32ModifiedValue;
423 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
424
425 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
426 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
427 {
428
429 PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i);
430 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
431 psSyncInfo->psSyncDataMemInfoKM,
432 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
433 sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
434 0,
435 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
436
437 PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n");
438 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
439 psSyncInfo->psSyncDataMemInfoKM,
440 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
441 sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
442 0,
443 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
444 }
445
446 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
447
448 ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
449
450 PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i);
451
452 PDUMPMEM(&ui32ModifiedValue,
453 psCCBMemInfo,
454 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
455 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
456 sizeof(IMG_UINT32),
457 0,
458 MAKEUNIQUETAG(psCCBMemInfo));
459
460 PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i);
461
462 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
463 psCCBMemInfo,
464 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
465 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
466 sizeof(IMG_UINT32),
467 0,
468 MAKEUNIQUETAG(psCCBMemInfo));
469 }
470#else
471 for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
472 {
473 IMG_UINT32 ui32ModifiedValue;
474 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
475
476 if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
477 (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
478 {
479
480 PDUMPCOMMENT("Init RT ROpsComplete\r\n");
481 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
482 psSyncInfo->psSyncDataMemInfoKM,
483 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
484 sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
485 0,
486 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
487
488 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
489 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
490 psSyncInfo->psSyncDataMemInfoKM,
491 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
492 sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
493 0,
494 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
495 }
496
497 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
498
499 ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
500
501 PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
502
503 PDUMPMEM(&ui32ModifiedValue,
504 psCCBMemInfo,
505 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
506 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
507 sizeof(IMG_UINT32),
508 0,
509 MAKEUNIQUETAG(psCCBMemInfo));
510
511 PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
512
513 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
514 psCCBMemInfo,
515 psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
516 (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
517 sizeof(IMG_UINT32),
518 0,
519 MAKEUNIQUETAG(psCCBMemInfo));
520 }
521#endif
522
523 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
524 {
525#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
526 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
527 PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
528 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
529 psCCBMemInfo,
530 psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue),
531 sizeof(IMG_UINT32),
532 0,
533 MAKEUNIQUETAG(psCCBMemInfo));
534#endif
535 }
536
537 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
538 {
539#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
540 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
541 PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
542 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
543 psCCBMemInfo,
544 psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
545 sizeof(IMG_UINT32),
546 0,
547 MAKEUNIQUETAG(psCCBMemInfo));
548#endif
549 }
550 }
551#endif
552
553 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0);
554 if (eError == PVRSRV_ERROR_RETRY)
555 {
556 if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
557 {
558 for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++)
559 {
560
561 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
562
563 if (psSyncInfo)
564 {
565 psSyncInfo->psSyncData->ui32WriteOpsPending--;
566#if defined(PDUMP)
567 if (PDumpIsCaptureFrameKM())
568 {
569 psSyncInfo->psSyncData->ui32LastOpDumpVal--;
570 }
571#endif
572 }
573 }
574 }
575
576#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
577 for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
578 {
579 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
580 psSyncInfo->psSyncData->ui32ReadOpsPending--;
581 }
582 for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
583 {
584 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
585 psSyncInfo->psSyncData->ui32WriteOpsPending--;
586 }
587 for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
588 {
589 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
590 psSyncInfo->psSyncData->ui32ReadOpsPending--;
591 }
592#else
593 for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
594 {
595 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
596 psSyncInfo->psSyncData->ui32ReadOpsPending--;
597 }
598#endif
599
600 return eError;
601 }
602 else if (PVRSRV_OK != eError)
603 {
604 PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed."));
605 return eError;
606 }
607
608
609#if defined(NO_HARDWARE)
610
611
612
613 if (psCCBKick->hTA3DSyncInfo)
614 {
615 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
616
617 if (psCCBKick->bTADependency)
618 {
619 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
620 }
621 }
622
623 if (psCCBKick->hTASyncInfo != IMG_NULL)
624 {
625 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
626
627 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
628 }
629
630 if (psCCBKick->h3DSyncInfo != IMG_NULL)
631 {
632 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
633
634 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
635 }
636
637
638 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
639 {
640#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
641 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo;
642
643 *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
644 + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr
645 - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
646#else
647 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
648 psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
649#endif
650 }
651
652#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
653
654 for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
655 {
656 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
657 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
658 }
659 for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
660 {
661 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
662 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
663 }
664 for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
665 {
666 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
667 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
668 }
669#else
670
671 for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
672 {
673 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
674 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
675 }
676#endif
677
678 if (psCCBKick->bTerminateOrAbort)
679 {
680 if (psCCBKick->ui32NumDstSyncObjects > 0)
681 {
682 PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
683 (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
684 SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
685
686 for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++)
687 {
688 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
689 if (psSyncInfo)
690 psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1;
691 }
692 }
693
694
695 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
696 {
697#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
698 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo;
699
700 *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
701 + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr
702 - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
703#else
704 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
705 psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
706#endif
707 }
708 }
709#endif
710
711 return eError;
712}
713
diff --git a/drivers/gpu/pvr/sgx/sgxpower.c b/drivers/gpu/pvr/sgx/sgxpower.c
new file mode 100644
index 00000000000..aeac6e3db2b
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxpower.c
@@ -0,0 +1,472 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "sgxdefs.h"
30#include "services_headers.h"
31#include "sgxapi_km.h"
32#include "sgx_mkif_km.h"
33#include "sgxutils.h"
34#include "pdump_km.h"
35
36
37#if defined(SUPPORT_HW_RECOVERY)
38static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE *psDeviceNode,
39 SGX_TIMING_INFORMATION *psSGXTimingInfo,
40 IMG_HANDLE *phTimer)
41{
42
43
44
45 *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode,
46 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq);
47 if(*phTimer == IMG_NULL)
48 {
49 PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function"));
50 return PVRSRV_ERROR_OUT_OF_MEMORY;
51 }
52
53 return PVRSRV_OK;
54}
55#endif
56
57
58static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode)
59{
60 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
61#if defined(SGX_DYNAMIC_TIMING_INFO)
62 SGX_TIMING_INFORMATION sSGXTimingInfo = {0};
63#else
64 SGX_DEVICE_MAP *psSGXDeviceMap;
65#endif
66 IMG_UINT32 ui32ActivePowManSampleRate;
67 SGX_TIMING_INFORMATION *psSGXTimingInfo;
68
69
70#if defined(SGX_DYNAMIC_TIMING_INFO)
71 psSGXTimingInfo = &sSGXTimingInfo;
72 SysGetSGXTimingInformation(psSGXTimingInfo);
73#else
74 SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
75 (IMG_VOID**)&psSGXDeviceMap);
76 psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo;
77#endif
78
79#if defined(SUPPORT_HW_RECOVERY)
80 {
81 PVRSRV_ERROR eError;
82 IMG_UINT32 ui32OlduKernelFreq;
83
84 if (psDevInfo->hTimer != IMG_NULL)
85 {
86 ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock;
87 if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq)
88 {
89
90
91 IMG_HANDLE hNewTimer;
92
93 eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer);
94 if (eError == PVRSRV_OK)
95 {
96 eError = OSRemoveTimer(psDevInfo->hTimer);
97 if (eError != PVRSRV_OK)
98 {
99 PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer"));
100 }
101 psDevInfo->hTimer = hNewTimer;
102 }
103 else
104 {
105
106 }
107 }
108 }
109 else
110 {
111 eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer);
112 if (eError != PVRSRV_OK)
113 {
114 return eError;
115 }
116 }
117
118 psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate =
119 psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq;
120 }
121#endif
122
123
124 psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed;
125 psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq;
126
127
128 psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock;
129#if defined(PDUMP)
130 PDUMPCOMMENT("Host Control - Microkernel clock");
131 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
132 offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock),
133 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
134 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
135#endif
136
137 if (psSGXTimingInfo->bEnableActivePM)
138 {
139 ui32ActivePowManSampleRate =
140 psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000;
141
142
143
144
145
146
147
148 ui32ActivePowManSampleRate += 1;
149 }
150 else
151 {
152 ui32ActivePowManSampleRate = 0;
153 }
154
155 psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate;
156#if defined(PDUMP)
157 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
158 offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate),
159 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
160 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
161#endif
162
163 return PVRSRV_OK;
164}
165
166
167static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo)
168{
169 #if defined(SUPPORT_HW_RECOVERY)
170 PVRSRV_ERROR eError;
171
172 eError = OSEnableTimer(psDevInfo->hTimer);
173 if (eError != PVRSRV_OK)
174 {
175 PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer"));
176 }
177 #else
178 PVR_UNREFERENCED_PARAMETER(psDevInfo);
179 #endif
180}
181
182
183static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo,
184 IMG_UINT32 ui32Register,
185 IMG_UINT32 ui32RegisterValue,
186 IMG_CHAR *pszComment)
187{
188 PVR_UNREFERENCED_PARAMETER(psDevInfo);
189 PVR_UNREFERENCED_PARAMETER(ui32Register);
190 PVR_UNREFERENCED_PARAMETER(ui32RegisterValue);
191 PVR_UNREFERENCED_PARAMETER(pszComment);
192
193 #if !defined(NO_HARDWARE)
194 PVR_ASSERT(psDevInfo != IMG_NULL);
195
196
197 if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2),
198 0,
199 ui32RegisterValue,
200 MAX_HW_TIME_US/WAIT_TRY_COUNT,
201 WAIT_TRY_COUNT) != PVRSRV_OK)
202 {
203 PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment));
204 PVR_DBG_BREAK;
205 }
206 #endif
207
208 PDUMPCOMMENT("%s", pszComment);
209 PDUMPREGPOL(SGX_PDUMPREG_NAME, ui32Register, 0, ui32RegisterValue);
210}
211
212
213PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle,
214 PVRSRV_DEV_POWER_STATE eNewPowerState,
215 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
216{
217 if ((eNewPowerState != eCurrentPowerState) &&
218 (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
219 {
220 PVRSRV_ERROR eError;
221 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
222 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
223 IMG_UINT32 ui32PowerCmd, ui32CompleteStatus;
224 SGXMKIF_COMMAND sCommand = {0};
225 IMG_UINT32 ui32Core;
226
227 #if defined(SUPPORT_HW_RECOVERY)
228
229 eError = OSDisableTimer(psDevInfo->hTimer);
230 if (eError != PVRSRV_OK)
231 {
232 PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer"));
233 return eError;
234 }
235 #endif
236
237 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
238 {
239
240 ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF;
241 ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE;
242 PDUMPCOMMENT("SGX power off request");
243 }
244 else
245 {
246
247 ui32PowerCmd = PVRSRV_POWERCMD_IDLE;
248 ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE;
249 PDUMPCOMMENT("SGX idle request");
250 }
251
252 sCommand.ui32Data[1] = ui32PowerCmd;
253
254 eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0);
255 if (eError != PVRSRV_OK)
256 {
257 PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command"));
258 return eError;
259 }
260
261
262 #if !defined(NO_HARDWARE)
263 if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus,
264 ui32CompleteStatus,
265 ui32CompleteStatus,
266 MAX_HW_TIME_US/WAIT_TRY_COUNT,
267 WAIT_TRY_COUNT) != PVRSRV_OK)
268 {
269 PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
270 PVR_DBG_BREAK;
271 }
272 #endif
273
274 #if defined(PDUMP)
275 PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel.");
276 PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo,
277 offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
278 ui32CompleteStatus,
279 ui32CompleteStatus,
280 PDUMP_POLL_OPERATOR_EQUAL,
281 0,
282 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
283 #endif
284
285 for (ui32Core = 0; ui32Core < SGX_FEATURE_MP_CORE_COUNT; ui32Core++)
286 {
287
288 SGXPollForClockGating(psDevInfo,
289 SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core),
290 psDevInfo->ui32ClkGateStatusMask,
291 "Wait for SGX clock gating");
292 }
293
294 #if defined(SGX_FEATURE_MP)
295
296 SGXPollForClockGating(psDevInfo,
297 psDevInfo->ui32MasterClkGateStatusReg,
298 psDevInfo->ui32MasterClkGateStatusMask,
299 "Wait for SGX master clock gating");
300
301 SGXPollForClockGating(psDevInfo,
302 psDevInfo->ui32MasterClkGateStatus2Reg,
303 psDevInfo->ui32MasterClkGateStatus2Mask,
304 "Wait for SGX master clock gating (2)");
305 #endif
306
307 if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
308 {
309
310 eError = SGXDeinitialise(psDevInfo);
311 if (eError != PVRSRV_OK)
312 {
313 PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %u", eError));
314 return eError;
315 }
316 }
317 }
318
319 return PVRSRV_OK;
320}
321
322
323PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle,
324 PVRSRV_DEV_POWER_STATE eNewPowerState,
325 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
326{
327 if ((eNewPowerState != eCurrentPowerState) &&
328 (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
329 {
330 PVRSRV_ERROR eError;
331 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
332 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
333 SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
334
335
336 psSGXHostCtl->ui32PowerStatus = 0;
337 #if defined(PDUMP)
338 PDUMPCOMMENT("Host Control - Reset power status");
339 PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
340 offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
341 sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
342 MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
343 #endif
344
345 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
346 {
347
348
349
350
351 eError = SGXUpdateTimingInfo(psDeviceNode);
352 if (eError != PVRSRV_OK)
353 {
354 PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
355 return eError;
356 }
357
358
359
360 eError = SGXInitialise(psDevInfo, IMG_FALSE);
361 if (eError != PVRSRV_OK)
362 {
363 PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed"));
364 return eError;
365 }
366 }
367 else
368 {
369
370
371 SGXMKIF_COMMAND sCommand = {0};
372
373 sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME;
374 eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0);
375 if (eError != PVRSRV_OK)
376 {
377 PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %u", eError));
378 return eError;
379 }
380 }
381
382 SGXStartTimer(psDevInfo);
383 }
384
385 return PVRSRV_OK;
386}
387
388
389PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE hDevHandle,
390 IMG_BOOL bIdleDevice,
391 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
392{
393 PVRSRV_ERROR eError;
394 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
395 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
396
397 PVR_UNREFERENCED_PARAMETER(psDevInfo);
398
399 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
400 {
401 if (bIdleDevice)
402 {
403
404 PDUMPSUSPEND();
405
406 eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE,
407 PVRSRV_DEV_POWER_STATE_ON);
408
409 if (eError != PVRSRV_OK)
410 {
411 PDUMPRESUME();
412 return eError;
413 }
414 }
415 }
416
417 PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %uHz",
418 psDevInfo->ui32CoreClockSpeed));
419
420 return PVRSRV_OK;
421}
422
423
424PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle,
425 IMG_BOOL bIdleDevice,
426 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
427{
428 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
429 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
430 IMG_UINT32 ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed;
431
432 PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed);
433
434 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
435 {
436 PVRSRV_ERROR eError;
437
438
439
440 eError = SGXUpdateTimingInfo(psDeviceNode);
441 if (eError != PVRSRV_OK)
442 {
443 PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
444 return eError;
445 }
446
447 if (bIdleDevice)
448 {
449
450 eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON,
451 PVRSRV_DEV_POWER_STATE_IDLE);
452
453 PDUMPRESUME();
454
455 if (eError != PVRSRV_OK)
456 {
457 return eError;
458 }
459 }
460 else
461 {
462 SGXStartTimer(psDevInfo);
463 }
464 }
465
466 PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %uHz to %uHz",
467 ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed));
468
469 return PVRSRV_OK;
470}
471
472
diff --git a/drivers/gpu/pvr/sgx/sgxreset.c b/drivers/gpu/pvr/sgx/sgxreset.c
new file mode 100644
index 00000000000..ee9f572ea74
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxreset.c
@@ -0,0 +1,499 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "sgxdefs.h"
28#include "sgxmmu.h"
29#include "services_headers.h"
30#include "sgxinfokm.h"
31#include "sgxconfig.h"
32
33#include "pdump_km.h"
34
35
36static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo,
37 IMG_BOOL bResetBIF,
38 IMG_UINT32 ui32PDUMPFlags,
39 IMG_BOOL bPDump)
40{
41 IMG_UINT32 ui32SoftResetRegVal;
42
43#if defined(SGX_FEATURE_MP)
44 ui32SoftResetRegVal =
45 EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK |
46 EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK |
47 EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
48
49#if defined(SGX_FEATURE_PTLA)
50 ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK;
51#endif
52#if defined(SGX_FEATURE_SYSTEM_CACHE)
53 ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK;
54#endif
55
56 if (bResetBIF)
57 {
58 ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK;
59 }
60
61 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal);
62 if (bPDump)
63 {
64 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
65 }
66#endif
67
68 ui32SoftResetRegVal =
69
70 EUR_CR_SOFT_RESET_DPM_RESET_MASK |
71 EUR_CR_SOFT_RESET_TA_RESET_MASK |
72 EUR_CR_SOFT_RESET_USE_RESET_MASK |
73 EUR_CR_SOFT_RESET_ISP_RESET_MASK |
74 EUR_CR_SOFT_RESET_TSP_RESET_MASK;
75
76#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK
77 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK;
78#endif
79#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK)
80 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK;
81#endif
82#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK)
83 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK;
84#endif
85#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK)
86 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK;
87#endif
88#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK)
89 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK;
90#endif
91#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK)
92 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK;
93#endif
94#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK)
95 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK;
96#endif
97#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK)
98 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK;
99#endif
100#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK)
101 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK;
102#endif
103#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK)
104 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK;
105#endif
106#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK)
107 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK;
108#endif
109#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK)
110 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK;
111#endif
112#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK)
113 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK;
114#endif
115#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK)
116 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK;
117#endif
118#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK)
119 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK;
120#endif
121#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK)
122 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK;
123#endif
124
125#if !defined(PDUMP)
126 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
127#endif
128
129 if (bResetBIF)
130 {
131 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK;
132 }
133
134 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal);
135 if (bPDump)
136 {
137 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
138 }
139}
140
141
142static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo,
143 IMG_UINT32 ui32PDUMPFlags,
144 IMG_BOOL bPDump)
145{
146#if !defined(PDUMP)
147 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
148#endif
149
150
151 OSWaitus(100 * 1000000 / psDevInfo->ui32CoreClockSpeed);
152 if (bPDump)
153 {
154 PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
155#if defined(PDUMP)
156 PDumpRegRead(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32PDUMPFlags);
157#endif
158 }
159
160}
161
162
163static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo,
164 IMG_UINT32 ui32PDUMPFlags,
165 IMG_BOOL bPDump)
166{
167 IMG_UINT32 ui32RegVal;
168
169
170#if defined(EUR_CR_BIF_CTRL_INVAL)
171 ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK;
172 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal);
173 if (bPDump)
174 {
175 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags);
176 }
177#else
178 ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
179 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
180 if (bPDump)
181 {
182 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
183 }
184
185 ui32RegVal = 0;
186 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
187 if (bPDump)
188 {
189 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
190 }
191#endif
192 SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
193
194#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
195 {
196
197
198
199 if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT),
200 0,
201 EUR_CR_BIF_MEM_REQ_STAT_READS_MASK,
202 MAX_HW_TIME_US/WAIT_TRY_COUNT,
203 WAIT_TRY_COUNT) != PVRSRV_OK)
204 {
205 PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed."));
206 PVR_DBG_BREAK;
207 }
208
209 if (bPDump)
210 {
211 PDUMPREGPOLWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags);
212 }
213 }
214#endif
215}
216
217
218IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
219 IMG_BOOL bHardwareRecovery,
220 IMG_UINT32 ui32PDUMPFlags)
221{
222 IMG_UINT32 ui32RegVal;
223#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK)
224 const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK;
225#else
226 const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK;
227#endif
228
229#ifndef PDUMP
230 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
231#endif
232
233 psDevInfo->ui32NumResets++;
234
235 PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n");
236
237#if defined(FIX_HW_BRN_23944)
238
239 ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
240 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
241 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
242
243 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
244
245 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
246 if (ui32RegVal & ui32BifFaultMask)
247 {
248
249 ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK;
250 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
251 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
252
253 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
254
255 ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
256 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
257 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
258
259 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
260 }
261#endif
262
263
264 SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE);
265
266 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
267
268
269
270#if defined(SGX_FEATURE_36BIT_MMU)
271
272 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK);
273 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags);
274#endif
275
276 ui32RegVal = 0;
277 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
278 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
279#if defined(SGX_FEATURE_MP)
280 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal);
281 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
282#endif
283#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
284 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal);
285 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags);
286 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
287 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
288#endif
289
290 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
291 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags);
292
293#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
294 {
295 IMG_UINT32 ui32DirList, ui32DirListReg;
296
297 for (ui32DirList = 1;
298 ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS;
299 ui32DirList++)
300 {
301 ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1);
302 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal);
303 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, ui32DirListReg, ui32RegVal, ui32PDUMPFlags);
304 }
305 }
306#endif
307
308#if defined(EUR_CR_BIF_MEM_ARB_CONFIG)
309
310
311 ui32RegVal = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) |
312 (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) |
313 (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT);
314 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal);
315 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags);
316#endif
317
318#if defined(SGX_FEATURE_SYSTEM_CACHE)
319#if defined(SGX_FEATURE_MP)
320 #if defined(SGX_BYPASS_SYSTEM_CACHE)
321 #error SGX_BYPASS_SYSTEM_CACHE not supported
322 #else
323 ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
324 (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT);
325 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
326 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
327
328 ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK;
329 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
330 PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
331 #endif
332#else
333 #if defined(SGX_BYPASS_SYSTEM_CACHE)
334
335 ui32RegVal = MNE_CR_CTRL_BYPASS_ALL_MASK;
336 #else
337 #if defined(FIX_HW_BRN_26620)
338 ui32RegVal = 0;
339 #else
340
341 ui32RegVal = MNE_CR_CTRL_BYP_CC_MASK;
342 #endif
343 #endif
344 OSWriteHWReg(psDevInfo->pvRegsBaseKM, MNE_CR_CTRL, ui32RegVal);
345 PDUMPREG(SGX_PDUMPREG_NAME, MNE_CR_CTRL, ui32RegVal);
346#endif
347#endif
348
349 if (bHardwareRecovery)
350 {
351
352
353
354
355
356
357
358 ui32RegVal = (IMG_UINT32)psDevInfo->sBIFResetPDDevPAddr.uiAddr;
359 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
360
361 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
362
363
364 SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
365 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
366
367 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
368
369
370
371 for (;;)
372 {
373 IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
374 IMG_DEV_VIRTADDR sBifFault;
375 IMG_UINT32 ui32PDIndex, ui32PTIndex;
376
377 if ((ui32BifIntStat & ui32BifFaultMask) == 0)
378 {
379 break;
380 }
381
382
383
384
385 sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
386 PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr));
387 ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
388 ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
389
390
391 SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE);
392
393
394 psDevInfo->pui32BIFResetPD[ui32PDIndex] = (psDevInfo->sBIFResetPTDevPAddr.uiAddr
395 >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
396 | SGX_MMU_PDE_PAGE_SIZE_4K
397 | SGX_MMU_PDE_VALID;
398 psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr
399 >>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
400 | SGX_MMU_PTE_VALID;
401
402
403 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
404 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal);
405 ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
406 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal);
407
408 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
409
410
411 SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE);
412 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
413
414
415 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
416
417
418 psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0;
419 psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0;
420 }
421 }
422 else
423 {
424
425 SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
426 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
427 }
428
429
430
431 #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
432
433 ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT);
434
435 #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
436
437 ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT);
438 #endif
439
440 #if defined(FIX_HW_BRN_23410)
441
442 ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT);
443 #endif
444
445 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
446 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
447 #endif
448
449 {
450 IMG_UINT32 ui32EDMDirListReg;
451
452
453 #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
454 ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
455 #else
456
457 ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
458 #endif
459
460#if defined(FIX_HW_BRN_28011)
461 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT);
462 PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
463#endif
464
465 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT);
466 PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
467 }
468
469#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
470
471 #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0)
472 #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment"
473 #endif
474
475 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE);
476 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags);
477#endif
478
479
480 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
481
482 PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX"));
483
484
485 ui32RegVal = 0;
486#if defined(SGX_FEATURE_MP)
487 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
488 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
489#endif
490 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
491 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
492
493
494 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
495
496 PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");
497}
498
499
diff --git a/drivers/gpu/pvr/sgx/sgxtransfer.c b/drivers/gpu/pvr/sgx/sgxtransfer.c
new file mode 100644
index 00000000000..abe5767e25d
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxtransfer.c
@@ -0,0 +1,573 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(TRANSFER_QUEUE)
28
29#include <stddef.h>
30
31#include "sgxdefs.h"
32#include "services_headers.h"
33#include "buffer_manager.h"
34#include "sgxinfo.h"
35#include "sysconfig.h"
36#include "regpaths.h"
37#include "pdump_km.h"
38#include "mmu.h"
39#include "pvr_bridge.h"
40#include "sgx_bridge_km.h"
41#include "sgxinfokm.h"
42#include "osfunc.h"
43#include "pvr_debug.h"
44#include "sgxutils.h"
45
46IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick)
47{
48 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
49 SGXMKIF_COMMAND sCommand = {0};
50 SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
51 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
52 PVRSRV_ERROR eError;
53
54#if defined(PDUMP)
55 IMG_BOOL bPersistentProcess = IMG_FALSE;
56
57 {
58 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
59 if(psPerProc != IMG_NULL)
60 {
61 bPersistentProcess = psPerProc->bPDumpPersistent;
62 }
63 }
64#endif
65
66 if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
67 {
68 PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset"));
69 return PVRSRV_ERROR_INVALID_PARAMS;
70 }
71
72
73 psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
74
75 if (psKick->hTASyncInfo != IMG_NULL)
76 {
77 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
78
79 psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
80 psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
81
82 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
83 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
84 }
85 else
86 {
87 psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
88 psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
89 }
90
91 if (psKick->h3DSyncInfo != IMG_NULL)
92 {
93 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
94
95 psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
96 psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
97
98 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
99 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
100 }
101 else
102 {
103 psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
104 psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
105 }
106
107 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
108 {
109 if (psKick->ui32NumSrcSync > 0)
110 {
111 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
112
113 psSharedTransferCmd->ui32SrcWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
114 psSharedTransferCmd->ui32SrcReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
115
116 psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
117 psSharedTransferCmd->sSrcReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
118
119 }
120
121 if (psKick->ui32NumDstSync > 0)
122 {
123 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
124
125 psSharedTransferCmd->ui32DstWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
126 psSharedTransferCmd->ui32DstReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
127
128 psSharedTransferCmd->sDstWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
129 psSharedTransferCmd->sDstReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
130
131 }
132
133
134 if (psKick->ui32NumSrcSync > 0)
135 {
136 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
137 psSyncInfo->psSyncData->ui32ReadOpsPending++;
138 }
139 if (psKick->ui32NumDstSync > 0)
140 {
141 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
142 psSyncInfo->psSyncData->ui32WriteOpsPending++;
143 }
144 }
145
146
147 if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync > 1)
148 {
149 PVR_DPF((PVR_DBG_ERROR,
150 "Transfer command doesn't support more than 1 sync object per src/dst\ndst: %d, src: %d",
151 psKick->ui32NumDstSync, psKick->ui32NumSrcSync));
152 }
153
154#if defined(PDUMP)
155 if ((PDumpIsCaptureFrameKM()
156 || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
157 && (bPersistentProcess == IMG_FALSE) )
158 {
159 PDUMPCOMMENT("Shared part of transfer command\r\n");
160 PDUMPMEM(psSharedTransferCmd,
161 psCCBMemInfo,
162 psKick->ui32CCBDumpWOff,
163 sizeof(SGXMKIF_TRANSFERCMD_SHARED),
164 psKick->ui32PDumpFlags,
165 MAKEUNIQUETAG(psCCBMemInfo));
166
167 if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
168 {
169 psSyncInfo = psKick->ahSrcSyncInfo[0];
170
171 PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n");
172 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
173 psCCBMemInfo,
174 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcWriteOpPendingVal),
175 sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
176 psKick->ui32PDumpFlags,
177 MAKEUNIQUETAG(psCCBMemInfo));
178
179 PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n");
180 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
181 psCCBMemInfo,
182 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcReadOpPendingVal),
183 sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
184 psKick->ui32PDumpFlags,
185 MAKEUNIQUETAG(psCCBMemInfo));
186
187 }
188 if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
189 {
190 psSyncInfo = psKick->ahDstSyncInfo[0];
191
192 PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n");
193 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
194 psCCBMemInfo,
195 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstWriteOpPendingVal),
196 sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
197 psKick->ui32PDumpFlags,
198 MAKEUNIQUETAG(psCCBMemInfo));
199
200 PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n");
201 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
202 psCCBMemInfo,
203 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstReadOpPendingVal),
204 sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
205 psKick->ui32PDumpFlags,
206 MAKEUNIQUETAG(psCCBMemInfo));
207
208 }
209
210
211 if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING)== 0UL))
212 {
213 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
214 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
215 }
216
217 if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
218 {
219 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
220 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
221 }
222 }
223#endif
224
225 sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
226
227 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags);
228
229 if (eError == PVRSRV_ERROR_RETRY)
230 {
231
232 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
233 {
234 if (psKick->ui32NumSrcSync > 0)
235 {
236 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
237 psSyncInfo->psSyncData->ui32ReadOpsPending--;
238 }
239 if (psKick->ui32NumDstSync > 0)
240 {
241 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
242 psSyncInfo->psSyncData->ui32WriteOpsPending--;
243 }
244#if defined(PDUMP)
245 if (PDumpIsCaptureFrameKM()
246 || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
247 {
248 if (psKick->ui32NumSrcSync > 0)
249 {
250 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
251 psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
252 }
253 if (psKick->ui32NumDstSync > 0)
254 {
255 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
256 psSyncInfo->psSyncData->ui32LastOpDumpVal--;
257 }
258 }
259#endif
260 }
261
262
263 if (psKick->hTASyncInfo != IMG_NULL)
264 {
265 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
266 psSyncInfo->psSyncData->ui32WriteOpsPending--;
267 }
268
269
270 if (psKick->h3DSyncInfo != IMG_NULL)
271 {
272 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
273 psSyncInfo->psSyncData->ui32WriteOpsPending--;
274 }
275 }
276
277 else if (PVRSRV_OK != eError)
278 {
279 PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed."));
280 return eError;
281 }
282
283
284#if defined(NO_HARDWARE)
285 if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0)
286 {
287 IMG_UINT32 i;
288
289
290 for(i = 0; i < psKick->ui32NumSrcSync; i++)
291 {
292 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
293 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
294 }
295
296 for(i = 0; i < psKick->ui32NumDstSync; i++)
297 {
298 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i];
299 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
300
301 }
302
303 if (psKick->hTASyncInfo != IMG_NULL)
304 {
305 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
306
307 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
308 }
309
310 if (psKick->h3DSyncInfo != IMG_NULL)
311 {
312 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
313
314 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
315 }
316 }
317#endif
318
319 return eError;
320}
321
322#if defined(SGX_FEATURE_2D_HARDWARE)
323IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick)
324
325{
326 PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
327 SGXMKIF_COMMAND sCommand = {0};
328 SGXMKIF_2DCMD_SHARED *ps2DCmd;
329 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
330 PVRSRV_ERROR eError;
331 IMG_UINT32 i;
332#if defined(PDUMP)
333 IMG_BOOL bPersistentProcess = IMG_FALSE;
334
335 {
336 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
337 if(psPerProc != IMG_NULL)
338 {
339 bPersistentProcess = psPerProc->bPDumpPersistent;
340 }
341 }
342#endif
343
344 if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
345 {
346 PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset"));
347 return PVRSRV_ERROR_INVALID_PARAMS;
348 }
349
350
351 ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
352
353 OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
354
355
356 if (psKick->hTASyncInfo != IMG_NULL)
357 {
358 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
359
360 ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
361 ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
362
363 ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
364 ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
365 }
366
367
368 if (psKick->h3DSyncInfo != IMG_NULL)
369 {
370 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
371
372 ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
373 ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
374
375 ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
376 ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
377 }
378
379
380 ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
381 for (i = 0; i < psKick->ui32NumSrcSync; i++)
382 {
383 psSyncInfo = psKick->ahSrcSyncInfo[i];
384
385 ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
386 ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
387
388 ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
389 ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
390 }
391
392 if (psKick->hDstSyncInfo != IMG_NULL)
393 {
394 psSyncInfo = psKick->hDstSyncInfo;
395
396 ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
397 ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
398
399 ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
400 ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
401 }
402
403
404 for (i = 0; i < psKick->ui32NumSrcSync; i++)
405 {
406 psSyncInfo = psKick->ahSrcSyncInfo[i];
407 psSyncInfo->psSyncData->ui32ReadOpsPending++;
408 }
409
410 if (psKick->hDstSyncInfo != IMG_NULL)
411 {
412 psSyncInfo = psKick->hDstSyncInfo;
413 psSyncInfo->psSyncData->ui32WriteOpsPending++;
414 }
415
416#if defined(PDUMP)
417 if ((PDumpIsCaptureFrameKM()
418 || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
419 && (bPersistentProcess == IMG_FALSE) )
420 {
421
422 PDUMPCOMMENT("Shared part of 2D command\r\n");
423 PDUMPMEM(ps2DCmd,
424 psCCBMemInfo,
425 psKick->ui32CCBDumpWOff,
426 sizeof(SGXMKIF_2DCMD_SHARED),
427 psKick->ui32PDumpFlags,
428 MAKEUNIQUETAG(psCCBMemInfo));
429
430 for (i = 0; i < psKick->ui32NumSrcSync; i++)
431 {
432 psSyncInfo = psKick->ahSrcSyncInfo[i];
433
434 PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n");
435 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
436 psCCBMemInfo,
437 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal),
438 sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
439 psKick->ui32PDumpFlags,
440 MAKEUNIQUETAG(psCCBMemInfo));
441
442 PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n");
443 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
444 psCCBMemInfo,
445 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal),
446 sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
447 psKick->ui32PDumpFlags,
448 MAKEUNIQUETAG(psCCBMemInfo));
449 }
450
451 if (psKick->hDstSyncInfo != IMG_NULL)
452 {
453 psSyncInfo = psKick->hDstSyncInfo;
454
455 PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n");
456 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
457 psCCBMemInfo,
458 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal),
459 sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
460 psKick->ui32PDumpFlags,
461 MAKEUNIQUETAG(psCCBMemInfo));
462
463 PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n");
464 PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
465 psCCBMemInfo,
466 psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal),
467 sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
468 psKick->ui32PDumpFlags,
469 MAKEUNIQUETAG(psCCBMemInfo));
470 }
471
472
473 for (i = 0; i < psKick->ui32NumSrcSync; i++)
474 {
475 psSyncInfo = psKick->ahSrcSyncInfo[i];
476 psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
477 }
478
479 if (psKick->hDstSyncInfo != IMG_NULL)
480 {
481 psSyncInfo = psKick->hDstSyncInfo;
482 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
483 }
484 }
485#endif
486
487 sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr;
488
489 eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags);
490
491 if (eError == PVRSRV_ERROR_RETRY)
492 {
493
494
495#if defined(PDUMP)
496 if (PDumpIsCaptureFrameKM())
497 {
498 for (i = 0; i < psKick->ui32NumSrcSync; i++)
499 {
500 psSyncInfo = psKick->ahSrcSyncInfo[i];
501 psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
502 }
503
504 if (psKick->hDstSyncInfo != IMG_NULL)
505 {
506 psSyncInfo = psKick->hDstSyncInfo;
507 psSyncInfo->psSyncData->ui32LastOpDumpVal--;
508 }
509 }
510#endif
511
512 for (i = 0; i < psKick->ui32NumSrcSync; i++)
513 {
514 psSyncInfo = psKick->ahSrcSyncInfo[i];
515 psSyncInfo->psSyncData->ui32ReadOpsPending--;
516 }
517
518 if (psKick->hDstSyncInfo != IMG_NULL)
519 {
520 psSyncInfo = psKick->hDstSyncInfo;
521 psSyncInfo->psSyncData->ui32WriteOpsPending--;
522 }
523
524
525 if (psKick->hTASyncInfo != IMG_NULL)
526 {
527 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
528
529 psSyncInfo->psSyncData->ui32WriteOpsPending--;
530 }
531
532
533 if (psKick->h3DSyncInfo != IMG_NULL)
534 {
535 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
536
537 psSyncInfo->psSyncData->ui32WriteOpsPending--;
538 }
539 }
540
541
542
543
544#if defined(NO_HARDWARE)
545
546 for(i = 0; i < psKick->ui32NumSrcSync; i++)
547 {
548 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
549 psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
550 }
551
552 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo;
553 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
554
555 if (psKick->hTASyncInfo != IMG_NULL)
556 {
557 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
558
559 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
560 }
561
562 if (psKick->h3DSyncInfo != IMG_NULL)
563 {
564 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
565
566 psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
567 }
568#endif
569
570 return eError;
571}
572#endif
573#endif
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
new file mode 100644
index 00000000000..3365af66425
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -0,0 +1,955 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include <stddef.h>
28
29#include "sgxdefs.h"
30#include "services_headers.h"
31#include "buffer_manager.h"
32#include "sgx_bridge_km.h"
33#include "sgxapi_km.h"
34#include "sgxinfo.h"
35#include "sgx_mkif_km.h"
36#include "sysconfig.h"
37#include "pdump_km.h"
38#include "mmu.h"
39#include "pvr_bridge_km.h"
40#include "osfunc.h"
41#include "pvr_debug.h"
42#include "sgxutils.h"
43
44#ifdef __linux__
45#include <linux/kernel.h>
46#include <linux/string.h>
47#else
48#include <stdio.h>
49#endif
50
51
52#if defined(SYS_CUSTOM_POWERDOWN)
53PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID);
54#endif
55
56
57
58static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode,
59 IMG_UINT32 ui32CallerID)
60{
61 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
62 SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
63
64
65 psSGXHostCtl->ui32NumActivePowerEvents++;
66
67 if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0)
68 {
69
70
71
72 if (ui32CallerID == ISR_ID)
73 {
74 psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
75 }
76 else
77 {
78 SGXScheduleProcessQueuesKM(psDeviceNode);
79 }
80 }
81}
82
83
84IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode,
85 IMG_UINT32 ui32CallerID)
86{
87 PVRSRV_ERROR eError = PVRSRV_OK;
88 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
89 SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
90
91 if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) &&
92 ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
93 {
94
95 psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
96
97
98 PDUMPSUSPEND();
99
100#if defined(SYS_CUSTOM_POWERDOWN)
101
102
103
104 eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
105#else
106 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
107 PVRSRV_DEV_POWER_STATE_OFF,
108 ui32CallerID, IMG_FALSE);
109 if (eError == PVRSRV_OK)
110 {
111 SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
112 }
113#endif
114 if (eError == PVRSRV_ERROR_RETRY)
115 {
116
117
118 psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
119 eError = PVRSRV_OK;
120 }
121
122
123 PDUMPRESUME();
124 }
125
126 if (eError != PVRSRV_OK)
127 {
128 PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
129 }
130}
131
132
133#ifdef INLINE_IS_PRAGMA
134#pragma inline(SGXAcquireKernelCCBSlot)
135#endif
136static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB)
137{
138 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
139 {
140 if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset)
141 {
142 return &psCCB->psCommands[*psCCB->pui32WriteOffset];
143 }
144
145 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
146 } END_LOOP_UNTIL_TIMEOUT();
147
148
149 return IMG_NULL;
150}
151
152PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo,
153 SGXMKIF_CMD_TYPE eCmdType,
154 SGXMKIF_COMMAND *psCommandData,
155 IMG_UINT32 ui32CallerID,
156 IMG_UINT32 ui32PDumpFlags)
157{
158 PVRSRV_SGX_CCB_INFO *psKernelCCB;
159 PVRSRV_ERROR eError = PVRSRV_OK;
160 SGXMKIF_COMMAND *psSGXCommand;
161 SYS_DATA *psSysData;
162#if defined(PDUMP)
163 IMG_VOID *pvDumpCommand;
164 IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
165 IMG_BOOL bPersistentProcess = IMG_FALSE;
166#else
167 PVR_UNREFERENCED_PARAMETER(ui32CallerID);
168 PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
169#endif
170
171#if defined(PDUMP)
172
173 {
174 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
175 if(psPerProc != IMG_NULL)
176 {
177 bPersistentProcess = psPerProc->bPDumpPersistent;
178 }
179 }
180#endif
181 psKernelCCB = psDevInfo->psKernelCCBInfo;
182
183 psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB);
184
185
186 if(!psSGXCommand)
187 {
188 eError = PVRSRV_ERROR_TIMEOUT;
189 goto Exit;
190 }
191
192
193 psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl;
194
195#if defined(PDUMP)
196
197 psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl;
198#endif
199
200
201 psDevInfo->ui32CacheControl = 0;
202
203
204 *psSGXCommand = *psCommandData;
205
206 if (eCmdType >= SGXMKIF_CMD_MAX)
207 {
208 PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCmdType)) ;
209 eError = PVRSRV_ERROR_INVALID_CCB_COMMAND;
210 goto Exit;
211 }
212
213
214 SysAcquireData(&psSysData);
215
216 if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
217 {
218 OSFlushCPUCacheKM();
219 }
220 else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
221 {
222 OSCleanCPUCacheKM();
223 }
224
225
226 psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
227
228 PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX);
229 psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType];
230
231#if defined(PDUMP)
232 if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
233 (bPersistentProcess == IMG_FALSE) )
234 {
235
236 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n");
237 PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
238 offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
239 (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff,
240 0xff,
241 PDUMP_POLL_OPERATOR_NOTEQUAL,
242 ui32PDumpFlags,
243 MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
244
245 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType);
246 pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND)));
247
248 PDUMPMEM(pvDumpCommand,
249 psKernelCCB->psCCBMemInfo,
250 psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND),
251 sizeof(SGXMKIF_COMMAND),
252 ui32PDumpFlags,
253 MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
254
255
256 PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl,
257 psKernelCCB->psCCBMemInfo,
258 psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) +
259 offsetof(SGXMKIF_COMMAND, ui32CacheControl),
260 sizeof(IMG_UINT32),
261 ui32PDumpFlags,
262 MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
263
264 if (PDumpIsCaptureFrameKM()
265 || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
266 {
267
268 psDevInfo->sPDContext.ui32CacheControl = 0;
269 }
270 }
271#endif
272
273#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
274
275 eError = PollForValueKM (psKernelCCB->pui32ReadOffset,
276 *psKernelCCB->pui32WriteOffset,
277 0xFF,
278 MAX_HW_TIME_US/WAIT_TRY_COUNT,
279 WAIT_TRY_COUNT);
280 if (eError != PVRSRV_OK)
281 {
282 eError = PVRSRV_ERROR_TIMEOUT;
283 goto Exit;
284 }
285#endif
286
287
288
289 *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255;
290
291#if defined(PDUMP)
292 if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
293 (bPersistentProcess == IMG_FALSE) )
294 {
295 #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
296 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n");
297 PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
298 offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
299 (psKernelCCB->ui32CCBDumpWOff),
300 0xFF,
301 PDUMP_POLL_OPERATOR_EQUAL,
302 ui32PDumpFlags,
303 MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
304 #endif
305
306 if (PDumpIsCaptureFrameKM()
307 || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
308 {
309 psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF;
310 psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF;
311 }
312
313 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n");
314 PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff,
315 psKernelCCB->psCCBCtlMemInfo,
316 offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset),
317 sizeof(IMG_UINT32),
318 ui32PDumpFlags,
319 MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
320 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n");
321 PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
322 psDevInfo->psKernelCCBEventKickerMemInfo,
323 0,
324 sizeof(IMG_UINT32),
325 ui32PDumpFlags,
326 MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
327 PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n");
328 #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
329 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags);
330 #else
331 PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags);
332 #endif
333 }
334#endif
335
336 *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
337
338 OSWriteMemoryBarrier();
339
340#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
341 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
342 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
343 EUR_CR_EVENT_KICK2_NOW_MASK);
344#else
345 OSWriteHWReg(psDevInfo->pvRegsBaseKM,
346 SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
347 EUR_CR_EVENT_KICK_NOW_MASK);
348#endif
349
350 OSMemoryBarrier();
351
352#if defined(NO_HARDWARE)
353
354 *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
355#endif
356
357Exit:
358 return eError;
359}
360
361
362PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
363 SGXMKIF_CMD_TYPE eCmdType,
364 SGXMKIF_COMMAND *psCommandData,
365 IMG_UINT32 ui32CallerID,
366 IMG_UINT32 ui32PDumpFlags)
367{
368 PVRSRV_ERROR eError;
369 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
370
371
372 PDUMPSUSPEND();
373
374
375 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
376 PVRSRV_DEV_POWER_STATE_ON,
377 ui32CallerID,
378 IMG_TRUE);
379
380 PDUMPRESUME();
381
382 if (eError == PVRSRV_OK)
383 {
384 psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
385 }
386 else
387 {
388 if (eError == PVRSRV_ERROR_RETRY)
389 {
390 if (ui32CallerID == ISR_ID)
391 {
392
393
394
395 psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
396 eError = PVRSRV_OK;
397 }
398 else
399 {
400
401
402 }
403 }
404 else
405 {
406 PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
407 "ui32CallerID:%d eError:%u", ui32CallerID, eError));
408 }
409
410 return eError;
411 }
412
413 eError = SGXScheduleCCBCommand(psDevInfo, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags);
414
415 PVRSRVPowerUnlock(ui32CallerID);
416
417
418 if (ui32CallerID != ISR_ID)
419 {
420
421
422
423 SGXTestActivePowerEvent(psDeviceNode, ui32CallerID);
424 }
425
426 return eError;
427}
428
429
430PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode)
431{
432 PVRSRV_ERROR eError;
433 PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
434 SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
435 IMG_UINT32 ui32PowerStatus;
436 SGXMKIF_COMMAND sCommand = {0};
437
438 ui32PowerStatus = psHostCtl->ui32PowerStatus;
439 if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
440 {
441
442 return PVRSRV_OK;
443 }
444
445 eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0);
446 if (eError != PVRSRV_OK)
447 {
448 PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError));
449 return eError;
450 }
451
452 return PVRSRV_OK;
453}
454
455
456IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode)
457{
458 return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
459}
460
461IMG_EXPORT
462PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
463 SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo)
464{
465 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
466
467 psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags;
468 psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff;
469
470
471 psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle =
472 (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo;
473
474 return PVRSRV_OK;
475}
476
477
478IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
479 IMG_DEV_VIRTADDR *psHWDataDevVAddr,
480 IMG_UINT32 ui32CleanupType)
481{
482 PVRSRV_ERROR eError;
483 PVRSRV_SGXDEV_INFO *psSGXDevInfo = psDeviceNode->pvDevice;
484 PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo;
485 SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
486
487 if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
488 {
489
490 }
491 else
492 {
493 SGXMKIF_COMMAND sCommand = {0};
494
495 PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resouce clean-up");
496 sCommand.ui32Data[0] = ui32CleanupType;
497 sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr;
498
499 eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0);
500 if (eError != PVRSRV_OK)
501 {
502 PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
503 PVR_DBG_BREAK;
504 }
505
506
507 #if !defined(NO_HARDWARE)
508 if(PollForValueKM(&psSGXHostCtl->ui32CleanupStatus,
509 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
510 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
511 2 * MAX_HW_TIME_US/WAIT_TRY_COUNT,
512 WAIT_TRY_COUNT) != PVRSRV_OK)
513 {
514 PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType));
515 PVR_DBG_BREAK;
516 }
517 #endif
518
519 #if defined(PDUMP)
520
521 PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
522 PDUMPMEMPOL(psSGXHostCtlMemInfo,
523 offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
524 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
525 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
526 PDUMP_POLL_OPERATOR_EQUAL,
527 0,
528 MAKEUNIQUETAG(psSGXHostCtlMemInfo));
529 #endif
530
531 psSGXHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
532 PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo));
533
534
535 #if defined(SGX_FEATURE_SYSTEM_CACHE)
536 psSGXDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA);
537 #else
538 psSGXDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
539 #endif
540 }
541}
542
543
544typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
545{
546 PVRSRV_DEVICE_NODE *psDeviceNode;
547 IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
548 IMG_HANDLE hBlockAlloc;
549 PRESMAN_ITEM psResItem;
550} SGX_HW_RENDER_CONTEXT_CLEANUP;
551
552
553static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
554 IMG_UINT32 ui32Param)
555{
556 SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam;
557
558 PVR_UNREFERENCED_PARAMETER(ui32Param);
559
560 SGXCleanupRequest(psCleanup->psDeviceNode,
561 &psCleanup->sHWRenderContextDevVAddr,
562 PVRSRV_CLEANUPCMD_RC);
563
564 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
565 sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
566 psCleanup,
567 psCleanup->hBlockAlloc);
568
569
570 return PVRSRV_OK;
571}
572
573typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
574{
575 PVRSRV_DEVICE_NODE *psDeviceNode;
576 IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
577 IMG_HANDLE hBlockAlloc;
578 PRESMAN_ITEM psResItem;
579} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
580
581
582static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam,
583 IMG_UINT32 ui32Param)
584{
585 SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam;
586
587 PVR_UNREFERENCED_PARAMETER(ui32Param);
588
589 SGXCleanupRequest(psCleanup->psDeviceNode,
590 &psCleanup->sHWTransferContextDevVAddr,
591 PVRSRV_CLEANUPCMD_TC);
592
593 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
594 sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
595 psCleanup,
596 psCleanup->hBlockAlloc);
597
598
599 return PVRSRV_OK;
600}
601
602IMG_EXPORT
603IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
604 IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
605 PVRSRV_PER_PROCESS_DATA *psPerProc)
606{
607 PVRSRV_ERROR eError;
608 IMG_HANDLE hBlockAlloc;
609 SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
610 PRESMAN_ITEM psResItem;
611
612 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
613 sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
614 (IMG_VOID **)&psCleanup,
615 &hBlockAlloc,
616 "SGX Hardware Render Context Cleanup");
617
618 if (eError != PVRSRV_OK)
619 {
620 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
621 return IMG_NULL;
622 }
623
624 psCleanup->hBlockAlloc = hBlockAlloc;
625 psCleanup->psDeviceNode = psDeviceNode;
626 psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr;
627
628 psResItem = ResManRegisterRes(psPerProc->hResManContext,
629 RESMAN_TYPE_HW_RENDER_CONTEXT,
630 (IMG_VOID *)psCleanup,
631 0,
632 &SGXCleanupHWRenderContextCallback);
633
634 if (psResItem == IMG_NULL)
635 {
636 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
637 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
638 sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
639 psCleanup,
640 psCleanup->hBlockAlloc);
641
642
643 return IMG_NULL;
644 }
645
646 psCleanup->psResItem = psResItem;
647
648 return (IMG_HANDLE)psCleanup;
649}
650
651IMG_EXPORT
652PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext)
653{
654 PVRSRV_ERROR eError;
655 SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
656
657 PVR_ASSERT(hHWRenderContext != IMG_NULL);
658
659 psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
660
661 if (psCleanup == IMG_NULL)
662 {
663 PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter"));
664 return PVRSRV_ERROR_INVALID_PARAMS;
665 }
666
667 eError = ResManFreeResByPtr(psCleanup->psResItem);
668
669 return eError;
670}
671
672
673IMG_EXPORT
674IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
675 IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
676 PVRSRV_PER_PROCESS_DATA *psPerProc)
677{
678 PVRSRV_ERROR eError;
679 IMG_HANDLE hBlockAlloc;
680 SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
681 PRESMAN_ITEM psResItem;
682
683 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
684 sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
685 (IMG_VOID **)&psCleanup,
686 &hBlockAlloc,
687 "SGX Hardware Transfer Context Cleanup");
688
689 if (eError != PVRSRV_OK)
690 {
691 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
692 return IMG_NULL;
693 }
694
695 psCleanup->hBlockAlloc = hBlockAlloc;
696 psCleanup->psDeviceNode = psDeviceNode;
697 psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr;
698
699 psResItem = ResManRegisterRes(psPerProc->hResManContext,
700 RESMAN_TYPE_HW_TRANSFER_CONTEXT,
701 psCleanup,
702 0,
703 &SGXCleanupHWTransferContextCallback);
704
705 if (psResItem == IMG_NULL)
706 {
707 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
708 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
709 sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
710 psCleanup,
711 psCleanup->hBlockAlloc);
712
713
714 return IMG_NULL;
715 }
716
717 psCleanup->psResItem = psResItem;
718
719 return (IMG_HANDLE)psCleanup;
720}
721
722IMG_EXPORT
723PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext)
724{
725 PVRSRV_ERROR eError;
726 SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
727
728 PVR_ASSERT(hHWTransferContext != IMG_NULL);
729
730 psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
731
732 if (psCleanup == IMG_NULL)
733 {
734 PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter"));
735 return PVRSRV_ERROR_INVALID_PARAMS;
736 }
737
738 eError = ResManFreeResByPtr(psCleanup->psResItem);
739
740 return eError;
741}
742
743#if defined(SGX_FEATURE_2D_HARDWARE)
744typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
745{
746 PVRSRV_DEVICE_NODE *psDeviceNode;
747 IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
748 IMG_HANDLE hBlockAlloc;
749 PRESMAN_ITEM psResItem;
750} SGX_HW_2D_CONTEXT_CLEANUP;
751
752static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
753{
754 SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam;
755
756 PVR_UNREFERENCED_PARAMETER(ui32Param);
757
758 SGXCleanupRequest(psCleanup->psDeviceNode,
759 &psCleanup->sHW2DContextDevVAddr,
760 PVRSRV_CLEANUPCMD_2DC);
761
762 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
763 sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
764 psCleanup,
765 psCleanup->hBlockAlloc);
766
767
768 return PVRSRV_OK;
769}
770
771IMG_EXPORT
772IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
773 IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
774 PVRSRV_PER_PROCESS_DATA *psPerProc)
775{
776 PVRSRV_ERROR eError;
777 IMG_HANDLE hBlockAlloc;
778 SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
779 PRESMAN_ITEM psResItem;
780
781 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
782 sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
783 (IMG_VOID **)&psCleanup,
784 &hBlockAlloc,
785 "SGX Hardware 2D Context Cleanup");
786
787 if (eError != PVRSRV_OK)
788 {
789 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
790 return IMG_NULL;
791 }
792
793 psCleanup->hBlockAlloc = hBlockAlloc;
794 psCleanup->psDeviceNode = psDeviceNode;
795 psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr;
796
797 psResItem = ResManRegisterRes(psPerProc->hResManContext,
798 RESMAN_TYPE_HW_2D_CONTEXT,
799 psCleanup,
800 0,
801 &SGXCleanupHW2DContextCallback);
802
803 if (psResItem == IMG_NULL)
804 {
805 PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
806 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
807 sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
808 psCleanup,
809 psCleanup->hBlockAlloc);
810
811
812 return IMG_NULL;
813 }
814
815 psCleanup->psResItem = psResItem;
816
817 return (IMG_HANDLE)psCleanup;
818}
819
820IMG_EXPORT
821PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext)
822{
823 PVRSRV_ERROR eError;
824 SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
825
826 PVR_ASSERT(hHW2DContext != IMG_NULL);
827
828 if (hHW2DContext == IMG_NULL)
829 {
830 return (PVRSRV_ERROR_INVALID_PARAMS);
831 }
832
833 psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext;
834
835 eError = ResManFreeResByPtr(psCleanup->psResItem);
836
837 return eError;
838}
839#endif
840
841#ifdef INLINE_IS_PRAGMA
842#pragma inline(SGX2DQuerySyncOpsComplete)
843#endif
844static INLINE
845IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
846 IMG_UINT32 ui32ReadOpsPending,
847 IMG_UINT32 ui32WriteOpsPending)
848{
849 PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
850
851 return (IMG_BOOL)(
852 (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) &&
853 (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending)
854 );
855}
856
857IMG_EXPORT
858PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo,
859 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
860 IMG_BOOL bWaitForComplete)
861{
862 IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending;
863
864 PVR_UNREFERENCED_PARAMETER(psDevInfo);
865
866 PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start"));
867
868 ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
869 ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
870
871 if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
872 {
873
874 PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete."));
875 return PVRSRV_OK;
876 }
877
878
879 if (!bWaitForComplete)
880 {
881
882 PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending."));
883 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
884 }
885
886
887 PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling."));
888
889 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
890 {
891 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
892
893 if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
894 {
895
896 PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete."));
897 return PVRSRV_OK;
898 }
899
900 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
901 } END_LOOP_UNTIL_TIMEOUT();
902
903
904 PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending."));
905
906#if defined(DEBUG)
907 {
908 PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
909
910 PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x",
911 (IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)psSyncData));
912
913 PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending));
914 PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending));
915
916 }
917#endif
918
919 return PVRSRV_ERROR_TIMEOUT;
920}
921
922
923IMG_EXPORT
924IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr)
925{
926 PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL);
927
928 SGXCleanupRequest(psDeviceNode,
929 &sHWRTDataSetDevVAddr,
930 PVRSRV_CLEANUPCMD_RT);
931}
932
933
934IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
935 IMG_UINT32 ui32TimeWraps,
936 IMG_UINT32 ui32Time)
937{
938#if defined(EUR_CR_TIMER)
939 PVR_UNREFERENCED_PARAMETER(psDevInfo);
940 PVR_UNREFERENCED_PARAMETER(ui32TimeWraps);
941 return ui32Time;
942#else
943 IMG_UINT64 ui64Clocks;
944 IMG_UINT32 ui32Clocksx16;
945
946 ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) +
947 (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK));
948 ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16);
949
950 return ui32Clocksx16;
951#endif
952}
953
954
955
diff --git a/drivers/gpu/pvr/sgx/sgxutils.h b/drivers/gpu/pvr/sgx/sgxutils.h
new file mode 100644
index 00000000000..bc4c0536795
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/sgxutils.h
@@ -0,0 +1,99 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "perproc.h"
28#include "sgxinfokm.h"
29
30#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \
31 ((sizeof(type) <= (psCCBMemInfo)->ui32AllocSize) && \
32 ((psCCBKick)->offset <= (psCCBMemInfo)->ui32AllocSize - sizeof(type)))
33
34#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \
35 ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
36 (psCCBKick)->offset))
37
38
39IMG_IMPORT
40IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode,
41 IMG_UINT32 ui32CallerID);
42
43IMG_IMPORT
44PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo,
45 SGXMKIF_CMD_TYPE eCommandType,
46 SGXMKIF_COMMAND *psCommandData,
47 IMG_UINT32 ui32CallerID,
48 IMG_UINT32 ui32PDumpFlags);
49IMG_IMPORT
50PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
51 SGXMKIF_CMD_TYPE eCommandType,
52 SGXMKIF_COMMAND *psCommandData,
53 IMG_UINT32 ui32CallerID,
54 IMG_UINT32 ui32PDumpFlags);
55
56IMG_IMPORT
57PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode);
58
59IMG_IMPORT
60IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode);
61
62IMG_IMPORT
63IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
64 IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
65 PVRSRV_PER_PROCESS_DATA *psPerProc);
66
67IMG_IMPORT
68IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
69 IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
70 PVRSRV_PER_PROCESS_DATA *psPerProc);
71
72IMG_IMPORT
73IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr);
74
75IMG_IMPORT
76PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext);
77
78IMG_IMPORT
79PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext);
80
81#if defined(SGX_FEATURE_2D_HARDWARE)
82IMG_IMPORT
83IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
84 IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
85 PVRSRV_PER_PROCESS_DATA *psPerProc);
86
87IMG_IMPORT
88PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext);
89#endif
90
91IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
92 IMG_UINT32 ui32TimeWraps,
93 IMG_UINT32 ui32Time);
94
95IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
96 IMG_DEV_VIRTADDR *psHWDataDevVAddr,
97 IMG_UINT32 ui32CleanupType);
98
99
diff --git a/drivers/gpu/pvr/sgx530defs.h b/drivers/gpu/pvr/sgx530defs.h
new file mode 100644
index 00000000000..525f51d6569
--- /dev/null
+++ b/drivers/gpu/pvr/sgx530defs.h
@@ -0,0 +1,488 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SGX530DEFS_KM_H_
28#define _SGX530DEFS_KM_H_
29
30#define EUR_CR_CLKGATECTL 0x0000
31#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U
32#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0
33#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
34#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
35#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
36#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
37#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
38#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
39#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
40#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
41#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
42#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
43#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
44#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
45#define EUR_CR_CLKGATESTATUS 0x0004
46#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001U
47#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0
48#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U
49#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
50#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
51#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
52#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
53#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
54#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
55#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
56#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
57#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
58#define EUR_CR_CLKGATECTLOVR 0x0008
59#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U
60#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0
61#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
62#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
63#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
64#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
65#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
66#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
67#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
68#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
69#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
70#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
71#define EUR_CR_CORE_ID 0x0010
72#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
73#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
74#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
75#define EUR_CR_CORE_ID_ID_SHIFT 16
76#define EUR_CR_CORE_REVISION 0x0014
77#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
78#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
79#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
80#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
81#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
82#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
83#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
84#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
85#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
86#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
87#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
88#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
89#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
90#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
91#define EUR_CR_SOFT_RESET 0x0080
92#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
93#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
94#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U
95#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1
96#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
97#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
98#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
99#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
100#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
101#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
102#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
103#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
104#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
105#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
106#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
107#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
108#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
109#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
110#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
111#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
112#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
113#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
114#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
115#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
116#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
117#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
118#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
119#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
120#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
121#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
122#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
123#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
124#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
125#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
126#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
127#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
128#define EUR_CR_EVENT_STATUS2 0x0118
129#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
130#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
131#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
132#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
133#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
134#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
135#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
136#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
137#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
138#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
139#define EUR_CR_EVENT_STATUS 0x012CU
140#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
141#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
142#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
143#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
144#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
145#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
146#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
147#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
148#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
149#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
150#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
151#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
152#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
153#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
154#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
155#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
156#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
157#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
158#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
159#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
160#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
161#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
162#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
163#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
164#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
165#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
166#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
167#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
168#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
169#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
170#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
171#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
172#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
173#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
174#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
175#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
176#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
177#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
178#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
179#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
180#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
181#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
182#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
183#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
184#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
185#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
186#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
187#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
188#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
189#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
190#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
191#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
192#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
193#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
194#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
195#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
196#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
197#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
198#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
199#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
200#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
201#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
202#define EUR_CR_EVENT_HOST_ENABLE 0x0130
203#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
204#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
205#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
206#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
207#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
208#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
209#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
210#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
211#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
212#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
213#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
214#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
215#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
216#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
217#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
218#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
219#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
220#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
221#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
222#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
223#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
224#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
225#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
226#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
227#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
228#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
229#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
230#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
231#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
232#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
233#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
234#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
235#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
236#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
237#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
238#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
239#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
240#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
241#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
242#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
243#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
244#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
245#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
246#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
247#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
248#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
249#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
250#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
251#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
252#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
253#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
254#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
255#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
256#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
257#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
258#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
259#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
260#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
261#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
262#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
263#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
264#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
265#define EUR_CR_EVENT_HOST_CLEAR 0x0134
266#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
267#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
268#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
269#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
270#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
271#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
272#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
273#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
274#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
275#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
276#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
277#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
278#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
279#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
280#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
281#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
282#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
283#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
284#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
285#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
286#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
287#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
288#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
289#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
290#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
291#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
292#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
293#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
294#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
295#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
296#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
297#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
298#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
299#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
300#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
301#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
302#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
303#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
304#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
305#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
306#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
307#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
308#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
309#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
310#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
311#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
312#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
313#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
314#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
315#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
316#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
317#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
318#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
319#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
320#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
321#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
322#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
323#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
324#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
325#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
326#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
327#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
328#define EUR_CR_PDS_EXEC_BASE 0x0AB8
329#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
330#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
331#define EUR_CR_EVENT_KICKER 0x0AC4
332#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
333#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
334#define EUR_CR_EVENT_KICK 0x0AC8
335#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
336#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
337#define EUR_CR_EVENT_TIMER 0x0ACC
338#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
339#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
340#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
341#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
342#define EUR_CR_PDS_INV0 0x0AD0
343#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
344#define EUR_CR_PDS_INV0_DSC_SHIFT 0
345#define EUR_CR_PDS_INV1 0x0AD4
346#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
347#define EUR_CR_PDS_INV1_DSC_SHIFT 0
348#define EUR_CR_PDS_INV2 0x0AD8
349#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
350#define EUR_CR_PDS_INV2_DSC_SHIFT 0
351#define EUR_CR_PDS_INV3 0x0ADC
352#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
353#define EUR_CR_PDS_INV3_DSC_SHIFT 0
354#define EUR_CR_PDS_INV_CSC 0x0AE0
355#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
356#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
357#define EUR_CR_PDS_PC_BASE 0x0B2C
358#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
359#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
360#define EUR_CR_BIF_CTRL 0x0C00
361#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
362#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
363#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
364#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
365#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
366#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
367#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
368#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
369#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
370#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
371#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
372#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
373#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
374#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
375#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
376#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
377#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
378#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
379#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
380#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
381#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
382#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
383#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
384#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
385#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
386#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
387#define EUR_CR_BIF_INT_STAT 0x0C04
388#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
389#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
390#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
391#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
392#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
393#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
394#define EUR_CR_BIF_FAULT 0x0C08
395#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
396#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
397#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
398#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
399#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
400#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88
401#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0x0FF00000U
402#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
403#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
404#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
405#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
406#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
407#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
408#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
409#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
410#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
411#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
412#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
413#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
414#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
415#define EUR_CR_2D_BLIT_STATUS 0x0E04
416#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
417#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
418#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
419#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
420#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
421#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
422#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
423#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
424#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
425#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
426#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
427#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
428#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
429#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
430#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
431#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
432#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
433#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
434#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
435#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
436#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
437#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
438#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
439#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
440#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
441#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
442#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
443#define EUR_CR_MNE_CR_CTRL 0x0D00
444#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_MASK 0x00010000U
445#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_SHIFT 16
446#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK 0x00008000U
447#define EUR_CR_MNE_CR_CTRL_BYP_CC_SHIFT 15
448#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_MASK 0x00007800U
449#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_SHIFT 11
450#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400U
451#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_SHIFT 10
452#define EUR_CR_MNE_CR_CTRL_BYPASS_MASK 0x000003E0U
453#define EUR_CR_MNE_CR_CTRL_BYPASS_SHIFT 5
454#define EUR_CR_MNE_CR_CTRL_PAUSE_MASK 0x00000010U
455#define EUR_CR_MNE_CR_CTRL_PAUSE_SHIFT 4
456#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_MASK 0x0000000EU
457#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT 1
458#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_PDS_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+2)
459#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_USEC_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+1)
460#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT)
461#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_MASK 0x00000001U
462#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_SHIFT 0
463#define EUR_CR_MNE_CR_USE_INVAL 0x0D04
464#define EUR_CR_MNE_CR_USE_INVAL_ADDR_MASK 0xFFFFFFFFU
465#define EUR_CR_MNE_CR_USE_INVAL_ADDR_SHIFT 0
466#define EUR_CR_MNE_CR_STAT 0x0D08
467#define EUR_CR_MNE_CR_STAT_PAUSED_MASK 0x00000400U
468#define EUR_CR_MNE_CR_STAT_PAUSED_SHIFT 10
469#define EUR_CR_MNE_CR_STAT_READS_MASK 0x000003FFU
470#define EUR_CR_MNE_CR_STAT_READS_SHIFT 0
471#define EUR_CR_MNE_CR_STAT_STATS 0x0D0C
472#define EUR_CR_MNE_CR_STAT_STATS_RST_MASK 0x000FFFF0U
473#define EUR_CR_MNE_CR_STAT_STATS_RST_SHIFT 4
474#define EUR_CR_MNE_CR_STAT_STATS_SEL_MASK 0x0000000FU
475#define EUR_CR_MNE_CR_STAT_STATS_SEL_SHIFT 0
476#define EUR_CR_MNE_CR_STAT_STATS_OUT 0x0D10
477#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_MASK 0xFFFFFFFFU
478#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_SHIFT 0
479#define EUR_CR_MNE_CR_EVENT_STATUS 0x0D14
480#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_MASK 0x00000001U
481#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_SHIFT 0
482#define EUR_CR_MNE_CR_EVENT_CLEAR 0x0D18
483#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_MASK 0x00000001U
484#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_SHIFT 0
485#define EUR_CR_MNE_CR_CTRL_INVAL 0x0D20
486
487#endif
488
diff --git a/drivers/gpu/pvr/sgx540defs.h b/drivers/gpu/pvr/sgx540defs.h
new file mode 100644
index 00000000000..dadbb1eaa01
--- /dev/null
+++ b/drivers/gpu/pvr/sgx540defs.h
@@ -0,0 +1,547 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SGX540DEFS_KM_H_
28#define _SGX540DEFS_KM_H_
29
30#define EUR_CR_CLKGATECTL 0x0000
31#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
32#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
33#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
34#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
35#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
36#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
37#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
38#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
39#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
40#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
41#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
42#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
43#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
44#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
45#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
46#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
47#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
48#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
49#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
50#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
51#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
52#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
53#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
54#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
55#define EUR_CR_CLKGATECTL2 0x0004
56#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
57#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
58#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
59#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
60#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
61#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
62#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
63#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
64#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
65#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
66#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
67#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
68#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
69#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
70#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
71#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
72#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
73#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
74#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
75#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
76#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
77#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
78#define EUR_CR_CLKGATESTATUS 0x0008
79#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
80#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
81#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
82#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
83#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
84#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
85#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
86#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
87#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
88#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
89#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
90#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
91#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
92#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
93#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
94#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
95#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
96#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
97#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
98#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
99#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
100#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
101#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
102#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
103#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
104#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
105#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
106#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
107#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
108#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
109#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
110#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
111#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
112#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
113#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
114#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
115#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
116#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
117#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
118#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
119#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
120#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
121#define EUR_CR_CLKGATECTLOVR 0x000C
122#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
123#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
124#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
125#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
126#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
127#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
128#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
129#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
130#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
131#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
132#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
133#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
134#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
135#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
136#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
137#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
138#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
139#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
140#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
141#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
142#define EUR_CR_POWER 0x001C
143#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
144#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
145#define EUR_CR_CORE_ID 0x0020
146#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
147#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
148#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
149#define EUR_CR_CORE_ID_ID_SHIFT 16
150#define EUR_CR_CORE_REVISION 0x0024
151#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
152#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
153#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
154#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
155#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
156#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
157#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
158#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
159#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
160#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
161#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
162#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
163#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
164#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
165#define EUR_CR_SOFT_RESET 0x0080
166#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
167#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
168#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
169#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
170#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
171#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
172#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
173#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
174#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
175#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
176#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
177#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
178#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
179#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
180#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
181#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
182#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
183#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
184#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
185#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
186#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
187#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
188#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
189#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
190#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U
191#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12
192#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
193#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
194#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
195#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
196#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
197#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
198#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
199#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
200#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
201#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
202#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
203#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
204#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
205#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
206#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
207#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
208#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
209#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
210#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
211#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
212#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
213#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
214#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
215#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
216#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
217#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
218#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
219#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
220#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
221#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
222#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
223#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
224#define EUR_CR_EVENT_STATUS2 0x0118
225#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
226#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
227#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
228#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
229#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
230#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
231#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
232#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
233#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
234#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
235#define EUR_CR_EVENT_STATUS 0x012CU
236#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
237#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
238#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
239#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
240#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
241#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
242#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
243#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
244#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
245#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
246#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
247#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
248#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
249#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
250#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
251#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
252#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
253#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
254#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
255#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
256#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
257#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
258#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
259#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
260#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
261#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
262#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
263#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
264#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
265#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
266#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
267#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
268#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
269#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
270#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
271#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
272#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
273#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
274#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
275#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
276#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
277#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
278#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
279#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
280#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
281#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
282#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
283#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
284#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
285#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
286#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
287#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
288#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
289#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
290#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
291#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
292#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
293#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
294#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
295#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
296#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
297#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
298#define EUR_CR_EVENT_HOST_ENABLE 0x0130
299#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
300#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
301#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
302#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
303#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
304#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
305#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
306#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
307#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
308#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
309#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
310#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
311#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
312#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
313#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
314#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
315#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
316#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
317#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
318#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
319#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
320#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
321#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
322#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
323#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
324#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
325#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
326#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
327#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
328#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
329#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
330#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
331#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
332#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
333#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
334#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
335#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
336#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
337#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
338#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
339#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
340#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
341#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
342#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
343#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
344#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
345#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
346#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
347#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
348#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
349#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
350#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
351#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
352#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
353#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
354#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
355#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
356#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
357#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
358#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
359#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
360#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
361#define EUR_CR_EVENT_HOST_CLEAR 0x0134
362#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
363#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
364#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
365#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
366#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
367#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
368#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
369#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
370#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
371#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
372#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
373#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
374#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
375#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
376#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
377#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
378#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
379#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
380#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
381#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
382#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
383#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
384#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
385#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
386#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
387#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
388#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
389#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
390#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
391#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
392#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
393#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
394#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
395#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
396#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
397#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
398#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
399#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
400#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
401#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
402#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
403#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
404#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
405#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
406#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
407#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
408#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
409#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
410#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
411#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
412#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
413#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
414#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
415#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
416#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
417#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
418#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
419#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
420#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
421#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
422#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
423#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
424#define EUR_CR_TIMER 0x0144
425#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
426#define EUR_CR_TIMER_VALUE_SHIFT 0
427#define EUR_CR_EVENT_KICK1 0x0AB0
428#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
429#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
430#define EUR_CR_PDS_EXEC_BASE 0x0AB8
431#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
432#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
433#define EUR_CR_EVENT_KICK2 0x0AC0
434#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
435#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
436#define EUR_CR_EVENT_KICKER 0x0AC4
437#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
438#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
439#define EUR_CR_EVENT_KICK 0x0AC8
440#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
441#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
442#define EUR_CR_EVENT_TIMER 0x0ACC
443#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
444#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
445#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
446#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
447#define EUR_CR_PDS_INV0 0x0AD0
448#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
449#define EUR_CR_PDS_INV0_DSC_SHIFT 0
450#define EUR_CR_PDS_INV1 0x0AD4
451#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
452#define EUR_CR_PDS_INV1_DSC_SHIFT 0
453#define EUR_CR_EVENT_KICK3 0x0AD8
454#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
455#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
456#define EUR_CR_PDS_INV3 0x0ADC
457#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
458#define EUR_CR_PDS_INV3_DSC_SHIFT 0
459#define EUR_CR_PDS_INV_CSC 0x0AE0
460#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
461#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
462#define EUR_CR_PDS_PC_BASE 0x0B2C
463#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU
464#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
465#define EUR_CR_BIF_CTRL 0x0C00
466#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
467#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
468#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
469#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
470#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
471#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
472#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
473#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
474#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
475#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
476#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
477#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
478#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
479#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
480#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
481#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
482#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
483#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
484#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
485#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
486#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
487#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
488#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
489#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
490#define EUR_CR_BIF_INT_STAT 0x0C04
491#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
492#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
493#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
494#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
495#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
496#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
497#define EUR_CR_BIF_FAULT 0x0C08
498#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
499#define EUR_CR_BIF_FAULT_SB_SHIFT 4
500#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
501#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
502#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
503#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
504#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
505#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
506#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
507#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
508#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
509#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
510#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
511#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
512#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
513#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
514#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
515#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
516#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
517#define EUR_CR_2D_BLIT_STATUS 0x0E04
518#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
519#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
520#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
521#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
522#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
523#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
524#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
525#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
526#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
527#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
528#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
529#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
530#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
531#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
532#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
533#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
534#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
535#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
536#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
537#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
538#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
539#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
540#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
541#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
542#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
543#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
544#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
545
546#endif
547
diff --git a/drivers/gpu/pvr/sgx_bridge.h b/drivers/gpu/pvr/sgx_bridge.h
new file mode 100644
index 00000000000..10e59196ef9
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_bridge.h
@@ -0,0 +1,466 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SGX_BRIDGE_H__)
28#define __SGX_BRIDGE_H__
29
30#include "sgxapi_km.h"
31#include "sgxinfo.h"
32#include "pvr_bridge.h"
33
34#if defined (__cplusplus)
35extern "C" {
36#endif
37
38
39#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
40#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0)
41#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1)
42#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2)
43#define PVRSRV_BRIDGE_SGX_DOKICK PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3)
44#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4)
45#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5)
46
47#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
48
49#define PVRSRV_BRIDGE_SGX_GETMMUPDADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+10)
50
51#if defined(TRANSFER_QUEUE)
52#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13)
53#endif
54#define PVRSRV_BRIDGE_SGX_GETMISCINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14)
55#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15)
56#define PVRSRV_BRIDGE_SGX_DEVINITPART2 PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16)
57
58#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17)
59#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18)
60#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19)
61#define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20)
62#define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21)
63#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22)
64#if defined(SGX_FEATURE_2D_HARDWARE)
65#define PVRSRV_BRIDGE_SGX_SUBMIT2D PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23)
66#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24)
67#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25)
68#endif
69#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26)
70#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27)
71
72#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28)
73
74#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
75
76#if defined(PDUMP)
77#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
78#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
79#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
80#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
81#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
82#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
83#endif
84
85
86
87#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+36)
88
89
90typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
91{
92 IMG_UINT32 ui32BridgeFlags;
93 IMG_HANDLE hDevMemHeap;
94 IMG_DEV_VIRTADDR sDevVAddr;
95}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR;
96
97
98typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
99{
100 PVRSRV_ERROR eError;
101 IMG_DEV_PHYADDR DevPAddr;
102 IMG_CPU_PHYADDR CpuPAddr;
103}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
104
105
106typedef struct PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR_TAG
107{
108 IMG_UINT32 ui32BridgeFlags;
109 IMG_HANDLE hDevCookie;
110 IMG_HANDLE hDevMemContext;
111}PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR;
112
113
114typedef struct PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR_TAG
115{
116 IMG_DEV_PHYADDR sPDDevPAddr;
117 PVRSRV_ERROR eError;
118}PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR;
119
120
121typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
122{
123 IMG_UINT32 ui32BridgeFlags;
124 IMG_HANDLE hDevCookie;
125}PVRSRV_BRIDGE_IN_GETCLIENTINFO;
126
127
128typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG
129{
130 SGX_INTERNAL_DEVINFO sSGXInternalDevInfo;
131 PVRSRV_ERROR eError;
132}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO;
133
134
135typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG
136{
137 IMG_UINT32 ui32BridgeFlags;
138 IMG_HANDLE hDevCookie;
139}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO;
140
141
142typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG
143{
144 SGX_CLIENT_INFO sClientInfo;
145 PVRSRV_ERROR eError;
146}PVRSRV_BRIDGE_OUT_GETCLIENTINFO;
147
148
149typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG
150{
151 IMG_UINT32 ui32BridgeFlags;
152 IMG_HANDLE hDevCookie;
153 SGX_CLIENT_INFO sClientInfo;
154}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO;
155
156
157typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG
158{
159 IMG_UINT32 ui32BridgeFlags;
160 IMG_HANDLE hDevCookie;
161}PVRSRV_BRIDGE_IN_ISPBREAKPOLL;
162
163
164typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG
165{
166 IMG_UINT32 ui32BridgeFlags;
167 IMG_HANDLE hDevCookie;
168 SGX_CCB_KICK sCCBKick;
169}PVRSRV_BRIDGE_IN_DOKICK;
170
171
172typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG
173{
174 IMG_UINT32 ui32BridgeFlags;
175 IMG_HANDLE hDevCookie;
176}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES;
177
178
179#if defined(TRANSFER_QUEUE)
180
181typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG
182{
183 IMG_UINT32 ui32BridgeFlags;
184 IMG_HANDLE hDevCookie;
185 PVRSRV_TRANSFER_SGX_KICK sKick;
186}PVRSRV_BRIDGE_IN_SUBMITTRANSFER;
187
188#if defined(SGX_FEATURE_2D_HARDWARE)
189
190typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG
191{
192 IMG_UINT32 ui32BridgeFlags;
193 IMG_HANDLE hDevCookie;
194 PVRSRV_2D_SGX_KICK sKick;
195} PVRSRV_BRIDGE_IN_SUBMIT2D;
196#endif
197#endif
198
199
200typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG
201{
202 IMG_UINT32 ui32BridgeFlags;
203 IMG_HANDLE hDevCookie;
204 IMG_PCHAR pszKey;
205 IMG_PCHAR pszValue;
206}PVRSRV_BRIDGE_IN_READREGDWORD;
207
208
209typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG
210{
211 PVRSRV_ERROR eError;
212 IMG_UINT32 ui32Data;
213}PVRSRV_BRIDGE_OUT_READREGDWORD;
214
215
216typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG
217{
218 IMG_UINT32 ui32BridgeFlags;
219 IMG_HANDLE hDevCookie;
220 SGX_MISC_INFO *psMiscInfo;
221}PVRSRV_BRIDGE_IN_SGXGETMISCINFO;
222
223typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG
224{
225 IMG_UINT32 ui32BridgeFlags;
226 IMG_HANDLE hDevCookie;
227}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT;
228
229typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG
230{
231 PVRSRV_ERROR eError;
232 SGX_BRIDGE_INFO_FOR_SRVINIT sInitInfo;
233}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT;
234
235typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG
236{
237 IMG_UINT32 ui32BridgeFlags;
238 IMG_HANDLE hDevCookie;
239 SGX_BRIDGE_INIT_INFO sInitInfo;
240}PVRSRV_BRIDGE_IN_SGXDEVINITPART2;
241
242
243typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG
244{
245 IMG_UINT32 ui32BridgeFlags;
246 IMG_HANDLE hDevCookie;
247 IMG_HANDLE hKernSyncInfo;
248 IMG_BOOL bWaitForComplete;
249}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE;
250
251
252#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10
253
254typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG
255{
256 IMG_UINT32 ui32BridgeFlags;
257 IMG_HANDLE hDevCookie;
258 IMG_BOOL bLockOnFailure;
259 IMG_UINT32 ui32TotalPBSize;
260}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC;
261
262typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG
263{
264 IMG_HANDLE hKernelMemInfo;
265 IMG_HANDLE hSharedPBDesc;
266 IMG_HANDLE hSharedPBDescKernelMemInfoHandle;
267 IMG_HANDLE hHWPBDescKernelMemInfoHandle;
268 IMG_HANDLE hBlockKernelMemInfoHandle;
269 IMG_HANDLE hHWBlockKernelMemInfoHandle;
270 IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
271 IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount;
272 PVRSRV_ERROR eError;
273}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC;
274
275typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG
276{
277 IMG_UINT32 ui32BridgeFlags;
278 IMG_HANDLE hSharedPBDesc;
279}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC;
280
281typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG
282{
283 PVRSRV_ERROR eError;
284}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC;
285
286
287typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG
288{
289 IMG_UINT32 ui32BridgeFlags;
290 IMG_HANDLE hDevCookie;
291 IMG_HANDLE hSharedPBDescKernelMemInfo;
292 IMG_HANDLE hHWPBDescKernelMemInfo;
293 IMG_HANDLE hBlockKernelMemInfo;
294 IMG_HANDLE hHWBlockKernelMemInfo;
295 IMG_UINT32 ui32TotalPBSize;
296 IMG_HANDLE *phKernelMemInfoHandles;
297 IMG_UINT32 ui32KernelMemInfoHandlesCount;
298}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC;
299
300typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG
301{
302 PVRSRV_ERROR eError;
303 IMG_HANDLE hSharedPBDesc;
304}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC;
305
306
307#ifdef PDUMP
308typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG
309{
310 IMG_UINT32 ui32BridgeFlags;
311 SGX_KICKTA_DUMP_BUFFER *psBufferArray;
312 IMG_UINT32 ui32BufferArrayLength;
313 IMG_BOOL bDumpPolls;
314} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY;
315
316typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG
317{
318 IMG_UINT32 ui32BridgeFlags;
319 IMG_HANDLE hDevCookie;
320 IMG_UINT32 ui32DumpFrameNum;
321 IMG_BOOL bLastFrame;
322 IMG_UINT32 *pui32Registers;
323 IMG_UINT32 ui32NumRegisters;
324}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS;
325
326typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG
327{
328 IMG_UINT32 ui32BridgeFlags;
329 IMG_HANDLE hDevCookie;
330 IMG_UINT32 ui32DumpFrameNum;
331 IMG_BOOL bLastFrame;
332 IMG_UINT32 *pui32Registers;
333 IMG_UINT32 ui32NumRegisters;
334}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS;
335
336typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG
337{
338 IMG_UINT32 ui32BridgeFlags;
339 IMG_HANDLE hDevCookie;
340 IMG_UINT32 ui32DumpFrameNum;
341 IMG_UINT32 ui32TAKickCount;
342 IMG_BOOL bLastFrame;
343 IMG_UINT32 *pui32Registers;
344 IMG_UINT32 ui32NumRegisters;
345}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS;
346
347typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG
348{
349 IMG_UINT32 ui32BridgeFlags;
350 IMG_HANDLE hDevCookie;
351 IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
352 IMG_UINT32 ui32FileOffset;
353 IMG_UINT32 ui32PDumpFlags;
354
355}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB;
356
357typedef struct PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM
358{
359 IMG_UINT32 ui32BridgeFlags;
360 IMG_HANDLE hDevCookie;
361 IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
362 IMG_UINT32 ui32FileOffset;
363 IMG_DEV_VIRTADDR sDevVAddr;
364 IMG_UINT32 ui32Size;
365 IMG_UINT32 ui32DataMaster;
366 IMG_UINT32 ui32PDumpFlags;
367
368}PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM;
369
370#endif
371
372typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
373{
374 IMG_UINT32 ui32BridgeFlags;
375 IMG_HANDLE hDevCookie;
376 IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
377}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
378
379typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
380{
381 PVRSRV_ERROR eError;
382 IMG_HANDLE hHWRenderContext;
383}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
384
385typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
386{
387 IMG_UINT32 ui32BridgeFlags;
388 IMG_HANDLE hDevCookie;
389 IMG_HANDLE hHWRenderContext;
390}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT;
391
392typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
393{
394 IMG_UINT32 ui32BridgeFlags;
395 IMG_HANDLE hDevCookie;
396 IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
397}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
398
399typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
400{
401 PVRSRV_ERROR eError;
402 IMG_HANDLE hHWTransferContext;
403}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
404
405typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
406{
407 IMG_UINT32 ui32BridgeFlags;
408 IMG_HANDLE hDevCookie;
409 IMG_HANDLE hHWTransferContext;
410}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT;
411
412typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG
413{
414 IMG_UINT32 ui32BridgeFlags;
415 IMG_HANDLE hDevCookie;
416 IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr;
417}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET;
418
419
420#if defined(SGX_FEATURE_2D_HARDWARE)
421typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
422{
423 IMG_UINT32 ui32BridgeFlags;
424 IMG_HANDLE hDevCookie;
425 IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
426}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
427
428typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
429{
430 PVRSRV_ERROR eError;
431 IMG_HANDLE hHW2DContext;
432}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
433
434typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
435{
436 IMG_UINT32 ui32BridgeFlags;
437 IMG_HANDLE hDevCookie;
438 IMG_HANDLE hHW2DContext;
439}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT;
440
441#define SGX2D_MAX_BLT_CMD_SIZ 256
442#endif
443
444
445typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG
446{
447 IMG_UINT32 ui32BridgeFlags;
448 IMG_HANDLE hDevCookie;
449 IMG_UINT32 ui32ArraySize;
450 PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData;
451} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB;
452
453typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG
454{
455 PVRSRV_ERROR eError;
456 IMG_UINT32 ui32DataCount;
457 IMG_UINT32 ui32ClockSpeed;
458 IMG_UINT32 ui32HostTimeStamp;
459} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB;
460
461#if defined (__cplusplus)
462}
463#endif
464
465#endif
466
diff --git a/drivers/gpu/pvr/sgx_mkif_km.h b/drivers/gpu/pvr/sgx_mkif_km.h
new file mode 100644
index 00000000000..32b3a25d93f
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_mkif_km.h
@@ -0,0 +1,338 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__SGX_MKIF_KM_H__)
28#define __SGX_MKIF_KM_H__
29
30#include "img_types.h"
31#include "servicesint.h"
32#include "sgxapi_km.h"
33
34
35#if defined(SGX_FEATURE_MP)
36 #define SGX_REG_BANK_SHIFT (12)
37 #define SGX_REG_BANK_SIZE (0x4000)
38 #if defined(SGX541)
39 #define SGX_REG_BANK_BASE_INDEX (1)
40 #define SGX_REG_BANK_MASTER_INDEX (SGX_REG_BANK_BASE_INDEX + SGX_FEATURE_MP_CORE_COUNT)
41 #else
42 #define SGX_REG_BANK_BASE_INDEX (2)
43 #define SGX_REG_BANK_MASTER_INDEX (1)
44 #endif
45 #define SGX_MP_CORE_SELECT(x,i) (x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE))
46 #define SGX_MP_MASTER_SELECT(x) (x + (SGX_REG_BANK_MASTER_INDEX * SGX_REG_BANK_SIZE))
47#else
48 #define SGX_MP_CORE_SELECT(x,i) (x)
49#endif
50
51
52typedef struct _SGXMKIF_COMMAND_
53{
54 IMG_UINT32 ui32ServiceAddress;
55 IMG_UINT32 ui32CacheControl;
56 IMG_UINT32 ui32Data[4];
57 IMG_UINT32 ui32Padding[2];
58} SGXMKIF_COMMAND;
59
60
61typedef struct _PVRSRV_SGX_KERNEL_CCB_
62{
63 SGXMKIF_COMMAND asCommands[256];
64} PVRSRV_SGX_KERNEL_CCB;
65
66
67typedef struct _PVRSRV_SGX_CCB_CTL_
68{
69 IMG_UINT32 ui32WriteOffset;
70 IMG_UINT32 ui32ReadOffset;
71} PVRSRV_SGX_CCB_CTL;
72
73
74typedef struct _SGXMKIF_HOST_CTL_
75{
76#if defined(PVRSRV_USSE_EDM_BREAKPOINTS)
77 IMG_UINT32 ui32BreakpointDisable;
78 IMG_UINT32 ui32Continue;
79#endif
80
81 volatile IMG_UINT32 ui32InitStatus;
82 volatile IMG_UINT32 ui32PowerStatus;
83 volatile IMG_UINT32 ui32CleanupStatus;
84#if defined(SUPPORT_HW_RECOVERY)
85 IMG_UINT32 ui32uKernelDetectedLockups;
86 IMG_UINT32 ui32HostDetectedLockups;
87 IMG_UINT32 ui32HWRecoverySampleRate;
88#endif
89 IMG_UINT32 ui32uKernelTimerClock;
90 IMG_UINT32 ui32ActivePowManSampleRate;
91 IMG_UINT32 ui32InterruptFlags;
92 IMG_UINT32 ui32InterruptClearFlags;
93 IMG_UINT32 ui32BPSetClearSignal;
94
95 IMG_UINT32 ui32NumActivePowerEvents;
96
97 IMG_UINT32 ui32TimeWraps;
98 IMG_UINT32 ui32HostClock;
99
100#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
101 IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
102 IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
103#else
104 IMG_UINT32 ui32PerfGroup;
105#endif
106} SGXMKIF_HOST_CTL;
107
108#define SGXMKIF_CMDTA_CTRLFLAGS_READY 0x00000001
109typedef struct _SGXMKIF_CMDTA_SHARED_
110{
111 IMG_UINT32 ui32CtrlFlags;
112
113 IMG_UINT32 ui32NumTAStatusVals;
114 IMG_UINT32 ui32Num3DStatusVals;
115
116
117 IMG_UINT32 ui32TATQSyncWriteOpsPendingVal;
118 IMG_DEV_VIRTADDR sTATQSyncWriteOpsCompleteDevVAddr;
119 IMG_UINT32 ui32TATQSyncReadOpsPendingVal;
120 IMG_DEV_VIRTADDR sTATQSyncReadOpsCompleteDevVAddr;
121
122
123 IMG_UINT32 ui323DTQSyncWriteOpsPendingVal;
124 IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr;
125 IMG_UINT32 ui323DTQSyncReadOpsPendingVal;
126 IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr;
127
128
129#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
130
131 IMG_UINT32 ui32NumTASrcSyncs;
132 PVRSRV_DEVICE_SYNC_OBJECT asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS];
133 IMG_UINT32 ui32NumTADstSyncs;
134 PVRSRV_DEVICE_SYNC_OBJECT asTADstSyncs[SGX_MAX_TA_DST_SYNCS];
135 IMG_UINT32 ui32Num3DSrcSyncs;
136 PVRSRV_DEVICE_SYNC_OBJECT as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS];
137#else
138
139 IMG_UINT32 ui32NumSrcSyncs;
140 PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS];
141#endif
142
143
144 PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency;
145
146 CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
147 CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
148
149} SGXMKIF_CMDTA_SHARED;
150
151#define SGXTQ_MAX_STATUS SGX_MAX_TRANSFER_STATUS_VALS + 2
152
153#define SGXMKIF_TQFLAGS_NOSYNCUPDATE 0x00000001
154#define SGXMKIF_TQFLAGS_KEEPPENDING 0x00000002
155#define SGXMKIF_TQFLAGS_TATQ_SYNC 0x00000004
156#define SGXMKIF_TQFLAGS_3DTQ_SYNC 0x00000008
157#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH)
158#define SGXMKIF_TQFLAGS_CTXSWITCH 0x00000010
159#endif
160#define SGXMKIF_TQFLAGS_DUMMYTRANSFER 0x00000020
161
162typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
163{
164
165
166 IMG_UINT32 ui32SrcReadOpPendingVal;
167 IMG_DEV_VIRTADDR sSrcReadOpsCompleteDevAddr;
168
169 IMG_UINT32 ui32SrcWriteOpPendingVal;
170 IMG_DEV_VIRTADDR sSrcWriteOpsCompleteDevAddr;
171
172
173
174 IMG_UINT32 ui32DstReadOpPendingVal;
175 IMG_DEV_VIRTADDR sDstReadOpsCompleteDevAddr;
176
177 IMG_UINT32 ui32DstWriteOpPendingVal;
178 IMG_DEV_VIRTADDR sDstWriteOpsCompleteDevAddr;
179
180
181 IMG_UINT32 ui32TASyncWriteOpsPendingVal;
182 IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr;
183 IMG_UINT32 ui32TASyncReadOpsPendingVal;
184 IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr;
185
186
187 IMG_UINT32 ui323DSyncWriteOpsPendingVal;
188 IMG_DEV_VIRTADDR s3DSyncWriteOpsCompleteDevVAddr;
189 IMG_UINT32 ui323DSyncReadOpsPendingVal;
190 IMG_DEV_VIRTADDR s3DSyncReadOpsCompleteDevVAddr;
191
192 IMG_UINT32 ui32NumStatusVals;
193 CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS];
194} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED;
195
196
197#if defined(SGX_FEATURE_2D_HARDWARE)
198typedef struct _SGXMKIF_2DCMD_SHARED_ {
199
200 IMG_UINT32 ui32NumSrcSync;
201 PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS];
202
203
204 PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData;
205
206
207 PVRSRV_DEVICE_SYNC_OBJECT sTASyncData;
208
209
210 PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData;
211} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED;
212#endif
213
214
215typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
216{
217 IMG_DEV_VIRTADDR sAccessDevAddr;
218 IMG_UINT32 ui32NumSyncObjects;
219
220 PVRSRV_DEVICE_SYNC_OBJECT asSyncData[1];
221} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST;
222
223
224#define PVRSRV_USSE_EDM_INIT_COMPLETE (1UL << 0)
225
226#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2)
227#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3)
228#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4)
229#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5)
230
231#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0)
232#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1)
233
234#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE (1UL << 0)
235
236#define PVRSRV_USSE_MISCINFO_READY 0x1UL
237#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES 0x2UL
238#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
239#define PVRSRV_USSE_MISCINFO_MEMREAD 0x4UL
240#define PVRSRV_USSE_MISCINFO_MEMWRITE 0x8UL
241#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
242#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL 0x1UL << 31
243#endif
244#endif
245
246
247#define PVRSRV_CLEANUPCMD_RT 0x1
248#define PVRSRV_CLEANUPCMD_RC 0x2
249#define PVRSRV_CLEANUPCMD_TC 0x3
250#define PVRSRV_CLEANUPCMD_2DC 0x4
251#define PVRSRV_CLEANUPCMD_PB 0x5
252
253#define PVRSRV_POWERCMD_POWEROFF 0x1
254#define PVRSRV_POWERCMD_IDLE 0x2
255#define PVRSRV_POWERCMD_RESUME 0x3
256
257
258#if defined(SGX_FEATURE_BIF_NUM_DIRLISTS)
259#define SGX_BIF_DIR_LIST_INDEX_EDM (SGX_FEATURE_BIF_NUM_DIRLISTS - 1)
260#else
261#define SGX_BIF_DIR_LIST_INDEX_EDM (0)
262#endif
263
264#define SGXMKIF_CC_INVAL_BIF_PT 0x1
265#define SGXMKIF_CC_INVAL_BIF_PD 0x2
266#define SGXMKIF_CC_INVAL_BIF_SL 0x4
267#define SGXMKIF_CC_INVAL_DATA 0x8
268
269
270typedef struct _SGX_MISCINFO_STRUCT_SIZES_
271{
272#if defined (SGX_FEATURE_2D_HARDWARE)
273 IMG_UINT32 ui32Sizeof_2DCMD;
274 IMG_UINT32 ui32Sizeof_2DCMD_SHARED;
275#endif
276 IMG_UINT32 ui32Sizeof_CMDTA;
277 IMG_UINT32 ui32Sizeof_CMDTA_SHARED;
278 IMG_UINT32 ui32Sizeof_TRANSFERCMD;
279 IMG_UINT32 ui32Sizeof_TRANSFERCMD_SHARED;
280 IMG_UINT32 ui32Sizeof_3DREGISTERS;
281 IMG_UINT32 ui32Sizeof_HWPBDESC;
282 IMG_UINT32 ui32Sizeof_HWRENDERCONTEXT;
283 IMG_UINT32 ui32Sizeof_HWRENDERDETAILS;
284 IMG_UINT32 ui32Sizeof_HWRTDATA;
285 IMG_UINT32 ui32Sizeof_HWRTDATASET;
286 IMG_UINT32 ui32Sizeof_HWTRANSFERCONTEXT;
287 IMG_UINT32 ui32Sizeof_HOST_CTL;
288 IMG_UINT32 ui32Sizeof_COMMAND;
289} SGX_MISCINFO_STRUCT_SIZES;
290
291
292#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
293typedef struct _PVRSRV_SGX_MISCINFO_MEMACCESS
294{
295 IMG_DEV_VIRTADDR sDevVAddr;
296 IMG_DEV_PHYADDR sPDDevPAddr;
297} PVRSRV_SGX_MISCINFO_MEMACCESS;
298#endif
299
300typedef struct _PVRSRV_SGX_MISCINFO_INFO
301{
302 IMG_UINT32 ui32MiscInfoFlags;
303 PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures;
304 SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
305#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
306 PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessSrc;
307 PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessDest;
308#endif
309} PVRSRV_SGX_MISCINFO_INFO;
310
311#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
312#define SGXMK_TRACE_BUFFER_SIZE 512
313#endif
314
315#define SGXMKIF_HWPERF_CB_SIZE 0x100
316
317typedef struct _SGXMKIF_HWPERF_CB_ENTRY_
318{
319 IMG_UINT32 ui32FrameNo;
320 IMG_UINT32 ui32Type;
321 IMG_UINT32 ui32Ordinal;
322 IMG_UINT32 ui32Info;
323 IMG_UINT32 ui32TimeWraps;
324 IMG_UINT32 ui32Time;
325 IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
326} SGXMKIF_HWPERF_CB_ENTRY;
327
328typedef struct _SGXMKIF_HWPERF_CB_
329{
330 IMG_UINT32 ui32Woff;
331 IMG_UINT32 ui32Roff;
332 IMG_UINT32 ui32Ordinal;
333 SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE];
334} SGXMKIF_HWPERF_CB;
335
336
337#endif
338
diff --git a/drivers/gpu/pvr/sgx_options.h b/drivers/gpu/pvr/sgx_options.h
new file mode 100644
index 00000000000..319db1c5854
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_options.h
@@ -0,0 +1,224 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(DEBUG) || defined (INTERNAL_TEST)
28#define DEBUG_SET_OFFSET OPTIONS_BIT0
29#define OPTIONS_BIT0 0x1
30#else
31#define OPTIONS_BIT0 0x0
32#endif
33
34#if defined(PDUMP) || defined (INTERNAL_TEST)
35#define PDUMP_SET_OFFSET OPTIONS_BIT1
36#define OPTIONS_BIT1 (0x1 << 1)
37#else
38#define OPTIONS_BIT1 0x0
39#endif
40
41#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST)
42#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET OPTIONS_BIT2
43#define OPTIONS_BIT2 (0x1 << 2)
44#else
45#define OPTIONS_BIT2 0x0
46#endif
47
48#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST)
49#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3
50#define OPTIONS_BIT3 (0x1 << 3)
51#else
52#define OPTIONS_BIT3 0x0
53#endif
54
55
56
57#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST)
58#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4
59#define OPTIONS_BIT4 (0x1 << 4)
60#else
61#define OPTIONS_BIT4 0x0
62#endif
63
64#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST)
65#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT5
66#define OPTIONS_BIT5 (0x1 << 5)
67#else
68#define OPTIONS_BIT5 0x0
69#endif
70
71#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST)
72#define SGX_DMS_AGE_ENABLE_SET_OFFSET OPTIONS_BIT6
73#define OPTIONS_BIT6 (0x1 << 6)
74#else
75#define OPTIONS_BIT6 0x0
76#endif
77
78#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST)
79#define SGX_FAST_DPM_INIT_SET_OFFSET OPTIONS_BIT8
80#define OPTIONS_BIT8 (0x1 << 8)
81#else
82#define OPTIONS_BIT8 0x0
83#endif
84
85#if defined(SGX_FEATURE_WRITEBACK_DCU) || defined (INTERNAL_TEST)
86#define SGX_FEATURE_DCU_SET_OFFSET OPTIONS_BIT9
87#define OPTIONS_BIT9 (0x1 << 9)
88#else
89#define OPTIONS_BIT9 0x0
90#endif
91
92#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
93#define SGX_FEATURE_MP_SET_OFFSET OPTIONS_BIT10
94#define OPTIONS_BIT10 (0x1 << 10)
95#else
96#define OPTIONS_BIT10 0x0
97#endif
98
99#if defined(SGX_FEATURE_MULTITHREADED_UKERNEL) || defined (INTERNAL_TEST)
100#define SGX_FEATURE_MULTITHREADED_UKERNEL_SET_OFFSET OPTIONS_BIT11
101#define OPTIONS_BIT11 (0x1 << 11)
102#else
103#define OPTIONS_BIT11 0x0
104#endif
105
106
107
108#if defined(SGX_FEATURE_OVERLAPPED_SPM) || defined (INTERNAL_TEST)
109#define SGX_FEATURE_OVERLAPPED_SPM_SET_OFFSET OPTIONS_BIT12
110#define OPTIONS_BIT12 (0x1 << 12)
111#else
112#define OPTIONS_BIT12 0x0
113#endif
114
115
116#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST)
117#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT13
118#define OPTIONS_BIT13 (0x1 << 13)
119#else
120#define OPTIONS_BIT13 0x0
121#endif
122
123#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST)
124#define SGX_SUPPORT_HWPROFILING_SET_OFFSET OPTIONS_BIT14
125#define OPTIONS_BIT14 (0x1 << 14)
126#else
127#define OPTIONS_BIT14 0x0
128#endif
129
130
131
132#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST)
133#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET OPTIONS_BIT15
134#define OPTIONS_BIT15 (0x1 << 15)
135#else
136#define OPTIONS_BIT15 0x0
137#endif
138
139#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST)
140#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET OPTIONS_BIT16
141#define OPTIONS_BIT16 (0x1 << 16)
142#else
143#define OPTIONS_BIT16 0x0
144#endif
145
146#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST)
147#define SUPPORT_PERCONTEXT_PB_SET_OFFSET OPTIONS_BIT17
148#define OPTIONS_BIT17 (0x1 << 17)
149#else
150#define OPTIONS_BIT17 0x0
151#endif
152
153#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST)
154#define SUPPORT_SGX_HWPERF_SET_OFFSET OPTIONS_BIT18
155#define OPTIONS_BIT18 (0x1 << 18)
156#else
157#define OPTIONS_BIT18 0x0
158#endif
159
160
161
162#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST)
163#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET OPTIONS_BIT19
164#define OPTIONS_BIT19 (0x1 << 19)
165#else
166#define OPTIONS_BIT19 0x0
167#endif
168
169#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST)
170#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET OPTIONS_BIT20
171#define OPTIONS_BIT20 (0x1 << 20)
172#else
173#define OPTIONS_BIT20 0x0
174#endif
175
176#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST)
177#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET OPTIONS_BIT21
178#define OPTIONS_BIT21 (0x1 << 21)
179#else
180#define OPTIONS_BIT21 0x0
181#endif
182
183#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST)
184#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22
185#define OPTIONS_BIT22 (0x1 << 22)
186#else
187#define OPTIONS_BIT22 0x0
188#endif
189
190
191#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
192#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET)
193#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 28UL
194#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF
195#else
196#define OPTIONS_HIGHBYTE 0x0
197#endif
198
199
200
201#define SGX_BUILD_OPTIONS \
202 OPTIONS_BIT0 |\
203 OPTIONS_BIT1 |\
204 OPTIONS_BIT2 |\
205 OPTIONS_BIT3 |\
206 OPTIONS_BIT4 |\
207 OPTIONS_BIT5 |\
208 OPTIONS_BIT6 |\
209 OPTIONS_BIT8 |\
210 OPTIONS_BIT9 |\
211 OPTIONS_BIT10 |\
212 OPTIONS_BIT11 |\
213 OPTIONS_BIT12 |\
214 OPTIONS_BIT13 |\
215 OPTIONS_BIT14 |\
216 OPTIONS_BIT15 |\
217 OPTIONS_BIT16 |\
218 OPTIONS_BIT17 |\
219 OPTIONS_BIT18 |\
220 OPTIONS_BIT19 |\
221 OPTIONS_BIT20 |\
222 OPTIONS_BIT21 |\
223 OPTIONS_HIGHBYTE
224
diff --git a/drivers/gpu/pvr/sgxapi_km.h b/drivers/gpu/pvr/sgxapi_km.h
new file mode 100644
index 00000000000..d9bad0346a5
--- /dev/null
+++ b/drivers/gpu/pvr/sgxapi_km.h
@@ -0,0 +1,381 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SGXAPI_KM_H__
28#define __SGXAPI_KM_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#include "sgxdefs.h"
35
36#if defined(__linux__) && !defined(USE_CODE)
37 #if defined(__KERNEL__)
38 #include <asm/unistd.h>
39 #else
40 #include <unistd.h>
41 #endif
42#endif
43
44#define SGX_UNDEFINED_HEAP_ID (~0LU)
45#define SGX_GENERAL_HEAP_ID 0
46#define SGX_TADATA_HEAP_ID 1
47#define SGX_KERNEL_CODE_HEAP_ID 2
48#define SGX_KERNEL_DATA_HEAP_ID 3
49#define SGX_PIXELSHADER_HEAP_ID 4
50#define SGX_VERTEXSHADER_HEAP_ID 5
51#define SGX_PDSPIXEL_CODEDATA_HEAP_ID 6
52#define SGX_PDSVERTEX_CODEDATA_HEAP_ID 7
53#define SGX_SYNCINFO_HEAP_ID 8
54#define SGX_3DPARAMETERS_HEAP_ID 9
55#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
56#define SGX_GENERAL_MAPPING_HEAP_ID 10
57#endif
58#if defined(SGX_FEATURE_2D_HARDWARE)
59#define SGX_2D_HEAP_ID 11
60#else
61#if defined(FIX_HW_BRN_26915)
62#define SGX_CGBUFFER_HEAP_ID 12
63#endif
64#endif
65#define SGX_MAX_HEAP_ID 13
66
67#if defined(SGX543) || defined(SGX544) || defined(SGX554)
68#define SGX_USE_CODE_SEGMENT_RANGE_BITS 23
69#else
70#define SGX_USE_CODE_SEGMENT_RANGE_BITS 19
71#endif
72
73#define SGX_MAX_TA_STATUS_VALS 32
74#define SGX_MAX_3D_STATUS_VALS 4
75
76#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
77#define SGX_MAX_TA_DST_SYNCS 1
78#define SGX_MAX_TA_SRC_SYNCS 1
79#define SGX_MAX_3D_SRC_SYNCS 4
80#else
81#if defined(ANDROID)
82#define SGX_MAX_SRC_SYNCS 8
83#else
84#define SGX_MAX_SRC_SYNCS 4
85#endif
86#endif
87
88
89#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
90#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 8
91#else
92#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9
93#endif
94
95#define PVRSRV_SGX_HWPERF_INVALID 0x1
96
97#define PVRSRV_SGX_HWPERF_TRANSFER 0x2
98#define PVRSRV_SGX_HWPERF_TA 0x3
99#define PVRSRV_SGX_HWPERF_3D 0x4
100#define PVRSRV_SGX_HWPERF_2D 0x5
101#define PVRSRV_SGX_HWPERF_POWER 0x6
102#define PVRSRV_SGX_HWPERF_PERIODIC 0x7
103
104#define PVRSRV_SGX_HWPERF_MK_EVENT 0x101
105#define PVRSRV_SGX_HWPERF_MK_TA 0x102
106#define PVRSRV_SGX_HWPERF_MK_3D 0x103
107#define PVRSRV_SGX_HWPERF_MK_2D 0x104
108
109#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT 28
110#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK ((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1)
111#define PVRSRV_SGX_HWPERF_TYPE_OP_START (0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
112#define PVRSRV_SGX_HWPERF_TYPE_OP_END (1Ul << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
113
114#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
115#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
116#define PVRSRV_SGX_HWPERF_TYPE_TA_START (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
117#define PVRSRV_SGX_HWPERF_TYPE_TA_END (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
118#define PVRSRV_SGX_HWPERF_TYPE_3D_START (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
119#define PVRSRV_SGX_HWPERF_TYPE_3D_END (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
120#define PVRSRV_SGX_HWPERF_TYPE_2D_START (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
121#define PVRSRV_SGX_HWPERF_TYPE_2D_END (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
122#define PVRSRV_SGX_HWPERF_TYPE_POWER_START (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
123#define PVRSRV_SGX_HWPERF_TYPE_POWER_END (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
124#define PVRSRV_SGX_HWPERF_TYPE_PERIODIC (PVRSRV_SGX_HWPERF_PERIODIC)
125
126#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START)
127#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END)
128#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
129#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
130#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
131#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
132#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
133#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
134
135#define PVRSRV_SGX_HWPERF_STATUS_OFF (0x0)
136#define PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS (1UL << 0)
137#define PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON (1UL << 1)
138#define PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON (1UL << 2)
139#define PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON (1UL << 3)
140
141
142typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_
143{
144 IMG_UINT32 ui32FrameNo;
145 IMG_UINT32 ui32Type;
146 IMG_UINT32 ui32Ordinal;
147 IMG_UINT32 ui32Info;
148 IMG_UINT32 ui32Clocksx16;
149 IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
150} PVRSRV_SGX_HWPERF_CB_ENTRY;
151
152
153typedef struct _CTL_STATUS_
154{
155 IMG_DEV_VIRTADDR sStatusDevAddr;
156 IMG_UINT32 ui32StatusValue;
157} CTL_STATUS;
158
159
160typedef enum _SGX_MISC_INFO_REQUEST_
161{
162 SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0,
163 SGX_MISC_INFO_REQUEST_SGXREV,
164 SGX_MISC_INFO_REQUEST_DRIVER_SGXREV,
165#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
166 SGX_MISC_INFO_REQUEST_MEMREAD,
167 SGX_MISC_INFO_REQUEST_MEMCOPY,
168#endif
169 SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS,
170#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
171 SGX_MISC_INFO_REQUEST_SET_BREAKPOINT,
172 SGX_MISC_INFO_REQUEST_WAIT_FOR_BREAKPOINT,
173 SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT,
174 SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT,
175#endif
176 SGX_MISC_INFO_DUMP_DEBUG_INFO,
177 SGX_MISC_INFO_PANIC,
178 SGX_MISC_INFO_REQUEST_SPM,
179 SGX_MISC_INFO_REQUEST_ACTIVEPOWER,
180 SGX_MISC_INFO_REQUEST_LOCKUPS,
181 SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff
182} SGX_MISC_INFO_REQUEST;
183
184
185typedef struct _PVRSRV_SGX_MISCINFO_FEATURES
186{
187 IMG_UINT32 ui32CoreRev;
188 IMG_UINT32 ui32CoreID;
189 IMG_UINT32 ui32DDKVersion;
190 IMG_UINT32 ui32DDKBuild;
191 IMG_UINT32 ui32CoreIdSW;
192 IMG_UINT32 ui32CoreRevSW;
193 IMG_UINT32 ui32BuildOptions;
194#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
195 IMG_UINT32 ui32DeviceMemValue;
196#endif
197#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
198 IMG_DEV_VIRTADDR sDevVAEDMStatusBuffer;
199 IMG_PVOID pvEDMStatusBuffer;
200#endif
201} PVRSRV_SGX_MISCINFO_FEATURES;
202
203
204typedef struct _PVRSRV_SGX_MISCINFO_LOCKUPS
205{
206 IMG_UINT32 ui32HostDetectedLockups;
207 IMG_UINT32 ui32uKernelDetectedLockups;
208} PVRSRV_SGX_MISCINFO_LOCKUPS;
209
210
211typedef struct _PVRSRV_SGX_MISCINFO_ACTIVEPOWER
212{
213 IMG_UINT32 ui32NumActivePowerEvents;
214} PVRSRV_SGX_MISCINFO_ACTIVEPOWER;
215
216
217typedef struct _PVRSRV_SGX_MISCINFO_SPM
218{
219 IMG_HANDLE hRTDataSet;
220 IMG_UINT32 ui32NumOutOfMemSignals;
221 IMG_UINT32 ui32NumSPMRenders;
222} PVRSRV_SGX_MISCINFO_SPM;
223
224
225#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
226typedef struct _SGX_BREAKPOINT_INFO
227{
228
229 IMG_BOOL bBPEnable;
230
231 IMG_UINT32 ui32BPIndex;
232
233 IMG_UINT32 ui32DataMasterMask;
234
235 IMG_DEV_VIRTADDR sBPDevVAddr, sBPDevVAddrEnd;
236
237 IMG_BOOL bTrapped;
238
239 IMG_BOOL bRead;
240
241 IMG_BOOL bWrite;
242
243 IMG_BOOL bTrappedBP;
244
245 IMG_UINT32 ui32CoreNum;
246 IMG_DEV_VIRTADDR sTrappedBPDevVAddr;
247 IMG_UINT32 ui32TrappedBPBurstLength;
248 IMG_BOOL bTrappedBPRead;
249 IMG_UINT32 ui32TrappedBPDataMaster;
250 IMG_UINT32 ui32TrappedBPTag;
251} SGX_BREAKPOINT_INFO;
252#endif
253
254
255typedef struct _PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS
256{
257
258 IMG_UINT32 ui32NewHWPerfStatus;
259
260 #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
261
262 IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
263
264 IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
265 #else
266
267 IMG_UINT32 ui32PerfGroup;
268 #endif
269} PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS;
270
271
272typedef struct _SGX_MISC_INFO_
273{
274 SGX_MISC_INFO_REQUEST eRequest;
275#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
276 IMG_DEV_VIRTADDR sDevVAddrSrc;
277 IMG_DEV_VIRTADDR sDevVAddrDest;
278 IMG_HANDLE hDevMemContext;
279#endif
280 union
281 {
282 IMG_UINT32 reserved;
283 PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures;
284 IMG_UINT32 ui32SGXClockSpeed;
285 PVRSRV_SGX_MISCINFO_ACTIVEPOWER sActivePower;
286 PVRSRV_SGX_MISCINFO_LOCKUPS sLockups;
287 PVRSRV_SGX_MISCINFO_SPM sSPM;
288#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
289 SGX_BREAKPOINT_INFO sSGXBreakpointInfo;
290#endif
291 PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS sSetHWPerfStatus;
292 } uData;
293} SGX_MISC_INFO;
294
295#if defined(SGX_FEATURE_2D_HARDWARE)
296#define PVRSRV_MAX_BLT_SRC_SYNCS 3
297#endif
298
299
300#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH 256
301
302typedef struct _SGX_KICKTA_DUMPBITMAP_
303{
304 IMG_DEV_VIRTADDR sDevBaseAddr;
305 IMG_UINT32 ui32Flags;
306 IMG_UINT32 ui32Width;
307 IMG_UINT32 ui32Height;
308 IMG_UINT32 ui32Stride;
309 IMG_UINT32 ui32PDUMPFormat;
310 IMG_UINT32 ui32BytesPP;
311 IMG_CHAR pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH];
312} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP;
313
314#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE (16)
315
316typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_
317{
318
319 IMG_UINT32 ui32CacheControl;
320
321} PVRSRV_SGX_PDUMP_CONTEXT;
322
323
324typedef struct _SGX_KICKTA_DUMP_ROFF_
325{
326 IMG_HANDLE hKernelMemInfo;
327 IMG_UINT32 uiAllocIndex;
328 IMG_UINT32 ui32Offset;
329 IMG_UINT32 ui32Value;
330 IMG_PCHAR pszName;
331} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF;
332
333typedef struct _SGX_KICKTA_DUMP_BUFFER_
334{
335 IMG_UINT32 ui32SpaceUsed;
336 IMG_UINT32 ui32Start;
337 IMG_UINT32 ui32End;
338 IMG_UINT32 ui32BufferSize;
339 IMG_UINT32 ui32BackEndLength;
340 IMG_UINT32 uiAllocIndex;
341 IMG_HANDLE hKernelMemInfo;
342 IMG_PVOID pvLinAddr;
343#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
344 IMG_HANDLE hCtrlKernelMemInfo;
345 IMG_DEV_VIRTADDR sCtrlDevVAddr;
346#endif
347 IMG_PCHAR pszName;
348} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER;
349
350#ifdef PDUMP
351typedef struct _SGX_KICKTA_PDUMP_
352{
353
354 PSGX_KICKTA_DUMPBITMAP psPDumpBitmapArray;
355 IMG_UINT32 ui32PDumpBitmapSize;
356
357
358 PSGX_KICKTA_DUMP_BUFFER psBufferArray;
359 IMG_UINT32 ui32BufferArraySize;
360
361
362 PSGX_KICKTA_DUMP_ROFF psROffArray;
363 IMG_UINT32 ui32ROffArraySize;
364} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP;
365#endif
366
367#if defined(TRANSFER_QUEUE)
368#if defined(SGX_FEATURE_2D_HARDWARE)
369#define SGX_MAX_2D_BLIT_CMD_SIZE 26
370#define SGX_MAX_2D_SRC_SYNC_OPS 3
371#endif
372#define SGX_MAX_TRANSFER_STATUS_VALS 2
373#define SGX_MAX_TRANSFER_SYNC_OPS 5
374#endif
375
376#if defined (__cplusplus)
377}
378#endif
379
380#endif
381
diff --git a/drivers/gpu/pvr/sgxdefs.h b/drivers/gpu/pvr/sgxdefs.h
new file mode 100644
index 00000000000..9e5effbc853
--- /dev/null
+++ b/drivers/gpu/pvr/sgxdefs.h
@@ -0,0 +1,94 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SGXDEFS_H_
28#define _SGXDEFS_H_
29
30#include "sgxerrata.h"
31#include "sgxfeaturedefs.h"
32
33#if defined(SGX520)
34#include "sgx520defs.h"
35#else
36#if defined(SGX530)
37#include "sgx530defs.h"
38#else
39#if defined(SGX535)
40#include "sgx535defs.h"
41#else
42#if defined(SGX535_V1_1)
43#include "sgx535defs.h"
44#else
45#if defined(SGX540)
46#include "sgx540defs.h"
47#else
48#if defined(SGX541)
49#include "sgx541defs.h"
50#else
51#if defined(SGX543)
52#include "sgx543defs.h"
53#else
54#if defined(SGX544)
55#include "sgx544defs.h"
56#else
57#if defined(SGX545)
58#include "sgx545defs.h"
59#else
60#if defined(SGX531)
61#include "sgx531defs.h"
62#else
63#if defined(SGX554)
64#include "sgx554defs.h"
65#endif
66#endif
67#endif
68#endif
69#endif
70#endif
71#endif
72#endif
73#endif
74#endif
75#endif
76
77#if defined(SGX_FEATURE_MP)
78#if defined(SGX541)
79#if SGX_CORE_REV == 100
80#include "sgx541_100mpdefs.h"
81#else
82#include "sgx541mpdefs.h"
83#endif
84#else
85#include "sgxmpdefs.h"
86#endif
87#else
88#if defined(SGX_FEATURE_SYSTEM_CACHE)
89#include "mnemedefs.h"
90#endif
91#endif
92
93#endif
94
diff --git a/drivers/gpu/pvr/sgxerrata.h b/drivers/gpu/pvr/sgxerrata.h
new file mode 100644
index 00000000000..552cb2c3523
--- /dev/null
+++ b/drivers/gpu/pvr/sgxerrata.h
@@ -0,0 +1,330 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SGXERRATA_KM_H_
28#define _SGXERRATA_KM_H_
29
30#if defined(SGX520) && !defined(SGX_CORE_DEFINED)
31
32 #define SGX_CORE_REV_HEAD 0
33 #if defined(USE_SGX_CORE_REV_HEAD)
34
35 #define SGX_CORE_REV SGX_CORE_REV_HEAD
36 #endif
37
38 #if SGX_CORE_REV == 100
39 #else
40 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
41
42 #else
43 #error "sgxerrata.h: SGX520 Core Revision unspecified"
44 #endif
45 #endif
46
47 #define SGX_CORE_DEFINED
48#endif
49
50#if defined(SGX530) && !defined(SGX_CORE_DEFINED)
51
52 #define SGX_CORE_REV_HEAD 0
53 #if defined(USE_SGX_CORE_REV_HEAD)
54
55 #define SGX_CORE_REV SGX_CORE_REV_HEAD
56 #endif
57
58 #if SGX_CORE_REV == 110
59 #define FIX_HW_BRN_22934
60 #else
61 #if SGX_CORE_REV == 111
62 #define FIX_HW_BRN_22934
63 #else
64 #if SGX_CORE_REV == 120
65 #define FIX_HW_BRN_22934
66 #else
67 #if SGX_CORE_REV == 121
68 #define FIX_HW_BRN_22934
69 #else
70 #if SGX_CORE_REV == 125
71 #define FIX_HW_BRN_22934
72 #else
73 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
74
75 #else
76 #error "sgxerrata.h: SGX530 Core Revision unspecified"
77 #endif
78 #endif
79 #endif
80 #endif
81#endif
82 #endif
83
84 #define SGX_CORE_DEFINED
85#endif
86
87#if defined(SGX531) && !defined(SGX_CORE_DEFINED)
88
89 #define SGX_CORE_REV_HEAD 0
90 #if defined(USE_SGX_CORE_REV_HEAD)
91
92 #define SGX_CORE_REV SGX_CORE_REV_HEAD
93 #endif
94
95 #if SGX_CORE_REV == 101
96 #define FIX_HW_BRN_26620
97 #define FIX_HW_BRN_28011
98 #else
99 #if SGX_CORE_REV == 110
100
101 #else
102 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
103
104 #else
105 #error "sgxerrata.h: SGX531 Core Revision unspecified"
106 #endif
107 #endif
108 #endif
109
110 #define SGX_CORE_DEFINED
111#endif
112
113#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED)
114
115 #define SGX_CORE_REV_HEAD 0
116 #if defined(USE_SGX_CORE_REV_HEAD)
117
118 #define SGX_CORE_REV SGX_CORE_REV_HEAD
119 #endif
120
121 #if SGX_CORE_REV == 112
122 #define FIX_HW_BRN_23281
123 #define FIX_HW_BRN_23410
124 #define FIX_HW_BRN_22693
125 #define FIX_HW_BRN_22934
126 #define FIX_HW_BRN_22997
127 #define FIX_HW_BRN_23030
128 #else
129 #if SGX_CORE_REV == 113
130 #define FIX_HW_BRN_22934
131 #define FIX_HW_BRN_23281
132 #define FIX_HW_BRN_23944
133 #define FIX_HW_BRN_23410
134 #else
135 #if SGX_CORE_REV == 121
136 #define FIX_HW_BRN_22934
137 #define FIX_HW_BRN_23944
138 #define FIX_HW_BRN_23410
139 #else
140 #if SGX_CORE_REV == 126
141 #define FIX_HW_BRN_22934
142 #else
143 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
144
145 #else
146 #error "sgxerrata.h: SGX535 Core Revision unspecified"
147
148 #endif
149 #endif
150 #endif
151 #endif
152 #endif
153
154 #define SGX_CORE_DEFINED
155#endif
156
157#if defined(SGX540) && !defined(SGX_CORE_DEFINED)
158
159 #define SGX_CORE_REV_HEAD 0
160 #if defined(USE_SGX_CORE_REV_HEAD)
161
162 #define SGX_CORE_REV SGX_CORE_REV_HEAD
163 #endif
164
165 #if SGX_CORE_REV == 101
166 #define FIX_HW_BRN_25499
167 #define FIX_HW_BRN_25503
168 #define FIX_HW_BRN_26620
169 #define FIX_HW_BRN_28011
170 #else
171 #if SGX_CORE_REV == 110
172 #define FIX_HW_BRN_25503
173 #define FIX_HW_BRN_26620
174 #define FIX_HW_BRN_28011
175 #else
176 #if SGX_CORE_REV == 120
177 #define FIX_HW_BRN_26620
178 #define FIX_HW_BRN_28011
179 #else
180 #if SGX_CORE_REV == 121
181 #define FIX_HW_BRN_28011
182 #else
183 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
184
185 #else
186 #error "sgxerrata.h: SGX540 Core Revision unspecified"
187 #endif
188 #endif
189 #endif
190 #endif
191 #endif
192
193 #define SGX_CORE_DEFINED
194#endif
195
196#if defined(SGX541) && !defined(SGX_CORE_DEFINED)
197 #if defined(SGX_FEATURE_MP)
198
199 #define SGX_CORE_REV_HEAD 0
200 #if defined(USE_SGX_CORE_REV_HEAD)
201
202 #define SGX_CORE_REV SGX_CORE_REV_HEAD
203 #endif
204
205 #if SGX_CORE_REV == 100
206 #define FIX_HW_BRN_27270
207 #define FIX_HW_BRN_28011
208 #define FIX_HW_BRN_27510
209
210 #else
211 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
212
213 #else
214 #error "sgxerrata.h: SGX541 Core Revision unspecified"
215 #endif
216 #endif
217
218 #define SGX_CORE_DEFINED
219 #else
220 #error "sgxerrata.h: SGX541 only supports MP configs (SGX_FEATURE_MP)"
221 #endif
222#endif
223
224#if defined(SGX543) && !defined(SGX_CORE_DEFINED)
225
226 #define SGX_CORE_REV_HEAD 0
227 #if defined(USE_SGX_CORE_REV_HEAD)
228
229 #define SGX_CORE_REV SGX_CORE_REV_HEAD
230 #endif
231
232 #if SGX_CORE_REV == 113
233
234 #else
235 #if SGX_CORE_REV == 122
236
237 #else
238 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
239
240 #else
241 #error "sgxerrata.h: SGX543 Core Revision unspecified"
242 #endif
243 #endif
244 #endif
245
246 #define SGX_CORE_DEFINED
247#endif
248
249#if defined(SGX544) && !defined(SGX_CORE_DEFINED)
250
251 #define SGX_CORE_REV_HEAD 0
252 #if defined(USE_SGX_CORE_REV_HEAD)
253
254 #define SGX_CORE_REV SGX_CORE_REV_HEAD
255 #endif
256
257 #if SGX_CORE_REV == 100
258
259 #else
260 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
261
262 #else
263 #error "sgxerrata.h: SGX544 Core Revision unspecified"
264 #endif
265 #endif
266
267 #define SGX_CORE_DEFINED
268#endif
269
270#if defined(SGX545) && !defined(SGX_CORE_DEFINED)
271
272 #define SGX_CORE_REV_HEAD 0
273 #if defined(USE_SGX_CORE_REV_HEAD)
274
275 #define SGX_CORE_REV SGX_CORE_REV_HEAD
276 #endif
277
278 #if SGX_CORE_REV == 100
279 #define FIX_HW_BRN_26620
280 #define FIX_HW_BRN_27266
281 #define FIX_HW_BRN_27456
282 #define FIX_HW_BRN_29702
283 #define FIX_HW_BRN_29823
284 #else
285 #if SGX_CORE_REV == 109
286 #define FIX_HW_BRN_29702
287 #define FIX_HW_BRN_29823
288 #else
289 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
290
291 #else
292 #error "sgxerrata.h: SGX545 Core Revision unspecified"
293 #endif
294 #endif
295 #endif
296
297 #define SGX_CORE_DEFINED
298#endif
299
300#if defined(SGX554) && !defined(SGX_CORE_DEFINED)
301
302 #define SGX_CORE_REV_HEAD 0
303 #if defined(USE_SGX_CORE_REV_HEAD)
304
305 #define SGX_CORE_REV SGX_CORE_REV_HEAD
306 #endif
307
308 #if SGX_CORE_REV == 100
309
310 #else
311 #if SGX_CORE_REV == SGX_CORE_REV_HEAD
312
313 #else
314 #error "sgxerrata.h: SGX554 Core Revision unspecified"
315 #endif
316 #endif
317
318 #define SGX_CORE_DEFINED
319#endif
320
321#if !defined(SGX_CORE_DEFINED)
322#if defined (__GNUC__)
323 #warning "sgxerrata.h: SGX Core Version unspecified"
324#else
325 #pragma message("sgxerrata.h: SGX Core Version unspecified")
326#endif
327#endif
328
329#endif
330
diff --git a/drivers/gpu/pvr/sgxfeaturedefs.h b/drivers/gpu/pvr/sgxfeaturedefs.h
new file mode 100644
index 00000000000..d815395523a
--- /dev/null
+++ b/drivers/gpu/pvr/sgxfeaturedefs.h
@@ -0,0 +1,199 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if defined(SGX520)
28 #define SGX_CORE_FRIENDLY_NAME "SGX520"
29 #define SGX_CORE_ID SGX_CORE_ID_520
30 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
31 #define SGX_FEATURE_AUTOCLOCKGATING
32#else
33#if defined(SGX530)
34 #define SGX_CORE_FRIENDLY_NAME "SGX530"
35 #define SGX_CORE_ID SGX_CORE_ID_530
36 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
37 #define SGX_FEATURE_AUTOCLOCKGATING
38#else
39#if defined(SGX531)
40 #define SGX_CORE_FRIENDLY_NAME "SGX531"
41 #define SGX_CORE_ID SGX_CORE_ID_531
42 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
43 #define SGX_FEATURE_AUTOCLOCKGATING
44 #define SGX_FEATURE_MULTI_EVENT_KICK
45#else
46#if defined(SGX535)
47 #define SGX_CORE_FRIENDLY_NAME "SGX535"
48 #define SGX_CORE_ID SGX_CORE_ID_535
49 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
50 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
51 #define SGX_FEATURE_BIF_NUM_DIRLISTS (16)
52 #define SGX_FEATURE_2D_HARDWARE
53 #define SGX_FEATURE_AUTOCLOCKGATING
54 #define SUPPORT_SGX_GENERAL_MAPPING_HEAP
55#else
56#if defined(SGX540)
57 #define SGX_CORE_FRIENDLY_NAME "SGX540"
58 #define SGX_CORE_ID SGX_CORE_ID_540
59 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
60 #define SGX_FEATURE_AUTOCLOCKGATING
61 #define SGX_FEATURE_MULTI_EVENT_KICK
62#else
63#if defined(SGX541)
64 #define SGX_CORE_FRIENDLY_NAME "SGX541"
65 #define SGX_CORE_ID SGX_CORE_ID_541
66 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
67 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
68 #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
69 #define SGX_FEATURE_AUTOCLOCKGATING
70 #define SGX_FEATURE_SPM_MODE_0
71 #define SGX_FEATURE_MULTI_EVENT_KICK
72#else
73#if defined(SGX543)
74 #define SGX_CORE_FRIENDLY_NAME "SGX543"
75 #define SGX_CORE_ID SGX_CORE_ID_543
76 #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
77 #define SGX_FEATURE_USE_UNLIMITED_PHASES
78 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
79 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
80 #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
81 #define SGX_FEATURE_AUTOCLOCKGATING
82 #define SGX_FEATURE_MONOLITHIC_UKERNEL
83 #define SGX_FEATURE_SPM_MODE_0
84 #define SGX_FEATURE_MULTI_EVENT_KICK
85 #define SGX_FEATURE_DATA_BREAKPOINTS
86 #define SGX_FEATURE_2D_HARDWARE
87 #define SGX_FEATURE_PTLA
88 #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
89#else
90#if defined(SGX544)
91 #define SGX_CORE_FRIENDLY_NAME "SGX544"
92 #define SGX_CORE_ID SGX_CORE_ID_544
93 #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
94 #define SGX_FEATURE_USE_UNLIMITED_PHASES
95 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
96 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
97 #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
98 #define SGX_FEATURE_AUTOCLOCKGATING
99 #define SGX_FEATURE_MONOLITHIC_UKERNEL
100 #define SGX_FEATURE_SPM_MODE_0
101 #define SGX_FEATURE_MULTI_EVENT_KICK
102 #define SGX_FEATURE_DATA_BREAKPOINTS
103 #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
104#else
105#if defined(SGX545)
106 #define SGX_CORE_FRIENDLY_NAME "SGX545"
107 #define SGX_CORE_ID SGX_CORE_ID_545
108 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
109 #define SGX_FEATURE_AUTOCLOCKGATING
110 #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
111 #define SGX_FEATURE_USE_UNLIMITED_PHASES
112 #define SGX_FEATURE_DXT_TEXTURES
113 #define SGX_FEATURE_VOLUME_TEXTURES
114 #define SGX_FEATURE_HOST_ALLOC_FROM_DPM
115 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
116 #define SGX_FEATURE_BIF_NUM_DIRLISTS (16)
117 #define SGX_FEATURE_NUM_USE_PIPES (4)
118 #define SGX_FEATURE_TEXTURESTRIDE_EXTENSION
119 #define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS
120 #define SGX_FEATURE_MONOLITHIC_UKERNEL
121 #define SGX_FEATURE_ZLS_EXTERNALZ
122 #define SGX_FEATURE_VDM_CONTEXT_SWITCH_REV_2
123 #define SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_2
124 #define SGX_FEATURE_NUM_PDS_PIPES (2)
125 #define SGX_FEATURE_NATIVE_BACKWARD_BLIT
126 #define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512)
127 #define SGX_FEATURE_SPM_MODE_0
128 #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK
129 #define SGX_FEATURE_WRITEBACK_DCU
130
131
132 #define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
133 #define SGX_FEATURE_MULTI_EVENT_KICK
134#else
135#if defined(SGX554)
136 #define SGX_CORE_FRIENDLY_NAME "SGX554"
137 #define SGX_CORE_ID SGX_CORE_ID_554
138 #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
139 #define SGX_FEATURE_USE_UNLIMITED_PHASES
140 #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
141 #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
142 #define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
143 #define SGX_FEATURE_AUTOCLOCKGATING
144 #define SGX_FEATURE_MONOLITHIC_UKERNEL
145 #define SGX_FEATURE_SPM_MODE_0
146 #define SGX_FEATURE_MULTI_EVENT_KICK
147 #define SGX_FEATURE_DATA_BREAKPOINTS
148 #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
149#endif
150#endif
151#endif
152#endif
153#endif
154#endif
155#endif
156#endif
157#endif
158#endif
159
160#if defined(FIX_HW_BRN_22693)
161#undef SGX_FEATURE_AUTOCLOCKGATING
162#endif
163
164#if defined(FIX_HW_BRN_27266)
165#undef SGX_FEATURE_36BIT_MMU
166#endif
167
168#if defined(FIX_HW_BRN_27456)
169#undef SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
170#endif
171
172#if defined(FIX_HW_BRN_22934) \
173 || defined(FIX_HW_BRN_25499)
174#undef SGX_FEATURE_MULTI_EVENT_KICK
175#endif
176
177#if defined(SGX_FEATURE_SYSTEM_CACHE)
178 #if defined(SGX_FEATURE_36BIT_MMU)
179 #error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU
180 #endif
181 #if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK)
182 #define SGX_BYPASS_SYSTEM_CACHE
183 #endif
184#endif
185
186#if defined(SGX_FEATURE_MP)
187#if !defined(SGX_FEATURE_MP_CORE_COUNT)
188#error SGX_FEATURE_MP_CORE_COUNT must be defined when SGX_FEATURE_MP is defined
189#endif
190#else
191#define SGX_FEATURE_MP_CORE_COUNT (1)
192#endif
193
194#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING)
195#define SUPPORT_SGX_PRIORITY_SCHEDULING
196#endif
197
198#include "img_types.h"
199
diff --git a/drivers/gpu/pvr/sgxinfo.h b/drivers/gpu/pvr/sgxinfo.h
new file mode 100644
index 00000000000..eaef12f4357
--- /dev/null
+++ b/drivers/gpu/pvr/sgxinfo.h
@@ -0,0 +1,286 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined (__SGXINFO_H__)
28#define __SGXINFO_H__
29
30#include "sgxscript.h"
31#include "servicesint.h"
32#include "services.h"
33#include "sgxapi_km.h"
34#include "sgx_mkif_km.h"
35
36
37#define SGX_MAX_DEV_DATA 24
38#define SGX_MAX_INIT_MEM_HANDLES 16
39
40
41typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT
42{
43 IMG_DEV_PHYADDR sPDDevPAddr;
44 PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
45} SGX_BRIDGE_INFO_FOR_SRVINIT;
46
47
48typedef enum _SGXMKIF_CMD_TYPE_
49{
50 SGXMKIF_CMD_TA = 0,
51 SGXMKIF_CMD_TRANSFER = 1,
52 SGXMKIF_CMD_2D = 2,
53 SGXMKIF_CMD_POWER = 3,
54 SGXMKIF_CMD_CLEANUP = 4,
55 SGXMKIF_CMD_GETMISCINFO = 5,
56 SGXMKIF_CMD_PROCESS_QUEUES = 6,
57 SGXMKIF_CMD_DATABREAKPOINT = 7,
58 SGXMKIF_CMD_SETHWPERFSTATUS = 8,
59 SGXMKIF_CMD_MAX = 9,
60
61 SGXMKIF_CMD_FORCE_I32 = -1,
62
63} SGXMKIF_CMD_TYPE;
64
65
66typedef struct _SGX_BRIDGE_INIT_INFO_
67{
68 IMG_HANDLE hKernelCCBMemInfo;
69 IMG_HANDLE hKernelCCBCtlMemInfo;
70 IMG_HANDLE hKernelCCBEventKickerMemInfo;
71 IMG_HANDLE hKernelSGXHostCtlMemInfo;
72 IMG_HANDLE hKernelSGXTA3DCtlMemInfo;
73 IMG_HANDLE hKernelSGXMiscMemInfo;
74
75 IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
76
77 SGX_INIT_SCRIPTS sScripts;
78
79 IMG_UINT32 ui32ClientBuildOptions;
80 SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
81
82#if defined(SGX_SUPPORT_HWPROFILING)
83 IMG_HANDLE hKernelHWProfilingMemInfo;
84#endif
85#if defined(SUPPORT_SGX_HWPERF)
86 IMG_HANDLE hKernelHWPerfCBMemInfo;
87#endif
88 IMG_HANDLE hKernelTASigBufferMemInfo;
89 IMG_HANDLE hKernel3DSigBufferMemInfo;
90
91#if defined(FIX_HW_BRN_29702)
92 IMG_HANDLE hKernelCFIMemInfo;
93#endif
94#if defined(FIX_HW_BRN_29823)
95 IMG_HANDLE hKernelDummyTermStreamMemInfo;
96#endif
97#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
98 IMG_HANDLE hKernelEDMStatusBufferMemInfo;
99#endif
100#if defined(SGX_FEATURE_OVERLAPPED_SPM)
101 IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
102#endif
103#if defined(SGX_FEATURE_SPM_MODE_0)
104 IMG_HANDLE hKernelTmpDPMStateMemInfo;
105#endif
106
107 IMG_UINT32 ui32EDMTaskReg0;
108 IMG_UINT32 ui32EDMTaskReg1;
109
110 IMG_UINT32 ui32ClkGateStatusReg;
111 IMG_UINT32 ui32ClkGateStatusMask;
112#if defined(SGX_FEATURE_MP)
113 IMG_UINT32 ui32MasterClkGateStatusReg;
114 IMG_UINT32 ui32MasterClkGateStatusMask;
115 IMG_UINT32 ui32MasterClkGateStatus2Reg;
116 IMG_UINT32 ui32MasterClkGateStatus2Mask;
117#endif
118
119 IMG_UINT32 ui32CacheControl;
120
121 IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA];
122 IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
123
124} SGX_BRIDGE_INIT_INFO;
125
126
127typedef struct _SGX_DEVICE_SYNC_LIST_
128{
129 PSGXMKIF_HWDEVICE_SYNC_LIST psHWDeviceSyncList;
130
131 IMG_HANDLE hKernelHWSyncListMemInfo;
132 PVRSRV_CLIENT_MEM_INFO *psHWDeviceSyncListClientMemInfo;
133 PVRSRV_CLIENT_MEM_INFO *psAccessResourceClientMemInfo;
134
135 volatile IMG_UINT32 *pui32Lock;
136
137 struct _SGX_DEVICE_SYNC_LIST_ *psNext;
138
139
140 IMG_UINT32 ui32NumSyncObjects;
141 IMG_HANDLE ahSyncHandles[1];
142} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST;
143
144
145typedef struct _SGX_INTERNEL_STATUS_UPDATE_
146{
147 CTL_STATUS sCtlStatus;
148 IMG_HANDLE hKernelMemInfo;
149} SGX_INTERNEL_STATUS_UPDATE;
150
151
152typedef struct _SGX_CCB_KICK_
153{
154 SGXMKIF_COMMAND sCommand;
155 IMG_HANDLE hCCBKernelMemInfo;
156
157 IMG_UINT32 ui32NumDstSyncObjects;
158 IMG_HANDLE hKernelHWSyncListMemInfo;
159
160
161 IMG_HANDLE *pahDstSyncHandles;
162
163 IMG_UINT32 ui32NumTAStatusVals;
164 IMG_UINT32 ui32Num3DStatusVals;
165
166#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
167 SGX_INTERNEL_STATUS_UPDATE asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
168 SGX_INTERNEL_STATUS_UPDATE as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
169#else
170 IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
171 IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
172#endif
173
174 IMG_BOOL bFirstKickOrResume;
175#if (defined(NO_HARDWARE) || defined(PDUMP))
176 IMG_BOOL bTerminateOrAbort;
177#endif
178
179
180 IMG_UINT32 ui32CCBOffset;
181
182#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
183
184 IMG_UINT32 ui32NumTASrcSyncs;
185 IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
186 IMG_UINT32 ui32NumTADstSyncs;
187 IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
188 IMG_UINT32 ui32Num3DSrcSyncs;
189 IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
190#else
191
192 IMG_UINT32 ui32NumSrcSyncs;
193 IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
194#endif
195
196
197 IMG_BOOL bTADependency;
198 IMG_HANDLE hTA3DSyncInfo;
199
200 IMG_HANDLE hTASyncInfo;
201 IMG_HANDLE h3DSyncInfo;
202#if defined(PDUMP)
203 IMG_UINT32 ui32CCBDumpWOff;
204#endif
205#if defined(NO_HARDWARE)
206 IMG_UINT32 ui32WriteOpsPendingVal;
207#endif
208} SGX_CCB_KICK;
209
210
211#define SGX_KERNEL_USE_CODE_BASE_INDEX 15
212
213
214typedef struct _SGX_CLIENT_INFO_
215{
216 IMG_UINT32 ui32ProcessID;
217 IMG_VOID *pvProcess;
218 PVRSRV_MISC_INFO sMiscInfo;
219
220 IMG_UINT32 asDevData[SGX_MAX_DEV_DATA];
221
222} SGX_CLIENT_INFO;
223
224typedef struct _SGX_INTERNAL_DEVINFO_
225{
226 IMG_UINT32 ui32Flags;
227 IMG_HANDLE hHostCtlKernelMemInfoHandle;
228 IMG_BOOL bForcePTOff;
229} SGX_INTERNAL_DEVINFO;
230
231
232#if defined(TRANSFER_QUEUE)
233typedef struct _PVRSRV_TRANSFER_SGX_KICK_
234{
235 IMG_HANDLE hCCBMemInfo;
236 IMG_UINT32 ui32SharedCmdCCBOffset;
237
238 IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
239
240 IMG_HANDLE hTASyncInfo;
241 IMG_HANDLE h3DSyncInfo;
242
243 IMG_UINT32 ui32NumSrcSync;
244 IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
245
246 IMG_UINT32 ui32NumDstSync;
247 IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
248
249 IMG_UINT32 ui32Flags;
250
251 IMG_UINT32 ui32PDumpFlags;
252#if defined(PDUMP)
253 IMG_UINT32 ui32CCBDumpWOff;
254#endif
255} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK;
256
257#if defined(SGX_FEATURE_2D_HARDWARE)
258typedef struct _PVRSRV_2D_SGX_KICK_
259{
260 IMG_HANDLE hCCBMemInfo;
261 IMG_UINT32 ui32SharedCmdCCBOffset;
262
263 IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
264
265 IMG_UINT32 ui32NumSrcSync;
266 IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
267
268
269 IMG_HANDLE hDstSyncInfo;
270
271
272 IMG_HANDLE hTASyncInfo;
273
274
275 IMG_HANDLE h3DSyncInfo;
276
277 IMG_UINT32 ui32PDumpFlags;
278#if defined(PDUMP)
279 IMG_UINT32 ui32CCBDumpWOff;
280#endif
281} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK;
282#endif
283#endif
284
285
286#endif
diff --git a/drivers/gpu/pvr/sgxmmu.h b/drivers/gpu/pvr/sgxmmu.h
new file mode 100644
index 00000000000..4df8003361c
--- /dev/null
+++ b/drivers/gpu/pvr/sgxmmu.h
@@ -0,0 +1,79 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#if !defined(__SGXMMU_KM_H__)
28#define __SGXMMU_KM_H__
29
30#define SGX_MMU_PAGE_SHIFT (12)
31#define SGX_MMU_PAGE_SIZE (1U<<SGX_MMU_PAGE_SHIFT)
32#define SGX_MMU_PAGE_MASK (SGX_MMU_PAGE_SIZE - 1U)
33
34#define SGX_MMU_PD_SHIFT (10)
35#define SGX_MMU_PD_SIZE (1U<<SGX_MMU_PD_SHIFT)
36#define SGX_MMU_PD_MASK (0xFFC00000U)
37
38#if defined(SGX_FEATURE_36BIT_MMU)
39 #define SGX_MMU_PDE_ADDR_MASK (0xFFFFFF00U)
40 #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (4)
41#else
42 #define SGX_MMU_PDE_ADDR_MASK (0xFFFFF000U)
43 #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (0)
44#endif
45#define SGX_MMU_PDE_VALID (0x00000001U)
46#define SGX_MMU_PDE_PAGE_SIZE_4K (0x00000000U)
47#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
48 #define SGX_MMU_PDE_PAGE_SIZE_16K (0x00000002U)
49 #define SGX_MMU_PDE_PAGE_SIZE_64K (0x00000004U)
50 #define SGX_MMU_PDE_PAGE_SIZE_256K (0x00000006U)
51 #define SGX_MMU_PDE_PAGE_SIZE_1M (0x00000008U)
52 #define SGX_MMU_PDE_PAGE_SIZE_4M (0x0000000AU)
53 #define SGX_MMU_PDE_PAGE_SIZE_MASK (0x0000000EU)
54#else
55 #define SGX_MMU_PDE_WRITEONLY (0x00000002U)
56 #define SGX_MMU_PDE_READONLY (0x00000004U)
57 #define SGX_MMU_PDE_CACHECONSISTENT (0x00000008U)
58 #define SGX_MMU_PDE_EDMPROTECT (0x00000010U)
59#endif
60
61#define SGX_MMU_PT_SHIFT (10)
62#define SGX_MMU_PT_SIZE (1U<<SGX_MMU_PT_SHIFT)
63#define SGX_MMU_PT_MASK (0x003FF000U)
64
65#if defined(SGX_FEATURE_36BIT_MMU)
66 #define SGX_MMU_PTE_ADDR_MASK (0xFFFFFF00U)
67 #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (4)
68#else
69 #define SGX_MMU_PTE_ADDR_MASK (0xFFFFF000U)
70 #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (0)
71#endif
72#define SGX_MMU_PTE_VALID (0x00000001U)
73#define SGX_MMU_PTE_WRITEONLY (0x00000002U)
74#define SGX_MMU_PTE_READONLY (0x00000004U)
75#define SGX_MMU_PTE_CACHECONSISTENT (0x00000008U)
76#define SGX_MMU_PTE_EDMPROTECT (0x00000010U)
77
78#endif
79
diff --git a/drivers/gpu/pvr/sgxscript.h b/drivers/gpu/pvr/sgxscript.h
new file mode 100644
index 00000000000..47c9e4830fd
--- /dev/null
+++ b/drivers/gpu/pvr/sgxscript.h
@@ -0,0 +1,81 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef __SGXSCRIPT_H__
28#define __SGXSCRIPT_H__
29
30#if defined (__cplusplus)
31extern "C" {
32#endif
33
34#define SGX_MAX_INIT_COMMANDS 64
35#define SGX_MAX_DEINIT_COMMANDS 16
36
37typedef enum _SGX_INIT_OPERATION
38{
39 SGX_INIT_OP_ILLEGAL = 0,
40 SGX_INIT_OP_WRITE_HW_REG,
41#if defined(PDUMP)
42 SGX_INIT_OP_PDUMP_HW_REG,
43#endif
44 SGX_INIT_OP_HALT
45} SGX_INIT_OPERATION;
46
47typedef union _SGX_INIT_COMMAND
48{
49 SGX_INIT_OPERATION eOp;
50 struct {
51 SGX_INIT_OPERATION eOp;
52 IMG_UINT32 ui32Offset;
53 IMG_UINT32 ui32Value;
54 } sWriteHWReg;
55#if defined(PDUMP)
56 struct {
57 SGX_INIT_OPERATION eOp;
58 IMG_UINT32 ui32Offset;
59 IMG_UINT32 ui32Value;
60 } sPDumpHWReg;
61#endif
62#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
63 struct {
64 SGX_INIT_OPERATION eOp;
65 } sWorkaroundBRN22997;
66#endif
67} SGX_INIT_COMMAND;
68
69typedef struct _SGX_INIT_SCRIPTS_
70{
71 SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS];
72 SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS];
73 SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS];
74} SGX_INIT_SCRIPTS;
75
76#if defined(__cplusplus)
77}
78#endif
79
80#endif
81
diff --git a/drivers/gpu/pvr/srvkm.h b/drivers/gpu/pvr/srvkm.h
new file mode 100644
index 00000000000..44a1daa9700
--- /dev/null
+++ b/drivers/gpu/pvr/srvkm.h
@@ -0,0 +1,78 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef SRVKM_H
28#define SRVKM_H
29
30
31#if defined(__cplusplus)
32extern "C" {
33#endif
34
35
36 #ifdef PVR_DISABLE_LOGGING
37 #define PVR_LOG(X)
38 #else
39
40 #define PVR_LOG(X) PVRSRVReleasePrintf X;
41 #endif
42
43 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
44
45 IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID);
46 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID);
47
48 IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID);
49
50 IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State);
51
52 PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave);
53
54 IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID);
55
56
57#if defined (__cplusplus)
58}
59#endif
60
61
62#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \
63{\
64 IMG_UINT32 uiOffset, uiStart, uiCurrent; \
65 IMG_INT32 iNotLastLoop; \
66 for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\
67 ((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--; \
68 uiCurrent = OSClockus(), \
69 uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \
70 uiStart = uiCurrent < uiStart ? 0 : uiStart)
71
72#define END_LOOP_UNTIL_TIMEOUT() \
73}
74
75IMG_IMPORT
76const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
77
78#endif
diff --git a/drivers/gpu/pvr/syscommon.h b/drivers/gpu/pvr/syscommon.h
new file mode 100644
index 00000000000..5ae080ad4b2
--- /dev/null
+++ b/drivers/gpu/pvr/syscommon.h
@@ -0,0 +1,223 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef _SYSCOMMON_H
28#define _SYSCOMMON_H
29
30#include "sysconfig.h"
31#include "sysinfo.h"
32#include "servicesint.h"
33#include "queue.h"
34#include "power.h"
35#include "resman.h"
36#include "ra.h"
37#include "device.h"
38#include "buffer_manager.h"
39#include "pvr_debug.h"
40#include "services.h"
41
42#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
43#include <asm/io.h>
44#endif
45
46#if defined (__cplusplus)
47extern "C" {
48#endif
49
50typedef struct _SYS_DEVICE_ID_TAG
51{
52 IMG_UINT32 uiID;
53 IMG_BOOL bInUse;
54
55} SYS_DEVICE_ID;
56
57
58#define SYS_MAX_LOCAL_DEVMEM_ARENAS 4
59
60typedef struct _SYS_DATA_TAG_
61{
62 IMG_UINT32 ui32NumDevices;
63 SYS_DEVICE_ID sDeviceID[SYS_DEVICE_COUNT];
64 PVRSRV_DEVICE_NODE *psDeviceNodeList;
65 PVRSRV_POWER_DEV *psPowerDeviceList;
66 PVRSRV_RESOURCE sPowerStateChangeResource;
67 PVRSRV_SYS_POWER_STATE eCurrentPowerState;
68 PVRSRV_SYS_POWER_STATE eFailedPowerState;
69 IMG_UINT32 ui32CurrentOSPowerState;
70 PVRSRV_QUEUE_INFO *psQueueList;
71 PVRSRV_KERNEL_SYNC_INFO *psSharedSyncInfoList;
72 IMG_PVOID pvEnvSpecificData;
73 IMG_PVOID pvSysSpecificData;
74 PVRSRV_RESOURCE sQProcessResource;
75 IMG_VOID *pvSOCRegsBase;
76 IMG_HANDLE hSOCTimerRegisterOSMemHandle;
77 IMG_UINT32 *pvSOCTimerRegisterKM;
78 IMG_VOID *pvSOCClockGateRegsBase;
79 IMG_UINT32 ui32SOCClockGateRegsSize;
80 PFN_CMD_PROC *ppfnCmdProcList[SYS_DEVICE_COUNT];
81
82
83
84 PCOMMAND_COMPLETE_DATA *ppsCmdCompleteData[SYS_DEVICE_COUNT];
85
86
87 IMG_BOOL bReProcessQueues;
88
89 RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS];
90
91 IMG_CHAR *pszVersionString;
92 PVRSRV_EVENTOBJECT *psGlobalEventObject;
93
94 PVRSRV_MISC_INFO_CPUCACHEOP_TYPE ePendingCacheOpType;
95} SYS_DATA;
96
97
98
99PVRSRV_ERROR SysInitialise(IMG_VOID);
100PVRSRV_ERROR SysFinalise(IMG_VOID);
101
102PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData);
103PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
104 IMG_VOID **ppvDeviceMap);
105
106IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
107IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
108
109IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
110 PVRSRV_DEVICE_NODE *psDeviceNode);
111
112IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits);
113
114PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex);
115
116PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
117PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
118PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
119 PVRSRV_DEV_POWER_STATE eNewPowerState,
120 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
121PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
122 PVRSRV_DEV_POWER_STATE eNewPowerState,
123 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
124
125#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
126PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData);
127IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData);
128#endif
129
130PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID,
131 IMG_VOID *pvIn,
132 IMG_UINT32 ulInSize,
133 IMG_VOID *pvOut,
134 IMG_UINT32 ulOutSize);
135
136
137IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr);
138IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
139IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr);
140IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr);
141IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr);
142#if defined(PVR_LMA)
143IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr);
144IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
145#endif
146
147extern SYS_DATA* gpsSysData;
148
149#if !defined(USE_CODE)
150
151#ifdef INLINE_IS_PRAGMA
152#pragma inline(SysAcquireData)
153#endif
154static INLINE IMG_VOID SysAcquireData(SYS_DATA **ppsSysData)
155{
156
157 *ppsSysData = gpsSysData;
158
159
160
161
162
163 PVR_ASSERT (gpsSysData != IMG_NULL);
164}
165
166
167#ifdef INLINE_IS_PRAGMA
168#pragma inline(SysAcquireDataNoCheck)
169#endif
170static INLINE SYS_DATA * SysAcquireDataNoCheck(IMG_VOID)
171{
172
173 return gpsSysData;
174}
175
176
177#ifdef INLINE_IS_PRAGMA
178#pragma inline(SysInitialiseCommon)
179#endif
180static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData)
181{
182 PVRSRV_ERROR eError;
183
184
185 eError = PVRSRVInit(psSysData);
186
187 return eError;
188}
189
190#ifdef INLINE_IS_PRAGMA
191#pragma inline(SysDeinitialiseCommon)
192#endif
193static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData)
194{
195
196 PVRSRVDeInit(psSysData);
197
198 OSDestroyResource(&psSysData->sPowerStateChangeResource);
199}
200#endif
201
202
203#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__))
204#define SysReadHWReg(p, o) OSReadHWReg(p, o)
205#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v)
206#else
207static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
208{
209 return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
210}
211
212static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
213{
214 writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
215}
216#endif
217
218#if defined(__cplusplus)
219}
220#endif
221
222#endif
223