]> code.ossystems Code Review - openembedded-core.git/blob
65048c8ffc673fdfe853faa2dcd959183c060d6f
[openembedded-core.git] /
1 From e6fbc1d68e24c1526e9e30d1d2381a77697f3b1d Mon Sep 17 00:00:00 2001
2 From: Prajwal Mohan <prajwal.karur.mohan@intel.com>
3 Date: Thu, 13 May 2010 14:50:27 -0700
4 Subject: [PATCH] IMG graphics driver consolidation patch
5
6 Signed-off-by: Prajwal Mohan <prajwal.karur.mohan@intel.com>
7 Patch-mainline: 2.6.35?
8 ---
9  drivers/gpu/drm/Kconfig                            |    2 +
10  drivers/gpu/drm/Makefile                           |    3 +-
11  drivers/gpu/drm/drm_crtc.c                         |    2 +
12  drivers/gpu/drm/drm_drv.c                          |   11 +-
13  drivers/gpu/drm/drm_global.c                       |  107 +
14  drivers/gpu/drm/drm_irq.c                          |   27 +
15  drivers/gpu/drm/mrst/Kconfig                       |  220 ++
16  drivers/gpu/drm/mrst/Makefile                      |  169 +
17  drivers/gpu/drm/mrst/drv/lnc_topaz.c               |  714 ++++
18  drivers/gpu/drm/mrst/drv/lnc_topaz.h               |  925 ++++++
19  drivers/gpu/drm/mrst/drv/lnc_topazinit.c           | 2051 ++++++++++++
20  drivers/gpu/drm/mrst/drv/msvdx_power.c             |  164 +
21  drivers/gpu/drm/mrst/drv/msvdx_power.h             |   48 +
22  drivers/gpu/drm/mrst/drv/psb_bl.c                  |  260 ++
23  drivers/gpu/drm/mrst/drv/psb_buffer.c              |  379 +++
24  drivers/gpu/drm/mrst/drv/psb_dpst.c                |  254 ++
25  drivers/gpu/drm/mrst/drv/psb_dpst.h                |   98 +
26  drivers/gpu/drm/mrst/drv/psb_drm.h                 |  634 ++++
27  drivers/gpu/drm/mrst/drv/psb_drv.c                 | 2218 +++++++++++++
28  drivers/gpu/drm/mrst/drv/psb_drv.h                 | 1025 ++++++
29  drivers/gpu/drm/mrst/drv/psb_fb.c                  | 1817 +++++++++++
30  drivers/gpu/drm/mrst/drv/psb_fb.h                  |   49 +
31  drivers/gpu/drm/mrst/drv/psb_fence.c               |  158 +
32  drivers/gpu/drm/mrst/drv/psb_gtt.c                 | 1040 ++++++
33  drivers/gpu/drm/mrst/drv/psb_gtt.h                 |  111 +
34  drivers/gpu/drm/mrst/drv/psb_hotplug.c             |  425 +++
35  drivers/gpu/drm/mrst/drv/psb_hotplug.h             |   90 +
36  drivers/gpu/drm/mrst/drv/psb_intel_bios.c          |  305 ++
37  drivers/gpu/drm/mrst/drv/psb_intel_bios.h          |  430 +++
38  drivers/gpu/drm/mrst/drv/psb_intel_display.c       | 2538 +++++++++++++++
39  drivers/gpu/drm/mrst/drv/psb_intel_display.h       |   25 +
40  drivers/gpu/drm/mrst/drv/psb_intel_drv.h           |  283 ++
41  drivers/gpu/drm/mrst/drv/psb_intel_dsi.c           | 2450 ++++++++++++++
42  drivers/gpu/drm/mrst/drv/psb_intel_dsi_aava.c      |  996 ++++++
43  drivers/gpu/drm/mrst/drv/psb_intel_i2c.c           |  172 +
44  drivers/gpu/drm/mrst/drv/psb_intel_lvds.c          | 1385 ++++++++
45  drivers/gpu/drm/mrst/drv/psb_intel_modes.c         |   77 +
46  drivers/gpu/drm/mrst/drv/psb_intel_reg.h           | 1099 +++++++
47  drivers/gpu/drm/mrst/drv/psb_intel_sdvo.c          | 1408 ++++++++
48  drivers/gpu/drm/mrst/drv/psb_intel_sdvo_regs.h     |  338 ++
49  drivers/gpu/drm/mrst/drv/psb_mmu.c                 | 1010 ++++++
50  drivers/gpu/drm/mrst/drv/psb_msvdx.c               | 1063 ++++++
51  drivers/gpu/drm/mrst/drv/psb_msvdx.h               |  610 ++++
52  drivers/gpu/drm/mrst/drv/psb_msvdxinit.c           |  770 +++++
53  drivers/gpu/drm/mrst/drv/psb_pvr_glue.c            |   74 +
54  drivers/gpu/drm/mrst/drv/psb_pvr_glue.h            |   26 +
55  drivers/gpu/drm/mrst/drv/psb_reg.h                 |  570 ++++
56  drivers/gpu/drm/mrst/drv/psb_reset.c               |  209 ++
57  drivers/gpu/drm/mrst/drv/psb_schedule.c            |   70 +
58  drivers/gpu/drm/mrst/drv/psb_schedule.h            |   81 +
59  drivers/gpu/drm/mrst/drv/psb_setup.c               |   35 +
60  drivers/gpu/drm/mrst/drv/psb_sgx.c                 |  929 ++++++
61  drivers/gpu/drm/mrst/drv/psb_sgx.h                 |   32 +
62  drivers/gpu/drm/mrst/drv/psb_socket.c              |  376 +++
63  drivers/gpu/drm/mrst/drv/psb_ttm_glue.c            |  344 ++
64  drivers/gpu/drm/mrst/drv/psb_umevents.c            |  485 +++
65  drivers/gpu/drm/mrst/drv/psb_umevents.h            |  154 +
66  drivers/gpu/drm/mrst/drv/topaz_power.c             |  173 +
67  drivers/gpu/drm/mrst/drv/topaz_power.h             |   53 +
68  drivers/gpu/drm/mrst/drv/ttm/ttm_agp_backend.c     |  144 +
69  drivers/gpu/drm/mrst/drv/ttm/ttm_bo.c              | 1729 ++++++++++
70  drivers/gpu/drm/mrst/drv/ttm/ttm_bo_api.h          |  573 ++++
71  drivers/gpu/drm/mrst/drv/ttm/ttm_bo_driver.h       |  862 +++++
72  drivers/gpu/drm/mrst/drv/ttm/ttm_bo_util.c         |  546 ++++
73  drivers/gpu/drm/mrst/drv/ttm/ttm_bo_vm.c           |  429 +++
74  drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.c    |  108 +
75  drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.h    |  103 +
76  drivers/gpu/drm/mrst/drv/ttm/ttm_fence.c           |  607 ++++
77  drivers/gpu/drm/mrst/drv/ttm/ttm_fence_api.h       |  272 ++
78  drivers/gpu/drm/mrst/drv/ttm/ttm_fence_driver.h    |  302 ++
79  drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.c      |  238 ++
80  drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.h      |  140 +
81  drivers/gpu/drm/mrst/drv/ttm/ttm_lock.c            |  155 +
82  drivers/gpu/drm/mrst/drv/ttm/ttm_lock.h            |  176 +
83  drivers/gpu/drm/mrst/drv/ttm/ttm_memory.c          |  228 ++
84  drivers/gpu/drm/mrst/drv/ttm/ttm_memory.h          |  147 +
85  drivers/gpu/drm/mrst/drv/ttm/ttm_object.c          |  440 +++
86  drivers/gpu/drm/mrst/drv/ttm/ttm_object.h          |  262 ++
87  drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.c      |  164 +
88  drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.h      |   34 +
89  .../gpu/drm/mrst/drv/ttm/ttm_placement_common.h    |   91 +
90  drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.c  |  468 +++
91  drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.h  |  252 ++
92  drivers/gpu/drm/mrst/drv/ttm/ttm_regman.h          |   67 +
93  drivers/gpu/drm/mrst/drv/ttm/ttm_tt.c              |  653 ++++
94  drivers/gpu/drm/mrst/drv/ttm/ttm_userobj_api.h     |   72 +
95  drivers/gpu/drm/mrst/pvr/COPYING                   |  351 ++
96  drivers/gpu/drm/mrst/pvr/INSTALL                   |   76 +
97  drivers/gpu/drm/mrst/pvr/README                    |   48 +
98  drivers/gpu/drm/mrst/pvr/eurasiacon/.gitignore     |    6 +
99  drivers/gpu/drm/mrst/pvr/include4/dbgdrvif.h       |  298 ++
100  drivers/gpu/drm/mrst/pvr/include4/img_defs.h       |  108 +
101  drivers/gpu/drm/mrst/pvr/include4/img_types.h      |  128 +
102  drivers/gpu/drm/mrst/pvr/include4/ioctldef.h       |   98 +
103  drivers/gpu/drm/mrst/pvr/include4/pdumpdefs.h      |   99 +
104  drivers/gpu/drm/mrst/pvr/include4/pvr_debug.h      |  127 +
105  drivers/gpu/drm/mrst/pvr/include4/pvrmodule.h      |   31 +
106  drivers/gpu/drm/mrst/pvr/include4/pvrversion.h     |   38 +
107  drivers/gpu/drm/mrst/pvr/include4/regpaths.h       |   43 +
108  drivers/gpu/drm/mrst/pvr/include4/services.h       |  872 +++++
109  drivers/gpu/drm/mrst/pvr/include4/servicesext.h    |  648 ++++
110  drivers/gpu/drm/mrst/pvr/include4/sgx_options.h    |  224 ++
111  drivers/gpu/drm/mrst/pvr/include4/sgxapi_km.h      |  323 ++
112  drivers/gpu/drm/mrst/pvr/include4/sgxscript.h      |   81 +
113  .../3rdparty/linux_framebuffer_mrst/.gitignore     |    6 +
114  .../linux_framebuffer_mrst/makefile.linux.common   |   41 +
115  .../3rdparty/linux_framebuffer_mrst/mrstlfb.h      |  295 ++
116  .../linux_framebuffer_mrst/mrstlfb_displayclass.c  | 2056 ++++++++++++
117  .../linux_framebuffer_mrst/mrstlfb_linux.c         |  206 ++
118  .../services4/include/env/linux/pvr_drm_shared.h   |   54 +
119  .../drm/mrst/pvr/services4/include/kernelbuffer.h  |   60 +
120  .../drm/mrst/pvr/services4/include/kerneldisplay.h |  153 +
121  .../drm/mrst/pvr/services4/include/pvr_bridge.h    | 1383 ++++++++
122  .../drm/mrst/pvr/services4/include/pvr_bridge_km.h |  288 ++
123  .../gpu/drm/mrst/pvr/services4/include/pvrmmap.h   |   36 +
124  .../drm/mrst/pvr/services4/include/servicesint.h   |  266 ++
125  .../drm/mrst/pvr/services4/include/sgx_bridge.h    |  477 +++
126  .../drm/mrst/pvr/services4/include/sgx_mkif_km.h   |  334 ++
127  .../gpu/drm/mrst/pvr/services4/include/sgxinfo.h   |  288 ++
128  .../mrst/pvr/services4/srvkm/bridged/.gitignore    |    5 +
129  .../services4/srvkm/bridged/bridged_pvr_bridge.c   | 3426 ++++++++++++++++++++
130  .../services4/srvkm/bridged/bridged_pvr_bridge.h   |  231 ++
131  .../pvr/services4/srvkm/bridged/bridged_support.c  |   85 +
132  .../pvr/services4/srvkm/bridged/bridged_support.h  |   43 +
133  .../srvkm/bridged/sgx/bridged_sgx_bridge.c         | 2511 ++++++++++++++
134  .../srvkm/bridged/sgx/bridged_sgx_bridge.h         |   42 +
135  .../drm/mrst/pvr/services4/srvkm/common/.gitignore |    5 +
136  .../pvr/services4/srvkm/common/buffer_manager.c    | 2036 ++++++++++++
137  .../mrst/pvr/services4/srvkm/common/deviceclass.c  | 1937 +++++++++++
138  .../mrst/pvr/services4/srvkm/common/devicemem.c    | 1448 +++++++++
139  .../drm/mrst/pvr/services4/srvkm/common/handle.c   | 1547 +++++++++
140  .../gpu/drm/mrst/pvr/services4/srvkm/common/hash.c |  463 +++
141  .../drm/mrst/pvr/services4/srvkm/common/lists.c    |   99 +
142  .../gpu/drm/mrst/pvr/services4/srvkm/common/mem.c  |  151 +
143  .../mrst/pvr/services4/srvkm/common/mem_debug.c    |  250 ++
144  .../drm/mrst/pvr/services4/srvkm/common/metrics.c  |  160 +
145  .../mrst/pvr/services4/srvkm/common/pdump_common.c | 1723 ++++++++++
146  .../drm/mrst/pvr/services4/srvkm/common/perproc.c  |  283 ++
147  .../drm/mrst/pvr/services4/srvkm/common/power.c    |  818 +++++
148  .../drm/mrst/pvr/services4/srvkm/common/pvrsrv.c   | 1195 +++++++
149  .../drm/mrst/pvr/services4/srvkm/common/queue.c    | 1137 +++++++
150  .../gpu/drm/mrst/pvr/services4/srvkm/common/ra.c   | 1871 +++++++++++
151  .../drm/mrst/pvr/services4/srvkm/common/resman.c   |  717 ++++
152  .../pvr/services4/srvkm/devices/sgx/.gitignore     |    5 +
153  .../drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.c | 2776 ++++++++++++++++
154  .../drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.h |  139 +
155  .../drm/mrst/pvr/services4/srvkm/devices/sgx/pb.c  |  458 +++
156  .../services4/srvkm/devices/sgx/sgx_bridge_km.h    |  147 +
157  .../pvr/services4/srvkm/devices/sgx/sgxconfig.h    |  134 +
158  .../pvr/services4/srvkm/devices/sgx/sgxinfokm.h    |  352 ++
159  .../mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c | 2218 +++++++++++++
160  .../mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c |  744 +++++
161  .../pvr/services4/srvkm/devices/sgx/sgxpower.c     |  453 +++
162  .../pvr/services4/srvkm/devices/sgx/sgxreset.c     |  489 +++
163  .../pvr/services4/srvkm/devices/sgx/sgxtransfer.c  |  543 ++++
164  .../pvr/services4/srvkm/devices/sgx/sgxutils.c     |  928 ++++++
165  .../pvr/services4/srvkm/devices/sgx/sgxutils.h     |   99 +
166  .../mrst/pvr/services4/srvkm/env/linux/.gitignore  |    5 +
167  .../mrst/pvr/services4/srvkm/env/linux/env_data.h  |   66 +
168  .../pvr/services4/srvkm/env/linux/env_perproc.h    |   56 +
169  .../drm/mrst/pvr/services4/srvkm/env/linux/event.c |  273 ++
170  .../drm/mrst/pvr/services4/srvkm/env/linux/event.h |   32 +
171  .../mrst/pvr/services4/srvkm/env/linux/linkage.h   |   61 +
172  .../drm/mrst/pvr/services4/srvkm/env/linux/lock.h  |   32 +
173  .../drm/mrst/pvr/services4/srvkm/env/linux/mm.c    | 2360 ++++++++++++++
174  .../drm/mrst/pvr/services4/srvkm/env/linux/mm.h    |  331 ++
175  .../drm/mrst/pvr/services4/srvkm/env/linux/mmap.c  | 1148 +++++++
176  .../drm/mrst/pvr/services4/srvkm/env/linux/mmap.h  |  107 +
177  .../mrst/pvr/services4/srvkm/env/linux/module.c    |  765 +++++
178  .../drm/mrst/pvr/services4/srvkm/env/linux/mutex.c |  136 +
179  .../drm/mrst/pvr/services4/srvkm/env/linux/mutex.h |   70 +
180  .../mrst/pvr/services4/srvkm/env/linux/mutils.c    |  133 +
181  .../mrst/pvr/services4/srvkm/env/linux/mutils.h    |  101 +
182  .../mrst/pvr/services4/srvkm/env/linux/osfunc.c    | 2564 +++++++++++++++
183  .../mrst/pvr/services4/srvkm/env/linux/osperproc.c |  113 +
184  .../drm/mrst/pvr/services4/srvkm/env/linux/pdump.c |  662 ++++
185  .../pvr/services4/srvkm/env/linux/private_data.h   |   67 +
186  .../drm/mrst/pvr/services4/srvkm/env/linux/proc.c  |  970 ++++++
187  .../drm/mrst/pvr/services4/srvkm/env/linux/proc.h  |  115 +
188  .../pvr/services4/srvkm/env/linux/pvr_bridge_k.c   |  651 ++++
189  .../mrst/pvr/services4/srvkm/env/linux/pvr_debug.c |  426 +++
190  .../mrst/pvr/services4/srvkm/env/linux/pvr_drm.c   |  310 ++
191  .../mrst/pvr/services4/srvkm/env/linux/pvr_drm.h   |   80 +
192  .../mrst/pvr/services4/srvkm/hwdefs/sgx535defs.h   |  637 ++++
193  .../drm/mrst/pvr/services4/srvkm/hwdefs/sgxdefs.h  |   82 +
194  .../mrst/pvr/services4/srvkm/hwdefs/sgxerrata.h    |  308 ++
195  .../pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h    |  163 +
196  .../drm/mrst/pvr/services4/srvkm/hwdefs/sgxmmu.h   |   79 +
197  .../pvr/services4/srvkm/include/buffer_manager.h   |  213 ++
198  .../drm/mrst/pvr/services4/srvkm/include/device.h  |  278 ++
199  .../drm/mrst/pvr/services4/srvkm/include/handle.h  |  382 +++
200  .../drm/mrst/pvr/services4/srvkm/include/hash.h    |   73 +
201  .../drm/mrst/pvr/services4/srvkm/include/lists.h   |  176 +
202  .../drm/mrst/pvr/services4/srvkm/include/metrics.h |  130 +
203  .../drm/mrst/pvr/services4/srvkm/include/osfunc.h  |  487 +++
204  .../mrst/pvr/services4/srvkm/include/osperproc.h   |   76 +
205  .../mrst/pvr/services4/srvkm/include/pdump_km.h    |  451 +++
206  .../pvr/services4/srvkm/include/pdump_osfunc.h     |  137 +
207  .../drm/mrst/pvr/services4/srvkm/include/perproc.h |  110 +
208  .../drm/mrst/pvr/services4/srvkm/include/power.h   |  133 +
209  .../drm/mrst/pvr/services4/srvkm/include/queue.h   |  119 +
210  .../gpu/drm/mrst/pvr/services4/srvkm/include/ra.h  |  155 +
211  .../drm/mrst/pvr/services4/srvkm/include/resman.h  |  113 +
212  .../pvr/services4/srvkm/include/services_headers.h |   49 +
213  .../drm/mrst/pvr/services4/srvkm/include/srvkm.h   |   69 +
214  .../mrst/pvr/services4/system/include/syscommon.h  |  217 ++
215  .../pvr/services4/system/moorestown/.gitignore     |    5 +
216  .../pvr/services4/system/moorestown/oemfuncs.h     |   72 +
217  .../pvr/services4/system/moorestown/ospm_power.c   |  479 +++
218  .../pvr/services4/system/moorestown/ospm_power.h   |   79 +
219  .../system/moorestown/sys_pvr_drm_export.c         |  135 +
220  .../system/moorestown/sys_pvr_drm_export.h         |   87 +
221  .../system/moorestown/sys_pvr_drm_import.h         |   45 +
222  .../pvr/services4/system/moorestown/sysconfig.c    | 1022 ++++++
223  .../pvr/services4/system/moorestown/sysconfig.h    |  139 +
224  .../mrst/pvr/services4/system/moorestown/sysinfo.h |   43 +
225  .../mrst/pvr/services4/system/moorestown/sysirq.c  |  565 ++++
226  .../mrst/pvr/services4/system/moorestown/sysirq.h  |   49 +
227  .../pvr/services4/system/moorestown/syslocal.h     |   82 +
228  .../pvr/services4/system/moorestown/sysutils.c     |   30 +
229  .../mrst/pvr/tools/intern/debug/client/linuxsrv.h  |   48 +
230  .../tools/intern/debug/dbgdriv/common/dbgdriv.c    | 2075 ++++++++++++
231  .../tools/intern/debug/dbgdriv/common/dbgdriv.h    |  116 +
232  .../tools/intern/debug/dbgdriv/common/hostfunc.h   |   58 +
233  .../pvr/tools/intern/debug/dbgdriv/common/hotkey.c |  135 +
234  .../pvr/tools/intern/debug/dbgdriv/common/hotkey.h |   60 +
235  .../pvr/tools/intern/debug/dbgdriv/common/ioctl.c  |  371 +++
236  .../pvr/tools/intern/debug/dbgdriv/common/ioctl.h  |   87 +
237  .../tools/intern/debug/dbgdriv/linux/hostfunc.c    |  302 ++
238  .../intern/debug/dbgdriv/linux/kbuild/Makefile     |   35 +
239  .../pvr/tools/intern/debug/dbgdriv/linux/main.c    |  298 ++
240  .../debug/dbgdriv/linux/makefile.linux.common      |   40 +
241  include/drm/drmP.h                                 |   22 +
242  include/drm/drm_mode.h                             |    2 +
243  include/linux/backlight.h                          |    3 +
244  235 files changed, 104731 insertions(+), 2 deletions(-)
245  create mode 100644 drivers/gpu/drm/drm_global.c
246  create mode 100644 drivers/gpu/drm/mrst/Kconfig
247  create mode 100644 drivers/gpu/drm/mrst/Makefile
248  create mode 100644 drivers/gpu/drm/mrst/drv/lnc_topaz.c
249  create mode 100644 drivers/gpu/drm/mrst/drv/lnc_topaz.h
250  create mode 100644 drivers/gpu/drm/mrst/drv/lnc_topazinit.c
251  create mode 100644 drivers/gpu/drm/mrst/drv/msvdx_power.c
252  create mode 100644 drivers/gpu/drm/mrst/drv/msvdx_power.h
253  create mode 100644 drivers/gpu/drm/mrst/drv/psb_bl.c
254  create mode 100644 drivers/gpu/drm/mrst/drv/psb_buffer.c
255  create mode 100644 drivers/gpu/drm/mrst/drv/psb_dpst.c
256  create mode 100644 drivers/gpu/drm/mrst/drv/psb_dpst.h
257  create mode 100644 drivers/gpu/drm/mrst/drv/psb_drm.h
258  create mode 100644 drivers/gpu/drm/mrst/drv/psb_drv.c
259  create mode 100644 drivers/gpu/drm/mrst/drv/psb_drv.h
260  create mode 100644 drivers/gpu/drm/mrst/drv/psb_fb.c
261  create mode 100644 drivers/gpu/drm/mrst/drv/psb_fb.h
262  create mode 100644 drivers/gpu/drm/mrst/drv/psb_fence.c
263  create mode 100644 drivers/gpu/drm/mrst/drv/psb_gtt.c
264  create mode 100644 drivers/gpu/drm/mrst/drv/psb_gtt.h
265  create mode 100644 drivers/gpu/drm/mrst/drv/psb_hotplug.c
266  create mode 100644 drivers/gpu/drm/mrst/drv/psb_hotplug.h
267  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_bios.c
268  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_bios.h
269  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_display.c
270  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_display.h
271  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_drv.h
272  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_dsi.c
273  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_dsi_aava.c
274  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_i2c.c
275  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_lvds.c
276  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_modes.c
277  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_reg.h
278  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_sdvo.c
279  create mode 100644 drivers/gpu/drm/mrst/drv/psb_intel_sdvo_regs.h
280  create mode 100644 drivers/gpu/drm/mrst/drv/psb_mmu.c
281  create mode 100644 drivers/gpu/drm/mrst/drv/psb_msvdx.c
282  create mode 100644 drivers/gpu/drm/mrst/drv/psb_msvdx.h
283  create mode 100644 drivers/gpu/drm/mrst/drv/psb_msvdxinit.c
284  create mode 100644 drivers/gpu/drm/mrst/drv/psb_pvr_glue.c
285  create mode 100644 drivers/gpu/drm/mrst/drv/psb_pvr_glue.h
286  create mode 100644 drivers/gpu/drm/mrst/drv/psb_reg.h
287  create mode 100644 drivers/gpu/drm/mrst/drv/psb_reset.c
288  create mode 100644 drivers/gpu/drm/mrst/drv/psb_schedule.c
289  create mode 100644 drivers/gpu/drm/mrst/drv/psb_schedule.h
290  create mode 100644 drivers/gpu/drm/mrst/drv/psb_setup.c
291  create mode 100644 drivers/gpu/drm/mrst/drv/psb_sgx.c
292  create mode 100644 drivers/gpu/drm/mrst/drv/psb_sgx.h
293  create mode 100644 drivers/gpu/drm/mrst/drv/psb_socket.c
294  create mode 100644 drivers/gpu/drm/mrst/drv/psb_ttm_glue.c
295  create mode 100644 drivers/gpu/drm/mrst/drv/psb_umevents.c
296  create mode 100644 drivers/gpu/drm/mrst/drv/psb_umevents.h
297  create mode 100644 drivers/gpu/drm/mrst/drv/topaz_power.c
298  create mode 100644 drivers/gpu/drm/mrst/drv/topaz_power.h
299  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_agp_backend.c
300  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_bo.c
301  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_bo_api.h
302  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_bo_driver.h
303  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_bo_util.c
304  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_bo_vm.c
305  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.c
306  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.h
307  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_fence.c
308  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_fence_api.h
309  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_fence_driver.h
310  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.c
311  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.h
312  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_lock.c
313  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_lock.h
314  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_memory.c
315  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_memory.h
316  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_object.c
317  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_object.h
318  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.c
319  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.h
320  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_placement_common.h
321  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.c
322  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.h
323  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_regman.h
324  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_tt.c
325  create mode 100644 drivers/gpu/drm/mrst/drv/ttm/ttm_userobj_api.h
326  create mode 100644 drivers/gpu/drm/mrst/pvr/COPYING
327  create mode 100644 drivers/gpu/drm/mrst/pvr/INSTALL
328  create mode 100644 drivers/gpu/drm/mrst/pvr/README
329  create mode 100644 drivers/gpu/drm/mrst/pvr/eurasiacon/.gitignore
330  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/dbgdrvif.h
331  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/img_defs.h
332  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/img_types.h
333  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/ioctldef.h
334  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/pdumpdefs.h
335  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/pvr_debug.h
336  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/pvrmodule.h
337  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/pvrversion.h
338  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/regpaths.h
339  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/services.h
340  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/servicesext.h
341  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/sgx_options.h
342  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/sgxapi_km.h
343  create mode 100644 drivers/gpu/drm/mrst/pvr/include4/sgxscript.h
344  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore
345  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common
346  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h
347  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
348  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
349  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/env/linux/pvr_drm_shared.h
350  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/kernelbuffer.h
351  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/kerneldisplay.h
352  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge.h
353  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge_km.h
354  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/pvrmmap.h
355  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/servicesint.h
356  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/sgx_bridge.h
357  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/sgx_mkif_km.h
358  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/include/sgxinfo.h
359  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/.gitignore
360  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c
361  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h
362  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.c
363  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.h
364  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
365  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
366  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/.gitignore
367  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/buffer_manager.c
368  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/deviceclass.c
369  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/devicemem.c
370  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/handle.c
371  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/hash.c
372  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/lists.c
373  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem.c
374  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem_debug.c
375  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/metrics.c
376  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pdump_common.c
377  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/perproc.c
378  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/power.c
379  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pvrsrv.c
380  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/queue.c
381  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/ra.c
382  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/common/resman.c
383  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/.gitignore
384  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.c
385  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.h
386  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/pb.c
387  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h
388  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxconfig.h
389  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h
390  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c
391  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
392  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxpower.c
393  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxreset.c
394  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxtransfer.c
395  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.c
396  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.h
397  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/.gitignore
398  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_data.h
399  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_perproc.h
400  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.c
401  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.h
402  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/linkage.h
403  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/lock.h
404  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.c
405  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.h
406  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.c
407  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.h
408  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/module.c
409  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.c
410  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.h
411  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.c
412  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.h
413  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osfunc.c
414  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osperproc.c
415  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pdump.c
416  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/private_data.h
417  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.c
418  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.h
419  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_bridge_k.c
420  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_debug.c
421  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.c
422  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.h
423  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgx535defs.h
424  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxdefs.h
425  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxerrata.h
426  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h
427  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxmmu.h
428  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/buffer_manager.h
429  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/device.h
430  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/handle.h
431  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/hash.h
432  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/lists.h
433  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/metrics.h
434  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osfunc.h
435  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osperproc.h
436  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_km.h
437  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_osfunc.h
438  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/perproc.h
439  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/power.h
440  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/queue.h
441  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/ra.h
442  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/resman.h
443  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/services_headers.h
444  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/srvkm/include/srvkm.h
445  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/include/syscommon.h
446  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/.gitignore
447  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/oemfuncs.h
448  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.c
449  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.h
450  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.c
451  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
452  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_import.h
453  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.c
454  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.h
455  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysinfo.h
456  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.c
457  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.h
458  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/syslocal.h
459  create mode 100644 drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysutils.c
460  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/client/linuxsrv.h
461  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c
462  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h
463  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h
464  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.c
465  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.h
466  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.c
467  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.h
468  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c
469  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
470  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/main.c
471  create mode 100644 drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common
472
473 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
474 index 305c590..8242c7f 100644
475 --- a/drivers/gpu/drm/Kconfig
476 +++ b/drivers/gpu/drm/Kconfig
477 @@ -157,3 +157,5 @@ config DRM_SAVAGE
478         help
479           Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
480           chipset. If M is selected the module will be called savage.
481 +
482 +source drivers/gpu/drm/mrst/Kconfig
483 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
484 index 39c5aa7..ca0eea7 100644
485 --- a/drivers/gpu/drm/Makefile
486 +++ b/drivers/gpu/drm/Makefile
487 @@ -11,7 +11,7 @@ drm-y       :=        drm_auth.o drm_bufs.o drm_cache.o \
488                 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
489                 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
490                 drm_crtc.o drm_modes.o drm_edid.o \
491 -               drm_info.o drm_debugfs.o drm_encoder_slave.o
492 +               drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o
493  
494  drm-$(CONFIG_COMPAT) += drm_ioc32.o
495  
496 @@ -33,4 +33,5 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage/
497  obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
498  obj-$(CONFIG_DRM_VIA)  +=via/
499  obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
500 +obj-$(CONFIG_DRM_MRST)  +=mrst/
501  obj-y                  += i2c/
502 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
503 index d91fb8c..9004741 100644
504 --- a/drivers/gpu/drm/drm_crtc.c
505 +++ b/drivers/gpu/drm/drm_crtc.c
506 @@ -159,6 +159,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
507         { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
508         { DRM_MODE_CONNECTOR_TV, "TV", 0 },
509         { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
510 +       { DRM_MODE_CONNECTOR_MIPI, "MIPI", 0 },
511  };
512  
513  static struct drm_prop_enum_list drm_encoder_enum_list[] =
514 @@ -167,6 +168,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] =
515         { DRM_MODE_ENCODER_TMDS, "TMDS" },
516         { DRM_MODE_ENCODER_LVDS, "LVDS" },
517         { DRM_MODE_ENCODER_TVDAC, "TV" },
518 +       { DRM_MODE_ENCODER_MIPI, "MIPI" },
519  };
520  
521  char *drm_get_encoder_name(struct drm_encoder *encoder)
522 diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
523 index 766c468..48d70c2 100644
524 --- a/drivers/gpu/drm/drm_drv.c
525 +++ b/drivers/gpu/drm/drm_drv.c
526 @@ -342,6 +342,8 @@ static int __init drm_core_init(void)
527  
528         DRM_INFO("Initialized %s %d.%d.%d %s\n",
529                  CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
530 +       drm_global_init();
531 +
532         return 0;
533  err_p3:
534         drm_sysfs_destroy();
535 @@ -355,6 +357,7 @@ err_p1:
536  
537  static void __exit drm_core_exit(void)
538  {
539 +       drm_global_release();
540         remove_proc_entry("dri", NULL);
541         debugfs_remove(drm_debugfs_root);
542         drm_sysfs_destroy();
543 @@ -437,6 +440,12 @@ static int drm_version(struct drm_device *dev, void *data,
544  long drm_ioctl(struct file *filp,
545               unsigned int cmd, unsigned long arg)
546  {
547 +       return drm_unlocked_ioctl(filp, cmd, arg);
548 +}
549 +EXPORT_SYMBOL(drm_ioctl);
550 +
551 +long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
552 +{
553         struct drm_file *file_priv = filp->private_data;
554         struct drm_device *dev;
555         struct drm_ioctl_desc *ioctl;
556 @@ -526,7 +535,7 @@ long drm_ioctl(struct file *filp,
557         return retcode;
558  }
559  
560 -EXPORT_SYMBOL(drm_ioctl);
561 +EXPORT_SYMBOL(drm_unlocked_ioctl);
562  
563  struct drm_local_map *drm_getsarea(struct drm_device *dev)
564  {
565 diff --git a/drivers/gpu/drm/drm_global.c b/drivers/gpu/drm/drm_global.c
566 new file mode 100644
567 index 0000000..e054c4f
568 --- /dev/null
569 +++ b/drivers/gpu/drm/drm_global.c
570 @@ -0,0 +1,107 @@
571 +/**************************************************************************
572 + *
573 + * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA
574 + * All Rights Reserved.
575 + *
576 + * Permission is hereby granted, free of charge, to any person obtaining a
577 + * copy of this software and associated documentation files (the
578 + * "Software"), to deal in the Software without restriction, including
579 + * without limitation the rights to use, copy, modify, merge, publish,
580 + * distribute, sub license, and/or sell copies of the Software, and to
581 + * permit persons to whom the Software is furnished to do so, subject to
582 + * the following conditions:
583 + *
584 + * The above copyright notice and this permission notice (including the
585 + * next paragraph) shall be included in all copies or substantial portions
586 + * of the Software.
587 + *
588 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
589 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
590 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
591 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
592 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
593 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
594 + * USE OR OTHER DEALINGS IN THE SOFTWARE.
595 + *
596 + **************************************************************************/
597 +#include <drmP.h>
598 +struct drm_global_item {
599 +       struct mutex mutex;
600 +       void *object;
601 +       int refcount;
602 +};
603 +
604 +static struct drm_global_item glob[DRM_GLOBAL_NUM];
605 +
606 +void drm_global_init(void)
607 +{
608 +       int i;
609 +
610 +       for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
611 +               struct drm_global_item *item = &glob[i];
612 +               mutex_init(&item->mutex);
613 +               item->object = NULL;
614 +               item->refcount = 0;
615 +       }
616 +}
617 +
618 +void drm_global_release(void)
619 +{
620 +       int i;
621 +       for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
622 +               struct drm_global_item *item = &glob[i];
623 +               BUG_ON(item->object != NULL);
624 +               BUG_ON(item->refcount != 0);
625 +       }
626 +}
627 +
628 +int drm_global_item_ref(struct drm_global_reference *ref)
629 +{
630 +       int ret;
631 +       struct drm_global_item *item = &glob[ref->global_type];
632 +       void *object;
633 +
634 +       mutex_lock(&item->mutex);
635 +       if (item->refcount == 0) {
636 +               item->object = kmalloc(ref->size, GFP_KERNEL);
637 +               if (unlikely(item->object == NULL)) {
638 +                       ret = -ENOMEM;
639 +                       goto out_err;
640 +               }
641 +
642 +               ref->object = item->object;
643 +               ret = ref->init(ref);
644 +               if (unlikely(ret != 0))
645 +                       goto out_err;
646 +
647 +               ++item->refcount;
648 +       }
649 +       ref->object = item->object;
650 +       object = item->object;
651 +       mutex_unlock(&item->mutex);
652 +       return 0;
653 +      out_err:
654 +       kfree(item->object);
655 +       mutex_unlock(&item->mutex);
656 +       item->object = NULL;
657 +       return ret;
658 +}
659 +
660 +EXPORT_SYMBOL(drm_global_item_ref);
661 +
662 +void drm_global_item_unref(struct drm_global_reference *ref)
663 +{
664 +       struct drm_global_item *item = &glob[ref->global_type];
665 +
666 +       mutex_lock(&item->mutex);
667 +       BUG_ON(item->refcount == 0);
668 +       BUG_ON(ref->object != item->object);
669 +       if (--item->refcount == 0) {
670 +               ref->release(ref);
671 +               kfree(item->object);
672 +               item->object = NULL;
673 +       }
674 +       mutex_unlock(&item->mutex);
675 +}
676 +
677 +EXPORT_SYMBOL(drm_global_item_unref);
678 diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
679 index b98384d..7991d00 100644
680 --- a/drivers/gpu/drm/drm_irq.c
681 +++ b/drivers/gpu/drm/drm_irq.c
682 @@ -72,6 +72,28 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
683         return 0;
684  }
685  
686 +#if 0
687 +static void drm_flip_work_func(struct work_struct *work)
688 +{
689 +       struct drm_device *dev =
690 +               container_of(work, struct drm_device, flip_work);
691 +#if 0
692 +       struct drm_pending_flip *f, *t;
693 +#endif
694 +       u32 frame;
695 +
696 +       mutex_lock(&dev->struct_mutex);
697 +
698 +       list_for_each_entry_safe(f, t, &dev->flip_list, link) {
699 +               frame = drm_vblank_count(dev, f->pipe);
700 +               if (vblank_after(frame, f->frame))
701 +                       drm_finish_pending_flip(dev, f, frame);
702 +       }
703 +
704 +       mutex_unlock(&dev->struct_mutex);
705 +}
706 +#endif
707 +
708  static void vblank_disable_fn(unsigned long arg)
709  {
710         struct drm_device *dev = (struct drm_device *)arg;
711 @@ -163,6 +185,11 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
712                 atomic_set(&dev->vblank_refcount[i], 0);
713         }
714  
715 +#if 0
716 +       INIT_LIST_HEAD(&dev->flip_list);
717 +       INIT_WORK(&dev->flip_work, drm_flip_work_func);
718 +#endif
719 +
720         dev->vblank_disable_allowed = 0;
721         return 0;
722  
723 diff --git a/drivers/gpu/drm/mrst/Kconfig b/drivers/gpu/drm/mrst/Kconfig
724 new file mode 100644
725 index 0000000..2fc22d1
726 --- /dev/null
727 +++ b/drivers/gpu/drm/mrst/Kconfig
728 @@ -0,0 +1,220 @@
729 +#
730 +# Drm device configuration
731 +#
732 +# This driver provides support for the
733 +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
734 +#
735 +menuconfig DRM_MRST
736 +       tristate "Intel Moorestown (load along with IMG driver)"
737 +       depends on DRM && PCI
738 +       select FB_CFB_COPYAREA
739 +        select FB_CFB_FILLRECT
740 +        select FB_CFB_IMAGEBLIT
741 +       select PVR_SUPPORT_DRI_DRM
742 +       select DRM_KMS_HELPER
743 +       help
744 +         Choose this option if you have a Moorestown platform.
745 +          If M is selected the module will be called mrst.
746 +
747 +config IMG_DOES_NOT_SUPPORT_MENLOW
748 +       bool "Disable MRST funtions for Menlow"
749 +       depends on DRM_MRST
750 +       default n
751 +       help
752 +         Choose Menlow
753 +
754 +config PVR_RELEASE
755 +       string "Build IMG kernel services as release"
756 +       depends on DRM_MRST
757 +       default "release"
758 +       help
759 +         xxxxxxx
760 +
761 +config PVR_SERVICES4
762 +       bool "Enable PVR services4"
763 +       depends on DRM_MRST
764 +       default y
765 +       help
766 +         xxxxxxx
767 +
768 +config PVR_XOPEN_SOURCE
769 +       int "Number of xopen source"
770 +       depends on DRM_MRST
771 +       default 600
772 +       help
773 +         xxxxxxx
774 +
775 +config PVR2D_VALIDATE_INPUT_PARAMS
776 +       bool "PVR2D Validate input params"
777 +       depends on DRM_MRST
778 +       default y
779 +       help
780 +         xxxxxxx
781 +
782 +config PVR_DISPLAY_CONTROLLER
783 +       string "Name of PVR display controller"
784 +       depends on DRM_MRST
785 +       default "mrstlfb"
786 +       help
787 +         xxxxxxx
788 +
789 +config PVR_SGX_CORE_REV
790 +       int "SGX core revison"
791 +       depends on DRM_MRST
792 +       default 121
793 +       help
794 +         xxxxxxx
795 +
796 +config PVR_SUPPORT_SVRINIT
797 +       bool "Support IMG Kernel Service Init"
798 +       depends on DRM_MRST
799 +       default y
800 +       help
801 +         xxxxxxxx
802 +
803 +config PVR_SUPPORT_SGX
804 +       bool "Support IMG SGX core"
805 +       depends on DRM_MRST
806 +       default y
807 +       help
808 +         xxxxxxxx
809 +
810 +config PVR_SUPPORT_PERCONTEXT_PB
811 +       bool "Support PVR PERCONTEXT_PB"
812 +       depends on DRM_MRST
813 +       default y
814 +       help
815 +         xxxxxxx
816 +
817 +config PVR_SUPPORT_LINUX_X86_WRITECOMBINE
818 +       bool "Support X86 write combine in IMG service"
819 +       depends on DRM_MRST
820 +       default y
821 +       help
822 +         xxxxxxx
823 +
824 +config PVR_TRANSFER_QUEUE
825 +       bool "Support IMG TRANSFER_QUEUE"
826 +       depends on DRM_MRST
827 +       default y
828 +       help
829 +         xxxxxxxx
830 +
831 +config PVR_SUPPORT_DRI_DRM
832 +       bool
833 +       depends on DRM_MRST
834 +       default y
835 +       help
836 +         xxxxxxxx
837 +
838 +config PVR_SYS_USING_INTERRUPTS
839 +       bool "Using interrupts in IMG kernel service"
840 +       depends on DRM_MRST
841 +       default y
842 +       help
843 +         xxxxxxxx
844 +
845 +config PVR_SUPPORT_HW_RECOVERY
846 +       bool "Support hardware recover in IMG kernel service"
847 +       depends on DRM_MRST
848 +       default y
849 +       help
850 +         xxxxxxxx
851 +
852 +config PVR_SUPPORT_POWER_MANAGEMENT
853 +       bool "Support POWER_MANAGEMENT in IMG kernel service"
854 +       depends on DRM_MRST
855 +       default y
856 +       help
857 +         xxxxxxxx
858 +
859 +config PVR_SECURE_HANDLES
860 +       bool "Support PVR_SECURE_HANDLES"
861 +       depends on DRM_MRST
862 +       default y
863 +       help
864 +         xxxxxxxx
865 +
866 +config PVR_USE_PTHREADS
867 +       bool "Use pthreads in IMG service"
868 +       depends on DRM_MRST
869 +       default y
870 +       help
871 +         xxxxxxx
872 +
873 +config PVR_SUPPORT_SGX_EVENT_OBJECT
874 +       bool "Support SGX event object"
875 +       depends on DRM_MRST
876 +       default y
877 +       help
878 +         xxxxxxx
879 +
880 +config PVR_SUPPORT_SGX_HWPERF
881 +       bool "Support SGX HWPERF"
882 +       depends on DRM_MRST
883 +       default y
884 +       help
885 +         xxxxxxxx
886 +
887 +config PVR_SUPPORT_SGX_LOW_LATENCY_SCHEDULING
888 +       bool "Support SGX LOW_LATENCY_SCHEDULING"
889 +       depends on DRM_MRST
890 +       default y
891 +       help
892 +         xxxxxxxx
893 +
894 +config PVR_SUPPORT_LINUX_X86_PAT
895 +       bool "Support PAT in IMG kernel service"
896 +       depends on DRM_MRST
897 +       default y
898 +       help
899 +         xxxxxxx
900 +
901 +config PVR_PROC_USE_SEQ_FILE
902 +       bool "Support PVR_PROC_USE_SEQ_FILE"
903 +       depends on DRM_MRST
904 +       default y
905 +       help
906 +         xxxxxx
907 +
908 +config PVR_SUPPORT_SGX535
909 +       bool "SUPPORT_SGX535"
910 +       depends on DRM_MRST
911 +       default y
912 +       help
913 +         xxxxxx
914 +
915 +config PVR_SUPPORT_CACHEFLUSH_ON_ALLOC
916 +       bool "SUPPORT_CACHEFLUSH_ON_ALLOC"
917 +       depends on DRM_MRST
918 +       default n
919 +       help
920 +         xxxxxx
921 +
922 +config PVR_SUPPORT_MEMINFO_IDS
923 +       bool "SUPPORT_MEMINFO_IDS"
924 +       depends on DRM_MRST
925 +       default n
926 +       help
927 +         xxxxxx
928 +
929 +config PVR_SUPPORT_CACHE_LINE_FLUSH
930 +       bool "SUPPORT_CACHE_LINE_FLUSH"
931 +       depends on DRM_MRST
932 +       default y
933 +       help
934 +         xxxxxx
935 +
936 +config PVR_SUPPORT_CPU_CACHED_BUFFERS
937 +       bool "SUPPORT_CPU_CACHED_BUFFERS"
938 +       depends on DRM_MRST
939 +       default y
940 +       help
941 +         xxxxxx
942 +
943 +config PVR_DEBUG_MESA_OGL_TRACE
944 +    bool "DEBUG_MESA_OGL_TRACE"
945 +    depends on DRM_MRST
946 +    default y
947 +    help
948 +      xxxxxx
949 diff --git a/drivers/gpu/drm/mrst/Makefile b/drivers/gpu/drm/mrst/Makefile
950 new file mode 100644
951 index 0000000..e23d8c3
952 --- /dev/null
953 +++ b/drivers/gpu/drm/mrst/Makefile
954 @@ -0,0 +1,169 @@
955 +# Makefile for the drm device driver.  This driver provides support for the
956 +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
957 +
958 +ccflags-y += -Idrivers/gpu/drm/mrst/pvr/include4 \
959 +            -Idrivers/gpu/drm/mrst/pvr/services4/include \
960 +            -Idrivers/gpu/drm/mrst/pvr/services4/include/env/linux \
961 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux \
962 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/include \
963 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/bridged \
964 +            -Idrivers/gpu/drm/mrst/pvr/services4/system/moorestown \
965 +            -Idrivers/gpu/drm/mrst/pvr/services4/system/include \
966 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs \
967 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx \
968 +            -Idrivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx \
969 +            -Idrivers/gpu/drm/mrst/drv \
970 +            -Idrivers/gpu/drm/mrst/drv/ttm \
971 +            -Iinclude/linux \
972 +         -Werror \
973 +            -DLINUX \
974 +            -DPVR_BUILD_DIR="\"pc_i686_moorestown_linux\"" \
975 +            -DSGX535
976 +
977 +#FIXME: whether we need the follow -D
978 +ccflags-$(CONFIG_PCI_MSI) += -DCONFIG_PCI_MSI
979 +ccflags-y += -DBUILD=$(CONFIG_PVR_RELEASE)
980 +ccflags-y += -DPVR_BUILD_TYPE="\"$(CONFIG_PVR_RELEASE)\""
981 +ifeq ($(CONFIG_PVR_RELEASE),"release")
982 +       ccflags-y += -DRELEASE
983 +else
984 +       ccflags-y += -DDEBUG
985 +endif
986 +ccflags-$(CONFIG_PVR_SERVICES4) += -DSERVICES4
987 +ccflags-y += -D_XOPEN_SOURCE=$(CONFIG_PVR_XOPEN_SOURCE)
988 +ccflags-$(CONFIG_PVR2D_VALIDATE_INPUT_PARAMS) += -DPVR2D_VALIDATE_INPUT_PARAMS
989 +ccflags-y += -DDISPLAY_CONTROLLER=$(CONFIG_PVR_DISPLAY_CONTROLLER)
990 +ccflags-y += -UDEBUG_LOG_PATH_TRUNCATE
991 +ccflags-$(CONFIG_PVR_SUPPORT_SVRINIT) += -DSUPPORT_SRVINIT
992 +ccflags-$(CONFIG_PVR_SUPPORT_SGX) += -DSUPPORT_SGX
993 +ccflags-$(CONFIG_PVR_SUPPORT_PERCONTEXT_PB) += -DSUPPORT_PERCONTEXT_PB
994 +ccflags-$(CONFIG_PVR_SUPPORT_LINUX_X86_WRITECOMBINE) += -DSUPPORT_LINUX_X86_WRITECOMBINE
995 +ccflags-$(CONFIG_PVR_TRANSFER_QUEUE) += -DTRANSFER_QUEUE
996 +ccflags-$(CONFIG_PVR_SUPPORT_DRI_DRM) +=  -DSUPPORT_DRI_DRM
997 +ccflags-$(CONFIG_PVR_SUPPORT_DRI_DRM) += -DSUPPORT_DRI_DRM_EXT
998 +ccflags-$(CONFIG_PVR_SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS
999 +ccflags-$(CONFIG_PVR_SUPPORT_HW_RECOVERY) += -DSUPPORT_HW_RECOVERY
1000 +ccflags-$(CONFIG_PVR_SUPPORT_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT
1001 +ccflags-$(CONFIG_PVR_SECURE_HANDLES) += -DPVR_SECURE_HANDLES
1002 +ccflags-$(CONFIG_PVR_USE_PTHREADS) += -DUSE_PTHREADS
1003 +ccflags-$(CONFIG_PVR_SUPPORT_SGX_EVENT_OBJECT) += -DSUPPORT_SGX_EVENT_OBJECT
1004 +ccflags-$(CONFIG_PVR_SUPPORT_SGX_HWPERF) += -DSUPPORT_SGX_HWPERF
1005 +ccflags-$(CONFIG_PVR_SUPPORT_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING
1006 +ccflags-$(CONFIG_PVR_SUPPORT_LINUX_X86_PAT) += -DSUPPORT_LINUX_X86_PAT
1007 +ccflags-$(CONFIG_PVR_PROC_USE_SEQ_FILE) += -DPVR_PROC_USE_SEQ_FILE
1008 +ccflags-$(CONFIG_PVR_SUPPORT_SGX535) +=  -DSUPPORT_SGX535
1009 +ccflags-y += -DSGX_CORE_REV=$(CONFIG_PVR_SGX_CORE_REV)
1010 +ccflags-$(CONFIG_PVR_SUPPORT_CACHEFLUSH_ON_ALLOC) += -DSUPPORT_CACHEFLUSH_ON_ALLOC
1011 +ccflags-$(CONFIG_PVR_SUPPORT_MEMINFO_IDS) += -DSUPPORT_MEMINFO_IDS
1012 +ccflags-$(CONFIG_PVR_SUPPORT_CACHE_LINE_FLUSH) += -DSUPPORT_CACHE_LINE_FLUSH
1013 +ccflags-$(CONFIG_PVR_SUPPORT_CPU_CACHED_BUFFERS) += -DSUPPORT_CPU_CACHED_BUFFERS
1014 +ccflags-$(CONFIG_PVR_DEBUG_MESA_OGL_TRACE)+= -DDEBUG_MESA_OGL_TRACE
1015 +
1016 +ENVDIR = pvr/services4/srvkm/env/linux
1017 +COMMONDIR = pvr/services4/srvkm/common
1018 +BRIDGEDDIR = pvr/services4/srvkm/bridged
1019 +SYSCONFIGDIR = pvr/services4/system/moorestown
1020 +SGXDIR = pvr/services4/srvkm/devices/sgx
1021 +FBDEVDIR = pvr/services4/3rdparty/linux_framebuffer_mrst
1022 +DRMDRVDIR = drv
1023 +
1024 +ENV_OBJS = $(ENVDIR)/osfunc.o \
1025 +          $(ENVDIR)/mutils.o \
1026 +          $(ENVDIR)/mmap.o \
1027 +          $(ENVDIR)/module.o \
1028 +          $(ENVDIR)/pdump.o \
1029 +          $(ENVDIR)/proc.o \
1030 +          $(ENVDIR)/pvr_bridge_k.o \
1031 +          $(ENVDIR)/pvr_debug.o \
1032 +          $(ENVDIR)/mm.o \
1033 +          $(ENVDIR)/mutex.o \
1034 +          $(ENVDIR)/event.o \
1035 +          $(ENVDIR)/osperproc.o \
1036 +          $(ENVDIR)/pvr_drm.o
1037 +
1038 +COMMON_OBJS = $(COMMONDIR)/buffer_manager.o \
1039 +             $(COMMONDIR)/devicemem.o \
1040 +           $(COMMONDIR)/deviceclass.o \
1041 +           $(COMMONDIR)/handle.o \
1042 +           $(COMMONDIR)/hash.o \
1043 +           $(COMMONDIR)/metrics.o \
1044 +           $(COMMONDIR)/pvrsrv.o \
1045 +           $(COMMONDIR)/queue.o \
1046 +           $(COMMONDIR)/ra.o \
1047 +           $(COMMONDIR)/resman.o \
1048 +           $(COMMONDIR)/power.o \
1049 +           $(COMMONDIR)/mem.o \
1050 +           $(COMMONDIR)/pdump_common.o \
1051 +           $(COMMONDIR)/perproc.o \
1052 +           $(COMMONDIR)/lists.o \
1053 +           $(COMMONDIR)/mem_debug.o
1054 +
1055 +BRIDGED_OBJS = $(BRIDGEDDIR)/bridged_support.o \
1056 +              $(BRIDGEDDIR)/bridged_pvr_bridge.o \
1057 +              $(BRIDGEDDIR)/sgx/bridged_sgx_bridge.o
1058 +
1059 +SYSCONFIG_OBJS = $(SYSCONFIGDIR)/sysconfig.o \
1060 +                $(SYSCONFIGDIR)/sysutils.o \
1061 +                $(SYSCONFIGDIR)/ospm_power.o \
1062 +                $(SYSCONFIGDIR)/sysirq.o \
1063 +                $(SYSCONFIGDIR)/sys_pvr_drm_export.o 
1064 +
1065 +SGX_OBJS = $(SGXDIR)/sgxinit.o \
1066 +          $(SGXDIR)/sgxpower.o \
1067 +        $(SGXDIR)/sgxreset.o \
1068 +        $(SGXDIR)/sgxutils.o \
1069 +        $(SGXDIR)/sgxkick.o \
1070 +        $(SGXDIR)/sgxtransfer.o \
1071 +        $(SGXDIR)/mmu.o \
1072 +        $(SGXDIR)/pb.o
1073 +
1074 +FB_OBJS = $(FBDEVDIR)/mrstlfb_displayclass.o \
1075 +         $(FBDEVDIR)/mrstlfb_linux.o
1076 +
1077 +DRV_OBJS = $(DRMDRVDIR)/lnc_topaz.o \
1078 +          $(DRMDRVDIR)/topaz_power.o \
1079 +          $(DRMDRVDIR)/lnc_topazinit.o \
1080 +        $(DRMDRVDIR)/psb_bl.o \
1081 +        $(DRMDRVDIR)/psb_buffer.o \
1082 +        $(DRMDRVDIR)/psb_dpst.o \
1083 +        $(DRMDRVDIR)/psb_drv.o \
1084 +        $(DRMDRVDIR)/psb_fb.o \
1085 +        $(DRMDRVDIR)/psb_fence.o \
1086 +        $(DRMDRVDIR)/psb_gtt.o \
1087 +        $(DRMDRVDIR)/psb_hotplug.o \
1088 +        $(DRMDRVDIR)/psb_intel_bios.o \
1089 +        $(DRMDRVDIR)/psb_intel_display.o \
1090 +        $(DRMDRVDIR)/psb_intel_i2c.o \
1091 +        $(DRMDRVDIR)/psb_intel_lvds.o \
1092 +        $(DRMDRVDIR)/psb_intel_modes.o \
1093 +        $(DRMDRVDIR)/psb_intel_sdvo.o \
1094 +        $(DRMDRVDIR)/psb_mmu.o \
1095 +        $(DRMDRVDIR)/psb_msvdx.o \
1096 +        $(DRMDRVDIR)/msvdx_power.o \
1097 +        $(DRMDRVDIR)/psb_msvdxinit.o \
1098 +        $(DRMDRVDIR)/psb_reset.o \
1099 +        $(DRMDRVDIR)/psb_schedule.o \
1100 +        $(DRMDRVDIR)/psb_sgx.o \
1101 +        $(DRMDRVDIR)/psb_socket.o \
1102 +        $(DRMDRVDIR)/psb_ttm_glue.o \
1103 +        $(DRMDRVDIR)/psb_pvr_glue.o \
1104 +        $(DRMDRVDIR)/psb_umevents.o \
1105 +        $(DRMDRVDIR)/ttm/ttm_agp_backend.o \
1106 +        $(DRMDRVDIR)/ttm/ttm_bo.o \
1107 +        $(DRMDRVDIR)/ttm/ttm_bo_util.o \
1108 +        $(DRMDRVDIR)/ttm/ttm_bo_vm.o \
1109 +        $(DRMDRVDIR)/ttm/ttm_execbuf_util.o \
1110 +        $(DRMDRVDIR)/ttm/ttm_fence.o \
1111 +        $(DRMDRVDIR)/ttm/ttm_fence_user.o \
1112 +        $(DRMDRVDIR)/ttm/ttm_lock.o \
1113 +        $(DRMDRVDIR)/ttm/ttm_memory.o \
1114 +        $(DRMDRVDIR)/ttm/ttm_object.o \
1115 +        $(DRMDRVDIR)/ttm/ttm_pat_compat.o \
1116 +        $(DRMDRVDIR)/ttm/ttm_placement_user.o \
1117 +        $(DRMDRVDIR)/ttm/ttm_tt.o
1118 +
1119 +mrst-objs += $(ENV_OBJS) $(COMMON_OBJS) $(BRIDGED_OBJS) $(SYSCONFIG_OBJS) $(SGX_OBJS) $(FB_OBJS) $(DRV_OBJS)
1120 +
1121 +obj-$(CONFIG_DRM_MRST) += mrst.o
1122 +obj-$(CONFIG_DRM_MRST_AAVA)    += $(DRMDRVDIR)/psb_intel_dsi_aava.o
1123 +obj-$(CONFIG_DRM_MRST_CDK)     += $(DRMDRVDIR)/psb_intel_dsi.o
1124 diff --git a/drivers/gpu/drm/mrst/drv/lnc_topaz.c b/drivers/gpu/drm/mrst/drv/lnc_topaz.c
1125 new file mode 100644
1126 index 0000000..04c42f8
1127 --- /dev/null
1128 +++ b/drivers/gpu/drm/mrst/drv/lnc_topaz.c
1129 @@ -0,0 +1,714 @@
1130 +/**
1131 + * file lnc_topaz.c
1132 + * TOPAZ I/O operations and IRQ handling
1133 + *
1134 + */
1135 +
1136 +/**************************************************************************
1137 + *
1138 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
1139 + * Copyright (c) Imagination Technologies Limited, UK
1140 + *
1141 + * This program is free software; you can redistribute it and/or modify it
1142 + * under the terms and conditions of the GNU General Public License,
1143 + * version 2, as published by the Free Software Foundation.
1144 + *
1145 + * This program is distributed in the hope it will be useful, but WITHOUT
1146 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1147 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1148 + * more details.
1149 + *
1150 + * You should have received a copy of the GNU General Public License along with
1151 + * this program; if not, write to the Free Software Foundation, Inc., 
1152 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1153 + *
1154 + **************************************************************************/
1155 +
1156 +/* include headers */
1157 +/* #define DRM_DEBUG_CODE 2 */
1158 +#include <drm/drmP.h>
1159 +#include <drm/drm_os_linux.h>
1160 +
1161 +#include "psb_drv.h"
1162 +#include "psb_drm.h"
1163 +#include "lnc_topaz.h"
1164 +#include "ospm_power.h"
1165 +
1166 +#include <linux/io.h>
1167 +#include <linux/delay.h>
1168 +
1169 +#define TOPAZ_RM_MULTI_MTX_WRITE
1170 +
1171 +/* static function define */
1172 +static int lnc_topaz_deliver_command(struct drm_device *dev,
1173 +                                    struct ttm_buffer_object *cmd_buffer,
1174 +                                    unsigned long cmd_offset,
1175 +                                    unsigned long cmd_size,
1176 +                                    void **topaz_cmd, uint32_t sequence,
1177 +                                    int copy_cmd);
1178 +static int lnc_topaz_send(struct drm_device *dev, void *cmd,
1179 +                       unsigned long cmd_size, uint32_t sync_seq);
1180 +static int lnc_mtx_send(struct drm_psb_private *dev_priv, const void *cmd);
1181 +static int lnc_topaz_dequeue_send(struct drm_device *dev);
1182 +static int lnc_topaz_save_command(struct drm_device *dev, void *cmd,
1183 +                       unsigned long cmd_size, uint32_t sequence);
1184 +
1185 +IMG_BOOL lnc_topaz_interrupt(IMG_VOID *pvData)
1186 +{
1187 +       struct drm_device *dev;
1188 +       struct drm_psb_private *dev_priv;
1189 +       uint32_t clr_flag;
1190 +       struct topaz_private *topaz_priv;
1191 +       uint32_t topaz_stat;
1192 +       uint32_t cur_seq;
1193 +
1194 +       if (pvData == IMG_NULL) {
1195 +               DRM_ERROR("ERROR: TOPAZ %s, Invalid params\n", __func__);
1196 +               return IMG_FALSE;
1197 +       }
1198 +
1199 +       if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
1200 +               DRM_ERROR("ERROR: interrupt arrived but HW is power off\n");
1201 +               return IMG_FALSE;
1202 +       }
1203 +
1204 +       dev = (struct drm_device *)pvData;
1205 +       dev_priv = (struct drm_psb_private *) dev->dev_private;
1206 +       topaz_priv = dev_priv->topaz_private;
1207 +
1208 +       topaz_priv->topaz_hw_busy = REG_READ(0x20D0) & (0x1 << 11);
1209 +
1210 +       TOPAZ_READ32(TOPAZ_CR_IMG_TOPAZ_INTSTAT, &topaz_stat);
1211 +       clr_flag = lnc_topaz_queryirq(dev);
1212 +
1213 +       lnc_topaz_clearirq(dev, clr_flag);
1214 +
1215 +       /* ignore non-SYNC interrupts */
1216 +       if ((CCB_CTRL_SEQ(dev_priv) & 0x8000) == 0)
1217 +               return IMG_TRUE;
1218 +
1219 +       cur_seq = *(uint32_t *)topaz_priv->topaz_sync_addr;
1220 +
1221 +       PSB_DEBUG_IRQ("TOPAZ:Got SYNC IRQ,sync seq:0x%08x (MTX) vs 0x%08x\n",
1222 +               cur_seq, dev_priv->sequence[LNC_ENGINE_ENCODE]);
1223 +
1224 +       psb_fence_handler(dev, LNC_ENGINE_ENCODE);
1225 +
1226 +       /* save frame skip flag for query */
1227 +       topaz_priv->frame_skip = CCB_CTRL_FRAMESKIP(dev_priv);
1228 +
1229 +       topaz_priv->topaz_busy = 1;
1230 +       lnc_topaz_dequeue_send(dev);
1231 +
1232 +       if (drm_topaz_pmpolicy != PSB_PMPOLICY_NOPM)
1233 +               schedule_delayed_work(&dev_priv->scheduler.topaz_suspend_wq, 0);
1234 +
1235 +       return IMG_TRUE;
1236 +}
1237 +
1238 +static int lnc_submit_encode_cmdbuf(struct drm_device *dev,
1239 +                       struct ttm_buffer_object *cmd_buffer,
1240 +                       unsigned long cmd_offset, unsigned long cmd_size,
1241 +                       struct ttm_fence_object *fence)
1242 +{
1243 +       struct drm_psb_private *dev_priv = dev->dev_private;
1244 +       unsigned long irq_flags;
1245 +       int ret = 0;
1246 +       void *cmd;
1247 +       uint32_t tmp;
1248 +       uint32_t sequence = dev_priv->sequence[LNC_ENGINE_ENCODE];
1249 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1250 +       uint32_t ui32_reg_value = 0;
1251 +
1252 +       PSB_DEBUG_GENERAL("TOPAZ: command submit\n");
1253 +
1254 +       PSB_DEBUG_GENERAL("TOPAZ: topaz busy = %d\n", topaz_priv->topaz_busy);
1255 +
1256 +       /* FIXME: workaround for HSD 3469585 
1257 +        *        disable DRAM Self Refresh Mode
1258 +        *        by resetting DUNIT.DPMC0
1259 +        */
1260 +       ui32_reg_value = MSG_READ32(0x1, 0x4);
1261 +       MSG_WRITE32(0x1, 0x4, (ui32_reg_value & (~(0x1 << 7))));
1262 +
1263 +       if (topaz_priv->topaz_fw_loaded == 0) {
1264 +               /* #.# load fw to driver */
1265 +               PSB_DEBUG_INIT("TOPAZ: load /lib/firmware/topaz_fw.bin\n");
1266 +               ret = topaz_init_fw(dev);
1267 +               if (ret != 0) {
1268 +                       /* FIXME: find a proper return value */
1269 +                       DRM_ERROR("TOPAX:load /lib/firmware/topaz_fw.bin fail,"
1270 +                               "ensure udevd is configured correctly!\n");
1271 +
1272 +                       return -EFAULT;
1273 +               }
1274 +               topaz_priv->topaz_fw_loaded = 1;
1275 +       }
1276 +
1277 +       tmp = atomic_cmpxchg(&dev_priv->topaz_mmu_invaldc, 1, 0);
1278 +       if (tmp == 1)
1279 +               topaz_mmu_flushcache(dev_priv);
1280 +
1281 +       /* # schedule watchdog */
1282 +       /* psb_schedule_watchdog(dev_priv); */
1283 +
1284 +       /* # spin lock irq save [msvdx_lock] */
1285 +       spin_lock_irqsave(&topaz_priv->topaz_lock, irq_flags);
1286 +
1287 +       /* # if topaz need to reset, reset it */
1288 +       if (topaz_priv->topaz_needs_reset) {
1289 +               /* #.# reset it */
1290 +               spin_unlock_irqrestore(&topaz_priv->topaz_lock, irq_flags);
1291 +               PSB_DEBUG_GENERAL("TOPAZ: needs reset.\n");
1292 +
1293 +               if (lnc_topaz_reset(dev_priv)) {
1294 +                       ret = -EBUSY;
1295 +                       DRM_ERROR("TOPAZ: reset failed.\n");
1296 +                       return ret;
1297 +               }
1298 +
1299 +               PSB_DEBUG_GENERAL("TOPAZ: reset ok.\n");
1300 +
1301 +               /* #.# upload firmware */
1302 +               if (topaz_setup_fw(dev, topaz_priv->topaz_cur_codec)) {
1303 +                       DRM_ERROR("TOPAZ: upload FW to HW failed\n");
1304 +                       return -EBUSY;
1305 +               }
1306 +
1307 +               spin_lock_irqsave(&topaz_priv->topaz_lock, irq_flags);
1308 +       }
1309 +
1310 +       if (!topaz_priv->topaz_busy) {
1311 +               /* # direct map topaz command if topaz is free */
1312 +               PSB_DEBUG_GENERAL("TOPAZ:direct send command,sequence %08x \n",
1313 +                          sequence);
1314 +
1315 +               topaz_priv->topaz_busy = 1;
1316 +               spin_unlock_irqrestore(&topaz_priv->topaz_lock, irq_flags);
1317 +
1318 +               ret = lnc_topaz_deliver_command(dev, cmd_buffer, cmd_offset,
1319 +                                               cmd_size, NULL, sequence, 0);
1320 +
1321 +               if (ret) {
1322 +                       DRM_ERROR("TOPAZ: failed to extract cmd...\n");
1323 +                       return ret;
1324 +               }
1325 +       } else {
1326 +               PSB_DEBUG_GENERAL("TOPAZ: queue command,sequence %08x \n",
1327 +                               sequence);
1328 +               cmd = NULL;
1329 +
1330 +               spin_unlock_irqrestore(&topaz_priv->topaz_lock, irq_flags);
1331 +
1332 +               ret = lnc_topaz_deliver_command(dev, cmd_buffer, cmd_offset,
1333 +                                               cmd_size, &cmd, sequence, 1);
1334 +               if (cmd == NULL || ret) {
1335 +                       DRM_ERROR("TOPAZ: map command for save fialed\n");
1336 +                       return ret;
1337 +               }
1338 +
1339 +               ret = lnc_topaz_save_command(dev, cmd, cmd_size, sequence);
1340 +               if (ret)
1341 +                       DRM_ERROR("TOPAZ: save command failed\n");
1342 +       }
1343 +
1344 +       return ret;
1345 +}
1346 +
1347 +static int lnc_topaz_save_command(struct drm_device *dev, void *cmd,
1348 +                       unsigned long cmd_size, uint32_t sequence)
1349 +{
1350 +       struct drm_psb_private *dev_priv = dev->dev_private;
1351 +       struct lnc_topaz_cmd_queue *topaz_cmd;
1352 +       unsigned long irq_flags;
1353 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1354 +
1355 +       PSB_DEBUG_GENERAL("TOPAZ: queue command,sequence: %08x..\n",
1356 +                       sequence);
1357 +
1358 +       topaz_cmd = kzalloc(sizeof(struct lnc_topaz_cmd_queue),
1359 +                       GFP_KERNEL);
1360 +       if (topaz_cmd == NULL) {
1361 +               mutex_unlock(&topaz_priv->topaz_mutex);
1362 +               DRM_ERROR("TOPAZ: out of memory....\n");
1363 +               return -ENOMEM;
1364 +       }
1365 +
1366 +       topaz_cmd->cmd = cmd;
1367 +       topaz_cmd->cmd_size = cmd_size;
1368 +       topaz_cmd->sequence = sequence;
1369 +
1370 +       spin_lock_irqsave(&topaz_priv->topaz_lock, irq_flags);
1371 +       list_add_tail(&topaz_cmd->head, &topaz_priv->topaz_queue);
1372 +       if (!topaz_priv->topaz_busy) {
1373 +               /* topaz_priv->topaz_busy = 1; */
1374 +               PSB_DEBUG_GENERAL("TOPAZ: need immediate dequeue...\n");
1375 +               lnc_topaz_dequeue_send(dev);
1376 +               PSB_DEBUG_GENERAL("TOPAZ: after dequeue command\n");
1377 +       }
1378 +
1379 +       spin_unlock_irqrestore(&topaz_priv->topaz_lock, irq_flags);
1380 +
1381 +       return 0;
1382 +}
1383 +
1384 +
1385 +int lnc_cmdbuf_video(struct drm_file *priv,
1386 +               struct list_head *validate_list,
1387 +               uint32_t fence_type,
1388 +               struct drm_psb_cmdbuf_arg *arg,
1389 +               struct ttm_buffer_object *cmd_buffer,
1390 +               struct psb_ttm_fence_rep *fence_arg)
1391 +{
1392 +       struct drm_device *dev = priv->minor->dev;
1393 +       struct ttm_fence_object *fence = NULL;
1394 +       int ret;
1395 +
1396 +       ret = lnc_submit_encode_cmdbuf(dev, cmd_buffer, arg->cmdbuf_offset,
1397 +                                     arg->cmdbuf_size, fence);
1398 +       if (ret)
1399 +               return ret;
1400 +
1401 +       /* workaround for interrupt issue */
1402 +       psb_fence_or_sync(priv, LNC_ENGINE_ENCODE, fence_type, arg->fence_flags,
1403 +                         validate_list, fence_arg, &fence);
1404 +
1405 +       if (fence)
1406 +               ttm_fence_object_unref(&fence);
1407 +
1408 +       mutex_lock(&cmd_buffer->mutex);
1409 +       if (cmd_buffer->sync_obj != NULL)
1410 +               ttm_fence_sync_obj_unref(&cmd_buffer->sync_obj);
1411 +       mutex_unlock(&cmd_buffer->mutex);
1412 +
1413 +       return 0;
1414 +}
1415 +
1416 +static int lnc_topaz_sync(struct drm_device *dev, uint32_t sync_seq)
1417 +{
1418 +       struct drm_psb_private *dev_priv = dev->dev_private;
1419 +       uint32_t sync_cmd[3];
1420 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1421 +
1422 +#if 0
1423 +       struct ttm_fence_device *fdev = &dev_priv->fdev;
1424 +       struct ttm_fence_class_manager *fc =
1425 +           &fdev->fence_class[LNC_ENGINE_ENCODE];
1426 +       unsigned long irq_flags;
1427 +#endif
1428 +#if LNC_TOPAZ_NO_IRQ
1429 +       uint32_t *sync_p = (uint32_t *)topaz_priv->topaz_sync_addr;
1430 +       int count = 10000;
1431 +       uint32_t cur_seq;
1432 +#endif
1433 +
1434 +       /* insert a SYNC command here */
1435 +       topaz_priv->topaz_sync_cmd_seq = (1 << 15) |
1436 +               topaz_priv->topaz_cmd_seq++;
1437 +       sync_cmd[0] = 1 | (MTX_CMDID_SYNC << 1) | (3 << 8) |
1438 +               (topaz_priv->topaz_sync_cmd_seq << 16);
1439 +       sync_cmd[1] = topaz_priv->topaz_sync_offset;
1440 +       sync_cmd[2] = sync_seq;
1441 +
1442 +       PSB_DEBUG_GENERAL("TOPAZ:MTX_CMDID_SYNC: size(3),cmd seq (0x%04x),"
1443 +                       "sync_seq (0x%08x)\n",
1444 +                       topaz_priv->topaz_sync_cmd_seq, sync_seq);
1445 +
1446 +       if (drm_topaz_sbuswa)
1447 +               TOPAZ_WAIT_UNTIL_IDLE;
1448 +
1449 +       lnc_mtx_send(dev_priv, sync_cmd);
1450 +
1451 +#if LNC_TOPAZ_NO_IRQ /* workaround for interrupt issue */
1452 +       /* # poll topaz register for certain times */
1453 +       while (count && *sync_p != sync_seq) {
1454 +               DRM_UDELAY(100);
1455 +               --count;
1456 +       }
1457 +       if ((count == 0) && (*sync_p != sync_seq)) {
1458 +               DRM_ERROR("TOPAZ: wait sycn timeout (0x%08x),actual 0x%08x\n",
1459 +                       sync_seq, *sync_p);
1460 +               return -EBUSY;
1461 +       }
1462 +       PSB_DEBUG_GENERAL("TOPAZ: SYNC done, seq=0x%08x\n", *sync_p);
1463 +
1464 +       topaz_priv->topaz_busy = 0;
1465 +
1466 +       /* XXX: check psb_fence_handler is suitable for topaz */
1467 +       cur_seq = *sync_p;
1468 +#if 0
1469 +       write_lock_irqsave(&fc->lock, irq_flags);
1470 +       ttm_fence_handler(fdev, LNC_ENGINE_ENCODE,
1471 +                       cur_seq,
1472 +                       _PSB_FENCE_TYPE_EXE, 0);
1473 +       write_unlock_irqrestore(&fc->lock, irq_flags);
1474 +#endif
1475 +#endif
1476 +       return 0;
1477 +}
1478 +
1479 +int
1480 +lnc_topaz_deliver_command(struct drm_device *dev,
1481 +                         struct ttm_buffer_object *cmd_buffer,
1482 +                         unsigned long cmd_offset, unsigned long cmd_size,
1483 +                         void **topaz_cmd, uint32_t sequence,
1484 +                         int copy_cmd)
1485 +{
1486 +       unsigned long cmd_page_offset = cmd_offset & ~PAGE_MASK;
1487 +       struct ttm_bo_kmap_obj cmd_kmap;
1488 +       bool is_iomem;
1489 +       int ret;
1490 +       unsigned char *cmd_start, *tmp;
1491 +
1492 +       ret = ttm_bo_kmap(cmd_buffer, cmd_offset >> PAGE_SHIFT, 2,
1493 +                       &cmd_kmap);
1494 +       if (ret) {
1495 +               DRM_ERROR("TOPAZ: drm_bo_kmap failed: %d\n", ret);
1496 +               return ret;
1497 +       }
1498 +       cmd_start = (unsigned char *) ttm_kmap_obj_virtual(&cmd_kmap,
1499 +                                       &is_iomem) + cmd_page_offset;
1500 +
1501 +       if (copy_cmd) {
1502 +               PSB_DEBUG_GENERAL("TOPAZ: queue commands\n");
1503 +               tmp = kzalloc(cmd_size, GFP_KERNEL);
1504 +               if (tmp == NULL) {
1505 +                       ret = -ENOMEM;
1506 +                       goto out;
1507 +               }
1508 +               memcpy(tmp, cmd_start, cmd_size);
1509 +               *topaz_cmd = tmp;
1510 +       } else {
1511 +               PSB_DEBUG_GENERAL("TOPAZ: directly send the command\n");
1512 +               ret = lnc_topaz_send(dev, cmd_start, cmd_size, sequence);
1513 +               if (ret) {
1514 +                       DRM_ERROR("TOPAZ: commit commands failed.\n");
1515 +                       ret = -EINVAL;
1516 +               }
1517 +       }
1518 +
1519 +out:
1520 +       PSB_DEBUG_GENERAL("TOPAZ:cmd_size(%ld), sequence(%d) copy_cmd(%d)\n",
1521 +                       cmd_size, sequence, copy_cmd);
1522 +
1523 +       ttm_bo_kunmap(&cmd_kmap);
1524 +
1525 +       return ret;
1526 +}
1527 +
1528 +int
1529 +lnc_topaz_send(struct drm_device *dev, void *cmd,
1530 +       unsigned long cmd_size, uint32_t sync_seq)
1531 +{
1532 +       struct drm_psb_private *dev_priv = dev->dev_private;
1533 +       int ret = 0;
1534 +       unsigned char *command = (unsigned char *) cmd;
1535 +       struct topaz_cmd_header *cur_cmd_header;
1536 +       uint32_t cur_cmd_size, cur_cmd_id;
1537 +       uint32_t codec;
1538 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1539 +
1540 +       PSB_DEBUG_GENERAL("TOPAZ: send the command in the buffer one by one\n");
1541 +
1542 +       while (cmd_size > 0) {
1543 +               cur_cmd_header = (struct topaz_cmd_header *) command;
1544 +               cur_cmd_size = cur_cmd_header->size * 4;
1545 +               cur_cmd_id = cur_cmd_header->id;
1546 +
1547 +               switch (cur_cmd_id) {
1548 +               case MTX_CMDID_SW_NEW_CODEC:
1549 +                       codec = *((uint32_t *) cmd + 1);
1550 +
1551 +                       PSB_DEBUG_GENERAL("TOPAZ: setup new codec %s (%d)\n",
1552 +                                       codec_to_string(codec), codec);
1553 +                       if (topaz_setup_fw(dev, codec)) {
1554 +                               DRM_ERROR("TOPAZ: upload FW to HW failed\n");
1555 +                               return -EBUSY;
1556 +                       }
1557 +
1558 +                       topaz_priv->topaz_cur_codec = codec;
1559 +                       break;
1560 +
1561 +               case MTX_CMDID_SW_ENTER_LOWPOWER:
1562 +                       PSB_DEBUG_GENERAL("TOPAZ: enter lowpower.... \n");
1563 +                       PSB_DEBUG_GENERAL("XXX: implement it\n");
1564 +                       break;
1565 +
1566 +               case MTX_CMDID_SW_LEAVE_LOWPOWER:
1567 +                       PSB_DEBUG_GENERAL("TOPAZ: leave lowpower... \n");
1568 +                       PSB_DEBUG_GENERAL("XXX: implement it\n");
1569 +                       break;
1570 +
1571 +                       /* ordinary commmand */
1572 +               case MTX_CMDID_START_PIC:
1573 +                       /* XXX: specially handle START_PIC hw command */
1574 +                       CCB_CTRL_SET_QP(dev_priv,
1575 +                                       *(command + cur_cmd_size - 4));
1576 +                       /* strip the QP parameter (it's software arg) */
1577 +                       cur_cmd_header->size--;
1578 +               default:
1579 +                       cur_cmd_header->seq = 0x7fff &
1580 +                               topaz_priv->topaz_cmd_seq++;
1581 +
1582 +                       PSB_DEBUG_GENERAL("TOPAZ: %s: size(%d),"
1583 +                                       " seq (0x%04x)\n",
1584 +                                       cmd_to_string(cur_cmd_id),
1585 +                                       cur_cmd_size, cur_cmd_header->seq);
1586 +
1587 +                       if (drm_topaz_sbuswa && cur_cmd_id != \
1588 +                           MTX_CMDID_START_PIC)
1589 +                               TOPAZ_WAIT_UNTIL_IDLE;
1590 +
1591 +                       ret = lnc_mtx_send(dev_priv, command);
1592 +                       if (ret) {
1593 +                               DRM_ERROR("TOPAZ: error -- ret(%d)\n", ret);
1594 +                               goto out;
1595 +                       }
1596 +                       break;
1597 +               }
1598 +
1599 +               command += cur_cmd_size;
1600 +               cmd_size -= cur_cmd_size;
1601 +       }
1602 +       lnc_topaz_sync(dev, sync_seq);
1603 +out:
1604 +       return ret;
1605 +}
1606 +
1607 +static int lnc_mtx_send(struct drm_psb_private *dev_priv, const void *cmd)
1608 +{
1609 +       struct topaz_cmd_header *cur_cmd_header =
1610 +               (struct topaz_cmd_header *) cmd;
1611 +       uint32_t cmd_size = cur_cmd_header->size;
1612 +       uint32_t read_index, write_index;
1613 +       const uint32_t *cmd_pointer = (uint32_t *) cmd;
1614 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1615 +
1616 +       int ret = 0;
1617 +
1618 +       /* <msvdx does> # enable all clock */
1619 +
1620 +       write_index = topaz_priv->topaz_cmd_windex;
1621 +       if (write_index + cmd_size + 1 > topaz_priv->topaz_ccb_size) {
1622 +               int free_space = topaz_priv->topaz_ccb_size - write_index;
1623 +
1624 +               PSB_DEBUG_GENERAL("TOPAZ: -------will wrap CCB write point.\n");
1625 +               if (free_space > 0) {
1626 +                       struct topaz_cmd_header pad_cmd;
1627 +
1628 +                       pad_cmd.id = MTX_CMDID_NULL;
1629 +                       pad_cmd.size = free_space;
1630 +                       pad_cmd.seq = 0x7fff & topaz_priv->topaz_cmd_seq;
1631 +
1632 +                       PSB_DEBUG_GENERAL("TOPAZ: MTX_CMDID_NULL:"
1633 +                                       " size(%d),seq (0x%04x)\n",
1634 +                                       pad_cmd.size, pad_cmd.seq);
1635 +
1636 +#ifndef TOPAZ_RM_MULTI_MTX_WRITE
1637 +                       TOPAZ_BEGIN_CCB(dev_priv);
1638 +                       TOPAZ_OUT_CCB(dev_priv, pad_cmd.val);
1639 +#else
1640 +                       topaz_write_mtx_mem(dev_priv,
1641 +                               topaz_priv->topaz_ccb_buffer_addr
1642 +                               + topaz_priv->topaz_cmd_windex * 4,
1643 +                               pad_cmd.val);
1644 +                       topaz_priv->topaz_cmd_windex++;
1645 +#endif
1646 +                       TOPAZ_END_CCB(dev_priv, 1);
1647 +
1648 +                       POLL_WB_SEQ(dev_priv, pad_cmd.seq);
1649 +                       ++topaz_priv->topaz_cmd_seq;
1650 +               }
1651 +               POLL_WB_RINDEX(dev_priv, 0);
1652 +               if (ret == 0)
1653 +                       topaz_priv->topaz_cmd_windex = 0;
1654 +               else {
1655 +                       DRM_ERROR("TOPAZ: poll rindex timeout\n");
1656 +                       return ret; /* HW may hang, need reset */
1657 +               }
1658 +               PSB_DEBUG_GENERAL("TOPAZ: -------wrap CCB was done.\n");
1659 +       }
1660 +
1661 +       read_index = CCB_CTRL_RINDEX(dev_priv);/* temperily use CCB CTRL */
1662 +       write_index = topaz_priv->topaz_cmd_windex;
1663 +
1664 +       PSB_DEBUG_GENERAL("TOPAZ: write index(%d), read index(%d,WB=%d)\n",
1665 +                       write_index, read_index, WB_CCB_CTRL_RINDEX(dev_priv));
1666 +
1667 +#ifndef TOPAZ_RM_MULTI_MTX_WRITE
1668 +       TOPAZ_BEGIN_CCB(dev_priv);
1669 +       while (cmd_size > 0) {
1670 +               TOPAZ_OUT_CCB(dev_priv, *cmd_pointer++);
1671 +               --cmd_size;
1672 +       }
1673 +#else
1674 +       while (cmd_size > 0) {
1675 +               topaz_write_mtx_mem(
1676 +                   dev_priv,
1677 +                   topaz_priv->topaz_ccb_buffer_addr
1678 +                   + topaz_priv->topaz_cmd_windex * 4,
1679 +                   *cmd_pointer++);
1680 +               topaz_priv->topaz_cmd_windex++;
1681 +               --cmd_size;
1682 +       }
1683 +#endif
1684 +       TOPAZ_END_CCB(dev_priv, 1);
1685 +
1686 +#if 0
1687 +       DRM_UDELAY(1000);
1688 +       lnc_topaz_clearirq(dev,
1689 +                       lnc_topaz_queryirq(dev));
1690 +       LNC_TRACEL("TOPAZ: after clear, query again\n");
1691 +       lnc_topaz_queryirq(dev_priv);
1692 +#endif
1693 +
1694 +       return ret;
1695 +}
1696 +
1697 +int lnc_topaz_dequeue_send(struct drm_device *dev)
1698 +{
1699 +       struct drm_psb_private *dev_priv = dev->dev_private;
1700 +       struct lnc_topaz_cmd_queue *topaz_cmd = NULL;
1701 +       int ret;
1702 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1703 +
1704 +       PSB_DEBUG_GENERAL("TOPAZ: dequeue command and send it to topaz\n");
1705 +
1706 +       if (list_empty(&topaz_priv->topaz_queue)) {
1707 +               topaz_priv->topaz_busy = 0;
1708 +               return 0;
1709 +       }
1710 +
1711 +       topaz_cmd = list_first_entry(&topaz_priv->topaz_queue,
1712 +                               struct lnc_topaz_cmd_queue, head);
1713 +
1714 +       PSB_DEBUG_GENERAL("TOPAZ: queue has id %08x\n", topaz_cmd->sequence);
1715 +       ret = lnc_topaz_send(dev, topaz_cmd->cmd, topaz_cmd->cmd_size,
1716 +                       topaz_cmd->sequence);
1717 +       if (ret) {
1718 +               DRM_ERROR("TOPAZ: lnc_topaz_send failed.\n");
1719 +               ret = -EINVAL;
1720 +       }
1721 +
1722 +       list_del(&topaz_cmd->head);
1723 +       kfree(topaz_cmd->cmd);
1724 +       kfree(topaz_cmd
1725 +                );
1726 +
1727 +       return ret;
1728 +}
1729 +
1730 +void topaz_mtx_kick(struct drm_psb_private *dev_priv, uint32_t kick_count)
1731 +{
1732 +       PSB_DEBUG_GENERAL("TOPAZ: kick mtx count(%d).\n", kick_count);
1733 +       MTX_WRITE32(MTX_CR_MTX_KICK, kick_count);
1734 +}
1735 +
1736 +int lnc_check_topaz_idle(struct drm_device *dev)
1737 +{
1738 +       struct drm_psb_private *dev_priv =
1739 +               (struct drm_psb_private *)dev->dev_private;
1740 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1741 +
1742 +       if (topaz_priv->topaz_fw_loaded == 0)
1743 +               return 0;
1744 +
1745 +       if (topaz_priv->topaz_busy)
1746 +               return -EBUSY;
1747 +
1748 +       if (topaz_priv->topaz_hw_busy) {
1749 +               PSB_DEBUG_PM("TOPAZ: %s, HW is busy\n", __func__);
1750 +               return -EBUSY;
1751 +       }
1752 +
1753 +       return 0; /* we think it is idle */
1754 +}
1755 +
1756 +int lnc_video_frameskip(struct drm_device *dev, uint64_t user_pointer)
1757 +{
1758 +       struct drm_psb_private *dev_priv =
1759 +               (struct drm_psb_private *)dev->dev_private;
1760 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1761 +       int ret;
1762 +
1763 +       ret = copy_to_user((void __user *) ((unsigned long)user_pointer),
1764 +               &topaz_priv->frame_skip, sizeof(topaz_priv->frame_skip));
1765 +
1766 +       if (ret)
1767 +               return -EFAULT;
1768 +
1769 +       return 0;
1770 +}
1771 +
1772 +static void lnc_topaz_flush_cmd_queue(struct topaz_private *topaz_priv)
1773 +{
1774 +       struct lnc_topaz_cmd_queue *entry, *next;
1775 +
1776 +       /* remind to reset topaz */
1777 +       topaz_priv->topaz_needs_reset = 1;
1778 +
1779 +       if (list_empty(&topaz_priv->topaz_queue)) {
1780 +               topaz_priv->topaz_busy = 0;
1781 +               return;
1782 +       }
1783 +
1784 +       /* flush all command in queue */
1785 +       list_for_each_entry_safe(entry, next,
1786 +                                &topaz_priv->topaz_queue,
1787 +                                head) {
1788 +               list_del(&entry->head);
1789 +               kfree(entry->cmd);
1790 +               kfree(entry);
1791 +       }
1792 +
1793 +       return;
1794 +}
1795 +
1796 +void lnc_topaz_handle_timeout(struct ttm_fence_device *fdev)
1797 +{
1798 +       struct drm_psb_private *dev_priv =
1799 +               container_of(fdev, struct drm_psb_private, fdev);
1800 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
1801 +
1802 +       lnc_topaz_flush_cmd_queue(topaz_priv);
1803 +}
1804 +
1805 +inline int psb_try_power_down_topaz(struct drm_device *dev)
1806 +{
1807 +       ospm_apm_power_down_topaz(dev);
1808 +       return 0;
1809 +}
1810 +
1811 +void lnc_map_topaz_reg(struct drm_device *dev)
1812 +{
1813 +       unsigned long resource_start;
1814 +       struct drm_psb_private *dev_priv =
1815 +               (struct drm_psb_private *)dev->dev_private;
1816 +
1817 +       resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
1818 +
1819 +       if (IS_MRST(dev) && !dev_priv->topaz_disabled) {
1820 +               dev_priv->topaz_reg =
1821 +                   ioremap(resource_start + LNC_TOPAZ_OFFSET,
1822 +                           LNC_TOPAZ_SIZE);
1823 +               if (!dev_priv->topaz_reg)
1824 +                       DRM_ERROR("failed to map TOPAZ register address\n");
1825 +       }
1826 +
1827 +       return;
1828 +}
1829 +
1830 +void lnc_unmap_topaz_reg(struct drm_device *dev)
1831 +{
1832 +       struct drm_psb_private *dev_priv =
1833 +               (struct drm_psb_private *)dev->dev_private;
1834 +
1835 +       if (IS_MRST(dev)) {
1836 +               if (dev_priv->topaz_reg) {
1837 +                       iounmap(dev_priv->topaz_reg);
1838 +                       dev_priv->topaz_reg = NULL;
1839 +               }
1840 +       }
1841 +
1842 +       return;
1843 +}
1844 diff --git a/drivers/gpu/drm/mrst/drv/lnc_topaz.h b/drivers/gpu/drm/mrst/drv/lnc_topaz.h
1845 new file mode 100644
1846 index 0000000..7511c32
1847 --- /dev/null
1848 +++ b/drivers/gpu/drm/mrst/drv/lnc_topaz.h
1849 @@ -0,0 +1,925 @@
1850 +/**************************************************************************
1851 + *
1852 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
1853 + * Copyright (c) Imagination Technologies Limited, UK
1854 + *
1855 + * This program is free software; you can redistribute it and/or modify it
1856 + * under the terms and conditions of the GNU General Public License,
1857 + * version 2, as published by the Free Software Foundation.
1858 + *
1859 + * This program is distributed in the hope it will be useful, but WITHOUT
1860 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1861 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1862 + * more details.
1863 + *
1864 + * You should have received a copy of the GNU General Public License along with
1865 + * this program; if not, write to the Free Software Foundation, Inc., 
1866 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1867 + *
1868 + **************************************************************************/
1869 +
1870 +#ifndef _LNC_TOPAZ_H_
1871 +#define _LNC_TOPAZ_H_
1872 +
1873 +#include "psb_drv.h"
1874 +#include "img_types.h"
1875 +
1876 +#define LNC_TOPAZ_NO_IRQ 0
1877 +#define TOPAZ_MTX_REG_SIZE (34 * 4 + 183 * 4)
1878 +
1879 +extern int drm_topaz_pmpolicy;
1880 +
1881 +/*
1882 + * MACROS to insert values into fields within a word. The basename of the
1883 + * field must have MASK_BASENAME and SHIFT_BASENAME constants.
1884 + */
1885 +#define MM_WRITE32(base, offset, value)  \
1886 +do {                                  \
1887 +       *((unsigned long *)((unsigned char *)(dev_priv->topaz_reg)      \
1888 +                               + base + offset)) = value;              \
1889 +} while (0)
1890 +
1891 +#define MM_READ32(base, offset, pointer) \
1892 +do {                                   \
1893 +       *(pointer) = *((unsigned long *)((unsigned char *)(dev_priv->topaz_reg)\
1894 +                                               + base + offset));      \
1895 +} while (0)
1896 +
1897 +#define F_MASK(basename)  (MASK_##basename)
1898 +#define F_SHIFT(basename) (SHIFT_##basename)
1899 +
1900 +#define F_ENCODE(val, basename)  \
1901 +       (((val) << (F_SHIFT(basename))) & (F_MASK(basename)))
1902 +
1903 +/* MVEA macro */
1904 +#define MVEA_START 0x03000
1905 +
1906 +#define MVEA_WRITE32(offset, value) MM_WRITE32(MVEA_START, offset, value)
1907 +#define MVEA_READ32(offset, pointer) MM_READ32(MVEA_START, offset, pointer);
1908 +
1909 +#define F_MASK_MVEA(basename)  (MASK_MVEA_##basename)  /*     MVEA    */
1910 +#define F_SHIFT_MVEA(basename) (SHIFT_MVEA_##basename) /*     MVEA    */
1911 +#define F_ENCODE_MVEA(val, basename)  \
1912 +       (((val)<<(F_SHIFT_MVEA(basename)))&(F_MASK_MVEA(basename)))
1913 +
1914 +/* VLC macro */
1915 +#define TOPAZ_VLC_START 0x05000
1916 +
1917 +/* TOPAZ macro */
1918 +#define TOPAZ_START 0x02000
1919 +
1920 +#define TOPAZ_WRITE32(offset, value) MM_WRITE32(TOPAZ_START, offset, value)
1921 +#define TOPAZ_READ32(offset, pointer) MM_READ32(TOPAZ_START, offset, pointer)
1922 +
1923 +#define F_MASK_TOPAZ(basename)  (MASK_TOPAZ_##basename)
1924 +#define F_SHIFT_TOPAZ(basename) (SHIFT_TOPAZ_##basename)
1925 +#define F_ENCODE_TOPAZ(val, basename) \
1926 +       (((val)<<(F_SHIFT_TOPAZ(basename)))&(F_MASK_TOPAZ(basename)))
1927 +
1928 +/* MTX macro */
1929 +#define MTX_START 0x0
1930 +
1931 +#define MTX_WRITE32(offset, value) MM_WRITE32(MTX_START, offset, value)
1932 +#define MTX_READ32(offset, pointer) MM_READ32(MTX_START, offset, pointer)
1933 +
1934 +/* DMAC macro */
1935 +#define DMAC_START 0x0f000
1936 +
1937 +#define DMAC_WRITE32(offset, value) MM_WRITE32(DMAC_START, offset, value)
1938 +#define DMAC_READ32(offset, pointer) MM_READ32(DMAC_START, offset, pointer)
1939 +
1940 +#define F_MASK_DMAC(basename)  (MASK_DMAC_##basename)
1941 +#define F_SHIFT_DMAC(basename) (SHIFT_DMAC_##basename)
1942 +#define F_ENCODE_DMAC(val, basename)  \
1943 +       (((val)<<(F_SHIFT_DMAC(basename)))&(F_MASK_DMAC(basename)))
1944 +
1945 +
1946 +/* Register CR_IMG_TOPAZ_INTENAB */
1947 +#define TOPAZ_CR_IMG_TOPAZ_INTENAB  0x0008
1948 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTEN_MVEA 0x00000001
1949 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTEN_MVEA 0
1950 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTEN_MVEA 0x0008
1951 +
1952 +#define MASK_TOPAZ_CR_IMG_TOPAZ_MAS_INTEN 0x80000000
1953 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_MAS_INTEN 31
1954 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_MAS_INTEN 0x0008
1955 +
1956 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTEN_MMU_FAULT 0x00000008
1957 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTEN_MMU_FAULT 3
1958 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTEN_MMU_FAULT 0x0008
1959 +
1960 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX 0x00000002
1961 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX 1
1962 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX 0x0008
1963 +
1964 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX_HALT 0x00000004
1965 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX_HALT 2
1966 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTEN_MTX_HALT 0x0008
1967 +
1968 +#define TOPAZ_CR_IMG_TOPAZ_INTCLEAR 0x000C
1969 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTCLR_MVEA 0x00000001
1970 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTCLR_MVEA 0
1971 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTCLR_MVEA 0x000C
1972 +
1973 +#define TOPAZ_CR_IMG_TOPAZ_INTSTAT  0x0004
1974 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTS_MVEA 0x00000001
1975 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTS_MVEA 0
1976 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTS_MVEA 0x0004
1977 +
1978 +#define MTX_CCBCTRL_ROFF               0
1979 +#define MTX_CCBCTRL_COMPLETE           4
1980 +#define MTX_CCBCTRL_CCBSIZE            8
1981 +#define MTX_CCBCTRL_QP                 12
1982 +#define MTX_CCBCTRL_FRAMESKIP          20
1983 +#define MTX_CCBCTRL_INITQP             24
1984 +
1985 +#define TOPAZ_CR_MMU_STATUS         0x001C
1986 +#define MASK_TOPAZ_CR_MMU_PF_N_RW   0x00000001
1987 +#define SHIFT_TOPAZ_CR_MMU_PF_N_RW  0
1988 +#define REGNUM_TOPAZ_CR_MMU_PF_N_RW 0x001C
1989 +
1990 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTCLR_MMU_FAULT 0x00000008
1991 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTCLR_MMU_FAULT 3
1992 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTCLR_MMU_FAULT 0x000C
1993 +
1994 +#define TOPAZ_CR_MMU_MEM_REQ        0x0020
1995 +#define MASK_TOPAZ_CR_MEM_REQ_STAT_READS 0x000000FF
1996 +#define SHIFT_TOPAZ_CR_MEM_REQ_STAT_READS 0
1997 +#define REGNUM_TOPAZ_CR_MEM_REQ_STAT_READS 0x0020
1998 +
1999 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX 0x00000002
2000 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX 1
2001 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX 0x000C
2002 +
2003 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX_HALT 0x00000004
2004 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX_HALT 2
2005 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX_HALT 0x000C
2006 +
2007 +#define MTX_CR_MTX_KICK             0x0080
2008 +#define MASK_MTX_MTX_KICK           0x0000FFFF
2009 +#define SHIFT_MTX_MTX_KICK          0
2010 +#define REGNUM_MTX_MTX_KICK         0x0080
2011 +
2012 +#define MTX_DATA_MEM_BASE              0x82880000
2013 +
2014 +#define MTX_CR_MTX_RAM_ACCESS_CONTROL 0x0108
2015 +#define MASK_MTX_MTX_MCMR           0x00000001
2016 +#define SHIFT_MTX_MTX_MCMR          0
2017 +#define REGNUM_MTX_MTX_MCMR         0x0108
2018 +
2019 +#define MASK_MTX_MTX_MCMID          0x0FF00000
2020 +#define SHIFT_MTX_MTX_MCMID         20
2021 +#define REGNUM_MTX_MTX_MCMID        0x0108
2022 +
2023 +#define MASK_MTX_MTX_MCM_ADDR       0x000FFFFC
2024 +#define SHIFT_MTX_MTX_MCM_ADDR      2
2025 +#define REGNUM_MTX_MTX_MCM_ADDR     0x0108
2026 +
2027 +#define MTX_CR_MTX_RAM_ACCESS_STATUS 0x010C
2028 +#define MASK_MTX_MTX_MTX_MCM_STAT   0x00000001
2029 +#define SHIFT_MTX_MTX_MTX_MCM_STAT  0
2030 +#define REGNUM_MTX_MTX_MTX_MCM_STAT 0x010C
2031 +
2032 +#define MASK_MTX_MTX_MCMAI          0x00000002
2033 +#define SHIFT_MTX_MTX_MCMAI         1
2034 +#define REGNUM_MTX_MTX_MCMAI        0x0108
2035 +
2036 +#define MTX_CR_MTX_RAM_ACCESS_DATA_TRANSFER 0x0104
2037 +
2038 +#define MVEA_CR_MVEA_BUSY           0x0018
2039 +#define MVEA_CR_MVEA_DMACMDFIFO_WAIT 0x001C
2040 +#define MVEA_CR_MVEA_DMACMDFIFO_STATUS 0x0020
2041 +
2042 +#define MVEA_CR_IMG_MVEA_SRST       0x0000
2043 +#define MASK_MVEA_CR_IMG_MVEA_SPE_SOFT_RESET 0x00000001
2044 +#define SHIFT_MVEA_CR_IMG_MVEA_SPE_SOFT_RESET 0
2045 +#define REGNUM_MVEA_CR_IMG_MVEA_SPE_SOFT_RESET 0x0000
2046 +
2047 +#define MASK_MVEA_CR_IMG_MVEA_IPE_SOFT_RESET 0x00000002
2048 +#define SHIFT_MVEA_CR_IMG_MVEA_IPE_SOFT_RESET 1
2049 +#define REGNUM_MVEA_CR_IMG_MVEA_IPE_SOFT_RESET 0x0000
2050 +
2051 +#define MASK_MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET 0x00000004
2052 +#define SHIFT_MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET 2
2053 +#define REGNUM_MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET 0x0000
2054 +
2055 +#define MASK_MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET 0x00000008
2056 +#define SHIFT_MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET 3
2057 +#define REGNUM_MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET 0x0000
2058 +
2059 +#define MASK_MVEA_CR_IMG_MVEA_CMC_SOFT_RESET 0x00000010
2060 +#define SHIFT_MVEA_CR_IMG_MVEA_CMC_SOFT_RESET 4
2061 +#define REGNUM_MVEA_CR_IMG_MVEA_CMC_SOFT_RESET 0x0000
2062 +
2063 +#define MASK_MVEA_CR_IMG_MVEA_DCF_SOFT_RESET 0x00000020
2064 +#define SHIFT_MVEA_CR_IMG_MVEA_DCF_SOFT_RESET 5
2065 +#define REGNUM_MVEA_CR_IMG_MVEA_DCF_SOFT_RESET 0x0000
2066 +
2067 +#define TOPAZ_CR_IMG_TOPAZ_CORE_ID  0x03C0
2068 +#define TOPAZ_CR_IMG_TOPAZ_CORE_REV 0x03D0
2069 +
2070 +#define TOPAZ_MTX_PC           (0x00000005)
2071 +#define PC_START_ADDRESS       (0x80900000)
2072 +
2073 +#define TOPAZ_CR_TOPAZ_AUTO_CLK_GATE 0x0014
2074 +#define MASK_TOPAZ_CR_TOPAZ_VLC_AUTO_CLK_GATE 0x00000001
2075 +#define SHIFT_TOPAZ_CR_TOPAZ_VLC_AUTO_CLK_GATE 0
2076 +#define REGNUM_TOPAZ_CR_TOPAZ_VLC_AUTO_CLK_GATE 0x0014
2077 +
2078 +#define MASK_TOPAZ_CR_TOPAZ_DB_AUTO_CLK_GATE 0x00000002
2079 +#define SHIFT_TOPAZ_CR_TOPAZ_DB_AUTO_CLK_GATE 1
2080 +#define REGNUM_TOPAZ_CR_TOPAZ_DB_AUTO_CLK_GATE 0x0014
2081 +
2082 +#define MASK_TOPAZ_CR_TOPAZ_MTX_MAN_CLK_GATE 0x00000002
2083 +#define SHIFT_TOPAZ_CR_TOPAZ_MTX_MAN_CLK_GATE 1
2084 +#define REGNUM_TOPAZ_CR_TOPAZ_MTX_MAN_CLK_GATE 0x0010
2085 +
2086 +#define        MTX_CORE_CR_MTX_REGISTER_READ_WRITE_DATA_OFFSET 0x000000F8
2087 +#define        MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_OFFSET 0x000000FC
2088 +#define        MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_MASK 0x00010000
2089 +#define        MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK 0x80000000
2090 +
2091 +#define        TOPAZ_CORE_CR_MTX_DEBUG_OFFSET  0x0000003C
2092 +
2093 +#define MASK_TOPAZ_CR_MTX_DBG_IS_SLAVE 0x00000004
2094 +#define SHIFT_TOPAZ_CR_MTX_DBG_IS_SLAVE 2
2095 +#define REGNUM_TOPAZ_CR_MTX_DBG_IS_SLAVE 0x003C
2096 +
2097 +#define MASK_TOPAZ_CR_MTX_DBG_GPIO_OUT 0x00000018
2098 +#define SHIFT_TOPAZ_CR_MTX_DBG_GPIO_OUT 3
2099 +#define REGNUM_TOPAZ_CR_MTX_DBG_GPIO_OUT 0x003C
2100 +
2101 +#define        MTX_CORE_CR_MTX_RAM_ACCESS_CONTROL_OFFSET 0x00000108
2102 +
2103 +#define TOPAZ_CR_MMU_CONTROL0       0x0024
2104 +#define MASK_TOPAZ_CR_MMU_BYPASS    0x00000800
2105 +#define SHIFT_TOPAZ_CR_MMU_BYPASS   11
2106 +#define REGNUM_TOPAZ_CR_MMU_BYPASS  0x0024
2107 +
2108 +#define TOPAZ_CR_MMU_DIR_LIST_BASE(X) (0x0030 + (4 * (X)))
2109 +#define MASK_TOPAZ_CR_MMU_DIR_LIST_BASE_ADDR 0xFFFFF000
2110 +#define SHIFT_TOPAZ_CR_MMU_DIR_LIST_BASE_ADDR 12
2111 +#define REGNUM_TOPAZ_CR_MMU_DIR_LIST_BASE_ADDR 0x0030
2112 +
2113 +#define MASK_TOPAZ_CR_MMU_INVALDC   0x00000008
2114 +#define SHIFT_TOPAZ_CR_MMU_INVALDC  3
2115 +#define REGNUM_TOPAZ_CR_MMU_INVALDC 0x0024
2116 +
2117 +#define MASK_TOPAZ_CR_MMU_FLUSH     0x00000004
2118 +#define SHIFT_TOPAZ_CR_MMU_FLUSH    2
2119 +#define REGNUM_TOPAZ_CR_MMU_FLUSH   0x0024
2120 +
2121 +#define TOPAZ_CR_MMU_BANK_INDEX     0x0038
2122 +#define MASK_TOPAZ_CR_MMU_BANK_N_INDEX_M(i) (0x00000003 << (8 + ((i) * 2)))
2123 +#define SHIFT_TOPAZ_CR_MMU_BANK_N_INDEX_M(i) (8 + ((i) * 2))
2124 +#define REGNUM_TOPAZ_CR_MMU_BANK_N_INDEX_M(i) 0x0038
2125 +
2126 +#define TOPAZ_CR_TOPAZ_MAN_CLK_GATE 0x0010
2127 +#define MASK_TOPAZ_CR_TOPAZ_MVEA_MAN_CLK_GATE 0x00000001
2128 +#define SHIFT_TOPAZ_CR_TOPAZ_MVEA_MAN_CLK_GATE 0
2129 +#define REGNUM_TOPAZ_CR_TOPAZ_MVEA_MAN_CLK_GATE 0x0010
2130 +
2131 +#define MTX_CORE_CR_MTX_TXRPT_OFFSET 0x0000000c
2132 +#define TXRPT_WAITONKICK_VALUE 0x8ade0000
2133 +
2134 +#define MTX_CORE_CR_MTX_ENABLE_MTX_TOFF_MASK 0x00000002
2135 +
2136 +#define MTX_CORE_CR_MTX_ENABLE_OFFSET 0x00000000
2137 +#define        MTX_CORE_CR_MTX_ENABLE_MTX_ENABLE_MASK 0x00000001
2138 +
2139 +#define MASK_TOPAZ_CR_IMG_TOPAZ_INTS_MTX 0x00000002
2140 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_INTS_MTX 1
2141 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_INTS_MTX 0x0004
2142 +
2143 +#define        MTX_CORE_CR_MTX_SOFT_RESET_OFFSET 0x00000200
2144 +#define        MTX_CORE_CR_MTX_SOFT_RESET_MTX_RESET_MASK 0x00000001
2145 +
2146 +#define MTX_CR_MTX_SYSC_CDMAA       0x0344
2147 +#define MASK_MTX_CDMAA_ADDRESS      0x03FFFFFC
2148 +#define SHIFT_MTX_CDMAA_ADDRESS     2
2149 +#define REGNUM_MTX_CDMAA_ADDRESS    0x0344
2150 +
2151 +#define MTX_CR_MTX_SYSC_CDMAC       0x0340
2152 +#define MASK_MTX_LENGTH             0x0000FFFF
2153 +#define SHIFT_MTX_LENGTH            0
2154 +#define REGNUM_MTX_LENGTH           0x0340
2155 +
2156 +#define MASK_MTX_BURSTSIZE          0x07000000
2157 +#define SHIFT_MTX_BURSTSIZE         24
2158 +#define REGNUM_MTX_BURSTSIZE        0x0340
2159 +
2160 +#define MASK_MTX_RNW                0x00020000
2161 +#define SHIFT_MTX_RNW               17
2162 +#define REGNUM_MTX_RNW              0x0340
2163 +
2164 +#define MASK_MTX_ENABLE             0x00010000
2165 +#define SHIFT_MTX_ENABLE            16
2166 +#define REGNUM_MTX_ENABLE           0x0340
2167 +
2168 +#define MASK_MTX_LENGTH             0x0000FFFF
2169 +#define SHIFT_MTX_LENGTH            0
2170 +#define REGNUM_MTX_LENGTH           0x0340
2171 +
2172 +#define TOPAZ_CR_IMG_TOPAZ_SRST     0x0000
2173 +#define MASK_TOPAZ_CR_IMG_TOPAZ_MVEA_SOFT_RESET 0x00000001
2174 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_MVEA_SOFT_RESET 0
2175 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_MVEA_SOFT_RESET 0x0000
2176 +
2177 +#define MASK_TOPAZ_CR_IMG_TOPAZ_VLC_SOFT_RESET 0x00000008
2178 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_VLC_SOFT_RESET 3
2179 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_VLC_SOFT_RESET 0x0000
2180 +
2181 +#define MASK_TOPAZ_CR_IMG_TOPAZ_MTX_SOFT_RESET 0x00000002
2182 +#define SHIFT_TOPAZ_CR_IMG_TOPAZ_MTX_SOFT_RESET 1
2183 +#define REGNUM_TOPAZ_CR_IMG_TOPAZ_MTX_SOFT_RESET 0x0000
2184 +
2185 +#define MVEA_CR_MVEA_AUTO_CLOCK_GATING 0x0024
2186 +#define MASK_MVEA_CR_MVEA_SPE_AUTO_CLK_GATE 0x00000001
2187 +#define SHIFT_MVEA_CR_MVEA_SPE_AUTO_CLK_GATE 0
2188 +#define REGNUM_MVEA_CR_MVEA_SPE_AUTO_CLK_GATE 0x0024
2189 +
2190 +#define MASK_MVEA_CR_MVEA_IPE_AUTO_CLK_GATE 0x00000002
2191 +#define SHIFT_MVEA_CR_MVEA_IPE_AUTO_CLK_GATE 1
2192 +#define REGNUM_MVEA_CR_MVEA_IPE_AUTO_CLK_GATE 0x0024
2193 +
2194 +#define MASK_MVEA_CR_MVEA_CMPRS_AUTO_CLK_GATE 0x00000004
2195 +#define SHIFT_MVEA_CR_MVEA_CMPRS_AUTO_CLK_GATE 2
2196 +#define REGNUM_MVEA_CR_MVEA_CMPRS_AUTO_CLK_GATE 0x0024
2197 +
2198 +#define MASK_MVEA_CR_MVEA_JMCOMP_AUTO_CLK_GATE 0x00000008
2199 +#define SHIFT_MVEA_CR_MVEA_JMCOMP_AUTO_CLK_GATE 3
2200 +#define REGNUM_MVEA_CR_MVEA_JMCOMP_AUTO_CLK_GATE 0x0024
2201 +
2202 +#define TOPAZ_CR_IMG_TOPAZ_DMAC_MODE 0x0040
2203 +#define MASK_TOPAZ_CR_DMAC_MASTER_MODE 0x00000001
2204 +#define SHIFT_TOPAZ_CR_DMAC_MASTER_MODE 0
2205 +#define REGNUM_TOPAZ_CR_DMAC_MASTER_MODE 0x0040
2206 +
2207 +#define MTX_CR_MTX_SYSC_CDMAT       0x0350
2208 +#define MASK_MTX_TRANSFERDATA       0xFFFFFFFF
2209 +#define SHIFT_MTX_TRANSFERDATA      0
2210 +#define REGNUM_MTX_TRANSFERDATA     0x0350
2211 +
2212 +#define IMG_SOC_DMAC_IRQ_STAT(X)    (0x000C + (32 * (X)))
2213 +#define MASK_IMG_SOC_TRANSFER_FIN   0x00020000
2214 +#define SHIFT_IMG_SOC_TRANSFER_FIN  17
2215 +#define REGNUM_IMG_SOC_TRANSFER_FIN 0x000C
2216 +
2217 +#define IMG_SOC_DMAC_COUNT(X)       (0x0004 + (32 * (X)))
2218 +#define MASK_IMG_SOC_CNT            0x0000FFFF
2219 +#define SHIFT_IMG_SOC_CNT           0
2220 +#define REGNUM_IMG_SOC_CNT          0x0004
2221 +
2222 +#define MASK_IMG_SOC_EN             0x00010000
2223 +#define SHIFT_IMG_SOC_EN            16
2224 +#define REGNUM_IMG_SOC_EN           0x0004
2225 +
2226 +#define MASK_IMG_SOC_LIST_EN        0x00040000
2227 +#define SHIFT_IMG_SOC_LIST_EN       18
2228 +#define REGNUM_IMG_SOC_LIST_EN      0x0004
2229 +
2230 +#define IMG_SOC_DMAC_PER_HOLD(X)    (0x0018 + (32 * (X)))
2231 +#define MASK_IMG_SOC_PER_HOLD       0x0000007F
2232 +#define SHIFT_IMG_SOC_PER_HOLD      0
2233 +#define REGNUM_IMG_SOC_PER_HOLD     0x0018
2234 +
2235 +#define IMG_SOC_DMAC_SETUP(X)       (0x0000 + (32 * (X)))
2236 +#define MASK_IMG_SOC_START_ADDRESS  0xFFFFFFF
2237 +#define SHIFT_IMG_SOC_START_ADDRESS 0
2238 +#define REGNUM_IMG_SOC_START_ADDRESS 0x0000
2239 +
2240 +#define MASK_IMG_SOC_BSWAP          0x40000000
2241 +#define SHIFT_IMG_SOC_BSWAP         30
2242 +#define REGNUM_IMG_SOC_BSWAP        0x0004
2243 +
2244 +#define MASK_IMG_SOC_PW             0x18000000
2245 +#define SHIFT_IMG_SOC_PW            27
2246 +#define REGNUM_IMG_SOC_PW           0x0004
2247 +
2248 +#define MASK_IMG_SOC_DIR            0x04000000
2249 +#define SHIFT_IMG_SOC_DIR           26
2250 +#define REGNUM_IMG_SOC_DIR          0x0004
2251 +
2252 +#define MASK_IMG_SOC_PI             0x03000000
2253 +#define SHIFT_IMG_SOC_PI            24
2254 +#define REGNUM_IMG_SOC_PI           0x0004
2255 +#define IMG_SOC_PI_1           0x00000002
2256 +#define IMG_SOC_PI_2           0x00000001
2257 +#define IMG_SOC_PI_4           0x00000000
2258 +
2259 +#define MASK_IMG_SOC_TRANSFER_IEN   0x20000000
2260 +#define SHIFT_IMG_SOC_TRANSFER_IEN  29
2261 +#define REGNUM_IMG_SOC_TRANSFER_IEN 0x0004
2262 +
2263 +#define DMAC_VALUE_COUNT(BSWAP, PW, DIR, PERIPH_INCR, COUNT)        \
2264 +       ((((BSWAP) << SHIFT_IMG_SOC_BSWAP) & MASK_IMG_SOC_BSWAP)|       \
2265 +               (((PW) << SHIFT_IMG_SOC_PW) & MASK_IMG_SOC_PW)|         \
2266 +               (((DIR) << SHIFT_IMG_SOC_DIR) & MASK_IMG_SOC_DIR)|      \
2267 +               (((PERIPH_INCR) << SHIFT_IMG_SOC_PI) & MASK_IMG_SOC_PI)| \
2268 +               (((COUNT) << SHIFT_IMG_SOC_CNT) & MASK_IMG_SOC_CNT))
2269 +
2270 +#define IMG_SOC_DMAC_PERIPH(X)      (0x0008 + (32 * (X)))
2271 +#define MASK_IMG_SOC_EXT_SA         0x0000000F
2272 +#define SHIFT_IMG_SOC_EXT_SA        0
2273 +#define REGNUM_IMG_SOC_EXT_SA       0x0008
2274 +
2275 +#define MASK_IMG_SOC_ACC_DEL        0xE0000000
2276 +#define SHIFT_IMG_SOC_ACC_DEL       29
2277 +#define REGNUM_IMG_SOC_ACC_DEL      0x0008
2278 +
2279 +#define MASK_IMG_SOC_INCR           0x08000000
2280 +#define SHIFT_IMG_SOC_INCR          27
2281 +#define REGNUM_IMG_SOC_INCR         0x0008
2282 +
2283 +#define MASK_IMG_SOC_BURST          0x07000000
2284 +#define SHIFT_IMG_SOC_BURST         24
2285 +#define REGNUM_IMG_SOC_BURST        0x0008
2286 +
2287 +#define DMAC_VALUE_PERIPH_PARAM(ACC_DEL, INCR, BURST)             \
2288 +((((ACC_DEL) << SHIFT_IMG_SOC_ACC_DEL) & MASK_IMG_SOC_ACC_DEL)|        \
2289 +(((INCR) << SHIFT_IMG_SOC_INCR) & MASK_IMG_SOC_INCR)|             \
2290 +(((BURST) << SHIFT_IMG_SOC_BURST) & MASK_IMG_SOC_BURST))
2291 +
2292 +#define IMG_SOC_DMAC_PERIPHERAL_ADDR(X) (0x0014 + (32 * (X)))
2293 +#define MASK_IMG_SOC_ADDR           0x007FFFFF
2294 +#define SHIFT_IMG_SOC_ADDR          0
2295 +#define REGNUM_IMG_SOC_ADDR         0x0014
2296 +
2297 +#define SHIFT_TOPAZ_VEC_BUSY        11
2298 +#define MASK_TOPAZ_VEC_BUSY         (0x1<<SHIFT_TOPAZ_VEC_BUSY)
2299 +
2300 +#define TOPAZ_MTX_TXRPT_OFFSET         0xc
2301 +#define TOPAZ_GUNIT_GVD_PSMI_GFX_OFFSET 0x20D0
2302 +
2303 +#define TOPAZ_GUNIT_READ32(offset)  ioread32(dev_priv->vdc_reg + offset)
2304 +#define TOPAZ_READ_BITS(val, basename) \
2305 +               (((val)&MASK_TOPAZ_##basename)>>SHIFT_TOPAZ_##basename)
2306 +
2307 +#define TOPAZ_WAIT_UNTIL_IDLE \
2308 +    do { \
2309 +       uint8_t tmp_poll_number = 0;\
2310 +       uint32_t tmp_reg; \
2311 +       if (topaz_priv->topaz_cmd_windex == WB_CCB_CTRL_RINDEX(dev_priv)) { \
2312 +               tmp_reg = TOPAZ_GUNIT_READ32(TOPAZ_GUNIT_GVD_PSMI_GFX_OFFSET);\
2313 +               if (0 != TOPAZ_READ_BITS(tmp_reg, VEC_BUSY)) { \
2314 +                       MTX_READ32(TOPAZ_MTX_TXRPT_OFFSET, &tmp_reg);\
2315 +                       while ((tmp_reg != 0x8ade0000) && \
2316 +                              (tmp_poll_number++ < 10)) \
2317 +                               MTX_READ32(0xc, &tmp_reg); \
2318 +                       PSB_DEBUG_GENERAL(      \
2319 +                         "TOPAZ: TXRPT reg remain: %x,poll %d times.\n",\
2320 +                         tmp_reg, tmp_poll_number);\
2321 +               } \
2322 +       } \
2323 +    } while (0)
2324 +
2325 +/* **************** DMAC define **************** */
2326 +enum  DMAC_eBSwap {
2327 +       DMAC_BSWAP_NO_SWAP = 0x0,/* !< No byte swapping will be performed. */
2328 +       DMAC_BSWAP_REVERSE = 0x1,/* !< Byte order will be reversed. */
2329 +};
2330 +
2331 +enum DMAC_ePW {
2332 +       DMAC_PWIDTH_32_BIT = 0x0,/* !< Peripheral width 32-bit. */
2333 +       DMAC_PWIDTH_16_BIT = 0x1,/* !< Peripheral width 16-bit. */
2334 +       DMAC_PWIDTH_8_BIT = 0x2,/* !< Peripheral width 8-bit. */
2335 +};
2336 +
2337 +enum DMAC_eAccDel {
2338 +       DMAC_ACC_DEL_0 = 0x0,   /* !< Access delay zero clock cycles */
2339 +       DMAC_ACC_DEL_256 = 0x1, /* !< Access delay 256 clock cycles */
2340 +       DMAC_ACC_DEL_512 = 0x2, /* !< Access delay 512 clock cycles */
2341 +       DMAC_ACC_DEL_768 = 0x3, /* !< Access delay 768 clock cycles */
2342 +       DMAC_ACC_DEL_1024 = 0x4,/* !< Access delay 1024 clock cycles */
2343 +       DMAC_ACC_DEL_1280 = 0x5,/* !< Access delay 1280 clock cycles */
2344 +       DMAC_ACC_DEL_1536 = 0x6,/* !< Access delay 1536 clock cycles */
2345 +       DMAC_ACC_DEL_1792 = 0x7,/* !< Access delay 1792 clock cycles */
2346 +};
2347 +
2348 +enum  DMAC_eBurst {
2349 +       DMAC_BURST_0 = 0x0,     /* !< burst size of 0 */
2350 +       DMAC_BURST_1 = 0x1,     /* !< burst size of 1 */
2351 +       DMAC_BURST_2 = 0x2,     /* !< burst size of 2 */
2352 +       DMAC_BURST_3 = 0x3,     /* !< burst size of 3 */
2353 +       DMAC_BURST_4 = 0x4,     /* !< burst size of 4 */
2354 +       DMAC_BURST_5 = 0x5,     /* !< burst size of 5 */
2355 +       DMAC_BURST_6 = 0x6,     /* !< burst size of 6 */
2356 +       DMAC_BURST_7 = 0x7,     /* !< burst size of 7 */
2357 +};
2358 +
2359 +/* commands for topaz,shared with user space driver */
2360 +enum drm_lnc_topaz_cmd {
2361 +       MTX_CMDID_NULL = 0,
2362 +       MTX_CMDID_DO_HEADER = 1,
2363 +       MTX_CMDID_ENCODE_SLICE = 2,
2364 +       MTX_CMDID_WRITEREG = 3,
2365 +       MTX_CMDID_START_PIC = 4,
2366 +       MTX_CMDID_END_PIC = 5,
2367 +       MTX_CMDID_SYNC = 6,
2368 +       MTX_CMDID_ENCODE_ONE_ROW = 7,
2369 +       MTX_CMDID_FLUSH = 8,
2370 +       MTX_CMDID_SW_LEAVE_LOWPOWER = 0x7c,
2371 +       MTX_CMDID_SW_ENTER_LOWPOWER = 0x7e,
2372 +       MTX_CMDID_SW_NEW_CODEC = 0x7f
2373 +};
2374 +
2375 +/* codecs topaz supports,shared with user space driver */
2376 +enum drm_lnc_topaz_codec {
2377 +       IMG_CODEC_JPEG = 0,
2378 +       IMG_CODEC_H264_NO_RC,
2379 +       IMG_CODEC_H264_VBR,
2380 +       IMG_CODEC_H264_CBR,
2381 +       IMG_CODEC_H263_NO_RC,
2382 +       IMG_CODEC_H263_VBR,
2383 +       IMG_CODEC_H263_CBR,
2384 +       IMG_CODEC_MPEG4_NO_RC,
2385 +       IMG_CODEC_MPEG4_VBR,
2386 +       IMG_CODEC_MPEG4_CBR,
2387 +       IMG_CODEC_NUM
2388 +};
2389 +
2390 +/* XXX: it's a copy of msvdx cmd queue. should have some change? */
2391 +struct lnc_topaz_cmd_queue {
2392 +       struct list_head head;
2393 +       void *cmd;
2394 +       unsigned long cmd_size;
2395 +       uint32_t sequence;
2396 +};
2397 +
2398 +
2399 +struct topaz_cmd_header {
2400 +       union {
2401 +               struct {
2402 +                       unsigned long enable_interrupt:1;
2403 +                       unsigned long id:7;
2404 +                       unsigned long size:8;
2405 +                       unsigned long seq:16;
2406 +               };
2407 +               uint32_t val;
2408 +       };
2409 +};
2410 +
2411 +/* define structure */
2412 +/* firmware file's info head */
2413 +struct topaz_fwinfo {
2414 +       unsigned int ver:16;
2415 +       unsigned int codec:16;
2416 +
2417 +       unsigned int text_size;
2418 +       unsigned int data_size;
2419 +       unsigned int data_location;
2420 +};
2421 +
2422 +/* firmware data array define  */
2423 +struct topaz_codec_fw {
2424 +       uint32_t ver;
2425 +       uint32_t codec;
2426 +
2427 +       uint32_t text_size;
2428 +       uint32_t data_size;
2429 +       uint32_t data_location;
2430 +
2431 +       struct ttm_buffer_object *text;
2432 +       struct ttm_buffer_object *data;
2433 +};
2434 +
2435 +struct topaz_private {
2436 +       /* current video task */
2437 +       unsigned int pmstate;
2438 +       struct sysfs_dirent *sysfs_pmstate;
2439 +       int frame_skip;
2440 +
2441 +       void *topaz_mtx_reg_state;
2442 +       struct ttm_buffer_object *topaz_mtx_data_mem;
2443 +       uint32_t topaz_cur_codec;
2444 +       uint32_t cur_mtx_data_size;
2445 +       int topaz_needs_reset;
2446 +
2447 +       /*
2448 +        *topaz command queue
2449 +        */
2450 +       spinlock_t topaz_lock;
2451 +       struct mutex topaz_mutex;
2452 +       struct list_head topaz_queue;
2453 +       int topaz_busy;         /* 0 means topaz is free */
2454 +       int topaz_fw_loaded;
2455 +
2456 +       /* topaz ccb data */
2457 +       /* XXX: should the addr stored by 32 bits? more compatible way?? */
2458 +       uint32_t topaz_ccb_buffer_addr;
2459 +       uint32_t topaz_ccb_ctrl_addr;
2460 +       uint32_t topaz_ccb_size;
2461 +       uint32_t topaz_cmd_windex;
2462 +       uint16_t topaz_cmd_seq;
2463 +
2464 +       uint32_t stored_initial_qp;
2465 +       uint32_t topaz_dash_access_ctrl;
2466 +
2467 +       struct ttm_buffer_object *topaz_bo; /* 4K->2K/2K for writeback/sync */
2468 +       struct ttm_bo_kmap_obj topaz_bo_kmap;
2469 +       void *topaz_ccb_wb;
2470 +       uint32_t topaz_wb_offset;
2471 +       uint32_t *topaz_sync_addr;
2472 +       uint32_t topaz_sync_offset;
2473 +       uint32_t topaz_sync_cmd_seq;
2474 +       uint32_t topaz_mtx_saved;
2475 +
2476 +       /* firmware */
2477 +       struct topaz_codec_fw topaz_fw[IMG_CODEC_NUM];
2478 +
2479 +       uint32_t topaz_hw_busy;
2480 +};
2481 +
2482 +/* external function declare */
2483 +/* lnc_topazinit.c */
2484 +int lnc_topaz_init(struct drm_device *dev);
2485 +int lnc_topaz_uninit(struct drm_device *dev);
2486 +int lnc_topaz_reset(struct drm_psb_private *dev_priv);
2487 +int topaz_init_fw(struct drm_device *dev);
2488 +int topaz_setup_fw(struct drm_device *dev, enum drm_lnc_topaz_codec codec);
2489 +int topaz_wait_for_register(struct drm_psb_private *dev_priv,
2490 +                           uint32_t addr, uint32_t value,
2491 +                           uint32_t enable);
2492 +void topaz_write_mtx_mem(struct drm_psb_private *dev_priv,
2493 +                        uint32_t byte_addr, uint32_t val);
2494 +uint32_t topaz_read_mtx_mem(struct drm_psb_private *dev_priv,
2495 +                           uint32_t byte_addr);
2496 +void topaz_write_mtx_mem_multiple_setup(struct drm_psb_private *dev_priv,
2497 +                                       uint32_t addr);
2498 +void topaz_write_mtx_mem_multiple(struct drm_psb_private *dev_priv,
2499 +                                 uint32_t val);
2500 +void topaz_mmu_flushcache(struct drm_psb_private *dev_priv);
2501 +int lnc_topaz_save_mtx_state(struct drm_device *dev);
2502 +int lnc_topaz_restore_mtx_state(struct drm_device *dev);
2503 +
2504 +/* lnc_topaz.c */
2505 +IMG_BOOL lnc_topaz_interrupt(IMG_VOID *pvData);
2506 +
2507 +int lnc_cmdbuf_video(struct drm_file *priv,
2508 +               struct list_head *validate_list,
2509 +               uint32_t fence_type,
2510 +               struct drm_psb_cmdbuf_arg *arg,
2511 +               struct ttm_buffer_object *cmd_buffer,
2512 +               struct psb_ttm_fence_rep *fence_arg);
2513 +
2514 +void topaz_mtx_kick(struct drm_psb_private *dev_priv, uint32_t kick_cout);
2515 +void lnc_topaz_handle_timeout(struct ttm_fence_device *fdev);
2516 +
2517 +uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver);
2518 +int lnc_wait_topaz_idle(struct drm_device *dev);
2519 +int lnc_check_topaz_idle(struct drm_device *dev);
2520 +void lnc_unmap_topaz_reg(struct drm_device *dev);
2521 +void lnc_map_topaz_reg(struct drm_device *dev);
2522 +
2523 +/* macros to get/set CCB control data */
2524 +#define WB_CCB_CTRL_RINDEX(dev_priv) \
2525 +(*((uint32_t *)((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_wb))
2526 +
2527 +#define WB_CCB_CTRL_SEQ(dev_priv) \
2528 +(*((uint32_t *)((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_wb\
2529 +       + 1))
2530 +
2531 +#define POLL_WB_RINDEX(dev_priv, value)                                \
2532 +do {                                                           \
2533 +       int i;                                                  \
2534 +       for (i = 0; i < 10000; i++) {                           \
2535 +               if (WB_CCB_CTRL_RINDEX(dev_priv) == value)      \
2536 +                       break;                                  \
2537 +               else                                            \
2538 +                       DRM_UDELAY(100);                        \
2539 +       }                                                       \
2540 +       if (WB_CCB_CTRL_RINDEX(dev_priv) != value) {            \
2541 +               DRM_ERROR("TOPAZ: poll rindex timeout\n");      \
2542 +               ret = -EBUSY;                                   \
2543 +       }                                                       \
2544 +} while (0)
2545 +
2546 +#define POLL_WB_SEQ(dev_priv, value)                           \
2547 +do {                                                           \
2548 +       int i;                                                  \
2549 +       for (i = 0; i < 10000; i++) {                           \
2550 +               if (CCB_CTRL_SEQ(dev_priv) == value)    \
2551 +                       break;                                  \
2552 +               else                                            \
2553 +                       DRM_UDELAY(1000);                       \
2554 +       }                                                       \
2555 +       if (CCB_CTRL_SEQ(dev_priv) != value) {          \
2556 +               DRM_ERROR("TOPAZ:poll mtxseq timeout,0x%08x(mtx) vs 0x%08x\n",\
2557 +                       WB_CCB_CTRL_SEQ(dev_priv), value);              \
2558 +               ret = -EBUSY;                                   \
2559 +       }                                                       \
2560 +} while (0)
2561 +
2562 +#define CCB_CTRL_RINDEX(dev_priv)                      \
2563 +       topaz_read_mtx_mem(dev_priv,                    \
2564 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2565 +                       + MTX_CCBCTRL_ROFF)
2566 +
2567 +#define CCB_CTRL_RINDEX(dev_priv)                      \
2568 +       topaz_read_mtx_mem(dev_priv,                    \
2569 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2570 +                       + MTX_CCBCTRL_ROFF)
2571 +
2572 +#define CCB_CTRL_QP(dev_priv)                                          \
2573 +       topaz_read_mtx_mem(dev_priv,                                    \
2574 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2575 +                       + MTX_CCBCTRL_QP)
2576 +
2577 +#define CCB_CTRL_SEQ(dev_priv)                                         \
2578 +       topaz_read_mtx_mem(dev_priv,                                    \
2579 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2580 +                       + MTX_CCBCTRL_COMPLETE)
2581 +
2582 +#define CCB_CTRL_FRAMESKIP(dev_priv)                              \
2583 +       topaz_read_mtx_mem(dev_priv,                               \
2584 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2585 +                       + MTX_CCBCTRL_FRAMESKIP)
2586 +
2587 +#define CCB_CTRL_SET_QP(dev_priv, qp)                                  \
2588 +       topaz_write_mtx_mem(dev_priv,                                   \
2589 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2590 +                       + MTX_CCBCTRL_QP, qp)
2591 +
2592 +#define CCB_CTRL_SET_INITIALQP(dev_priv, qp)                       \
2593 +       topaz_write_mtx_mem(dev_priv,                               \
2594 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_ctrl_addr \
2595 +                       + MTX_CCBCTRL_INITQP, qp)
2596 +
2597 +
2598 +#define TOPAZ_BEGIN_CCB(dev_priv)                                      \
2599 +       topaz_write_mtx_mem_multiple_setup(dev_priv,                    \
2600 +   ((struct topaz_private *)dev_priv->topaz_private)->topaz_ccb_buffer_addr + \
2601 +   ((struct topaz_private *)dev_priv->topaz_private)->topaz_cmd_windex * 4)
2602 +
2603 +#define TOPAZ_OUT_CCB(dev_priv, cmd)                                   \
2604 +do {                                                                   \
2605 +       topaz_write_mtx_mem_multiple(dev_priv, cmd);                    \
2606 +       ((struct topaz_private *)dev_priv->topaz_private)->topaz_cmd_windex++; \
2607 +} while (0)
2608 +
2609 +#define TOPAZ_END_CCB(dev_priv, kick_count)    \
2610 +       topaz_mtx_kick(dev_priv, 1);
2611 +
2612 +static inline char *cmd_to_string(int cmd_id)
2613 +{
2614 +       switch (cmd_id) {
2615 +       case MTX_CMDID_START_PIC:
2616 +               return "MTX_CMDID_START_PIC";
2617 +       case MTX_CMDID_END_PIC:
2618 +               return "MTX_CMDID_END_PIC";
2619 +       case MTX_CMDID_DO_HEADER:
2620 +               return "MTX_CMDID_DO_HEADER";
2621 +       case MTX_CMDID_ENCODE_SLICE:
2622 +               return "MTX_CMDID_ENCODE_SLICE";
2623 +       case MTX_CMDID_SYNC:
2624 +               return "MTX_CMDID_SYNC";
2625 +
2626 +       default:
2627 +               return "Undefined command";
2628 +
2629 +       }
2630 +}
2631 +
2632 +static inline char *codec_to_string(int codec)
2633 +{
2634 +       switch (codec) {
2635 +       case IMG_CODEC_H264_NO_RC:
2636 +               return "H264_NO_RC";
2637 +       case IMG_CODEC_H264_VBR:
2638 +               return "H264_VBR";
2639 +       case IMG_CODEC_H264_CBR:
2640 +               return "H264_CBR";
2641 +       case IMG_CODEC_H263_NO_RC:
2642 +               return "H263_NO_RC";
2643 +       case IMG_CODEC_H263_VBR:
2644 +               return "H263_VBR";
2645 +       case IMG_CODEC_H263_CBR:
2646 +               return "H263_CBR";
2647 +       case IMG_CODEC_MPEG4_NO_RC:
2648 +               return "MPEG4_NO_RC";
2649 +       case IMG_CODEC_MPEG4_VBR:
2650 +               return "MPEG4_VBR";
2651 +       case IMG_CODEC_MPEG4_CBR:
2652 +               return "MPEG4_CBR";
2653 +       default:
2654 +               return "Undefined codec";
2655 +       }
2656 +}
2657 +
2658 +
2659 +static inline void lnc_topaz_enableirq(struct drm_device *dev)
2660 +{
2661 +       struct drm_psb_private *dev_priv = dev->dev_private;
2662 +       /* uint32_t ier = dev_priv->vdc_irq_mask | _LNC_IRQ_TOPAZ_FLAG; */
2663 +
2664 +       PSB_DEBUG_IRQ("TOPAZ: enable IRQ\n");
2665 +
2666 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_INTENAB,
2667 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_MAS_INTEN) |
2668 +               /* F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTEN_MVEA) | */
2669 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTEN_MMU_FAULT) |
2670 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTEN_MTX) |
2671 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTEN_MTX_HALT));
2672 +
2673 +       /* write in sysirq.c */
2674 +       /* PSB_WVDC32(ier, PSB_INT_ENABLE_R); /\* essential *\/ */
2675 +}
2676 +
2677 +static inline void lnc_topaz_disableirq(struct drm_device *dev)
2678 +{
2679 +
2680 +       struct drm_psb_private *dev_priv = dev->dev_private;
2681 +       /* uint32_t ier = dev_priv->vdc_irq_mask & (~_LNC_IRQ_TOPAZ_FLAG); */
2682 +
2683 +       PSB_DEBUG_INIT("TOPAZ: disable IRQ\n");
2684 +
2685 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_INTENAB, 0);
2686 +
2687 +       /* write in sysirq.c */
2688 +       /* PSB_WVDC32(ier, PSB_INT_ENABLE_R); /\* essential *\/ */
2689 +}
2690 +
2691 +
2692 +static inline void lnc_topaz_clearirq(struct drm_device *dev,
2693 +                               uint32_t clear_topaz)
2694 +{
2695 +       struct drm_psb_private *dev_priv = dev->dev_private;
2696 +
2697 +       PSB_DEBUG_INIT("TOPAZ: clear IRQ\n");
2698 +       if (clear_topaz != 0)
2699 +               TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_INTCLEAR, clear_topaz);
2700 +
2701 +       /* PSB_WVDC32(_LNC_IRQ_TOPAZ_FLAG, PSB_INT_IDENTITY_R); */
2702 +}
2703 +
2704 +static inline uint32_t lnc_topaz_queryirq(struct drm_device *dev)
2705 +{
2706 +       struct drm_psb_private *dev_priv = dev->dev_private;
2707 +       uint32_t val, /* iir, */ clear = 0;
2708 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
2709 +
2710 +       TOPAZ_READ32(TOPAZ_CR_IMG_TOPAZ_INTSTAT, &val);
2711 +       /* iir = PSB_RVDC32(PSB_INT_IDENTITY_R); */
2712 +
2713 +       (void) topaz_priv;
2714 +
2715 +       if ((val == 0) /* && (iir == 0) */) {/* no interrupt */
2716 +               PSB_DEBUG_GENERAL("TOPAZ: no interrupt,IIR=TOPAZ_INTSTAT=0\n");
2717 +               return 0;
2718 +       }
2719 +
2720 +       PSB_DEBUG_IRQ("TOPAZ:TOPAZ_INTSTAT=0x%08x\n", val);
2721 +
2722 +       if (val & (1<<31))
2723 +               PSB_DEBUG_IRQ("TOPAZ:IRQ pin activated,cmd seq=0x%04x,"
2724 +                       "sync seq: 0x%08x vs 0x%08x (MTX)\n",
2725 +                       CCB_CTRL_SEQ(dev_priv),
2726 +                       dev_priv->sequence[LNC_ENGINE_ENCODE],
2727 +                       *(uint32_t *)topaz_priv->topaz_sync_addr);
2728 +       else
2729 +               PSB_DEBUG_IRQ("TOPAZ:IRQ pin not activated,cmd seq=0x%04x,"
2730 +                       "sync seq: 0x%08x vs 0x%08x (MTX)\n",
2731 +                       CCB_CTRL_SEQ(dev_priv),
2732 +                       dev_priv->sequence[LNC_ENGINE_ENCODE],
2733 +                       *(uint32_t *)topaz_priv->topaz_sync_addr);
2734 +
2735 +       if (val & 0x8) {
2736 +               uint32_t mmu_status, mmu_req;
2737 +
2738 +               TOPAZ_READ32(TOPAZ_CR_MMU_STATUS, &mmu_status);
2739 +               TOPAZ_READ32(TOPAZ_CR_MMU_MEM_REQ, &mmu_req);
2740 +
2741 +               PSB_DEBUG_IRQ("TOPAZ: detect a page fault interrupt, "
2742 +                       "address=0x%08x,mem req=0x%08x\n",
2743 +                       mmu_status, mmu_req);
2744 +               clear |= F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MMU_FAULT);
2745 +       }
2746 +
2747 +       if (val & 0x4) {
2748 +               PSB_DEBUG_IRQ("TOPAZ: detect a MTX_HALT interrupt\n");
2749 +               clear |= F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX_HALT);
2750 +       }
2751 +
2752 +       if (val & 0x2) {
2753 +               PSB_DEBUG_IRQ("TOPAZ: detect a MTX interrupt\n");
2754 +               clear |= F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX);
2755 +       }
2756 +
2757 +       if (val & 0x1) {
2758 +               PSB_DEBUG_IRQ("TOPAZ: detect a MVEA interrupt\n");
2759 +               clear |= F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MVEA);
2760 +       }
2761 +
2762 +       return clear;
2763 +}
2764 +
2765 +
2766 +#define TOPAZ_NEW_PMSTATE(drm_dev, topaz_priv, new_state)              \
2767 +do { \
2768 +       topaz_priv->pmstate = new_state;                                \
2769 +       sysfs_notify_dirent(topaz_priv->sysfs_pmstate);                 \
2770 +       PSB_DEBUG_PM("TOPAZ: %s\n",                                     \
2771 +               (new_state == PSB_PMSTATE_POWERUP) ? "powerup": "powerdown"); \
2772 +} while (0)
2773 +
2774 +#endif /* _LNC_TOPAZ_H_ */
2775 diff --git a/drivers/gpu/drm/mrst/drv/lnc_topazinit.c b/drivers/gpu/drm/mrst/drv/lnc_topazinit.c
2776 new file mode 100644
2777 index 0000000..f968d5b
2778 --- /dev/null
2779 +++ b/drivers/gpu/drm/mrst/drv/lnc_topazinit.c
2780 @@ -0,0 +1,2051 @@
2781 +/**
2782 + * file lnc_topazinit.c
2783 + * TOPAZ initialization and mtx-firmware upload
2784 + *
2785 + */
2786 +
2787 +/**************************************************************************
2788 + *
2789 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
2790 + * Copyright (c) Imagination Technologies Limited, UK
2791 + *
2792 + * This program is free software; you can redistribute it and/or modify it
2793 + * under the terms and conditions of the GNU General Public License,
2794 + * version 2, as published by the Free Software Foundation.
2795 + *
2796 + * This program is distributed in the hope it will be useful, but WITHOUT
2797 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2798 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
2799 + * more details.
2800 + *
2801 + * You should have received a copy of the GNU General Public License along with
2802 + * this program; if not, write to the Free Software Foundation, Inc., 
2803 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2804 + *
2805 + **************************************************************************/
2806 +
2807 +/* NOTE: (READ BEFORE REFINE CODE)
2808 + * 1. The FIRMWARE's SIZE is measured by byte, we have to pass the size
2809 + * measured by word to DMAC.
2810 + *
2811 + *
2812 + *
2813 + */
2814 +
2815 +/* include headers */
2816 +
2817 +/* #define DRM_DEBUG_CODE 2 */
2818 +
2819 +#include <linux/firmware.h>
2820 +
2821 +#include <drm/drmP.h>
2822 +#include <drm/drm.h>
2823 +
2824 +#include "psb_drv.h"
2825 +#include "lnc_topaz.h"
2826 +#include "ospm_power.h"
2827 +#include "sysirq.h"
2828 +
2829 +/* WARNING: this define is very important */
2830 +#define RAM_SIZE (1024 * 24)
2831 +
2832 +/* register default values
2833 + * THIS HEADER IS ONLY INCLUDE ONCE*/
2834 +static unsigned long topaz_default_regs[183][3] = {
2835 +       {MVEA_START, 0x00000000, 0x00000000},
2836 +       {MVEA_START, 0x00000004, 0x00000400},
2837 +       {MVEA_START, 0x00000008, 0x00000000},
2838 +       {MVEA_START, 0x0000000C, 0x00000000},
2839 +       {MVEA_START, 0x00000010, 0x00000000},
2840 +       {MVEA_START, 0x00000014, 0x00000000},
2841 +       {MVEA_START, 0x00000018, 0x00000000},
2842 +       {MVEA_START, 0x0000001C, 0x00000000},
2843 +       {MVEA_START, 0x00000020, 0x00000120},
2844 +       {MVEA_START, 0x00000024, 0x00000000},
2845 +       {MVEA_START, 0x00000028, 0x00000000},
2846 +       {MVEA_START, 0x00000100, 0x00000000},
2847 +       {MVEA_START, 0x00000104, 0x00000000},
2848 +       {MVEA_START, 0x00000108, 0x00000000},
2849 +       {MVEA_START, 0x0000010C, 0x00000000},
2850 +       {MVEA_START, 0x0000011C, 0x00000001},
2851 +       {MVEA_START, 0x0000012C, 0x00000000},
2852 +       {MVEA_START, 0x00000180, 0x00000000},
2853 +       {MVEA_START, 0x00000184, 0x00000000},
2854 +       {MVEA_START, 0x00000188, 0x00000000},
2855 +       {MVEA_START, 0x0000018C, 0x00000000},
2856 +       {MVEA_START, 0x00000190, 0x00000000},
2857 +       {MVEA_START, 0x00000194, 0x00000000},
2858 +       {MVEA_START, 0x00000198, 0x00000000},
2859 +       {MVEA_START, 0x0000019C, 0x00000000},
2860 +       {MVEA_START, 0x000001A0, 0x00000000},
2861 +       {MVEA_START, 0x000001A4, 0x00000000},
2862 +       {MVEA_START, 0x000001A8, 0x00000000},
2863 +       {MVEA_START, 0x000001AC, 0x00000000},
2864 +       {MVEA_START, 0x000001B0, 0x00000000},
2865 +       {MVEA_START, 0x000001B4, 0x00000000},
2866 +       {MVEA_START, 0x000001B8, 0x00000000},
2867 +       {MVEA_START, 0x000001BC, 0x00000000},
2868 +       {MVEA_START, 0x000001F8, 0x00000000},
2869 +       {MVEA_START, 0x000001FC, 0x00000000},
2870 +       {MVEA_START, 0x00000200, 0x00000000},
2871 +       {MVEA_START, 0x00000204, 0x00000000},
2872 +       {MVEA_START, 0x00000208, 0x00000000},
2873 +       {MVEA_START, 0x0000020C, 0x00000000},
2874 +       {MVEA_START, 0x00000210, 0x00000000},
2875 +       {MVEA_START, 0x00000220, 0x00000001},
2876 +       {MVEA_START, 0x00000224, 0x0000001F},
2877 +       {MVEA_START, 0x00000228, 0x00000100},
2878 +       {MVEA_START, 0x0000022C, 0x00001F00},
2879 +       {MVEA_START, 0x00000230, 0x00000101},
2880 +       {MVEA_START, 0x00000234, 0x00001F1F},
2881 +       {MVEA_START, 0x00000238, 0x00001F01},
2882 +       {MVEA_START, 0x0000023C, 0x0000011F},
2883 +       {MVEA_START, 0x00000240, 0x00000200},
2884 +       {MVEA_START, 0x00000244, 0x00001E00},
2885 +       {MVEA_START, 0x00000248, 0x00000002},
2886 +       {MVEA_START, 0x0000024C, 0x0000001E},
2887 +       {MVEA_START, 0x00000250, 0x00000003},
2888 +       {MVEA_START, 0x00000254, 0x0000001D},
2889 +       {MVEA_START, 0x00000258, 0x00001F02},
2890 +       {MVEA_START, 0x0000025C, 0x00000102},
2891 +       {MVEA_START, 0x00000260, 0x0000011E},
2892 +       {MVEA_START, 0x00000264, 0x00000000},
2893 +       {MVEA_START, 0x00000268, 0x00000000},
2894 +       {MVEA_START, 0x0000026C, 0x00000000},
2895 +       {MVEA_START, 0x00000270, 0x00000000},
2896 +       {MVEA_START, 0x00000274, 0x00000000},
2897 +       {MVEA_START, 0x00000278, 0x00000000},
2898 +       {MVEA_START, 0x00000280, 0x00008000},
2899 +       {MVEA_START, 0x00000284, 0x00000000},
2900 +       {MVEA_START, 0x00000288, 0x00000000},
2901 +       {MVEA_START, 0x0000028C, 0x00000000},
2902 +       {MVEA_START, 0x00000314, 0x00000000},
2903 +       {MVEA_START, 0x00000318, 0x00000000},
2904 +       {MVEA_START, 0x0000031C, 0x00000000},
2905 +       {MVEA_START, 0x00000320, 0x00000000},
2906 +       {MVEA_START, 0x00000324, 0x00000000},
2907 +       {MVEA_START, 0x00000348, 0x00000000},
2908 +       {MVEA_START, 0x00000380, 0x00000000},
2909 +       {MVEA_START, 0x00000384, 0x00000000},
2910 +       {MVEA_START, 0x00000388, 0x00000000},
2911 +       {MVEA_START, 0x0000038C, 0x00000000},
2912 +       {MVEA_START, 0x00000390, 0x00000000},
2913 +       {MVEA_START, 0x00000394, 0x00000000},
2914 +       {MVEA_START, 0x00000398, 0x00000000},
2915 +       {MVEA_START, 0x0000039C, 0x00000000},
2916 +       {MVEA_START, 0x000003A0, 0x00000000},
2917 +       {MVEA_START, 0x000003A4, 0x00000000},
2918 +       {MVEA_START, 0x000003A8, 0x00000000},
2919 +       {MVEA_START, 0x000003B0, 0x00000000},
2920 +       {MVEA_START, 0x000003B4, 0x00000000},
2921 +       {MVEA_START, 0x000003B8, 0x00000000},
2922 +       {MVEA_START, 0x000003BC, 0x00000000},
2923 +       {MVEA_START, 0x000003D4, 0x00000000},
2924 +       {MVEA_START, 0x000003D8, 0x00000000},
2925 +       {MVEA_START, 0x000003DC, 0x00000000},
2926 +       {MVEA_START, 0x000003E0, 0x00000000},
2927 +       {MVEA_START, 0x000003E4, 0x00000000},
2928 +       {MVEA_START, 0x000003EC, 0x00000000},
2929 +       {MVEA_START, 0x000002D0, 0x00000000},
2930 +       {MVEA_START, 0x000002D4, 0x00000000},
2931 +       {MVEA_START, 0x000002D8, 0x00000000},
2932 +       {MVEA_START, 0x000002DC, 0x00000000},
2933 +       {MVEA_START, 0x000002E0, 0x00000000},
2934 +       {MVEA_START, 0x000002E4, 0x00000000},
2935 +       {MVEA_START, 0x000002E8, 0x00000000},
2936 +       {MVEA_START, 0x000002EC, 0x00000000},
2937 +       {MVEA_START, 0x000002F0, 0x00000000},
2938 +       {MVEA_START, 0x000002F4, 0x00000000},
2939 +       {MVEA_START, 0x000002F8, 0x00000000},
2940 +       {MVEA_START, 0x000002FC, 0x00000000},
2941 +       {MVEA_START, 0x00000300, 0x00000000},
2942 +       {MVEA_START, 0x00000304, 0x00000000},
2943 +       {MVEA_START, 0x00000308, 0x00000000},
2944 +       {MVEA_START, 0x0000030C, 0x00000000},
2945 +       {MVEA_START, 0x00000290, 0x00000000},
2946 +       {MVEA_START, 0x00000294, 0x00000000},
2947 +       {MVEA_START, 0x00000298, 0x00000000},
2948 +       {MVEA_START, 0x0000029C, 0x00000000},
2949 +       {MVEA_START, 0x000002A0, 0x00000000},
2950 +       {MVEA_START, 0x000002A4, 0x00000000},
2951 +       {MVEA_START, 0x000002A8, 0x00000000},
2952 +       {MVEA_START, 0x000002AC, 0x00000000},
2953 +       {MVEA_START, 0x000002B0, 0x00000000},
2954 +       {MVEA_START, 0x000002B4, 0x00000000},
2955 +       {MVEA_START, 0x000002B8, 0x00000000},
2956 +       {MVEA_START, 0x000002BC, 0x00000000},
2957 +       {MVEA_START, 0x000002C0, 0x00000000},
2958 +       {MVEA_START, 0x000002C4, 0x00000000},
2959 +       {MVEA_START, 0x000002C8, 0x00000000},
2960 +       {MVEA_START, 0x000002CC, 0x00000000},
2961 +       {MVEA_START, 0x00000080, 0x00000000},
2962 +       {MVEA_START, 0x00000084, 0x80705700},
2963 +       {MVEA_START, 0x00000088, 0x00000000},
2964 +       {MVEA_START, 0x0000008C, 0x00000000},
2965 +       {MVEA_START, 0x00000090, 0x00000000},
2966 +       {MVEA_START, 0x00000094, 0x00000000},
2967 +       {MVEA_START, 0x00000098, 0x00000000},
2968 +       {MVEA_START, 0x0000009C, 0x00000000},
2969 +       {MVEA_START, 0x000000A0, 0x00000000},
2970 +       {MVEA_START, 0x000000A4, 0x00000000},
2971 +       {MVEA_START, 0x000000A8, 0x00000000},
2972 +       {MVEA_START, 0x000000AC, 0x00000000},
2973 +       {MVEA_START, 0x000000B0, 0x00000000},
2974 +       {MVEA_START, 0x000000B4, 0x00000000},
2975 +       {MVEA_START, 0x000000B8, 0x00000000},
2976 +       {MVEA_START, 0x000000BC, 0x00000000},
2977 +       {MVEA_START, 0x000000C0, 0x00000000},
2978 +       {MVEA_START, 0x000000C4, 0x00000000},
2979 +       {MVEA_START, 0x000000C8, 0x00000000},
2980 +       {MVEA_START, 0x000000CC, 0x00000000},
2981 +       {MVEA_START, 0x000000D0, 0x00000000},
2982 +       {MVEA_START, 0x000000D4, 0x00000000},
2983 +       {MVEA_START, 0x000000D8, 0x00000000},
2984 +       {MVEA_START, 0x000000DC, 0x00000000},
2985 +       {MVEA_START, 0x000000E0, 0x00000000},
2986 +       {MVEA_START, 0x000000E4, 0x00000000},
2987 +       {MVEA_START, 0x000000E8, 0x00000000},
2988 +       {MVEA_START, 0x000000EC, 0x00000000},
2989 +       {MVEA_START, 0x000000F0, 0x00000000},
2990 +       {MVEA_START, 0x000000F4, 0x00000000},
2991 +       {MVEA_START, 0x000000F8, 0x00000000},
2992 +       {MVEA_START, 0x000000FC, 0x00000000},
2993 +       {TOPAZ_VLC_START, 0x00000000, 0x00000000},
2994 +       {TOPAZ_VLC_START, 0x00000004, 0x00000000},
2995 +       {TOPAZ_VLC_START, 0x00000008, 0x00000000},
2996 +       {TOPAZ_VLC_START, 0x0000000C, 0x00000000},
2997 +       {TOPAZ_VLC_START, 0x00000010, 0x00000000},
2998 +       {TOPAZ_VLC_START, 0x00000014, 0x00000000},
2999 +       {TOPAZ_VLC_START, 0x0000001C, 0x00000000},
3000 +       {TOPAZ_VLC_START, 0x00000020, 0x00000000},
3001 +       {TOPAZ_VLC_START, 0x00000024, 0x00000000},
3002 +       {TOPAZ_VLC_START, 0x0000002C, 0x00000000},
3003 +       {TOPAZ_VLC_START, 0x00000034, 0x00000000},
3004 +       {TOPAZ_VLC_START, 0x00000038, 0x00000000},
3005 +       {TOPAZ_VLC_START, 0x0000003C, 0x00000000},
3006 +       {TOPAZ_VLC_START, 0x00000040, 0x00000000},
3007 +       {TOPAZ_VLC_START, 0x00000044, 0x00000000},
3008 +       {TOPAZ_VLC_START, 0x00000048, 0x00000000},
3009 +       {TOPAZ_VLC_START, 0x0000004C, 0x00000000},
3010 +       {TOPAZ_VLC_START, 0x00000050, 0x00000000},
3011 +       {TOPAZ_VLC_START, 0x00000054, 0x00000000},
3012 +       {TOPAZ_VLC_START, 0x00000058, 0x00000000},
3013 +       {TOPAZ_VLC_START, 0x0000005C, 0x00000000},
3014 +       {TOPAZ_VLC_START, 0x00000060, 0x00000000},
3015 +       {TOPAZ_VLC_START, 0x00000064, 0x00000000},
3016 +       {TOPAZ_VLC_START, 0x00000068, 0x00000000},
3017 +       {TOPAZ_VLC_START, 0x0000006C, 0x00000000}
3018 +};
3019 +
3020 +#define FIRMWARE_NAME "topaz_fw.bin"
3021 +
3022 +/* static function define */
3023 +static int topaz_upload_fw(struct drm_device *dev,
3024 +                       enum drm_lnc_topaz_codec codec);
3025 +static inline void topaz_set_default_regs(struct drm_psb_private
3026 +                                         *dev_priv);
3027 +
3028 +#define UPLOAD_FW_BY_DMA 1
3029 +
3030 +#if UPLOAD_FW_BY_DMA
3031 +static void topaz_dma_transfer(struct drm_psb_private *dev_priv,
3032 +                              uint32_t channel, uint32_t src_phy_addr,
3033 +                              uint32_t offset, uint32_t dst_addr,
3034 +                              uint32_t byte_num, uint32_t is_increment,
3035 +                              uint32_t is_write);
3036 +#else
3037 +static void topaz_mtx_upload_by_register(struct drm_device *dev,
3038 +                                        uint32_t mtx_mem, uint32_t addr,
3039 +                                        uint32_t size,
3040 +                                        struct ttm_buffer_object *buf);
3041 +#endif
3042 +
3043 +static void topaz_write_core_reg(struct drm_psb_private *dev_priv,
3044 +                                uint32_t reg, const uint32_t val);
3045 +static void topaz_read_core_reg(struct drm_psb_private *dev_priv,
3046 +                               uint32_t reg, uint32_t *ret_val);
3047 +static void get_mtx_control_from_dash(struct drm_psb_private *dev_priv);
3048 +static void release_mtx_control_from_dash(struct drm_psb_private
3049 +                                         *dev_priv);
3050 +static void topaz_mmu_hwsetup(struct drm_psb_private *dev_priv);
3051 +static void mtx_dma_read(struct drm_device *dev, uint32_t source_addr,
3052 +                       uint32_t size);
3053 +static void mtx_dma_write(struct drm_device *dev);
3054 +
3055 +
3056 +#define DEBUG_FUNCTION 0
3057 +
3058 +#if  DEBUG_FUNCTION
3059 +static int topaz_test_null(struct drm_device *dev, uint32_t seq);
3060 +static int topaz_test_sync(struct drm_device *dev, uint32_t seq,
3061 +                       uint32_t sync_seq);
3062 +static void topaz_mmu_test(struct drm_device *dev, uint32_t sync_value);
3063 +static void topaz_save_default_regs(struct drm_psb_private *dev_priv,
3064 +                               uint32_t *data);
3065 +static void topaz_restore_default_regs(struct drm_psb_private *dev_priv,
3066 +                               uint32_t *data);
3067 +static int topaz_test_sync_manual_alloc_page(struct drm_device *dev,
3068 +                                            uint32_t seq,
3069 +                                            uint32_t sync_seq,
3070 +                                            uint32_t offset);
3071 +static int topaz_test_sync_tt_test(struct drm_device *dev,
3072 +                                  uint32_t seq,
3073 +                                  uint32_t sync_seq);
3074 +#endif
3075 +
3076 +uint32_t topaz_read_mtx_mem(struct drm_psb_private *dev_priv,
3077 +                           uint32_t byte_addr)
3078 +{
3079 +       uint32_t read_val;
3080 +       uint32_t reg, bank_size, ram_bank_size, ram_id;
3081 +
3082 +       TOPAZ_READ32(0x3c, &reg);
3083 +       reg = 0x0a0a0606;
3084 +       bank_size = (reg & 0xF0000) >> 16;
3085 +
3086 +       ram_bank_size = (uint32_t) (1 << (bank_size + 2));
3087 +       ram_id = (byte_addr - MTX_DATA_MEM_BASE) / ram_bank_size;
3088 +
3089 +       MTX_WRITE32(MTX_CR_MTX_RAM_ACCESS_CONTROL,
3090 +                   F_ENCODE(0x18 + ram_id, MTX_MTX_MCMID) |
3091 +                   F_ENCODE(byte_addr >> 2, MTX_MTX_MCM_ADDR) |
3092 +                   F_ENCODE(1, MTX_MTX_MCMR));
3093 +
3094 +       /* ?? poll this reg? */
3095 +       topaz_wait_for_register(dev_priv,
3096 +                               MTX_START + MTX_CR_MTX_RAM_ACCESS_STATUS,
3097 +                               1, 1);
3098 +
3099 +       MTX_READ32(MTX_CR_MTX_RAM_ACCESS_DATA_TRANSFER, &read_val);
3100 +
3101 +       return read_val;
3102 +}
3103 +
3104 +void topaz_write_mtx_mem(struct drm_psb_private *dev_priv,
3105 +                        uint32_t byte_addr, uint32_t val)
3106 +{
3107 +       uint32_t ram_id = 0;
3108 +       uint32_t reg, bank_size, ram_bank_size;
3109 +
3110 +       TOPAZ_READ32(0x3c, &reg);
3111 +
3112 +       /* PSB_DEBUG_GENERAL ("TOPAZ: DEBUG REG(%x)\n", reg); */
3113 +       reg = 0x0a0a0606;
3114 +
3115 +       bank_size = (reg & 0xF0000) >> 16;
3116 +
3117 +       ram_bank_size = (uint32_t) (1 << (bank_size + 2));
3118 +       ram_id = (byte_addr - MTX_DATA_MEM_BASE) / ram_bank_size;
3119 +
3120 +       MTX_WRITE32(MTX_CR_MTX_RAM_ACCESS_CONTROL,
3121 +                   F_ENCODE(0x18 + ram_id, MTX_MTX_MCMID) |
3122 +                   F_ENCODE(byte_addr >> 2, MTX_MTX_MCM_ADDR));
3123 +
3124 +       MTX_WRITE32(MTX_CR_MTX_RAM_ACCESS_DATA_TRANSFER, val);
3125 +
3126 +       /* ?? poll this reg? */
3127 +       topaz_wait_for_register(dev_priv,
3128 +                               MTX_START + MTX_CR_MTX_RAM_ACCESS_STATUS,
3129 +                               1, 1);
3130 +
3131 +       return;
3132 +}
3133 +
3134 +void topaz_write_mtx_mem_multiple_setup(struct drm_psb_private *dev_priv,
3135 +                                       uint32_t byte_addr)
3136 +{
3137 +       uint32_t ram_id = 0;
3138 +       uint32_t reg, bank_size, ram_bank_size;
3139 +
3140 +       TOPAZ_READ32(0x3c, &reg);
3141 +
3142 +       reg = 0x0a0a0606;
3143 +
3144 +       bank_size = (reg & 0xF0000) >> 16;
3145 +
3146 +       ram_bank_size = (uint32_t) (1 << (bank_size + 2));
3147 +       ram_id = (byte_addr - MTX_DATA_MEM_BASE) / ram_bank_size;
3148 +
3149 +       MTX_WRITE32(MTX_CR_MTX_RAM_ACCESS_CONTROL,
3150 +                   F_ENCODE(0x18 + ram_id, MTX_MTX_MCMID) |
3151 +                   F_ENCODE(1, MTX_MTX_MCMAI) |
3152 +                   F_ENCODE(byte_addr >> 2, MTX_MTX_MCM_ADDR));
3153 +}
3154 +
3155 +void topaz_write_mtx_mem_multiple(struct drm_psb_private *dev_priv,
3156 +                                 uint32_t val)
3157 +{
3158 +       MTX_WRITE32(MTX_CR_MTX_RAM_ACCESS_DATA_TRANSFER, val);
3159 +}
3160 +
3161 +
3162 +int topaz_wait_for_register(struct drm_psb_private *dev_priv,
3163 +                       uint32_t addr, uint32_t value, uint32_t mask)
3164 +{
3165 +       uint32_t tmp;
3166 +       uint32_t count = 10000;
3167 +
3168 +       /* # poll topaz register for certain times */
3169 +       while (count) {
3170 +               /* #.# read */
3171 +               MM_READ32(addr, 0, &tmp);
3172 +
3173 +               if (value == (tmp & mask))
3174 +                       return 0;
3175 +
3176 +               /* #.# delay and loop */
3177 +               DRM_UDELAY(100);
3178 +               --count;
3179 +       }
3180 +
3181 +       /* # now waiting is timeout, return 1 indicat failed */
3182 +       /* XXX: testsuit means a timeout 10000 */
3183 +
3184 +       DRM_ERROR("TOPAZ:time out to poll addr(0x%x) expected value(0x%08x), "
3185 +               "actual 0x%08x (0x%08x & 0x%08x)\n",
3186 +               addr, value, tmp & mask, tmp, mask);
3187 +
3188 +       return -EBUSY;
3189 +
3190 +}
3191 +
3192 +static ssize_t psb_topaz_pmstate_show(struct device *dev,
3193 +                               struct device_attribute *attr, char *buf)
3194 +{
3195 +       struct drm_device *drm_dev = dev_get_drvdata(dev);
3196 +       struct drm_psb_private *dev_priv;
3197 +       struct topaz_private *topaz_priv;
3198 +       unsigned int pmstate;
3199 +       unsigned long flags;
3200 +       int ret = -EINVAL;
3201 +
3202 +       if (drm_dev == NULL)
3203 +               return 0;
3204 +
3205 +       dev_priv = drm_dev->dev_private;
3206 +       topaz_priv = dev_priv->topaz_private;
3207 +       pmstate = topaz_priv->pmstate;
3208 +
3209 +       pmstate = topaz_priv->pmstate;
3210 +       spin_lock_irqsave(&topaz_priv->topaz_lock, flags);
3211 +       ret = sprintf(buf, "%s\n",
3212 +               (pmstate == PSB_PMSTATE_POWERUP) ? "powerup" : "powerdown");
3213 +       spin_unlock_irqrestore(&topaz_priv->topaz_lock, flags);
3214 +
3215 +       return ret;
3216 +}
3217 +
3218 +static DEVICE_ATTR(topaz_pmstate, 0444, psb_topaz_pmstate_show, NULL);
3219 +
3220 +
3221 +/* this function finish the first part of initialization, the rest
3222 + * should be done in topaz_setup_fw
3223 + */
3224 +int lnc_topaz_init(struct drm_device *dev)
3225 +{
3226 +       struct drm_psb_private *dev_priv = dev->dev_private;
3227 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
3228 +       uint32_t core_id, core_rev;
3229 +       int ret = 0, n;
3230 +       bool is_iomem;
3231 +       struct topaz_private *topaz_priv;
3232 +       void *topaz_bo_virt;
3233 +
3234 +       PSB_DEBUG_GENERAL("TOPAZ: init topaz data structures\n");
3235 +       topaz_priv = kmalloc(sizeof(struct topaz_private), GFP_KERNEL);
3236 +       if (topaz_priv == NULL)
3237 +               return -1;
3238 +
3239 +       dev_priv->topaz_private = topaz_priv;
3240 +       memset(topaz_priv, 0, sizeof(struct topaz_private));
3241 +
3242 +       /* get device --> drm_device --> drm_psb_private --> topaz_priv
3243 +        * for psb_topaz_pmstate_show: topaz_pmpolicy
3244 +        * if not pci_set_drvdata, can't get drm_device from device
3245 +        */
3246 +       pci_set_drvdata(dev->pdev, dev);
3247 +       if (device_create_file(&dev->pdev->dev,
3248 +                              &dev_attr_topaz_pmstate))
3249 +               DRM_ERROR("TOPAZ: could not create sysfs file\n");
3250 +       topaz_priv->sysfs_pmstate = sysfs_get_dirent(
3251 +               dev->pdev->dev.kobj.sd, "topaz_pmstate");
3252 +
3253 +       topaz_priv = dev_priv->topaz_private;
3254 +
3255 +       /* # initialize comand topaz queueing [msvdx_queue] */
3256 +       INIT_LIST_HEAD(&topaz_priv->topaz_queue);
3257 +       /* # init mutex? CHECK: mutex usage [msvdx_mutex] */
3258 +       mutex_init(&topaz_priv->topaz_mutex);
3259 +       /* # spin lock init? CHECK spin lock usage [msvdx_lock] */
3260 +       spin_lock_init(&topaz_priv->topaz_lock);
3261 +
3262 +       /* # topaz status init. [msvdx_busy] */
3263 +       topaz_priv->topaz_busy = 0;
3264 +       topaz_priv->topaz_cmd_seq = 0;
3265 +       topaz_priv->topaz_fw_loaded = 0;
3266 +       /* FIXME: workaround since JPEG firmware is not ready */
3267 +       topaz_priv->topaz_cur_codec = 1;
3268 +       topaz_priv->cur_mtx_data_size = 0;
3269 +       topaz_priv->topaz_hw_busy = 1;
3270 +
3271 +       topaz_priv->topaz_mtx_reg_state = kmalloc(TOPAZ_MTX_REG_SIZE,
3272 +                                                 GFP_KERNEL);
3273 +       if (topaz_priv->topaz_mtx_reg_state == NULL) {
3274 +               DRM_ERROR("TOPAZ: failed to allocate space "
3275 +                         "for mtx register\n");
3276 +               return -1;
3277 +       }
3278 +
3279 +       /* # gain write back structure,we may only need 32+4=40DW */
3280 +       ret = ttm_buffer_object_create(bdev, 4096,
3281 +                               ttm_bo_type_kernel,
3282 +                               DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT,
3283 +                               0, 0, 0, NULL, &(topaz_priv->topaz_bo));
3284 +       if (ret != 0) {
3285 +               DRM_ERROR("TOPAZ: failed to allocate topaz BO.\n");
3286 +               return ret;
3287 +       }
3288 +
3289 +       ret = ttm_bo_kmap(topaz_priv->topaz_bo, 0,
3290 +                         topaz_priv->topaz_bo->num_pages,
3291 +                         &topaz_priv->topaz_bo_kmap);
3292 +       if (ret) {
3293 +               DRM_ERROR("TOPAZ: map topaz BO bo failed......\n");
3294 +               ttm_bo_unref(&topaz_priv->topaz_bo);
3295 +               return ret;
3296 +       }
3297 +
3298 +       topaz_bo_virt = ttm_kmap_obj_virtual(&topaz_priv->topaz_bo_kmap,
3299 +                                            &is_iomem);
3300 +       topaz_priv->topaz_ccb_wb =  (void *) topaz_bo_virt;
3301 +       topaz_priv->topaz_wb_offset = topaz_priv->topaz_bo->offset;
3302 +       topaz_priv->topaz_sync_addr =  (uint32_t *) (topaz_bo_virt
3303 +                                                    + 2048);
3304 +       topaz_priv->topaz_sync_offset = topaz_priv->topaz_wb_offset
3305 +               + 2048;
3306 +       PSB_DEBUG_GENERAL("TOPAZ: alloc BO for WriteBack and SYNC\n");
3307 +       PSB_DEBUG_GENERAL("TOPAZ: WB offset=0x%08x\n",
3308 +                         topaz_priv->topaz_wb_offset);
3309 +       PSB_DEBUG_GENERAL("TOPAZ: SYNC offset=0x%08x\n",
3310 +                         topaz_priv->topaz_sync_offset);
3311 +
3312 +       *(topaz_priv->topaz_sync_addr) =  ~0; /* reset sync seq */
3313 +
3314 +       /* # reset topaz */
3315 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3316 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3317 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3318 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3319 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3320 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3321 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3322 +
3323 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3324 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3325 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3326 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3327 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3328 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3329 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3330 +
3331 +       /* # set up MMU */
3332 +       topaz_mmu_hwsetup(dev_priv);
3333 +
3334 +       PSB_DEBUG_GENERAL("TOPAZ: defer firmware loading to the place"
3335 +                         "when receiving user space commands\n");
3336 +
3337 +#if 0 /* can't load FW here */
3338 +       /* #.# load fw to driver */
3339 +       PSB_DEBUG_GENERAL("TOPAZ: will init firmware\n");
3340 +       ret = topaz_init_fw(dev);
3341 +       if (ret != 0)
3342 +               return -1;
3343 +
3344 +       topaz_setup_fw(dev, IMG_CODEC_MPEG4_NO_RC);/* just for test */
3345 +#endif
3346 +       /* <msvdx does> # minimal clock */
3347 +
3348 +       /* <msvdx does> # return 0 */
3349 +       TOPAZ_READ32(TOPAZ_CR_IMG_TOPAZ_CORE_ID, &core_id);
3350 +       TOPAZ_READ32(TOPAZ_CR_IMG_TOPAZ_CORE_REV, &core_rev);
3351 +
3352 +       PSB_DEBUG_GENERAL("TOPAZ: core_id(%x) core_rev(%x)\n",
3353 +                         core_id, core_rev);
3354 +
3355 +       /* create firmware storage */
3356 +       for (n = 1; n < IMG_CODEC_NUM; ++n) {
3357 +               /* #.# malloc DRM object for fw storage */
3358 +               ret = ttm_buffer_object_create(bdev, 12 * 4096,
3359 +                               ttm_bo_type_kernel,
3360 +                               DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT,
3361 +                               0, 0, 0, NULL, &topaz_priv->topaz_fw[n].text);
3362 +               if (ret) {
3363 +                       DRM_ERROR("Failed to allocate firmware.\n");
3364 +                       goto out;
3365 +               }
3366 +
3367 +               /* #.# malloc DRM object for fw storage */
3368 +               ret = ttm_buffer_object_create(bdev, 12 * 4096,
3369 +                               ttm_bo_type_kernel,
3370 +                               DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_NO_EVICT,
3371 +                               0, 0, 0, NULL, &topaz_priv->topaz_fw[n].data);
3372 +               if (ret) {
3373 +                       DRM_ERROR("Failed to allocate firmware.\n");
3374 +                       goto out;
3375 +               }
3376 +       }
3377 +
3378 +       ret = ttm_buffer_object_create(bdev,
3379 +                                      12 * 4096,
3380 +                                      ttm_bo_type_kernel,
3381 +                                      DRM_PSB_FLAG_MEM_MMU |
3382 +                                      TTM_PL_FLAG_NO_EVICT,
3383 +                                      0, 0, 0, NULL,
3384 +                                      &topaz_priv->topaz_mtx_data_mem);
3385 +       if (ret) {
3386 +               DRM_ERROR("TOPAZ: failed to allocate ttm buffer for "
3387 +                         "mtx data save\n");
3388 +               goto out;
3389 +       }
3390 +       topaz_priv->cur_mtx_data_size = 0;
3391 +
3392 +       PSB_DEBUG_INIT("TOPAZ:old clock gating disable = 0x%08x\n",
3393 +               PSB_RVDC32(PSB_TOPAZ_CLOCKGATING));
3394 +
3395 +       PSB_DEBUG_INIT("TOPAZ:rest MSDVX to disable clock gating\n");
3396 +
3397 +       PSB_WVDC32(0x00011fff, PSB_TOPAZ_CLOCKGATING);
3398 +
3399 +       PSB_DEBUG_INIT("MSDVX:new clock gating disable = 0x%08x\n",
3400 +               PSB_RVDC32(PSB_TOPAZ_CLOCKGATING));
3401 +
3402 +       return 0;
3403 +
3404 +out:
3405 +       for (n = 1; n < IMG_CODEC_NUM; ++n) {
3406 +               if (topaz_priv->topaz_fw[n].text != NULL)
3407 +                       ttm_bo_unref(&topaz_priv->topaz_fw[n].text);
3408 +               if (topaz_priv->topaz_fw[n].data != NULL)
3409 +                       ttm_bo_unref(&topaz_priv->topaz_fw[n].data);
3410 +       }
3411 +
3412 +       if (topaz_priv->topaz_mtx_data_mem != NULL)
3413 +               ttm_bo_unref(&topaz_priv->topaz_mtx_data_mem);
3414 +
3415 +       return ret;
3416 +}
3417 +
3418 +int lnc_topaz_uninit(struct drm_device *dev)
3419 +{
3420 +       struct drm_psb_private *dev_priv = dev->dev_private;
3421 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
3422 +       int n;
3423 +
3424 +       /* flush MMU */
3425 +       PSB_DEBUG_GENERAL("XXX: need to flush mmu cache here??\n");
3426 +       /* topaz_mmu_flushcache (dev_priv); */
3427 +
3428 +       /* # reset TOPAZ chip */
3429 +       lnc_topaz_reset(dev_priv);
3430 +
3431 +       /* release resources */
3432 +       /* # release write back memory */
3433 +       topaz_priv->topaz_ccb_wb = NULL;
3434 +
3435 +       /* release mtx register save space */
3436 +       kfree(topaz_priv->topaz_mtx_reg_state);
3437 +
3438 +       /* release mtx data memory save space */
3439 +       if (topaz_priv->topaz_mtx_data_mem)
3440 +               ttm_bo_unref(&topaz_priv->topaz_mtx_data_mem);
3441 +
3442 +       /* # release firmware storage */
3443 +       for (n = 1; n < IMG_CODEC_NUM; ++n) {
3444 +               if (topaz_priv->topaz_fw[n].text != NULL)
3445 +                       ttm_bo_unref(&topaz_priv->topaz_fw[n].text);
3446 +               if (topaz_priv->topaz_fw[n].data != NULL)
3447 +                       ttm_bo_unref(&topaz_priv->topaz_fw[n].data);
3448 +       }
3449 +
3450 +       ttm_bo_kunmap(&topaz_priv->topaz_bo_kmap);
3451 +       ttm_bo_unref(&topaz_priv->topaz_bo);
3452 +
3453 +       if (topaz_priv) {
3454 +               pci_set_drvdata(dev->pdev, NULL);
3455 +               device_remove_file(&dev->pdev->dev, &dev_attr_topaz_pmstate);
3456 +               sysfs_put(topaz_priv->sysfs_pmstate);
3457 +               topaz_priv->sysfs_pmstate = NULL;
3458 +
3459 +               kfree(topaz_priv);
3460 +               dev_priv->topaz_private = NULL;
3461 +       }
3462 +
3463 +       return 0;
3464 +}
3465 +
3466 +int lnc_topaz_reset(struct drm_psb_private *dev_priv)
3467 +{
3468 +       struct topaz_private *topaz_priv;
3469 +
3470 +       topaz_priv = dev_priv->topaz_private;
3471 +       topaz_priv->topaz_busy = 0;
3472 +       topaz_priv->topaz_cmd_seq = 0;
3473 +       topaz_priv->cur_mtx_data_size = 0;
3474 +       topaz_priv->topaz_cmd_windex = 0;
3475 +       topaz_priv->topaz_needs_reset = 0;
3476 +
3477 +       /* # reset topaz */
3478 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3479 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3480 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3481 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3482 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3483 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3484 +                    F_ENCODE(1, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3485 +
3486 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3487 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3488 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3489 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3490 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3491 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3492 +                    F_ENCODE(0, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3493 +
3494 +       /* # set up MMU */
3495 +       topaz_mmu_hwsetup(dev_priv);
3496 +
3497 +       return 0;
3498 +}
3499 +
3500 +/* read firmware bin file and load all data into driver */
3501 +int topaz_init_fw(struct drm_device *dev)
3502 +{
3503 +       struct drm_psb_private *dev_priv = dev->dev_private;
3504 +       const struct firmware *raw = NULL;
3505 +       unsigned char *ptr;
3506 +       int ret = 0;
3507 +       int n;
3508 +       struct topaz_fwinfo *cur_fw;
3509 +       int cur_size;
3510 +       struct topaz_codec_fw *cur_codec;
3511 +       struct ttm_buffer_object **cur_drm_obj;
3512 +       struct ttm_bo_kmap_obj tmp_kmap;
3513 +       bool is_iomem;
3514 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
3515 +
3516 +       topaz_priv->stored_initial_qp = 0;
3517 +
3518 +       /* # get firmware */
3519 +       ret = request_firmware(&raw, FIRMWARE_NAME, &dev->pdev->dev);
3520 +       if (ret != 0) {
3521 +               DRM_ERROR("TOPAZ: request_firmware failed: %d\n", ret);
3522 +               return ret;
3523 +       }
3524 +
3525 +       PSB_DEBUG_GENERAL("TOPAZ: opened firmware\n");
3526 +
3527 +       if (raw && (raw->size < sizeof(struct topaz_fwinfo))) {
3528 +               DRM_ERROR("TOPAZ: firmware file is not correct size.\n");
3529 +               goto out;
3530 +       }
3531 +
3532 +       ptr = (unsigned char *) raw->data;
3533 +
3534 +       if (!ptr) {
3535 +               DRM_ERROR("TOPAZ: failed to load firmware.\n");
3536 +               goto out;
3537 +       }
3538 +
3539 +       /* # load fw from file */
3540 +       PSB_DEBUG_GENERAL("TOPAZ: load firmware.....\n");
3541 +       cur_fw = NULL;
3542 +       /* didn't use the first element */
3543 +       for (n = 1; n < IMG_CODEC_NUM; ++n) {
3544 +               cur_fw = (struct topaz_fwinfo *) ptr;
3545 +
3546 +               cur_codec = &topaz_priv->topaz_fw[cur_fw->codec];
3547 +               cur_codec->ver = cur_fw->ver;
3548 +               cur_codec->codec = cur_fw->codec;
3549 +               cur_codec->text_size = cur_fw->text_size;
3550 +               cur_codec->data_size = cur_fw->data_size;
3551 +               cur_codec->data_location = cur_fw->data_location;
3552 +
3553 +               PSB_DEBUG_GENERAL("TOPAZ: load firemware %s.\n",
3554 +                               codec_to_string(cur_fw->codec));
3555 +
3556 +               /* #.# handle text section */
3557 +               ptr += sizeof(struct topaz_fwinfo);
3558 +               cur_drm_obj = &cur_codec->text;
3559 +               cur_size = cur_fw->text_size;
3560 +
3561 +               /* #.# fill DRM object with firmware data */
3562 +               ret = ttm_bo_kmap(*cur_drm_obj, 0, (*cur_drm_obj)->num_pages,
3563 +                               &tmp_kmap);
3564 +               if (ret) {
3565 +                       PSB_DEBUG_GENERAL("drm_bo_kmap failed: %d\n", ret);
3566 +                       ttm_bo_unref(cur_drm_obj);
3567 +                       *cur_drm_obj = NULL;
3568 +                       goto out;
3569 +               }
3570 +
3571 +               memcpy(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), ptr,
3572 +                      cur_size);
3573 +
3574 +               ttm_bo_kunmap(&tmp_kmap);
3575 +
3576 +               /* #.# handle data section */
3577 +               ptr += cur_fw->text_size;
3578 +               cur_drm_obj = &cur_codec->data;
3579 +               cur_size = cur_fw->data_size;
3580 +
3581 +               /* #.# fill DRM object with firmware data */
3582 +               ret = ttm_bo_kmap(*cur_drm_obj, 0, (*cur_drm_obj)->num_pages,
3583 +                               &tmp_kmap);
3584 +               if (ret) {
3585 +                       PSB_DEBUG_GENERAL("drm_bo_kmap failed: %d\n", ret);
3586 +                       ttm_bo_unref(cur_drm_obj);
3587 +                       *cur_drm_obj = NULL;
3588 +                       goto out;
3589 +               }
3590 +
3591 +               memcpy(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), ptr,
3592 +                      cur_size);
3593 +
3594 +               ttm_bo_kunmap(&tmp_kmap);
3595 +
3596 +               /* #.# validate firmware */
3597 +
3598 +               /* #.# update ptr */
3599 +               ptr += cur_fw->data_size;
3600 +       }
3601 +
3602 +       release_firmware(raw);
3603 +
3604 +       PSB_DEBUG_GENERAL("TOPAZ: return from firmware init\n");
3605 +
3606 +       return 0;
3607 +
3608 +out:
3609 +       if (raw) {
3610 +               PSB_DEBUG_GENERAL("release firmware....\n");
3611 +               release_firmware(raw);
3612 +       }
3613 +
3614 +       return -1;
3615 +}
3616 +
3617 +/* setup fw when start a new context */
3618 +int topaz_setup_fw(struct drm_device *dev, enum drm_lnc_topaz_codec codec)
3619 +{
3620 +       struct drm_psb_private *dev_priv = dev->dev_private;
3621 +       uint32_t mem_size = RAM_SIZE; /* follow DDK */
3622 +       uint32_t verify_pc;
3623 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
3624 +
3625 +#if 0
3626 +       if (codec == topaz_priv->topaz_current_codec) {
3627 +               LNC_TRACEL("TOPAZ: reuse previous codec\n");
3628 +               return 0;
3629 +       }
3630 +#endif
3631 +
3632 +       /* XXX: need to rest topaz? */
3633 +       PSB_DEBUG_GENERAL("XXX: should reset topaz when context change?\n");
3634 +
3635 +       /* XXX: interrupt enable shouldn't be enable here,
3636 +        * this funtion is called when interrupt is enable,
3637 +        * but here, we've no choice since we have to call setup_fw by
3638 +        * manual */
3639 +       /* # upload firmware, clear interruputs and start the firmware
3640 +        * -- from  hostutils.c in TestSuits*/
3641 +
3642 +       /* # reset MVEA */
3643 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3644 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3645 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3646 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3647 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3648 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3649 +               F_ENCODE(1, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3650 +
3651 +       MVEA_WRITE32(MVEA_CR_IMG_MVEA_SRST,
3652 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_SPE_SOFT_RESET) |
3653 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_IPE_SOFT_RESET) |
3654 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_CMPRS_SOFT_RESET) |
3655 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_JMCOMP_SOFT_RESET) |
3656 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_CMC_SOFT_RESET) |
3657 +               F_ENCODE(0, MVEA_CR_IMG_MVEA_DCF_SOFT_RESET));
3658 +
3659 +
3660 +       topaz_mmu_hwsetup(dev_priv);
3661 +
3662 +#if !LNC_TOPAZ_NO_IRQ
3663 +       sysirq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
3664 +#endif
3665 +
3666 +       PSB_DEBUG_GENERAL("TOPAZ: will setup firmware....\n");
3667 +
3668 +       topaz_set_default_regs(dev_priv);
3669 +
3670 +       /* # reset mtx */
3671 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_SRST,
3672 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_MVEA_SOFT_RESET) |
3673 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_MTX_SOFT_RESET) |
3674 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_VLC_SOFT_RESET));
3675 +
3676 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_SRST, 0x0);
3677 +
3678 +       /* # upload fw by drm */
3679 +       PSB_DEBUG_GENERAL("TOPAZ: will upload firmware\n");
3680 +
3681 +       topaz_upload_fw(dev, codec);
3682 +#if 0
3683 +       /* allocate the space for context save & restore if needed */
3684 +       if (topaz_priv->topaz_mtx_data_mem == NULL) {
3685 +               ret = ttm_buffer_object_create(bdev,
3686 +                                       topaz_priv->cur_mtx_data_size * 4,
3687 +                                       ttm_bo_type_kernel,
3688 +                                       DRM_PSB_FLAG_MEM_MMU |
3689 +                                       TTM_PL_FLAG_NO_EVICT,
3690 +                                       0, 0, 0, NULL,
3691 +                                       &topaz_priv->topaz_mtx_data_mem);
3692 +               if (ret) {
3693 +                       DRM_ERROR("TOPAZ: failed to allocate ttm buffer for "
3694 +                               "mtx data save\n");
3695 +                       return -1;
3696 +               }
3697 +       }
3698 +       PSB_DEBUG_GENERAL("TOPAZ: after upload fw ....\n");
3699 +#endif
3700 +
3701 +       /* XXX: In power save mode, need to save the complete data memory
3702 +        * and restore it. MTX_FWIF.c record the data size  */
3703 +       PSB_DEBUG_GENERAL("TOPAZ:in power save mode need to save memory?\n");
3704 +
3705 +       PSB_DEBUG_GENERAL("TOPAZ: setting up pc address\n");
3706 +       topaz_write_core_reg(dev_priv, TOPAZ_MTX_PC, PC_START_ADDRESS);
3707 +
3708 +       PSB_DEBUG_GENERAL("TOPAZ: verify pc address\n");
3709 +
3710 +       topaz_read_core_reg(dev_priv, TOPAZ_MTX_PC, &verify_pc);
3711 +
3712 +       /* enable auto clock is essential for this driver */
3713 +       TOPAZ_WRITE32(TOPAZ_CR_TOPAZ_AUTO_CLK_GATE,
3714 +               F_ENCODE(1, TOPAZ_CR_TOPAZ_VLC_AUTO_CLK_GATE) |
3715 +               F_ENCODE(1, TOPAZ_CR_TOPAZ_DB_AUTO_CLK_GATE));
3716 +       MVEA_WRITE32(MVEA_CR_MVEA_AUTO_CLOCK_GATING,
3717 +               F_ENCODE(1, MVEA_CR_MVEA_IPE_AUTO_CLK_GATE) |
3718 +               F_ENCODE(1, MVEA_CR_MVEA_SPE_AUTO_CLK_GATE) |
3719 +               F_ENCODE(1, MVEA_CR_MVEA_CMPRS_AUTO_CLK_GATE) |
3720 +               F_ENCODE(1, MVEA_CR_MVEA_JMCOMP_AUTO_CLK_GATE));
3721 +
3722 +       PSB_DEBUG_GENERAL("TOPAZ: current pc(%08X) vs %08X\n",
3723 +                       verify_pc, PC_START_ADDRESS);
3724 +
3725 +       /* # turn on MTX */
3726 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_INTCLEAR,
3727 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX));
3728 +
3729 +       MTX_WRITE32(MTX_CORE_CR_MTX_ENABLE_OFFSET,
3730 +               MTX_CORE_CR_MTX_ENABLE_MTX_ENABLE_MASK);
3731 +
3732 +       /* # poll on the interrupt which the firmware will generate */
3733 +       topaz_wait_for_register(dev_priv,
3734 +                               TOPAZ_START + TOPAZ_CR_IMG_TOPAZ_INTSTAT,
3735 +                               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTS_MTX),
3736 +                               F_MASK(TOPAZ_CR_IMG_TOPAZ_INTS_MTX));
3737 +
3738 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_INTCLEAR,
3739 +               F_ENCODE(1, TOPAZ_CR_IMG_TOPAZ_INTCLR_MTX));
3740 +
3741 +       PSB_DEBUG_GENERAL("TOPAZ: after topaz mtx setup ....\n");
3742 +
3743 +       /* # get ccb buffer addr -- file hostutils.c */
3744 +       topaz_priv->topaz_ccb_buffer_addr =
3745 +               topaz_read_mtx_mem(dev_priv,
3746 +                               MTX_DATA_MEM_BASE + mem_size - 4);
3747 +       topaz_priv->topaz_ccb_ctrl_addr =
3748 +               topaz_read_mtx_mem(dev_priv,
3749 +                               MTX_DATA_MEM_BASE + mem_size - 8);
3750 +       topaz_priv->topaz_ccb_size =
3751 +               topaz_read_mtx_mem(dev_priv,
3752 +                               topaz_priv->topaz_ccb_ctrl_addr +
3753 +                               MTX_CCBCTRL_CCBSIZE);
3754 +
3755 +       topaz_priv->topaz_cmd_windex = 0;
3756 +
3757 +       PSB_DEBUG_GENERAL("TOPAZ:ccb_buffer_addr(%x),ctrl_addr(%x) size(%d)\n",
3758 +                       topaz_priv->topaz_ccb_buffer_addr,
3759 +                       topaz_priv->topaz_ccb_ctrl_addr,
3760 +                       topaz_priv->topaz_ccb_size);
3761 +
3762 +       /* # write back the initial QP Value */
3763 +       topaz_write_mtx_mem(dev_priv,
3764 +                       topaz_priv->topaz_ccb_ctrl_addr + MTX_CCBCTRL_INITQP,
3765 +                       topaz_priv->stored_initial_qp);
3766 +
3767 +       PSB_DEBUG_GENERAL("TOPAZ: write WB mem address 0x%08x\n",
3768 +                       topaz_priv->topaz_wb_offset);
3769 +       topaz_write_mtx_mem(dev_priv, MTX_DATA_MEM_BASE + mem_size - 12,
3770 +                       topaz_priv->topaz_wb_offset);
3771 +
3772 +       /* this kick is essential for mtx.... */
3773 +       *((uint32_t *) topaz_priv->topaz_ccb_wb) = 0x01020304;
3774 +       topaz_mtx_kick(dev_priv, 1);
3775 +       DRM_UDELAY(1000);
3776 +       PSB_DEBUG_GENERAL("TOPAZ: DDK expected 0x12345678 in WB memory,"
3777 +                       " and here it is 0x%08x\n",
3778 +                       *((uint32_t *) topaz_priv->topaz_ccb_wb));
3779 +
3780 +       *((uint32_t *) topaz_priv->topaz_ccb_wb) = 0x0;/* reset it to 0 */
3781 +       PSB_DEBUG_GENERAL("TOPAZ: firmware uploaded.\n");
3782 +
3783 +       /* XXX: is there any need to record next cmd num??
3784 +        * we use fence seqence number to record it
3785 +        */
3786 +       topaz_priv->topaz_busy = 0;
3787 +       topaz_priv->topaz_cmd_seq = 0;
3788 +
3789 +#if !LNC_TOPAZ_NO_IRQ
3790 +       sysirq_preinstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
3791 +       sysirq_postinstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
3792 +       lnc_topaz_enableirq(dev);
3793 +#endif
3794 +
3795 +#if 0
3796 +       topaz_mmu_flushcache(dev_priv);
3797 +       topaz_test_null(dev, 0xe1e1);
3798 +       topaz_test_null(dev, 0xe2e2);
3799 +       topaz_test_sync(dev, 0xe2e2, 0x87654321);
3800 +
3801 +       topaz_mmu_test(dev, 0x12345678);
3802 +       topaz_test_null(dev, 0xe3e3);
3803 +       topaz_mmu_test(dev, 0x8764321);
3804 +
3805 +       topaz_test_null(dev, 0xe4e4);
3806 +       topaz_test_null(dev, 0xf3f3);
3807 +#endif
3808 +
3809 +       return 0;
3810 +}
3811 +
3812 +#if UPLOAD_FW_BY_DMA
3813 +int topaz_upload_fw(struct drm_device *dev, enum drm_lnc_topaz_codec codec)
3814 +{
3815 +       struct drm_psb_private *dev_priv = dev->dev_private;
3816 +       const struct topaz_codec_fw *cur_codec_fw;
3817 +       uint32_t text_size, data_size;
3818 +       uint32_t data_location;
3819 +       uint32_t cur_mtx_data_size;
3820 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
3821 +
3822 +       /* # refer HLD document */
3823 +
3824 +       /* # MTX reset */
3825 +       PSB_DEBUG_GENERAL("TOPAZ: mtx reset.\n");
3826 +       MTX_WRITE32(MTX_CORE_CR_MTX_SOFT_RESET_OFFSET,
3827 +               MTX_CORE_CR_MTX_SOFT_RESET_MTX_RESET_MASK);
3828 +
3829 +       DRM_UDELAY(6000);
3830 +
3831 +       /* # upload the firmware by DMA */
3832 +       cur_codec_fw = &topaz_priv->topaz_fw[codec];
3833 +
3834 +       PSB_DEBUG_GENERAL("Topaz:upload codec %s(%d) text sz=%d data sz=%d"
3835 +                       " data location(%d)\n", codec_to_string(codec), codec,
3836 +                       cur_codec_fw->text_size, cur_codec_fw->data_size,
3837 +                       cur_codec_fw->data_location);
3838 +
3839 +       /* # upload text */
3840 +       text_size = cur_codec_fw->text_size / 4;
3841 +
3842 +       /* setup the MTX to start recieving data:
3843 +          use a register for the transfer which will point to the source
3844 +          (MTX_CR_MTX_SYSC_CDMAT) */
3845 +       /* #.# fill the dst addr */
3846 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAA, 0x80900000);
3847 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAC,
3848 +               F_ENCODE(2, MTX_BURSTSIZE) |
3849 +               F_ENCODE(0, MTX_RNW) |
3850 +               F_ENCODE(1, MTX_ENABLE) |
3851 +               F_ENCODE(text_size, MTX_LENGTH));
3852 +
3853 +       /* #.# set DMAC access to host memory via BIF */
3854 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 1);
3855 +
3856 +       /* #.# transfer the codec */
3857 +       topaz_dma_transfer(dev_priv, 0, cur_codec_fw->text->offset, 0,
3858 +                       MTX_CR_MTX_SYSC_CDMAT, text_size, 0, 0);
3859 +
3860 +       /* #.# wait dma finish */
3861 +       topaz_wait_for_register(dev_priv,
3862 +                               DMAC_START + IMG_SOC_DMAC_IRQ_STAT(0),
3863 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN),
3864 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN));
3865 +
3866 +       /* #.# clear interrupt */
3867 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(0), 0);
3868 +
3869 +       /* # return access to topaz core */
3870 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 0);
3871 +
3872 +       /* # upload data */
3873 +       data_size = cur_codec_fw->data_size / 4;
3874 +       data_location = cur_codec_fw->data_location;
3875 +
3876 +       /* #.# fill the dst addr */
3877 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAA,
3878 +                   0x80900000 + (data_location - 0x82880000));
3879 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAC,
3880 +               F_ENCODE(2, MTX_BURSTSIZE) |
3881 +               F_ENCODE(0, MTX_RNW) |
3882 +               F_ENCODE(1, MTX_ENABLE) |
3883 +               F_ENCODE(data_size, MTX_LENGTH));
3884 +
3885 +       /* #.# set DMAC access to host memory via BIF */
3886 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 1);
3887 +
3888 +       /* #.# transfer the codec */
3889 +       topaz_dma_transfer(dev_priv, 0, cur_codec_fw->data->offset, 0,
3890 +                       MTX_CR_MTX_SYSC_CDMAT, data_size, 0, 0);
3891 +
3892 +       /* #.# wait dma finish */
3893 +       topaz_wait_for_register(dev_priv,
3894 +                               DMAC_START + IMG_SOC_DMAC_IRQ_STAT(0),
3895 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN),
3896 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN));
3897 +
3898 +       /* #.# clear interrupt */
3899 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(0), 0);
3900 +
3901 +       /* # return access to topaz core */
3902 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 0);
3903 +
3904 +       /* record this codec's mtx data size for
3905 +        * context save & restore */
3906 +       /* FIXME: since non-root sighting fixed by pre allocated,
3907 +        * only need to correct the buffer size
3908 +        */
3909 +       cur_mtx_data_size = data_size;
3910 +       if (topaz_priv->cur_mtx_data_size != cur_mtx_data_size)
3911 +               topaz_priv->cur_mtx_data_size = cur_mtx_data_size;
3912 +
3913 +       return 0;
3914 +}
3915 +
3916 +#else
3917 +
3918 +void topaz_mtx_upload_by_register(struct drm_device *dev, uint32_t mtx_mem,
3919 +                                 uint32_t addr, uint32_t size,
3920 +                                 struct ttm_buffer_object *buf)
3921 +{
3922 +       struct drm_psb_private *dev_priv = dev->dev_private;
3923 +       uint32_t *buf_p;
3924 +       uint32_t debug_reg, bank_size, bank_ram_size, bank_count;
3925 +       uint32_t cur_ram_id, ram_addr , ram_id;
3926 +       int map_ret, lp;
3927 +       struct ttm_bo_kmap_obj bo_kmap;
3928 +       bool is_iomem;
3929 +       uint32_t cur_addr;
3930 +
3931 +       get_mtx_control_from_dash(dev_priv);
3932 +
3933 +       map_ret = ttm_bo_kmap(buf, 0, buf->num_pages, &bo_kmap);
3934 +       if (map_ret) {
3935 +               DRM_ERROR("TOPAZ: drm_bo_kmap failed: %d\n", map_ret);
3936 +               return;
3937 +       }
3938 +       buf_p = (uint32_t *) ttm_kmap_obj_virtual(&bo_kmap, &is_iomem);
3939 +
3940 +
3941 +       TOPAZ_READ32(TOPAZ_CORE_CR_MTX_DEBUG_OFFSET, &debug_reg);
3942 +       debug_reg = 0x0a0a0606;
3943 +       bank_size = (debug_reg & 0xf0000) >> 16;
3944 +       bank_ram_size = 1 << (bank_size + 2);
3945 +
3946 +       bank_count = (debug_reg & 0xf00) >> 8;
3947 +
3948 +       topaz_wait_for_register(dev_priv,
3949 +               MTX_START+MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_OFFSET,
3950 +               MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_MTX_MTX_MCM_STAT_MASK,
3951 +               MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_MTX_MTX_MCM_STAT_MASK);
3952 +
3953 +       cur_ram_id = -1;
3954 +       cur_addr = addr;
3955 +       for (lp = 0; lp < size / 4; ++lp) {
3956 +               ram_id = mtx_mem + (cur_addr / bank_ram_size);
3957 +
3958 +               if (cur_ram_id != ram_id) {
3959 +                       ram_addr = cur_addr >> 2;
3960 +
3961 +                       MTX_WRITE32(MTX_CORE_CR_MTX_RAM_ACCESS_CONTROL_OFFSET,
3962 +                               F_ENCODE(ram_id, MTX_MTX_MCMID) |
3963 +                               F_ENCODE(ram_addr, MTX_MTX_MCM_ADDR) |
3964 +                               F_ENCODE(1, MTX_MTX_MCMAI));
3965 +
3966 +                       cur_ram_id = ram_id;
3967 +               }
3968 +               cur_addr += 4;
3969 +
3970 +               MTX_WRITE32(MTX_CORE_CR_MTX_RAM_ACCESS_DATA_TRANSFER_OFFSET,
3971 +                       *(buf_p + lp));
3972 +
3973 +               topaz_wait_for_register(dev_priv,
3974 +                       MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_OFFSET + MTX_START,
3975 +               MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_MTX_MTX_MCM_STAT_MASK,
3976 +               MTX_CORE_CR_MTX_RAM_ACCESS_STATUS_MTX_MTX_MCM_STAT_MASK);
3977 +       }
3978 +
3979 +       ttm_bo_kunmap(&bo_kmap);
3980 +
3981 +       PSB_DEBUG_GENERAL("TOPAZ: register data upload done\n");
3982 +       return;
3983 +}
3984 +
3985 +int topaz_upload_fw(struct drm_device *dev, enum drm_lnc_topaz_codec codec)
3986 +{
3987 +       struct drm_psb_private *dev_priv = dev->dev_private;
3988 +       const struct topaz_codec_fw *cur_codec_fw;
3989 +       uint32_t text_size, data_size;
3990 +       uint32_t data_location;
3991 +
3992 +       /* # refer HLD document */
3993 +       /* # MTX reset */
3994 +       PSB_DEBUG_GENERAL("TOPAZ: mtx reset.\n");
3995 +       MTX_WRITE32(MTX_CORE_CR_MTX_SOFT_RESET_OFFSET,
3996 +                   MTX_CORE_CR_MTX_SOFT_RESET_MTX_RESET_MASK);
3997 +
3998 +       DRM_UDELAY(6000);
3999 +
4000 +       /* # upload the firmware by DMA */
4001 +       cur_codec_fw = &topaz_priv->topaz_fw[codec];
4002 +
4003 +       PSB_DEBUG_GENERAL("Topaz: upload codec %s text size(%d) data size(%d)"
4004 +                       " data location(0x%08x)\n", codec_to_string(codec),
4005 +                       cur_codec_fw->text_size, cur_codec_fw->data_size,
4006 +                       cur_codec_fw->data_location);
4007 +
4008 +       /* # upload text */
4009 +       text_size = cur_codec_fw->text_size;
4010 +
4011 +       topaz_mtx_upload_by_register(dev, LNC_MTX_CORE_CODE_MEM,
4012 +                                    PC_START_ADDRESS - MTX_MEMORY_BASE,
4013 +                                    text_size, cur_codec_fw->text);
4014 +
4015 +       /* # upload data */
4016 +       data_size = cur_codec_fw->data_size;
4017 +       data_location = cur_codec_fw->data_location;
4018 +
4019 +       topaz_mtx_upload_by_register(dev, LNC_MTX_CORE_DATA_MEM,
4020 +                                    data_location - 0x82880000, data_size,
4021 +                                    cur_codec_fw->data);
4022 +
4023 +       return 0;
4024 +}
4025 +
4026 +#endif /* UPLOAD_FW_BY_DMA */
4027 +
4028 +void
4029 +topaz_dma_transfer(struct drm_psb_private *dev_priv, uint32_t channel,
4030 +                  uint32_t src_phy_addr, uint32_t offset,
4031 +                  uint32_t soc_addr, uint32_t byte_num,
4032 +                  uint32_t is_increment, uint32_t is_write)
4033 +{
4034 +       uint32_t dmac_count;
4035 +       uint32_t irq_stat;
4036 +       uint32_t count;
4037 +
4038 +       PSB_DEBUG_GENERAL("TOPAZ: using dma to transfer firmware\n");
4039 +       /* # check that no transfer is currently in progress and no
4040 +          interrupts are outstanding ?? (why care interrupt) */
4041 +       DMAC_READ32(IMG_SOC_DMAC_COUNT(channel), &dmac_count);
4042 +       if (0 != (dmac_count & (MASK_IMG_SOC_EN | MASK_IMG_SOC_LIST_EN)))
4043 +               DRM_ERROR("TOPAZ: there is tranfer in progress\n");
4044 +
4045 +       /* assert(0==(dmac_count & (MASK_IMG_SOC_EN | MASK_IMG_SOC_LIST_EN)));*/
4046 +
4047 +       /* no hold off period */
4048 +       DMAC_WRITE32(IMG_SOC_DMAC_PER_HOLD(channel), 0);
4049 +       /* clear previous interrupts */
4050 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(channel), 0);
4051 +       /* check irq status */
4052 +       DMAC_READ32(IMG_SOC_DMAC_IRQ_STAT(channel), &irq_stat);
4053 +       /* assert(0 == irq_stat); */
4054 +       if (0 != irq_stat)
4055 +               DRM_ERROR("TOPAZ: there is hold up\n");
4056 +
4057 +       DMAC_WRITE32(IMG_SOC_DMAC_SETUP(channel),
4058 +                    (src_phy_addr + offset));
4059 +       count = DMAC_VALUE_COUNT(DMAC_BSWAP_NO_SWAP, DMAC_PWIDTH_32_BIT,
4060 +                               is_write, DMAC_PWIDTH_32_BIT, byte_num);
4061 +       /* generate an interrupt at the end of transfer */
4062 +       count |= MASK_IMG_SOC_TRANSFER_IEN;
4063 +       count |= F_ENCODE(is_write, IMG_SOC_DIR);
4064 +       DMAC_WRITE32(IMG_SOC_DMAC_COUNT(channel), count);
4065 +
4066 +       DMAC_WRITE32(IMG_SOC_DMAC_PERIPH(channel),
4067 +                    DMAC_VALUE_PERIPH_PARAM(DMAC_ACC_DEL_0,
4068 +                                            is_increment, DMAC_BURST_2));
4069 +
4070 +       DMAC_WRITE32(IMG_SOC_DMAC_PERIPHERAL_ADDR(channel), soc_addr);
4071 +
4072 +       /* Finally, rewrite the count register with
4073 +        * the enable bit set to kick off the transfer
4074 +        */
4075 +       DMAC_WRITE32(IMG_SOC_DMAC_COUNT(channel), count | MASK_IMG_SOC_EN);
4076 +
4077 +       PSB_DEBUG_GENERAL("TOPAZ: dma transfer started.\n");
4078 +
4079 +       return;
4080 +}
4081 +
4082 +void topaz_set_default_regs(struct drm_psb_private *dev_priv)
4083 +{
4084 +       int n;
4085 +       int count = sizeof(topaz_default_regs) / (sizeof(unsigned long) * 3);
4086 +
4087 +       for (n = 0; n < count; n++)
4088 +               MM_WRITE32(topaz_default_regs[n][0],
4089 +                          topaz_default_regs[n][1],
4090 +                          topaz_default_regs[n][2]);
4091 +
4092 +}
4093 +
4094 +void topaz_write_core_reg(struct drm_psb_private *dev_priv, uint32_t reg,
4095 +                         const uint32_t val)
4096 +{
4097 +       uint32_t tmp;
4098 +       get_mtx_control_from_dash(dev_priv);
4099 +
4100 +       /* put data into MTX_RW_DATA */
4101 +       MTX_WRITE32(MTX_CORE_CR_MTX_REGISTER_READ_WRITE_DATA_OFFSET, val);
4102 +
4103 +       /* request a write */
4104 +       tmp = reg &
4105 +               ~MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK;
4106 +       MTX_WRITE32(MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_OFFSET, tmp);
4107 +
4108 +       /* wait for operation finished */
4109 +       topaz_wait_for_register(dev_priv,
4110 +               MTX_START +
4111 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_OFFSET,
4112 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK,
4113 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK);
4114 +
4115 +       release_mtx_control_from_dash(dev_priv);
4116 +}
4117 +
4118 +void topaz_read_core_reg(struct drm_psb_private *dev_priv, uint32_t reg,
4119 +                       uint32_t *ret_val)
4120 +{
4121 +       uint32_t tmp;
4122 +
4123 +       get_mtx_control_from_dash(dev_priv);
4124 +
4125 +       /* request a write */
4126 +       tmp = (reg &
4127 +               ~MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK);
4128 +       MTX_WRITE32(MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_OFFSET,
4129 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_MASK | tmp);
4130 +
4131 +       /* wait for operation finished */
4132 +       topaz_wait_for_register(dev_priv,
4133 +               MTX_START +
4134 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_OFFSET,
4135 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK,
4136 +               MTX_CORE_CR_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK);
4137 +
4138 +       /* read  */
4139 +       MTX_READ32(MTX_CORE_CR_MTX_REGISTER_READ_WRITE_DATA_OFFSET,
4140 +                  ret_val);
4141 +
4142 +       release_mtx_control_from_dash(dev_priv);
4143 +}
4144 +
4145 +void get_mtx_control_from_dash(struct drm_psb_private *dev_priv)
4146 +{
4147 +       int debug_reg_slave_val;
4148 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4149 +
4150 +       /* GetMTXControlFromDash */
4151 +       TOPAZ_WRITE32(TOPAZ_CORE_CR_MTX_DEBUG_OFFSET,
4152 +                     F_ENCODE(1, TOPAZ_CR_MTX_DBG_IS_SLAVE) |
4153 +                     F_ENCODE(2, TOPAZ_CR_MTX_DBG_GPIO_OUT));
4154 +       do {
4155 +               TOPAZ_READ32(TOPAZ_CORE_CR_MTX_DEBUG_OFFSET,
4156 +                            &debug_reg_slave_val);
4157 +       } while ((debug_reg_slave_val & 0x18) != 0);
4158 +
4159 +       /* save access control */
4160 +       TOPAZ_READ32(MTX_CORE_CR_MTX_RAM_ACCESS_CONTROL_OFFSET,
4161 +                    &topaz_priv->topaz_dash_access_ctrl);
4162 +}
4163 +
4164 +void release_mtx_control_from_dash(struct drm_psb_private *dev_priv)
4165 +{
4166 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4167 +
4168 +       /* restore access control */
4169 +       TOPAZ_WRITE32(MTX_CORE_CR_MTX_RAM_ACCESS_CONTROL_OFFSET,
4170 +                     topaz_priv->topaz_dash_access_ctrl);
4171 +
4172 +       /* release bus */
4173 +       TOPAZ_WRITE32(TOPAZ_CORE_CR_MTX_DEBUG_OFFSET,
4174 +                     F_ENCODE(1, TOPAZ_CR_MTX_DBG_IS_SLAVE));
4175 +}
4176 +
4177 +void topaz_mmu_hwsetup(struct drm_psb_private *dev_priv)
4178 +{
4179 +       uint32_t pd_addr = psb_get_default_pd_addr(dev_priv->mmu);
4180 +
4181 +       /* bypass all request while MMU is being configured */
4182 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_CONTROL0,
4183 +                     F_ENCODE(1, TOPAZ_CR_MMU_BYPASS));
4184 +
4185 +       /* set MMU hardware at the page table directory */
4186 +       PSB_DEBUG_GENERAL("TOPAZ: write PD phyaddr=0x%08x "
4187 +                       "into MMU_DIR_LIST0/1\n", pd_addr);
4188 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_DIR_LIST_BASE(0), pd_addr);
4189 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_DIR_LIST_BASE(1), 0);
4190 +
4191 +       /* setup index register, all pointing to directory bank 0 */
4192 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_BANK_INDEX, 0);
4193 +
4194 +       /* now enable MMU access for all requestors */
4195 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_CONTROL0, 0);
4196 +}
4197 +
4198 +void topaz_mmu_flushcache(struct drm_psb_private *dev_priv)
4199 +{
4200 +       uint32_t mmu_control;
4201 +
4202 +       if (dev_priv->topaz_disabled)
4203 +               return;
4204 +
4205 +#if 0
4206 +       PSB_DEBUG_GENERAL("XXX: Only one PTD/PTE cache"
4207 +                       " so flush using the master core\n");
4208 +#endif
4209 +       /* XXX: disable interrupt */
4210 +
4211 +       TOPAZ_READ32(TOPAZ_CR_MMU_CONTROL0, &mmu_control);
4212 +       mmu_control |= F_ENCODE(1, TOPAZ_CR_MMU_INVALDC);
4213 +       mmu_control |= F_ENCODE(1, TOPAZ_CR_MMU_FLUSH);
4214 +
4215 +#if 0
4216 +       PSB_DEBUG_GENERAL("Set Invalid flag (this causes a flush with MMU\n"
4217 +                  "still operating afterwards even if not cleared,\n"
4218 +                  "but may want to replace with MMU_FLUSH?\n");
4219 +#endif
4220 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_CONTROL0, mmu_control);
4221 +
4222 +       /* clear it */
4223 +       mmu_control &= (~F_ENCODE(1, TOPAZ_CR_MMU_INVALDC));
4224 +       mmu_control &= (~F_ENCODE(1, TOPAZ_CR_MMU_FLUSH));
4225 +       TOPAZ_WRITE32(TOPAZ_CR_MMU_CONTROL0, mmu_control);
4226 +}
4227 +
4228 +#if DEBUG_FUNCTION
4229 +
4230 +static int topaz_test_sync(struct drm_device *dev, uint32_t seq,
4231 +                       uint32_t sync_seq)
4232 +{
4233 +       struct drm_psb_private *dev_priv = dev->dev_private;
4234 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4235 +       uint32_t sync_cmd[3];
4236 +       struct topaz_cmd_header *cmd_hdr;
4237 +       uint32_t *sync_p = (uint32_t *)topaz_priv->topaz_sync_addr;
4238 +       int count = 1000;
4239 +       uint32_t clr_flag;
4240 +
4241 +       cmd_hdr = (struct topaz_cmd_header *)&sync_cmd[0];
4242 +
4243 +       /* reset sync area */
4244 +       *sync_p = 0;
4245 +
4246 +       /* insert a SYNC command here */
4247 +       cmd_hdr->id = MTX_CMDID_SYNC;
4248 +       cmd_hdr->size = 3;
4249 +       cmd_hdr->seq = seq;
4250 +
4251 +       sync_cmd[1] = topaz_priv->topaz_sync_offset;
4252 +       sync_cmd[2] = sync_seq;
4253 +
4254 +       TOPAZ_BEGIN_CCB(dev_priv);
4255 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[0]);
4256 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[1]);
4257 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[2]);
4258 +       TOPAZ_END_CCB(dev_priv, 1);
4259 +
4260 +       PSB_DEBUG_GENERAL("Topaz: Sent SYNC with cmd seq=0x%08x,"
4261 +                       "sync_seq=0x%08x\n", seq, sync_seq);
4262 +
4263 +       while (count && *sync_p != sync_seq) {
4264 +               DRM_UDELAY(100);
4265 +               --count;
4266 +       }
4267 +       if ((count == 0) && (*sync_p != sync_seq)) {
4268 +               DRM_ERROR("TOPAZ: wait sycn timeout, expect sync seq 0x%08x,"
4269 +                       "actual 0x%08x\n", sync_seq, *sync_p);
4270 +       }
4271 +       PSB_DEBUG_GENERAL("TOPAZ: SYNC succeed, sync seq=0x%08x\n", *sync_p);
4272 +       PSB_DEBUG_GENERAL("Topaz: after SYNC test, query IRQ and clear it\n");
4273 +
4274 +       clr_flag = lnc_topaz_queryirq(dev);
4275 +       lnc_topaz_clearirq(dev, clr_flag);
4276 +
4277 +       return 0;
4278 +}
4279 +static int topaz_test_sync_tt_test(struct drm_device *dev,
4280 +                                  uint32_t seq,
4281 +                                  uint32_t sync_seq)
4282 +{
4283 +       struct drm_psb_private *dev_priv = dev->dev_private;
4284 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
4285 +       int ret;
4286 +       bool is_iomem;
4287 +       struct ttm_buffer_object *test_obj;
4288 +       struct ttm_bo_kmap_obj test_kmap;
4289 +       unsigned int *test_adr;
4290 +       uint32_t sync_cmd[3];
4291 +       int count = 1000;
4292 +       unsigned long pfn;
4293 +
4294 +       ret = ttm_buffer_object_create(bdev, 4096,
4295 +                                      ttm_bo_type_kernel,
4296 +                                      TTM_PL_FLAG_TT | TTM_PL_FLAG_NO_EVICT,
4297 +                                      0, 0, 0, NULL, &test_obj);
4298 +       if (ret) {
4299 +               DRM_ERROR("failed create test object buffer\n");
4300 +               return -1;
4301 +       }
4302 +
4303 +       ret = psb_mmu_virtual_to_pfn(psb_mmu_get_default_pd(dev_priv->mmu),
4304 +                                    test_obj->offset, &pfn);
4305 +       if (ret) {
4306 +               DRM_ERROR("failed to get pfn from virtual\n");
4307 +               return -1;
4308 +       }
4309 +
4310 +       PSB_DEBUG_GENERAL("Topaz:offset %lx, pfn %lx\n", test_obj->offset, pfn);
4311 +
4312 +       ret = ttm_bo_kmap(test_obj, 0, test_obj->num_pages,
4313 +                         &test_kmap);
4314 +       if (ret) {
4315 +               DRM_ERROR("failed map buffer\n");
4316 +               return -1;
4317 +       }
4318 +       test_adr = ttm_kmap_obj_virtual(&test_kmap, &is_iomem);
4319 +       *test_adr = 0xff55;
4320 +       ttm_bo_kunmap(&test_kmap);
4321 +
4322 +       /* insert a SYNC command here */
4323 +       sync_cmd[0] = (MTX_CMDID_SYNC << 1) | (3 << 8) |
4324 +               (seq << 16);
4325 +       sync_cmd[1] = test_obj->offset;
4326 +       sync_cmd[2] = sync_seq;
4327 +
4328 +       TOPAZ_BEGIN_CCB(dev_priv);
4329 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[0]);
4330 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[1]);
4331 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[2]);
4332 +       TOPAZ_END_CCB(dev_priv, 1);
4333 +
4334 +       ret = ttm_bo_kmap(test_obj, 0, test_obj->num_pages,
4335 +                         &test_kmap);
4336 +       if (ret) {
4337 +               DRM_ERROR("failed map buffer\n");
4338 +               return -1;
4339 +       }
4340 +       test_adr = ttm_kmap_obj_virtual(&test_kmap, &is_iomem);
4341 +
4342 +       while (count && *test_adr != sync_seq) {
4343 +               DRM_UDELAY(100);
4344 +               --count;
4345 +       }
4346 +       if ((count == 0) && (*test_adr != sync_seq)) {
4347 +               DRM_ERROR("TOPAZ: wait sycn timeout (0x%08x),"
4348 +                         "actual 0x%08x\n",
4349 +                         sync_seq, *test_adr);
4350 +       }
4351 +       PSB_DEBUG_GENERAL("TOPAZ: SYNC done, seq=0x%08x\n", *test_adr);
4352 +       ttm_bo_kunmap(&test_kmap);
4353 +       ttm_bo_unref(&test_obj);
4354 +
4355 +       return 0;
4356 +}
4357 +
4358 +static int topaz_test_sync_manual_alloc_page(struct drm_device *dev,
4359 +                                            uint32_t seq,
4360 +                                            uint32_t sync_seq,
4361 +                                            uint32_t offset)
4362 +{
4363 +       struct drm_psb_private *dev_priv = dev->dev_private;
4364 +       int ret;
4365 +       uint32_t sync_cmd[3];
4366 +       int count = 1000;
4367 +       unsigned long pfn;
4368 +
4369 +       struct page *p;
4370 +       uint32_t *v;
4371 +/*     uint32_t offset = 0xd0000000; */
4372 +
4373 +       p = alloc_page(GFP_DMA32);
4374 +       if (!p) {
4375 +               DRM_ERROR("Topaz:Failed allocating page\n");
4376 +               return -1;
4377 +       }
4378 +
4379 +       v = kmap(p);
4380 +       memset(v, 0x67, PAGE_SIZE);
4381 +       pfn = (offset >> PAGE_SHIFT);
4382 +       kunmap(p);
4383 +
4384 +       ret = psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu),
4385 +                                  &p, pfn << PAGE_SHIFT, 1, 0, 0, 0);
4386 +       if (ret) {
4387 +               DRM_ERROR("Topaz:Failed inserting mmu page\n");
4388 +               return -1;
4389 +       }
4390 +
4391 +       /* insert a SYNC command here */
4392 +       sync_cmd[0] = (MTX_CMDID_SYNC << 1) | (3 << 8) |
4393 +               (0x5b << 16);
4394 +       sync_cmd[1] = pfn << PAGE_SHIFT;
4395 +       sync_cmd[2] = seq;
4396 +
4397 +       TOPAZ_BEGIN_CCB(dev_priv);
4398 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[0]);
4399 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[1]);
4400 +       TOPAZ_OUT_CCB(dev_priv, sync_cmd[2]);
4401 +       TOPAZ_END_CCB(dev_priv, 1);
4402 +
4403 +       v = kmap(p);
4404 +       while (count && *v != sync_seq) {
4405 +               DRM_UDELAY(100);
4406 +               --count;
4407 +       }
4408 +       if ((count == 0) && (*v != sync_seq)) {
4409 +               DRM_ERROR("TOPAZ: wait sycn timeout (0x%08x),"
4410 +                         "actual 0x%08x\n",
4411 +                         sync_seq, *v);
4412 +       }
4413 +       PSB_DEBUG_GENERAL("TOPAZ: SYNC done, seq=0x%08x\n", *v);
4414 +       kunmap(p);
4415 +
4416 +       return 0;
4417 +}
4418 +
4419 +static int topaz_test_null(struct drm_device *dev, uint32_t seq)
4420 +{
4421 +       struct drm_psb_private *dev_priv = dev->dev_private;
4422 +       struct topaz_cmd_header null_cmd;
4423 +       uint32_t clr_flag;
4424 +
4425 +       /* XXX: here we finished firmware setup....
4426 +        * using a NULL command to verify the
4427 +        * correctness of firmware
4428 +        */
4429 +
4430 +       null_cmd.id = MTX_CMDID_NULL;
4431 +       null_cmd.size = 1;
4432 +       null_cmd.seq = seq;
4433 +
4434 +       TOPAZ_BEGIN_CCB(dev_priv);
4435 +       TOPAZ_OUT_CCB(dev_priv, *((uint32_t *)&null_cmd));
4436 +       TOPAZ_END_CCB(dev_priv, 1);
4437 +
4438 +       DRM_UDELAY(1000); /* wait to finish */
4439 +
4440 +       PSB_DEBUG_GENERAL("Topaz: Sent NULL with sequence=0x%08x,"
4441 +                       " got sequence=0x%08x (WB_seq=0x%08x,WB_roff=%d)\n",
4442 +                       seq, CCB_CTRL_SEQ(dev_priv), WB_CCB_CTRL_SEQ(dev_priv),
4443 +                       WB_CCB_CTRL_RINDEX(dev_priv));
4444 +
4445 +       PSB_DEBUG_GENERAL("Topaz: after NULL test, query IRQ and clear it\n");
4446 +
4447 +       clr_flag = lnc_topaz_queryirq(dev);
4448 +       lnc_topaz_clearirq(dev, clr_flag);
4449 +
4450 +       return 0;
4451 +}
4452 +
4453 +
4454 +/*
4455 + * this function will test whether the mmu is correct:
4456 + * it get a drm_buffer_object and use CMD_SYNC to write
4457 + * certain value into this buffer.
4458 + */
4459 +static void topaz_mmu_test(struct drm_device *dev, uint32_t sync_value)
4460 +{
4461 +       struct drm_psb_private *dev_priv = dev->dev_private;
4462 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4463 +       unsigned long real_pfn;
4464 +       int ret;
4465 +
4466 +       /* topaz_mmu_flush(dev); */
4467 +       topaz_test_sync(dev, 0x55, sync_value);
4468 +
4469 +       ret = psb_mmu_virtual_to_pfn(psb_mmu_get_default_pd(dev_priv->mmu),
4470 +                               topaz_priv->topaz_sync_offset, &real_pfn);
4471 +       if (ret != 0) {
4472 +               PSB_DEBUG_GENERAL("psb_mmu_virtual_to_pfn failed,exit\n");
4473 +               return;
4474 +       }
4475 +       PSB_DEBUG_GENERAL("TOPAZ: issued SYNC command, "
4476 +                       "BO offset=0x%08x (pfn=%lu), synch value=0x%08x\n",
4477 +                       topaz_priv->topaz_sync_offset, real_pfn, sync_value);
4478 +}
4479 +
4480 +void topaz_save_default_regs(struct drm_psb_private *dev_priv, uint32_t *data)
4481 +{
4482 +       int n;
4483 +       int count;
4484 +
4485 +       count = sizeof(topaz_default_regs) / (sizeof(unsigned long) * 3);
4486 +       for (n = 0; n < count; n++, ++data)
4487 +               MM_READ32(topaz_default_regs[n][0],
4488 +                          topaz_default_regs[n][1],
4489 +                          data);
4490 +
4491 +}
4492 +
4493 +void topaz_restore_default_regs(struct drm_psb_private *dev_priv,
4494 +                               uint32_t *data)
4495 +{
4496 +       int n;
4497 +       int count;
4498 +
4499 +       count = sizeof(topaz_default_regs) / (sizeof(unsigned long) * 3);
4500 +       for (n = 0; n < count; n++, ++data)
4501 +               MM_WRITE32(topaz_default_regs[n][0],
4502 +                          topaz_default_regs[n][1],
4503 +                          *data);
4504 +
4505 +}
4506 +
4507 +#endif
4508 +
4509 +int lnc_topaz_restore_mtx_state(struct drm_device *dev)
4510 +{
4511 +       struct drm_psb_private *dev_priv =
4512 +           (struct drm_psb_private *)dev->dev_private;
4513 +       uint32_t reg_val;
4514 +       uint32_t *mtx_reg_state;
4515 +       int i;
4516 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4517 +
4518 +       if (!topaz_priv->topaz_mtx_saved)
4519 +               return -1;
4520 +
4521 +       if (topaz_priv->topaz_mtx_data_mem == NULL) {
4522 +               PSB_DEBUG_GENERAL("TOPAZ: try to restore context without "
4523 +                       "space allocated, return directly without restore\n");
4524 +               return -1;
4525 +       }
4526 +
4527 +       /* turn on mtx clocks */
4528 +       MTX_READ32(TOPAZ_CR_TOPAZ_MAN_CLK_GATE, &reg_val);
4529 +       MTX_WRITE32(TOPAZ_CR_TOPAZ_MAN_CLK_GATE,
4530 +               reg_val & (~MASK_TOPAZ_CR_TOPAZ_MTX_MAN_CLK_GATE));
4531 +
4532 +       /* reset mtx */
4533 +       /* FIXME: should use core_write??? */
4534 +       MTX_WRITE32(MTX_CORE_CR_MTX_SOFT_RESET_OFFSET,
4535 +               MTX_CORE_CR_MTX_SOFT_RESET_MTX_RESET_MASK);
4536 +       DRM_UDELAY(6000);
4537 +
4538 +       topaz_mmu_hwsetup(dev_priv);
4539 +       /* upload code, restore mtx data */
4540 +       mtx_dma_write(dev);
4541 +
4542 +       mtx_reg_state = topaz_priv->topaz_mtx_reg_state;
4543 +       /* restore register */
4544 +       /* FIXME: conside to put read/write into one function */
4545 +       /* Saves 8 Registers of D0 Bank  */
4546 +       /* DoRe0, D0Ar6, D0Ar4, D0Ar2, D0FrT, D0.5, D0.6 and D0.7 */
4547 +       for (i = 0; i < 8; i++) {
4548 +               topaz_write_core_reg(dev_priv, 0x1 | (i<<4),
4549 +                               *mtx_reg_state);
4550 +               mtx_reg_state++;
4551 +       }
4552 +       /* Saves 8 Registers of D1 Bank  */
4553 +       /* D1Re0, D1Ar5, D1Ar3, D1Ar1, D1RtP, D1.5, D1.6 and D1.7 */
4554 +       for (i = 0; i < 8; i++) {
4555 +               topaz_write_core_reg(dev_priv, 0x2 | (i<<4),
4556 +                               *mtx_reg_state);
4557 +               mtx_reg_state++;
4558 +       }
4559 +       /* Saves 4 Registers of A0 Bank  */
4560 +       /* A0StP, A0FrP, A0.2 and A0.3 */
4561 +       for (i = 0; i < 4; i++) {
4562 +               topaz_write_core_reg(dev_priv, 0x3 | (i<<4),
4563 +                               *mtx_reg_state);
4564 +               mtx_reg_state++;
4565 +       }
4566 +       /* Saves 4 Registers of A1 Bank  */
4567 +       /* A1GbP, A1LbP, A1.2 and A1.3 */
4568 +       for (i = 0; i < 4; i++) {
4569 +               topaz_write_core_reg(dev_priv, 0x4 | (i<<4),
4570 +                               *mtx_reg_state);
4571 +               mtx_reg_state++;
4572 +       }
4573 +       /* Saves PC and PCX  */
4574 +       for (i = 0; i < 2; i++) {
4575 +               topaz_write_core_reg(dev_priv, 0x5 | (i<<4),
4576 +                               *mtx_reg_state);
4577 +               mtx_reg_state++;
4578 +       }
4579 +       /* Saves 8 Control Registers */
4580 +       /* TXSTAT, TXMASK, TXSTATI, TXMASKI, TXPOLL, TXGPIOI, TXPOLLI,
4581 +        * TXGPIOO */
4582 +       for (i = 0; i < 8; i++) {
4583 +               topaz_write_core_reg(dev_priv, 0x7 | (i<<4),
4584 +                               *mtx_reg_state);
4585 +               mtx_reg_state++;
4586 +       }
4587 +
4588 +       /* turn on MTX */
4589 +       MTX_WRITE32(MTX_CORE_CR_MTX_ENABLE_OFFSET,
4590 +               MTX_CORE_CR_MTX_ENABLE_MTX_ENABLE_MASK);
4591 +
4592 +       topaz_priv->topaz_mtx_saved = 0;
4593 +
4594 +       return 0;
4595 +}
4596 +
4597 +int lnc_topaz_save_mtx_state(struct drm_device *dev)
4598 +{
4599 +       struct drm_psb_private *dev_priv =
4600 +               (struct drm_psb_private *)dev->dev_private;
4601 +       uint32_t *mtx_reg_state;
4602 +       int i;
4603 +       struct topaz_codec_fw *cur_codec_fw;
4604 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4605 +
4606 +       /* FIXME: make sure the topaz_mtx_data_mem is allocated */
4607 +       if (topaz_priv->topaz_mtx_data_mem == NULL) {
4608 +               PSB_DEBUG_GENERAL("TOPAZ: try to save context without space "
4609 +                       "allocated, return directly without save\n");
4610 +               return -1;
4611 +       }
4612 +       if (topaz_priv->topaz_fw_loaded == 0) {
4613 +               PSB_DEBUG_GENERAL("TOPAZ: try to save context without firmware "
4614 +                                 "uploaded\n");
4615 +               return -1;
4616 +       }
4617 +
4618 +       topaz_wait_for_register(dev_priv,
4619 +                               MTX_START + MTX_CORE_CR_MTX_TXRPT_OFFSET,
4620 +                               TXRPT_WAITONKICK_VALUE,
4621 +                               0xffffffff);
4622 +
4623 +       /* stop mtx */
4624 +       MTX_WRITE32(MTX_CORE_CR_MTX_ENABLE_OFFSET,
4625 +               MTX_CORE_CR_MTX_ENABLE_MTX_TOFF_MASK);
4626 +
4627 +       mtx_reg_state = topaz_priv->topaz_mtx_reg_state;
4628 +
4629 +       /* FIXME: conside to put read/write into one function */
4630 +       /* Saves 8 Registers of D0 Bank  */
4631 +       /* DoRe0, D0Ar6, D0Ar4, D0Ar2, D0FrT, D0.5, D0.6 and D0.7 */
4632 +       for (i = 0; i < 8; i++) {
4633 +               topaz_read_core_reg(dev_priv, 0x1 | (i<<4),
4634 +                               mtx_reg_state);
4635 +               mtx_reg_state++;
4636 +       }
4637 +       /* Saves 8 Registers of D1 Bank  */
4638 +       /* D1Re0, D1Ar5, D1Ar3, D1Ar1, D1RtP, D1.5, D1.6 and D1.7 */
4639 +       for (i = 0; i < 8; i++) {
4640 +               topaz_read_core_reg(dev_priv, 0x2 | (i<<4),
4641 +                               mtx_reg_state);
4642 +               mtx_reg_state++;
4643 +       }
4644 +       /* Saves 4 Registers of A0 Bank  */
4645 +       /* A0StP, A0FrP, A0.2 and A0.3 */
4646 +       for (i = 0; i < 4; i++) {
4647 +               topaz_read_core_reg(dev_priv, 0x3 | (i<<4),
4648 +                               mtx_reg_state);
4649 +               mtx_reg_state++;
4650 +       }
4651 +       /* Saves 4 Registers of A1 Bank  */
4652 +       /* A1GbP, A1LbP, A1.2 and A1.3 */
4653 +       for (i = 0; i < 4; i++) {
4654 +               topaz_read_core_reg(dev_priv, 0x4 | (i<<4),
4655 +                               mtx_reg_state);
4656 +               mtx_reg_state++;
4657 +       }
4658 +       /* Saves PC and PCX  */
4659 +       for (i = 0; i < 2; i++) {
4660 +               topaz_read_core_reg(dev_priv, 0x5 | (i<<4),
4661 +                               mtx_reg_state);
4662 +               mtx_reg_state++;
4663 +       }
4664 +       /* Saves 8 Control Registers */
4665 +       /* TXSTAT, TXMASK, TXSTATI, TXMASKI, TXPOLL, TXGPIOI, TXPOLLI,
4666 +        * TXGPIOO */
4667 +       for (i = 0; i < 8; i++) {
4668 +               topaz_read_core_reg(dev_priv, 0x7 | (i<<4),
4669 +                               mtx_reg_state);
4670 +               mtx_reg_state++;
4671 +       }
4672 +
4673 +       /* save mtx data memory */
4674 +       cur_codec_fw = &topaz_priv->topaz_fw[topaz_priv->topaz_cur_codec];
4675 +
4676 +       mtx_dma_read(dev, cur_codec_fw->data_location + 0x80900000 - 0x82880000,
4677 +               topaz_priv->cur_mtx_data_size);
4678 +
4679 +       /* turn off mtx clocks */
4680 +       MTX_WRITE32(TOPAZ_CR_TOPAZ_MAN_CLK_GATE,
4681 +               MASK_TOPAZ_CR_TOPAZ_MTX_MAN_CLK_GATE);
4682 +
4683 +       topaz_priv->topaz_mtx_saved = 1;
4684 +
4685 +       return 0;
4686 +}
4687 +
4688 +void mtx_dma_read(struct drm_device *dev, uint32_t source_addr, uint32_t size)
4689 +{
4690 +       struct drm_psb_private *dev_priv =
4691 +               (struct drm_psb_private *)dev->dev_private;
4692 +       struct ttm_buffer_object *target;
4693 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4694 +
4695 +       /* setup mtx DMAC registers to do transfer */
4696 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAA, source_addr);
4697 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAC,
4698 +               F_ENCODE(2, MTX_BURSTSIZE) |
4699 +               F_ENCODE(1, MTX_RNW) |
4700 +               F_ENCODE(1, MTX_ENABLE) |
4701 +               F_ENCODE(size, MTX_LENGTH));
4702 +
4703 +       /* give the DMAC access to the host memory via BIF */
4704 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 1);
4705 +
4706 +       target = topaz_priv->topaz_mtx_data_mem;
4707 +       /* transfert the data */
4708 +       /* FIXME: size is meaured by bytes? */
4709 +       topaz_dma_transfer(dev_priv, 0, target->offset, 0,
4710 +                       MTX_CR_MTX_SYSC_CDMAT,
4711 +                       size, 0, 1);
4712 +
4713 +       /* wait for it transfer */
4714 +       topaz_wait_for_register(dev_priv, IMG_SOC_DMAC_IRQ_STAT(0) + DMAC_START,
4715 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN),
4716 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN));
4717 +       /* clear interrupt */
4718 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(0), 0);
4719 +       /* give access back to topaz core */
4720 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 0);
4721 +}
4722 +
4723 +void dmac_transfer(struct drm_device *dev, uint32_t channel, uint32_t dst_addr,
4724 +               uint32_t soc_addr, uint32_t bytes_num,
4725 +               int increment, int rnw)
4726 +{
4727 +       struct drm_psb_private *dev_priv =
4728 +               (struct drm_psb_private *)dev->dev_private;
4729 +       uint32_t count_reg;
4730 +       uint32_t irq_state;
4731 +
4732 +       /* check no transfer is in progress */
4733 +       DMAC_READ32(IMG_SOC_DMAC_COUNT(channel), &count_reg);
4734 +       if (0 != (count_reg & (MASK_IMG_SOC_EN | MASK_IMG_SOC_LIST_EN))) {
4735 +               DRM_ERROR("TOPAZ: there's transfer in progress when wanna "
4736 +                       "save mtx data\n");
4737 +               /* FIXME: how to handle this error */
4738 +               return;
4739 +       }
4740 +
4741 +       /* no hold off period */
4742 +       DMAC_WRITE32(IMG_SOC_DMAC_PER_HOLD(channel), 0);
4743 +       /* cleare irq state */
4744 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(channel), 0);
4745 +       DMAC_READ32(IMG_SOC_DMAC_IRQ_STAT(channel), &irq_state);
4746 +       if (0 != irq_state) {
4747 +               DRM_ERROR("TOPAZ: there's irq cann't clear\n");
4748 +               return;
4749 +       }
4750 +
4751 +       DMAC_WRITE32(IMG_SOC_DMAC_SETUP(channel), dst_addr);
4752 +       count_reg = DMAC_VALUE_COUNT(DMAC_BSWAP_NO_SWAP,
4753 +                               DMAC_PWIDTH_32_BIT, rnw,
4754 +                               DMAC_PWIDTH_32_BIT, bytes_num);
4755 +       /* generate an interrupt at end of transfer */
4756 +       count_reg |= MASK_IMG_SOC_TRANSFER_IEN;
4757 +       count_reg |= F_ENCODE(rnw, IMG_SOC_DIR);
4758 +       DMAC_WRITE32(IMG_SOC_DMAC_COUNT(channel), count_reg);
4759 +
4760 +       DMAC_WRITE32(IMG_SOC_DMAC_PERIPH(channel),
4761 +               DMAC_VALUE_PERIPH_PARAM(DMAC_ACC_DEL_0, increment,
4762 +                                       DMAC_BURST_2));
4763 +       DMAC_WRITE32(IMG_SOC_DMAC_PERIPHERAL_ADDR(channel), soc_addr);
4764 +
4765 +       /* Finally, rewrite the count register with the enable
4766 +        * bit set to kick off the transfer */
4767 +       DMAC_WRITE32(IMG_SOC_DMAC_COUNT(channel),
4768 +               count_reg | MASK_IMG_SOC_EN);
4769 +}
4770 +
4771 +void mtx_dma_write(struct drm_device *dev)
4772 +{
4773 +       struct topaz_codec_fw *cur_codec_fw;
4774 +       struct drm_psb_private *dev_priv =
4775 +               (struct drm_psb_private *)dev->dev_private;
4776 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
4777 +
4778 +       cur_codec_fw = &topaz_priv->topaz_fw[topaz_priv->topaz_cur_codec];
4779 +
4780 +       /* upload code */
4781 +       /* setup mtx DMAC registers to recieve transfer */
4782 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAA, 0x80900000);
4783 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAC,
4784 +               F_ENCODE(2, MTX_BURSTSIZE) |
4785 +               F_ENCODE(0, MTX_RNW) |
4786 +               F_ENCODE(1, MTX_ENABLE) |
4787 +               F_ENCODE(cur_codec_fw->text_size / 4, MTX_LENGTH));
4788 +
4789 +       /* give DMAC access to host memory */
4790 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 1);
4791 +
4792 +       /* transfer code */
4793 +       topaz_dma_transfer(dev_priv, 0, cur_codec_fw->text->offset, 0,
4794 +               MTX_CR_MTX_SYSC_CDMAT, cur_codec_fw->text_size / 4,
4795 +               0, 0);
4796 +       /* wait finished */
4797 +       topaz_wait_for_register(dev_priv, IMG_SOC_DMAC_IRQ_STAT(0) + DMAC_START,
4798 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN),
4799 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN));
4800 +       /* clear interrupt */
4801 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(0), 0);
4802 +
4803 +       /* setup mtx start recieving data */
4804 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAA, 0x80900000 +
4805 +               (cur_codec_fw->data_location) - 0x82880000);
4806 +
4807 +       MTX_WRITE32(MTX_CR_MTX_SYSC_CDMAC,
4808 +               F_ENCODE(2, MTX_BURSTSIZE) |
4809 +               F_ENCODE(0, MTX_RNW) |
4810 +               F_ENCODE(1, MTX_ENABLE) |
4811 +               F_ENCODE(topaz_priv->cur_mtx_data_size, MTX_LENGTH));
4812 +
4813 +       /* give DMAC access to host memory */
4814 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 1);
4815 +
4816 +       /* transfer data */
4817 +       topaz_dma_transfer(dev_priv, 0, topaz_priv->topaz_mtx_data_mem->offset,
4818 +                       0, MTX_CR_MTX_SYSC_CDMAT,
4819 +                       topaz_priv->cur_mtx_data_size,
4820 +                       0, 0);
4821 +       /* wait finished */
4822 +       topaz_wait_for_register(dev_priv, IMG_SOC_DMAC_IRQ_STAT(0) + DMAC_START,
4823 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN),
4824 +                               F_ENCODE(1, IMG_SOC_TRANSFER_FIN));
4825 +       /* clear interrupt */
4826 +       DMAC_WRITE32(IMG_SOC_DMAC_IRQ_STAT(0), 0);
4827 +
4828 +       /* give access back to Topaz Core */
4829 +       TOPAZ_WRITE32(TOPAZ_CR_IMG_TOPAZ_DMAC_MODE, 0);
4830 +}
4831 +
4832 diff --git a/drivers/gpu/drm/mrst/drv/msvdx_power.c b/drivers/gpu/drm/mrst/drv/msvdx_power.c
4833 new file mode 100644
4834 index 0000000..803e04d
4835 --- /dev/null
4836 +++ b/drivers/gpu/drm/mrst/drv/msvdx_power.c
4837 @@ -0,0 +1,164 @@
4838 +/*
4839 + * Copyright (c) 2009, Intel Corporation.
4840 + *
4841 + * This program is free software; you can redistribute it and/or modify it
4842 + * under the terms and conditions of the GNU General Public License,
4843 + * version 2, as published by the Free Software Foundation.
4844 + *
4845 + * This program is distributed in the hope it will be useful, but WITHOUT
4846 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4847 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
4848 + * more details.
4849 + *
4850 + * You should have received a copy of the GNU General Public License along with
4851 + * this program; if not, write to the Free Software Foundation, Inc., 
4852 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
4853 + *
4854 + * Authors: binglin.chen@intel.com>
4855 + *
4856 + */
4857 +
4858 +#include "msvdx_power.h"
4859 +#include "psb_msvdx.h"
4860 +#include "psb_drv.h"
4861 +
4862 +#include "services_headers.h"
4863 +#include "sysconfig.h"
4864 +
4865 +static PVRSRV_ERROR DevInitMSVDXPart1(IMG_VOID *pvDeviceNode)
4866 +{
4867 +       PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
4868 +       PVRSRV_ERROR eError;
4869 +       PVRSRV_DEV_POWER_STATE eDefaultPowerState;
4870 +
4871 +       /* register power operation function */
4872 +       /* FIXME: this should be in part2 init function, but
4873 +        * currently here only OSPM needs IMG device... */
4874 +       eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
4875 +       eError = PVRSRVRegisterPowerDevice(psDeviceNode->sDevId.ui32DeviceIndex,
4876 +                                          MSVDXPrePowerState,
4877 +                                          MSVDXPostPowerState,
4878 +                                          MSVDXPreClockSpeedChange,
4879 +                                          MSVDXPostClockSpeedChange,
4880 +                                          (IMG_HANDLE)psDeviceNode,
4881 +                                          PVRSRV_DEV_POWER_STATE_ON,
4882 +                                          eDefaultPowerState);
4883 +       if (eError != PVRSRV_OK) {
4884 +               PVR_DPF((PVR_DBG_ERROR, "DevInitMSVDXPart1: failed to "
4885 +                        "register device with power manager"));
4886 +               return eError;
4887 +       }
4888 +
4889 +       return PVRSRV_OK;
4890 +}
4891 +
4892 +static PVRSRV_ERROR DevDeInitMSVDX(IMG_VOID *pvDeviceNode)
4893 +{
4894 +       PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
4895 +       PVRSRV_ERROR eError;
4896 +
4897 +       /* should deinit all resource */
4898 +
4899 +       eError = PVRSRVRemovePowerDevice(psDeviceNode->sDevId.ui32DeviceIndex);
4900 +       if (eError != PVRSRV_OK)
4901 +               return eError;
4902 +
4903 +       return PVRSRV_OK;
4904 +}
4905 +
4906 +PVRSRV_ERROR MSVDXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
4907 +{
4908 +       /* version check */
4909 +
4910 +       return PVRSRV_OK;
4911 +}
4912 +
4913 +PVRSRV_ERROR MSVDXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
4914 +{
4915 +       psDeviceNode->sDevId.eDeviceType        = PVRSRV_DEVICE_TYPE_MSVDX;
4916 +       psDeviceNode->sDevId.eDeviceClass       = PVRSRV_DEVICE_CLASS_VIDEO;
4917 +
4918 +       psDeviceNode->pfnInitDevice             = DevInitMSVDXPart1;
4919 +       psDeviceNode->pfnDeInitDevice           = DevDeInitMSVDX;
4920 +
4921 +       psDeviceNode->pfnInitDeviceCompatCheck  = MSVDXDevInitCompatCheck;
4922 +
4923 +       psDeviceNode->pfnDeviceISR = psb_msvdx_interrupt;
4924 +       psDeviceNode->pvISRData = (IMG_VOID *)gpDrmDevice;
4925 +
4926 +       return PVRSRV_OK;
4927 +}
4928 +
4929 +PVRSRV_ERROR MSVDXPrePowerState(IMG_HANDLE hDevHandle,
4930 +                                PVRSRV_DEV_POWER_STATE eNewPowerState,
4931 +                                PVRSRV_DEV_POWER_STATE eCurrentPowerState)
4932 +{
4933 +       /* ask for a change not power on*/
4934 +       if ((eNewPowerState != eCurrentPowerState) &&
4935 +           (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
4936 +               struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
4937 +               struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
4938 +               MSVDX_NEW_PMSTATE(gpDrmDevice, msvdx_priv, PSB_PMSTATE_POWERDOWN);
4939 +
4940 +               /* context save */
4941 +               psb_msvdx_save_context(gpDrmDevice);
4942 +
4943 +               /* internally close the device */
4944 +
4945 +               /* ask for power off */
4946 +               if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
4947 +                       /* here will deinitialize the driver if needed */
4948 +               } else {
4949 +                       PVR_DPF((PVR_DBG_MESSAGE,
4950 +                               "%s no action for transform from %d to %d",
4951 +                                __func__,
4952 +                               eCurrentPowerState,
4953 +                               eNewPowerState));
4954 +               }
4955 +       }
4956 +
4957 +       return PVRSRV_OK;
4958 +}
4959 +
4960 +PVRSRV_ERROR MSVDXPostPowerState(IMG_HANDLE hDevHandle,
4961 +                                PVRSRV_DEV_POWER_STATE eNewPowerState,
4962 +                                PVRSRV_DEV_POWER_STATE eCurrentPowerState)
4963 +{
4964 +       /* if ask for change & current status is not on */
4965 +       if ((eNewPowerState != eCurrentPowerState) &&
4966 +           (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
4967 +               /* internally open device */
4968 +               struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
4969 +               struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
4970 +               MSVDX_NEW_PMSTATE(gpDrmDevice, msvdx_priv, PSB_PMSTATE_POWERUP);
4971 +
4972 +               /* context restore */
4973 +               psb_msvdx_restore_context(gpDrmDevice);
4974 +
4975 +               if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
4976 +                       /* here will initialize the driver if needed */
4977 +               } else {
4978 +                       PVR_DPF((PVR_DBG_MESSAGE,
4979 +                               "%s no action for transform from %d to %d",
4980 +                                __func__,
4981 +                               eCurrentPowerState,
4982 +                               eNewPowerState));
4983 +               }
4984 +       }
4985 +
4986 +       return PVRSRV_OK;
4987 +}
4988 +
4989 +PVRSRV_ERROR MSVDXPreClockSpeedChange(IMG_HANDLE hDevHandle,
4990 +                                     IMG_BOOL bIdleDevice,
4991 +                                     PVRSRV_DEV_POWER_STATE eCurrentPowerState)
4992 +{
4993 +       return PVRSRV_OK;
4994 +}
4995 +
4996 +PVRSRV_ERROR MSVDXPostClockSpeedChange(IMG_HANDLE hDevHandle,
4997 +                                     IMG_BOOL bIdleDevice,
4998 +                                     PVRSRV_DEV_POWER_STATE eCurrentPowerState)
4999 +{
5000 +       return PVRSRV_OK;
5001 +}
5002 diff --git a/drivers/gpu/drm/mrst/drv/msvdx_power.h b/drivers/gpu/drm/mrst/drv/msvdx_power.h
5003 new file mode 100644
5004 index 0000000..19a3d44
5005 --- /dev/null
5006 +++ b/drivers/gpu/drm/mrst/drv/msvdx_power.h
5007 @@ -0,0 +1,48 @@
5008 +/*
5009 + * Copyright (c) 2009, Intel Corporation.
5010 + *
5011 + * This program is free software; you can redistribute it and/or modify it
5012 + * under the terms and conditions of the GNU General Public License,
5013 + * version 2, as published by the Free Software Foundation.
5014 + *
5015 + * This program is distributed in the hope it will be useful, but WITHOUT
5016 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5017 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5018 + * more details.
5019 + *
5020 + * You should have received a copy of the GNU General Public License along with
5021 + * this program; if not, write to the Free Software Foundation, Inc., 
5022 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5023 + *
5024 + * Authors: binglin.chen@intel.com>
5025 + *
5026 + */
5027 +
5028 +#ifndef MSVDX_POWER_H_
5029 +#define MSVDX_POWER_H_
5030 +
5031 +#include "services_headers.h"
5032 +#include "sysconfig.h"
5033 +
5034 +extern struct drm_device *gpDrmDevice;
5035 +
5036 +/* function define */
5037 +PVRSRV_ERROR MSVDXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
5038 +PVRSRV_ERROR MSVDXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
5039 +
5040 +/* power function define */
5041 +PVRSRV_ERROR MSVDXPrePowerState(IMG_HANDLE     hDevHandle,
5042 +                       PVRSRV_DEV_POWER_STATE  eNewPowerState,
5043 +                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
5044 +PVRSRV_ERROR MSVDXPostPowerState(IMG_HANDLE    hDevHandle,
5045 +                        PVRSRV_DEV_POWER_STATE eNewPowerState,
5046 +                        PVRSRV_DEV_POWER_STATE eCurrentPowerState);
5047 +PVRSRV_ERROR MSVDXPreClockSpeedChange(IMG_HANDLE       hDevHandle,
5048 +                             IMG_BOOL                  bIdleDevice,
5049 +                             PVRSRV_DEV_POWER_STATE    eCurrentPowerState);
5050 +PVRSRV_ERROR MSVDXPostClockSpeedChange(IMG_HANDLE      hDevHandle,
5051 +                              IMG_BOOL                 bIdleDevice,
5052 +                              PVRSRV_DEV_POWER_STATE   eCurrentPowerState);
5053 +PVRSRV_ERROR MSVDXInitOSPM(PVRSRV_DEVICE_NODE *psDeviceNode);
5054 +
5055 +#endif /* !MSVDX_POWER_H_ */
5056 diff --git a/drivers/gpu/drm/mrst/drv/psb_bl.c b/drivers/gpu/drm/mrst/drv/psb_bl.c
5057 new file mode 100644
5058 index 0000000..0ef6c41
5059 --- /dev/null
5060 +++ b/drivers/gpu/drm/mrst/drv/psb_bl.c
5061 @@ -0,0 +1,260 @@
5062 +/*
5063 + *  psb backlight using HAL
5064 + *
5065 + * Copyright (c) 2009, Intel Corporation.
5066 + *
5067 + * This program is free software; you can redistribute it and/or modify it
5068 + * under the terms and conditions of the GNU General Public License,
5069 + * version 2, as published by the Free Software Foundation.
5070 + *
5071 + * This program is distributed in the hope it will be useful, but WITHOUT
5072 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5073 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5074 + * more details.
5075 + *
5076 + * You should have received a copy of the GNU General Public License along with
5077 + * this program; if not, write to the Free Software Foundation, Inc., 
5078 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5079 + *
5080 + * Authors: Eric Knopp
5081 + *
5082 + */
5083 +
5084 +#include <linux/backlight.h>
5085 +#include "psb_drv.h"
5086 +#include "psb_intel_reg.h"
5087 +#include "psb_intel_drv.h"
5088 +#include "psb_intel_bios.h"
5089 +#include "ospm_power.h"
5090 +
5091 +#define MRST_BLC_MAX_PWM_REG_FREQ          0xFFFF
5092 +#define BLC_PWM_PRECISION_FACTOR 100   /* 10000000 */
5093 +#define BLC_PWM_FREQ_CALC_CONSTANT 32
5094 +#define MHz 1000000
5095 +#define BRIGHTNESS_MIN_LEVEL 1
5096 +#define BRIGHTNESS_MAX_LEVEL 100
5097 +#define BRIGHTNESS_MASK        0xFF
5098 +#define BLC_POLARITY_NORMAL 0
5099 +#define BLC_POLARITY_INVERSE 1
5100 +#define BLC_ADJUSTMENT_MAX 100
5101 +
5102 +#define PSB_BLC_PWM_PRECISION_FACTOR    10
5103 +#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
5104 +#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
5105 +
5106 +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
5107 +#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
5108 +
5109 +static int psb_brightness;
5110 +static struct backlight_device *psb_backlight_device;
5111 +static u8 blc_brightnesscmd;
5112 +u8 blc_pol;
5113 +u8 blc_type;
5114 +
5115 +
5116 +int psb_set_brightness(struct backlight_device *bd)
5117 +{
5118 +       u32 blc_pwm_ctl;
5119 +       u32 max_pwm_blc;
5120 +
5121 +       struct drm_device *dev =
5122 +               (struct drm_device *)psb_backlight_device->priv;
5123 +       struct drm_psb_private *dev_priv =
5124 +               (struct drm_psb_private *) dev->dev_private;
5125 +
5126 +       int level = bd->props.brightness;
5127 +
5128 +       DRM_DEBUG("backlight level set to %d\n", level);
5129 +
5130 +       /* Perform value bounds checking */
5131 +       if (level < BRIGHTNESS_MIN_LEVEL)
5132 +               level = BRIGHTNESS_MIN_LEVEL;
5133 +
5134 +       if (IS_POULSBO(dev)) {
5135 +               psb_intel_lvds_set_brightness(dev, level);
5136 +               psb_brightness = level;
5137 +               return 0;
5138 +       }
5139 +
5140 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
5141 +                                       OSPM_UHB_ONLY_IF_ON)) {
5142 +               /* Calculate and set the brightness value */
5143 +               max_pwm_blc = REG_READ(BLC_PWM_CTL) >>
5144 +                       MRST_BACKLIGHT_MODULATION_FREQ_SHIFT;
5145 +               blc_pwm_ctl = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
5146 +
5147 +               /* Adjust the backlight level with the percent in
5148 +               * dev_priv->blc_adj1;
5149 +               */
5150 +               blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
5151 +               blc_pwm_ctl = blc_pwm_ctl / BLC_ADJUSTMENT_MAX;
5152 +
5153 +               /* Adjust the backlight level with the percent in
5154 +               * dev_priv->blc_adj2;
5155 +               */
5156 +               blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
5157 +               blc_pwm_ctl = blc_pwm_ctl / BLC_ADJUSTMENT_MAX;
5158 +
5159 +
5160 +               if (blc_pol == BLC_POLARITY_INVERSE)
5161 +                       blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl;
5162 +
5163 +               /* force PWM bit on */
5164 +               REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
5165 +               REG_WRITE(BLC_PWM_CTL,
5166 +                       (max_pwm_blc << MRST_BACKLIGHT_MODULATION_FREQ_SHIFT) |
5167 +                       blc_pwm_ctl);
5168 +
5169 +       /*      printk("***backlight brightness = %i\n", level); */
5170 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
5171 +       }
5172 +
5173 +       /* cache the brightness for later use */
5174 +       psb_brightness = level;
5175 +       return 0;
5176 +}
5177 +
5178 +int psb_get_brightness(struct backlight_device *bd)
5179 +{
5180 +       /* return locally cached var instead of HW read (due to DPST etc.) */
5181 +       return psb_brightness;
5182 +}
5183 +
5184 +struct backlight_ops psb_ops = {
5185 +       .get_brightness = psb_get_brightness,
5186 +       .update_status  = psb_set_brightness,
5187 +};
5188 +
5189 +int psb_backlight_init(struct drm_device *dev)
5190 +{
5191 +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
5192 +       unsigned long CoreClock;
5193 +       /* u32 bl_max_freq; */
5194 +       /* unsigned long value; */
5195 +       u16 bl_max_freq;
5196 +       uint32_t value;
5197 +       uint32_t clock;
5198 +       uint32_t blc_pwm_precision_factor;
5199 +
5200 +       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
5201 +
5202 +       struct drm_psb_private *dev_priv =
5203 +           (struct drm_psb_private *) dev->dev_private;
5204 +
5205 +       psb_backlight_device = backlight_device_register("psb-bl",
5206 +               NULL, NULL, &psb_ops);
5207 +       if (IS_ERR(psb_backlight_device))
5208 +               return PTR_ERR(psb_backlight_device);
5209 +
5210 +       psb_backlight_device->priv = dev;
5211 +
5212 +       if (IS_MRST(dev)) {
5213 +               dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
5214 +               dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
5215 +
5216 +               /* this needs to come from VBT when available */
5217 +               bl_max_freq = 256;
5218 +               /* this needs to be set elsewhere */
5219 +               blc_pol = BLC_POLARITY_NORMAL;
5220 +               blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
5221 +
5222 +               if (dev_priv->sku_83)
5223 +                       CoreClock = 166;
5224 +               else if (dev_priv->sku_100)
5225 +                       CoreClock = 200;
5226 +               else if (dev_priv->sku_100L)
5227 +                       CoreClock = 100;
5228 +               else
5229 +                       return 1;
5230 +       } else {
5231 +               /* get bl_max_freq and pol from dev_priv*/
5232 +               if (!dev_priv->lvds_bl) {
5233 +                       DRM_ERROR("Has no valid LVDS backlight info\n");
5234 +                       return 1;
5235 +               }
5236 +               bl_max_freq = dev_priv->lvds_bl->freq;
5237 +               blc_pol = dev_priv->lvds_bl->pol;
5238 +               blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
5239 +               blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
5240 +               blc_type = dev_priv->lvds_bl->type;
5241 +
5242 +               /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
5243 +               /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/
5244 +
5245 +               pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
5246 +               pci_read_config_dword(pci_root, 0xD4, &clock);
5247 +
5248 +               switch (clock & 0x07) {
5249 +               case 0:
5250 +                       CoreClock = 100;
5251 +                       break;
5252 +               case 1:
5253 +                       CoreClock = 133;
5254 +                       break;
5255 +               case 2:
5256 +                       CoreClock = 150;
5257 +                       break;
5258 +               case 3:
5259 +                       CoreClock = 178;
5260 +                       break;
5261 +               case 4:
5262 +                       CoreClock = 200;
5263 +                       break;
5264 +               case 5:
5265 +               case 6:
5266 +               case 7:
5267 +                       CoreClock = 266;
5268 +               default:
5269 +                       return 1;
5270 +               }
5271 +       } /*end if(IS_MRST(dev))*/
5272 +
5273 +       value = (CoreClock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
5274 +       value *= blc_pwm_precision_factor;
5275 +       value /= bl_max_freq;
5276 +       value /= blc_pwm_precision_factor;
5277 +
5278 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
5279 +                                       OSPM_UHB_ONLY_IF_ON)) {
5280 +               if (IS_MRST(dev)) {
5281 +                       if (value >
5282 +                               (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
5283 +                               return 2;
5284 +                       else {
5285 +                               REG_WRITE(BLC_PWM_CTL2,
5286 +                                       (0x80000000 | REG_READ(BLC_PWM_CTL2)));
5287 +                               REG_WRITE(BLC_PWM_CTL, value |
5288 +                               (value <<
5289 +                                       MRST_BACKLIGHT_MODULATION_FREQ_SHIFT));
5290 +                       }
5291 +               } else {
5292 +                       if (
5293 +                        value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
5294 +                        value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
5295 +                               return 2;
5296 +                       else {
5297 +                               value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
5298 +                               REG_WRITE(BLC_PWM_CTL,
5299 +                                       (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
5300 +                                       (value));
5301 +                       }
5302 +               } /*end if(IS_MRST(dev))*/
5303 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
5304 +       }
5305 +
5306 +       psb_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL;
5307 +       psb_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL;
5308 +       backlight_update_status(psb_backlight_device);
5309 +#endif
5310 +       return 0;
5311 +}
5312 +
5313 +void psb_backlight_exit(void)
5314 +{
5315 +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
5316 +       psb_backlight_device->props.brightness = 0;
5317 +       backlight_update_status(psb_backlight_device);
5318 +       backlight_device_unregister(psb_backlight_device);
5319 +#endif
5320 +       return;
5321 +}
5322 diff --git a/drivers/gpu/drm/mrst/drv/psb_buffer.c b/drivers/gpu/drm/mrst/drv/psb_buffer.c
5323 new file mode 100644
5324 index 0000000..d54a429
5325 --- /dev/null
5326 +++ b/drivers/gpu/drm/mrst/drv/psb_buffer.c
5327 @@ -0,0 +1,379 @@
5328 +/**************************************************************************
5329 + * Copyright (c) 2007, Intel Corporation.
5330 + *
5331 + * This program is free software; you can redistribute it and/or modify it
5332 + * under the terms and conditions of the GNU General Public License,
5333 + * version 2, as published by the Free Software Foundation.
5334 + *
5335 + * This program is distributed in the hope it will be useful, but WITHOUT
5336 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5337 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5338 + * more details.
5339 + *
5340 + * You should have received a copy of the GNU General Public License along with
5341 + * this program; if not, write to the Free Software Foundation, Inc., 
5342 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5343 + *
5344 + **************************************************************************/
5345 +/*
5346 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
5347 + */
5348 +#include "ttm/ttm_placement_common.h"
5349 +#include "ttm/ttm_execbuf_util.h"
5350 +#include "ttm/ttm_fence_api.h"
5351 +#include <drm/drmP.h>
5352 +#include "psb_drv.h"
5353 +#include "psb_schedule.h"
5354 +
5355 +#define DRM_MEM_TTM       26
5356 +
5357 +struct drm_psb_ttm_backend {
5358 +       struct ttm_backend base;
5359 +       struct page **pages;
5360 +       unsigned int desired_tile_stride;
5361 +       unsigned int hw_tile_stride;
5362 +       int mem_type;
5363 +       unsigned long offset;
5364 +       unsigned long num_pages;
5365 +};
5366 +
5367 +/*
5368 + * MSVDX/TOPAZ GPU virtual space looks like this
5369 + * (We currently use only one MMU context).
5370 + * PSB_MEM_MMU_START: from 0x40000000, for generic buffers
5371 + * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing
5372 + * TTM_PL_RAR: from TTM_PL_CI, for RAR/video buffer sharing
5373 + * TTM_PL_TT: from TTM_PL_RAR, for buffers need to mapping into GTT
5374 + */
5375 +static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
5376 +                            struct ttm_mem_type_manager *man)
5377 +{
5378 +
5379 +       struct drm_psb_private *dev_priv =
5380 +           container_of(bdev, struct drm_psb_private, bdev);
5381 +       struct psb_gtt *pg = dev_priv->pg;
5382 +
5383 +       switch (type) {
5384 +       case TTM_PL_SYSTEM:
5385 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
5386 +               man->available_caching = TTM_PL_FLAG_CACHED |
5387 +                   TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
5388 +               man->default_caching = TTM_PL_FLAG_CACHED;
5389 +               break;
5390 +       case DRM_PSB_MEM_MMU:
5391 +               man->io_offset = 0x00000000;
5392 +               man->io_size = 0x00000000;
5393 +               man->io_addr = NULL;
5394 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
5395 +                   TTM_MEMTYPE_FLAG_CMA;
5396 +               man->gpu_offset = PSB_MEM_MMU_START;
5397 +               man->available_caching = TTM_PL_FLAG_CACHED |
5398 +                   TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
5399 +               man->default_caching = TTM_PL_FLAG_WC;
5400 +               break;
5401 +       case TTM_PL_CI:
5402 +               man->io_addr = NULL;
5403 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
5404 +                       TTM_MEMTYPE_FLAG_FIXED |
5405 +                       TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
5406 +               man->io_offset = dev_priv->ci_region_start;
5407 +               man->io_size = pg->ci_stolen_size;
5408 +               man->gpu_offset = pg->mmu_gatt_start;
5409 +               man->available_caching = TTM_PL_FLAG_UNCACHED;
5410 +               man->default_caching = TTM_PL_FLAG_UNCACHED;
5411 +               break;
5412 +       case TTM_PL_RAR:        /* Unmappable RAR memory */
5413 +               man->io_offset = dev_priv->rar_region_start;
5414 +               man->io_size = pg->rar_stolen_size;
5415 +               man->io_addr = NULL;
5416 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
5417 +                       TTM_MEMTYPE_FLAG_FIXED |
5418 +                       TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
5419 +               man->available_caching = TTM_PL_FLAG_UNCACHED;
5420 +               man->default_caching = TTM_PL_FLAG_UNCACHED;
5421 +               man->gpu_offset = pg->mmu_gatt_start;
5422 +               break;
5423 +       case TTM_PL_TT: /* Mappable GATT memory */
5424 +               man->io_offset = pg->gatt_start;
5425 +               man->io_size = pg->gatt_pages << PAGE_SHIFT;
5426 +               man->io_addr = NULL;
5427 +#ifdef PSB_WORKING_HOST_MMU_ACCESS
5428 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
5429 +                   TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
5430 +#else
5431 +               man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
5432 +                   TTM_MEMTYPE_FLAG_CMA;
5433 +#endif
5434 +               man->available_caching = TTM_PL_FLAG_CACHED |
5435 +                   TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
5436 +               man->default_caching = TTM_PL_FLAG_WC;
5437 +               man->gpu_offset = pg->mmu_gatt_start;
5438 +               break;
5439 +       default:
5440 +               DRM_ERROR("Unsupported memory type %u\n", (unsigned) type);
5441 +               return -EINVAL;
5442 +       }
5443 +       return 0;
5444 +}
5445 +
5446 +static uint32_t psb_evict_mask(struct ttm_buffer_object *bo)
5447 +{
5448 +       uint32_t cur_placement = bo->mem.flags & ~TTM_PL_MASK_MEM;
5449 +       
5450 +       /* all buffers evicted to system memory */
5451 +       return cur_placement | TTM_PL_FLAG_SYSTEM;
5452 +}
5453 +
5454 +static int psb_invalidate_caches(struct ttm_bo_device *bdev,
5455 +                                uint32_t placement)
5456 +{
5457 +       return 0;
5458 +}
5459 +
5460 +static int psb_move_blit(struct ttm_buffer_object *bo,
5461 +                        bool evict, bool no_wait,
5462 +                        struct ttm_mem_reg *new_mem)
5463 +{
5464 +       BUG();
5465 +       return 0;
5466 +}
5467 +
5468 +/*
5469 + * Flip destination ttm into GATT,
5470 + * then blit and subsequently move out again.
5471 + */
5472 +
5473 +static int psb_move_flip(struct ttm_buffer_object *bo,
5474 +                        bool evict, bool interruptible, bool no_wait,
5475 +                        struct ttm_mem_reg *new_mem)
5476 +{
5477 +       struct ttm_bo_device *bdev = bo->bdev;
5478 +       struct ttm_mem_reg tmp_mem;
5479 +       int ret;
5480 +
5481 +       tmp_mem = *new_mem;
5482 +       tmp_mem.mm_node = NULL;
5483 +       tmp_mem.proposed_flags = TTM_PL_FLAG_TT;
5484 +
5485 +       ret = ttm_bo_mem_space(bo, &tmp_mem, interruptible, no_wait);
5486 +       if (ret)
5487 +               return ret;
5488 +       ret = ttm_tt_bind(bo->ttm, &tmp_mem);
5489 +       if (ret)
5490 +               goto out_cleanup;
5491 +       ret = psb_move_blit(bo, true, no_wait, &tmp_mem);
5492 +       if (ret)
5493 +               goto out_cleanup;
5494 +
5495 +       ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem);
5496 +out_cleanup:
5497 +       if (tmp_mem.mm_node) {
5498 +               spin_lock(&bdev->lru_lock);
5499 +               drm_mm_put_block(tmp_mem.mm_node);
5500 +               tmp_mem.mm_node = NULL;
5501 +               spin_unlock(&bdev->lru_lock);
5502 +       }
5503 +       return ret;
5504 +}
5505 +
5506 +static int psb_move(struct ttm_buffer_object *bo,
5507 +                   bool evict, bool interruptible,
5508 +                   bool no_wait, struct ttm_mem_reg *new_mem)
5509 +{
5510 +       struct ttm_mem_reg *old_mem = &bo->mem;
5511 +
5512 +       if ((old_mem->mem_type == TTM_PL_RAR) ||
5513 +           (new_mem->mem_type == TTM_PL_RAR)) {
5514 +               ttm_bo_free_old_node(bo);
5515 +               *old_mem = *new_mem;
5516 +       } else if (old_mem->mem_type == TTM_PL_SYSTEM) {
5517 +               return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
5518 +       } else if (new_mem->mem_type == TTM_PL_SYSTEM) {
5519 +               int ret = psb_move_flip(bo, evict, interruptible,
5520 +                                       no_wait, new_mem);
5521 +               if (unlikely(ret != 0)) {
5522 +                       if (ret == -ERESTART)
5523 +                               return ret;
5524 +                       else
5525 +                               return ttm_bo_move_memcpy(bo, evict, no_wait,
5526 +                                                         new_mem);
5527 +               }
5528 +       } else {
5529 +               if (psb_move_blit(bo, evict, no_wait, new_mem))
5530 +                       return ttm_bo_move_memcpy(bo, evict, no_wait,
5531 +                                                 new_mem);
5532 +       }
5533 +       return 0;
5534 +}
5535 +
5536 +static int drm_psb_tbe_populate(struct ttm_backend *backend,
5537 +                               unsigned long num_pages,
5538 +                               struct page **pages,
5539 +                               struct page *dummy_read_page)
5540 +{
5541 +       struct drm_psb_ttm_backend *psb_be =
5542 +           container_of(backend, struct drm_psb_ttm_backend, base);
5543 +
5544 +       psb_be->pages = pages;
5545 +       return 0;
5546 +}
5547 +
5548 +static int drm_psb_tbe_unbind(struct ttm_backend *backend)
5549 +{
5550 +       struct ttm_bo_device *bdev = backend->bdev;
5551 +       struct drm_psb_private *dev_priv =
5552 +           container_of(bdev, struct drm_psb_private, bdev);
5553 +       struct drm_psb_ttm_backend *psb_be =
5554 +           container_of(backend, struct drm_psb_ttm_backend, base);
5555 +       struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
5556 +       struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type];
5557 +
5558 +       PSB_DEBUG_RENDER("MMU unbind.\n");
5559 +
5560 +       if (psb_be->mem_type == TTM_PL_TT) {
5561 +               uint32_t gatt_p_offset =
5562 +                   (psb_be->offset - man->gpu_offset) >> PAGE_SHIFT;
5563 +
5564 +               (void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset,
5565 +                                           psb_be->num_pages,
5566 +                                           psb_be->desired_tile_stride,
5567 +                                           psb_be->hw_tile_stride);
5568 +       }
5569 +
5570 +       psb_mmu_remove_pages(pd, psb_be->offset,
5571 +                            psb_be->num_pages,
5572 +                            psb_be->desired_tile_stride,
5573 +                            psb_be->hw_tile_stride);
5574 +
5575 +       return 0;
5576 +}
5577 +
5578 +static int drm_psb_tbe_bind(struct ttm_backend *backend,
5579 +                           struct ttm_mem_reg *bo_mem)
5580 +{
5581 +       struct ttm_bo_device *bdev = backend->bdev;
5582 +       struct drm_psb_private *dev_priv =
5583 +           container_of(bdev, struct drm_psb_private, bdev);
5584 +       struct drm_psb_ttm_backend *psb_be =
5585 +           container_of(backend, struct drm_psb_ttm_backend, base);
5586 +       struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
5587 +       struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type];
5588 +       int type;
5589 +       int ret = 0;
5590 +
5591 +       psb_be->mem_type = bo_mem->mem_type;
5592 +       psb_be->num_pages = bo_mem->num_pages;
5593 +       psb_be->desired_tile_stride = 0;
5594 +       psb_be->hw_tile_stride = 0;
5595 +       psb_be->offset = (bo_mem->mm_node->start << PAGE_SHIFT) +
5596 +           man->gpu_offset;
5597 +
5598 +       type =
5599 +           (bo_mem->
5600 +            flags & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0;
5601 +
5602 +       PSB_DEBUG_RENDER("MMU bind.\n");
5603 +       if (psb_be->mem_type == TTM_PL_TT) {
5604 +               uint32_t gatt_p_offset =
5605 +                   (psb_be->offset - man->gpu_offset) >> PAGE_SHIFT;
5606 +
5607 +               ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages,
5608 +                                          gatt_p_offset,
5609 +                                          psb_be->num_pages,
5610 +                                          psb_be->desired_tile_stride,
5611 +                                          psb_be->hw_tile_stride, type);
5612 +       }
5613 +
5614 +       ret = psb_mmu_insert_pages(pd, psb_be->pages,
5615 +                                  psb_be->offset, psb_be->num_pages,
5616 +                                  psb_be->desired_tile_stride,
5617 +                                  psb_be->hw_tile_stride, type);
5618 +       if (ret)
5619 +               goto out_err;
5620 +
5621 +       return 0;
5622 +out_err:
5623 +       drm_psb_tbe_unbind(backend);
5624 +       return ret;
5625 +
5626 +}
5627 +
5628 +static void drm_psb_tbe_clear(struct ttm_backend *backend)
5629 +{
5630 +       struct drm_psb_ttm_backend *psb_be =
5631 +           container_of(backend, struct drm_psb_ttm_backend, base);
5632 +
5633 +       psb_be->pages = NULL;
5634 +       return;
5635 +}
5636 +
5637 +static void drm_psb_tbe_destroy(struct ttm_backend *backend)
5638 +{
5639 +       struct drm_psb_ttm_backend *psb_be =
5640 +           container_of(backend, struct drm_psb_ttm_backend, base);
5641 +
5642 +       if (backend)
5643 +               kfree(psb_be);
5644 +}
5645 +
5646 +static struct ttm_backend_func psb_ttm_backend = {
5647 +       .populate = drm_psb_tbe_populate,
5648 +       .clear = drm_psb_tbe_clear,
5649 +       .bind = drm_psb_tbe_bind,
5650 +       .unbind = drm_psb_tbe_unbind,
5651 +       .destroy = drm_psb_tbe_destroy,
5652 +};
5653 +
5654 +static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev)
5655 +{
5656 +       struct drm_psb_ttm_backend *psb_be;
5657 +
5658 +       psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL);
5659 +       if (!psb_be)
5660 +               return NULL;
5661 +       psb_be->pages = NULL;
5662 +       psb_be->base.func = &psb_ttm_backend;
5663 +       psb_be->base.bdev = bdev;
5664 +       return &psb_be->base;
5665 +}
5666 +
5667 +/*
5668 + * Use this memory type priority if no eviction is needed.
5669 + */
5670 +static uint32_t psb_mem_prios[] = {
5671 +       TTM_PL_CI,
5672 +       TTM_PL_RAR,
5673 +       TTM_PL_TT,
5674 +       DRM_PSB_MEM_MMU,
5675 +       TTM_PL_SYSTEM
5676 +};
5677 +
5678 +/*
5679 + * Use this memory type priority if need to evict.
5680 + */
5681 +static uint32_t psb_busy_prios[] = {
5682 +       TTM_PL_TT,
5683 +       TTM_PL_CI,
5684 +       TTM_PL_RAR,
5685 +       DRM_PSB_MEM_MMU,
5686 +       TTM_PL_SYSTEM
5687 +};
5688 +
5689 +
5690 +struct ttm_bo_driver psb_ttm_bo_driver = {
5691 +       .mem_type_prio = psb_mem_prios,
5692 +       .mem_busy_prio = psb_busy_prios,
5693 +       .num_mem_type_prio = ARRAY_SIZE(psb_mem_prios),
5694 +       .num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios),
5695 +       .create_ttm_backend_entry = &drm_psb_tbe_init,
5696 +       .invalidate_caches = &psb_invalidate_caches,
5697 +       .init_mem_type = &psb_init_mem_type,
5698 +       .evict_flags = &psb_evict_mask,
5699 +       .move = &psb_move,
5700 +       .verify_access = &psb_verify_access,
5701 +       .sync_obj_signaled = &ttm_fence_sync_obj_signaled,
5702 +       .sync_obj_wait = &ttm_fence_sync_obj_wait,
5703 +       .sync_obj_flush = &ttm_fence_sync_obj_flush,
5704 +       .sync_obj_unref = &ttm_fence_sync_obj_unref,
5705 +       .sync_obj_ref = &ttm_fence_sync_obj_ref
5706 +};
5707 diff --git a/drivers/gpu/drm/mrst/drv/psb_dpst.c b/drivers/gpu/drm/mrst/drv/psb_dpst.c
5708 new file mode 100644
5709 index 0000000..c16c982
5710 --- /dev/null
5711 +++ b/drivers/gpu/drm/mrst/drv/psb_dpst.c
5712 @@ -0,0 +1,254 @@
5713 +/*
5714 + * Copyright Â© 2009 Intel Corporation
5715 + *
5716 + * This program is free software; you can redistribute it and/or modify it
5717 + * under the terms and conditions of the GNU General Public License,
5718 + * version 2, as published by the Free Software Foundation.
5719 + *
5720 + * This program is distributed in the hope it will be useful, but WITHOUT
5721 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5722 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5723 + * more details.
5724 + *
5725 + * You should have received a copy of the GNU General Public License along with
5726 + * this program; if not, write to the Free Software Foundation, Inc., 
5727 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5728 + *
5729 + * Authors:
5730 + *    James C. Gualario <james.c.gualario@intel.com>
5731 + *
5732 + */
5733 +
5734 +#include "psb_umevents.h"
5735 +#include "psb_dpst.h"
5736 +/**
5737 + * inform the kernel of the work to be performed and related function.
5738 + *
5739 + */
5740 +DECLARE_WORK(dpst_dev_change_work, &psb_dpst_dev_change_wq);
5741 +/**
5742 + * psb_dpst_notify_change_um - notify user mode of hotplug changes
5743 + *
5744 + * @name: name of event to notify user mode of change to
5745 + * @state: dpst state struct to get workqueue from
5746 + *
5747 + */
5748 +int psb_dpst_notify_change_um(enum dpst_event_enum event,
5749 +                             struct dpst_state *state)
5750 +{
5751 +       if (state == NULL)
5752 +               return IRQ_HANDLED;
5753 +
5754 +       state->dpst_change_wq_data.dev_name_arry_rw_status
5755 +               [state->dpst_change_wq_data.dev_name_write] =
5756 +               DRM_DPST_READY_TO_READ;
5757 +       state->dpst_change_wq_data.dpst_events
5758 +               [state->dpst_change_wq_data.dev_name_write] =
5759 +               event;
5760 +       if (state->dpst_change_wq_data.dev_name_read_write_wrap_ack == 1)
5761 +               state->dpst_change_wq_data.dev_name_read_write_wrap_ack = 0;
5762 +       state->dpst_change_wq_data.dev_name_write++;
5763 +       if (state->dpst_change_wq_data.dev_name_write ==
5764 +          state->dpst_change_wq_data.dev_name_read) {
5765 +               state->dpst_change_wq_data.dev_name_write--;
5766 +               return IRQ_NONE;
5767 +       }
5768 +       if (state->dpst_change_wq_data.dev_name_write >
5769 +          DRM_DPST_RING_DEPTH_MAX) {
5770 +               state->dpst_change_wq_data.dev_name_write = 0;
5771 +               state->dpst_change_wq_data.dev_name_write_wrap = 1;
5772 +       }
5773 +       state->dpst_change_wq_data.hotplug_dev_list = state->list;
5774 +       queue_work(state->dpst_wq, &(state->dpst_change_wq_data.work));
5775 +       return IRQ_HANDLED;
5776 +}
5777 +EXPORT_SYMBOL(psb_dpst_notify_change_um);
5778 +/**
5779 + *
5780 + * psb_dpst_create_and_notify_um - create and notify user mode of new dev
5781 + *
5782 + * @name: name to give for new event / device
5783 + * @state: dpst state instaces to associate event with
5784 + *
5785 + */
5786 +struct umevent_obj *psb_dpst_create_and_notify_um(const char *name,
5787 +                                                 struct dpst_state *state)
5788 +{
5789 +       return psb_create_umevent_obj(name, state->list);
5790 +
5791 +}
5792 +EXPORT_SYMBOL(psb_dpst_create_and_notify_um);
5793 +/**
5794 + * psb_dpst_device_pool_create_and_init - make new hotplug device pool
5795 + *
5796 + * @parent_kobj - parent kobject to associate dpst kset with
5797 + * @state - dpst state instance to associate list with
5798 + *
5799 + */
5800 +struct umevent_list *psb_dpst_device_pool_create_and_init(
5801 +                                                 struct kobject *parent_kobj,
5802 +                                                 struct dpst_state *state)
5803 +{
5804 +       struct umevent_list *new_hotplug_dev_list = NULL;
5805 +       new_hotplug_dev_list = psb_umevent_create_list();
5806 +       if (new_hotplug_dev_list)
5807 +               psb_umevent_init(parent_kobj, new_hotplug_dev_list,
5808 +                                "psb_dpst");
5809 +
5810 +       state->dpst_wq = create_singlethread_workqueue("dpst-wq");
5811 +
5812 +       if (!state->dpst_wq)
5813 +               return NULL;
5814 +
5815 +       INIT_WORK(&state->dpst_change_wq_data.work, psb_dpst_dev_change_wq);
5816 +
5817 +       state->dpst_change_wq_data.dev_name_read = 0;
5818 +       state->dpst_change_wq_data.dev_name_write = 0;
5819 +       state->dpst_change_wq_data.dev_name_write_wrap = 0;
5820 +       state->dpst_change_wq_data.dev_name_read_write_wrap_ack = 0;
5821 +
5822 +       memset(&(state->dpst_change_wq_data.dev_name_arry_rw_status[0]),
5823 +              0, sizeof(int)*DRM_DPST_RING_DEPTH);
5824 +
5825 +       return new_hotplug_dev_list;
5826 +}
5827 +EXPORT_SYMBOL(psb_dpst_device_pool_create_and_init);
5828 +/**
5829 + * psb_dpst_init - init dpst subsystem
5830 + * @parent_kobj - parent kobject to associate dpst state with
5831 + *
5832 + */
5833 +struct dpst_state *psb_dpst_init(struct kobject *parent_kobj)
5834 +{
5835 +       struct dpst_state *state;
5836 +       struct umevent_obj *working_umevent;
5837 +
5838 +       state = kzalloc(sizeof(struct dpst_state), GFP_KERNEL);
5839 +       printk(KERN_ALERT "after kzalloc\n");
5840 +       state->list = NULL;
5841 +       state->list = psb_dpst_device_pool_create_and_init(
5842 +                                                 parent_kobj,
5843 +                                                 state);
5844 +       working_umevent  =
5845 +               psb_dpst_create_and_notify_um("init",
5846 +                                          state);
5847 +       state->dpst_change_wq_data.dev_umevent_arry
5848 +               [DPST_EVENT_INIT_COMPLETE] = &(working_umevent->head);
5849 +       working_umevent  =
5850 +               psb_dpst_create_and_notify_um("hist_int",
5851 +                                          state);
5852 +       state->dpst_change_wq_data.dev_umevent_arry
5853 +               [DPST_EVENT_HIST_INTERRUPT] = &(working_umevent->head);
5854 +       working_umevent  =
5855 +               psb_dpst_create_and_notify_um("term",
5856 +                                          state);
5857 +       state->dpst_change_wq_data.dev_umevent_arry
5858 +               [DPST_EVENT_TERMINATE] = &(working_umevent->head);
5859 +       working_umevent  =
5860 +               psb_dpst_create_and_notify_um("phase_done",
5861 +                                          state);
5862 +       state->dpst_change_wq_data.dev_umevent_arry
5863 +               [DPST_EVENT_PHASE_COMPLETE] = &(working_umevent->head);
5864 +
5865 +       return state;
5866 +}
5867 +EXPORT_SYMBOL(psb_dpst_init);
5868 +/**
5869 + * psb_dpst_device_pool_destroy - destroy all dpst related resources
5870 + *
5871 + * @state: dpst state instance to destroy
5872 + *
5873 + */
5874 +void psb_dpst_device_pool_destroy(struct dpst_state *state)
5875 +{
5876 +       int i;
5877 +       struct umevent_list *list;
5878 +       struct umevent_obj *umevent_test;
5879 +       list = state->list;
5880 +       flush_workqueue(state->dpst_wq);
5881 +       destroy_workqueue(state->dpst_wq);
5882 +       for (i = 0; i < DRM_DPST_MAX_NUM_EVENTS;  i++) {
5883 +               umevent_test = list_entry(
5884 +                         (state->dpst_change_wq_data.dev_umevent_arry[i]),
5885 +                         struct umevent_obj, head);
5886 +               state->dpst_change_wq_data.dev_umevent_arry[i] = NULL;
5887 +       }
5888 +       psb_umevent_cleanup(list);
5889 +       kfree(state);
5890 +}
5891 +EXPORT_SYMBOL(psb_dpst_device_pool_destroy);
5892 +/**
5893 + * psb_dpst_dev_change_wq - change workqueue implementation
5894 + *
5895 + * @work: work struct to use for kernel scheduling
5896 + *
5897 + */
5898 +void psb_dpst_dev_change_wq(struct work_struct *work)
5899 +{
5900 +       struct dpst_disp_workqueue_data *wq_data;
5901 +       int curr_event_index;
5902 +       wq_data = to_dpst_disp_workqueue_data(work);
5903 +       if (wq_data->dev_name_write_wrap == 1) {
5904 +               wq_data->dev_name_read_write_wrap_ack = 1;
5905 +               wq_data->dev_name_write_wrap = 0;
5906 +               while (wq_data->dev_name_read != DRM_DPST_RING_DEPTH_MAX) {
5907 +                       if (wq_data->dev_name_arry_rw_status
5908 +                          [wq_data->dev_name_read] ==
5909 +                          DRM_DPST_READY_TO_READ) {
5910 +                               wq_data->dev_name_arry_rw_status
5911 +                               [wq_data->dev_name_read] =
5912 +                               DRM_DPST_READ_COMPLETE;
5913 +                               curr_event_index = wq_data->dpst_events
5914 +                                       [wq_data->dev_name_read];
5915 +                               psb_umevent_notify_change_gfxsock
5916 +                                       (list_entry(
5917 +                                          (wq_data->dev_umevent_arry
5918 +                                           [curr_event_index]),
5919 +                                          struct umevent_obj, head),
5920 +                                        DRM_DPST_SOCKET_GROUP_ID);
5921 +                       }
5922 +                       wq_data->dev_name_read++;
5923 +               }
5924 +               wq_data->dev_name_read = 0;
5925 +               while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
5926 +                       if (wq_data->dev_name_arry_rw_status
5927 +                          [wq_data->dev_name_read] ==
5928 +                          DRM_DPST_READY_TO_READ) {
5929 +                               wq_data->dev_name_arry_rw_status
5930 +                               [wq_data->dev_name_read] =
5931 +                               DRM_DPST_READ_COMPLETE;
5932 +                               curr_event_index = wq_data->dpst_events
5933 +                                       [wq_data->dev_name_read];
5934 +                               psb_umevent_notify_change_gfxsock
5935 +                                       (list_entry(
5936 +                                          (wq_data->dev_umevent_arry
5937 +                                           [curr_event_index]),
5938 +                                          struct umevent_obj, head),
5939 +                                        DRM_DPST_SOCKET_GROUP_ID);
5940 +                       }
5941 +                       wq_data->dev_name_read++;
5942 +               }
5943 +       } else {
5944 +               while (wq_data->dev_name_read < wq_data->dev_name_write) {
5945 +                       if (wq_data->dev_name_arry_rw_status
5946 +                          [wq_data->dev_name_read] ==
5947 +                          DRM_DPST_READY_TO_READ) {
5948 +                               wq_data->dev_name_arry_rw_status
5949 +                               [wq_data->dev_name_read] =
5950 +                                       DRM_DPST_READ_COMPLETE;
5951 +                               curr_event_index = wq_data->dpst_events
5952 +                                       [wq_data->dev_name_read];
5953 +                               psb_umevent_notify_change_gfxsock
5954 +                                       (list_entry(
5955 +                                          (wq_data->dev_umevent_arry
5956 +                                           [curr_event_index]),
5957 +                                          struct umevent_obj, head),
5958 +                                        DRM_DPST_SOCKET_GROUP_ID);
5959 +                       }
5960 +                       wq_data->dev_name_read++;
5961 +               }
5962 +       }
5963 +       if (wq_data->dev_name_read > DRM_DPST_RING_DEPTH_MAX)
5964 +               wq_data->dev_name_read = 0;
5965 +}
5966 +EXPORT_SYMBOL(psb_dpst_dev_change_wq);
5967 diff --git a/drivers/gpu/drm/mrst/drv/psb_dpst.h b/drivers/gpu/drm/mrst/drv/psb_dpst.h
5968 new file mode 100644
5969 index 0000000..6f24a05
5970 --- /dev/null
5971 +++ b/drivers/gpu/drm/mrst/drv/psb_dpst.h
5972 @@ -0,0 +1,98 @@
5973 +/*
5974 + * Copyright Â© 2009 Intel Corporation
5975 + *
5976 + * This program is free software; you can redistribute it and/or modify it
5977 + * under the terms and conditions of the GNU General Public License,
5978 + * version 2, as published by the Free Software Foundation.
5979 + *
5980 + * This program is distributed in the hope it will be useful, but WITHOUT
5981 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5982 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5983 + * more details.
5984 + *
5985 + * You should have received a copy of the GNU General Public License along with
5986 + * this program; if not, write to the Free Software Foundation, Inc., 
5987 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5988 + *
5989 + * Authors:
5990 + *    James C. Gualario <james.c.gualario@intel.com>
5991 + *
5992 + */
5993 +
5994 +#ifndef _PSB_DPST_H_
5995 +#define _PSB_DPST_H_
5996 +/**
5997 + * required includes
5998 + *
5999 + */
6000 +#include "psb_umevents.h"
6001 +/**
6002 + * dpst event enumeration
6003 + *
6004 + */
6005 +enum dpst_event_enum {
6006 +       DPST_EVENT_INIT_COMPLETE,
6007 +       DPST_EVENT_HIST_INTERRUPT,
6008 +       DPST_EVENT_TERMINATE,
6009 +       DPST_EVENT_PHASE_COMPLETE,
6010 +       DPST_MAX_EVENT
6011 +};
6012 +/**
6013 + * dpst specific defines
6014 + *
6015 + */
6016 +#define DRM_DPST_RING_DEPTH 256
6017 +#define DRM_DPST_RING_DEPTH_MAX (DRM_DPST_RING_DEPTH-1)
6018 +#define DRM_DPST_READY_TO_READ 1
6019 +#define DRM_DPST_READ_COMPLETE 2
6020 +#define DRM_DPST_MAX_NUM_EVENTS (DPST_MAX_EVENT)
6021 +/**
6022 + * dpst workqueue data struct.
6023 + */
6024 +struct dpst_disp_workqueue_data {
6025 +       struct work_struct work;
6026 +       const char *dev_name;
6027 +       int dev_name_write;
6028 +       int dev_name_read;
6029 +       int dev_name_write_wrap;
6030 +       int dev_name_read_write_wrap_ack;
6031 +       enum dpst_event_enum dpst_events[DRM_DPST_RING_DEPTH];
6032 +       int dev_name_arry_rw_status[DRM_DPST_RING_DEPTH];
6033 +       struct umevent_list *hotplug_dev_list;
6034 +       struct list_head *dev_umevent_arry[DRM_DPST_MAX_NUM_EVENTS];
6035 +};
6036 +/**
6037 + * dpst state structure
6038 + *
6039 + */
6040 +struct dpst_state {
6041 +       struct workqueue_struct *dpst_wq;
6042 +       struct dpst_disp_workqueue_data dpst_change_wq_data;
6043 +       struct umevent_list *list;
6044 +};
6045 +/**
6046 + * main interface function prototytpes for dpst support.
6047 + *
6048 + */
6049 +extern struct dpst_state *psb_dpst_init(struct kobject *parent_kobj);
6050 +extern int psb_dpst_notify_change_um(enum dpst_event_enum event,
6051 +                                    struct dpst_state *state);
6052 +extern struct umevent_obj *psb_dpst_create_and_notify_um(const char *name,
6053 +                                                struct dpst_state *state);
6054 +extern struct umevent_list *psb_dpst_device_pool_create_and_init(
6055 +                                                struct kobject *parent_kobj,
6056 +                                                struct dpst_state *state);
6057 +extern void psb_dpst_device_pool_destroy(struct dpst_state *state);
6058 +/**
6059 + * to go back and forth between work struct and workqueue data
6060 + *
6061 + */
6062 +#define to_dpst_disp_workqueue_data(x) \
6063 +       container_of(x, struct dpst_disp_workqueue_data, work)
6064 +
6065 +/**
6066 + * function prototypes for workqueue implementation
6067 + *
6068 + */
6069 +extern void psb_dpst_dev_change_wq(struct work_struct *work);
6070 +#endif
6071 diff --git a/drivers/gpu/drm/mrst/drv/psb_drm.h b/drivers/gpu/drm/mrst/drv/psb_drm.h
6072 new file mode 100644
6073 index 0000000..f23afd0
6074 --- /dev/null
6075 +++ b/drivers/gpu/drm/mrst/drv/psb_drm.h
6076 @@ -0,0 +1,634 @@
6077 +/**************************************************************************
6078 + * Copyright (c) 2007, Intel Corporation.
6079 + * All Rights Reserved.
6080 + * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
6081 + * All Rights Reserved.
6082 + *
6083 + * This program is free software; you can redistribute it and/or modify it
6084 + * under the terms and conditions of the GNU General Public License,
6085 + * version 2, as published by the Free Software Foundation.
6086 + *
6087 + * This program is distributed in the hope it will be useful, but WITHOUT
6088 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6089 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
6090 + * more details.
6091 + *
6092 + * You should have received a copy of the GNU General Public License along with
6093 + * this program; if not, write to the Free Software Foundation, Inc., 
6094 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6095 + *
6096 + **************************************************************************/
6097 +
6098 +#ifndef _PSB_DRM_H_
6099 +#define _PSB_DRM_H_
6100 +
6101 +#if defined(__linux__) && !defined(__KERNEL__)
6102 +#include<stdint.h>
6103 +#include <linux/types.h>
6104 +#include "drm_mode.h"
6105 +#endif
6106 +
6107 +#include "ttm/ttm_fence_user.h"
6108 +#include "ttm/ttm_placement_user.h"
6109 +
6110 +/*
6111 + * Menlow/MRST graphics driver package version
6112 + * a.b.c.xxxx
6113 + * a - Product Family: 5 - Linux
6114 + * b - Major Release Version: 0 - non-Gallium (Unbuntu);
6115 + *                            1 - Gallium (Moblin2)
6116 + * c - Hotfix Release
6117 + * xxxx - Graphics internal build #
6118 + */
6119 +#define PSB_PACKAGE_VERSION "5.3.0.32L.0007"
6120 +
6121 +#define DRM_PSB_SAREA_MAJOR 0
6122 +#define DRM_PSB_SAREA_MINOR 2
6123 +#define PSB_FIXED_SHIFT 16
6124 +
6125 +
6126 +#define PSB_NUM_PIPE 2
6127 +
6128 +/*
6129 + * Public memory types.
6130 + */
6131 +
6132 +#define DRM_PSB_MEM_MMU TTM_PL_PRIV1
6133 +#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1
6134 +
6135 +typedef int32_t psb_fixed;
6136 +typedef uint32_t psb_ufixed;
6137 +
6138 +static inline int32_t psb_int_to_fixed(int a)
6139 +{
6140 +       return a * (1 << PSB_FIXED_SHIFT);
6141 +}
6142 +
6143 +static inline uint32_t psb_unsigned_to_ufixed(unsigned int a)
6144 +{
6145 +       return a << PSB_FIXED_SHIFT;
6146 +}
6147 +
6148 +/*Status of the command sent to the gfx device.*/
6149 +typedef enum {
6150 +       DRM_CMD_SUCCESS,
6151 +       DRM_CMD_FAILED,
6152 +       DRM_CMD_HANG
6153 +} drm_cmd_status_t;
6154 +
6155 +struct drm_psb_scanout {
6156 +       uint32_t buffer_id;     /* DRM buffer object ID */
6157 +       uint32_t rotation;      /* Rotation as in RR_rotation definitions */
6158 +       uint32_t stride;        /* Buffer stride in bytes */
6159 +       uint32_t depth;         /* Buffer depth in bits (NOT) bpp */
6160 +       uint32_t width;         /* Buffer width in pixels */
6161 +       uint32_t height;        /* Buffer height in lines */
6162 +       int32_t transform[3][3];        /* Buffer composite transform */
6163 +       /* (scaling, rot, reflect) */
6164 +};
6165 +
6166 +#define DRM_PSB_SAREA_OWNERS 16
6167 +#define DRM_PSB_SAREA_OWNER_2D 0
6168 +#define DRM_PSB_SAREA_OWNER_3D 1
6169 +
6170 +#define DRM_PSB_SAREA_SCANOUTS 3
6171 +
6172 +struct drm_psb_sarea {
6173 +       /* Track changes of this data structure */
6174 +
6175 +       uint32_t major;
6176 +       uint32_t minor;
6177 +
6178 +       /* Last context to touch part of hw */
6179 +       uint32_t ctx_owners[DRM_PSB_SAREA_OWNERS];
6180 +
6181 +       /* Definition of front- and rotated buffers */
6182 +       uint32_t num_scanouts;
6183 +       struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS];
6184 +
6185 +       int planeA_x;
6186 +       int planeA_y;
6187 +       int planeA_w;
6188 +       int planeA_h;
6189 +       int planeB_x;
6190 +       int planeB_y;
6191 +       int planeB_w;
6192 +       int planeB_h;
6193 +       /* Number of active scanouts */
6194 +       uint32_t num_active_scanouts;
6195 +};
6196 +
6197 +#define PSB_RELOC_MAGIC         0x67676767
6198 +#define PSB_RELOC_SHIFT_MASK    0x0000FFFF
6199 +#define PSB_RELOC_SHIFT_SHIFT   0
6200 +#define PSB_RELOC_ALSHIFT_MASK  0xFFFF0000
6201 +#define PSB_RELOC_ALSHIFT_SHIFT 16
6202 +
6203 +#define PSB_RELOC_OP_OFFSET     0      /* Offset of the indicated
6204 +                                        * buffer
6205 +                                        */
6206 +
6207 +struct drm_psb_reloc {
6208 +       uint32_t reloc_op;
6209 +       uint32_t where;         /* offset in destination buffer */
6210 +       uint32_t buffer;        /* Buffer reloc applies to */
6211 +       uint32_t mask;          /* Destination format: */
6212 +       uint32_t shift;         /* Destination format: */
6213 +       uint32_t pre_add;       /* Destination format: */
6214 +       uint32_t background;    /* Destination add */
6215 +       uint32_t dst_buffer;    /* Destination buffer. Index into buffer_list */
6216 +       uint32_t arg0;          /* Reloc-op dependant */
6217 +       uint32_t arg1;
6218 +};
6219 +
6220 +
6221 +#define PSB_GPU_ACCESS_READ         (1ULL << 32)
6222 +#define PSB_GPU_ACCESS_WRITE        (1ULL << 33)
6223 +#define PSB_GPU_ACCESS_MASK         (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
6224 +
6225 +#define PSB_BO_FLAG_COMMAND         (1ULL << 52)
6226 +
6227 +#define PSB_ENGINE_2D 0
6228 +#define PSB_ENGINE_VIDEO 1
6229 +#define LNC_ENGINE_ENCODE 5
6230 +
6231 +/*
6232 + * For this fence class we have a couple of
6233 + * fence types.
6234 + */
6235 +
6236 +#define _PSB_FENCE_EXE_SHIFT           0
6237 +#define _PSB_FENCE_FEEDBACK_SHIFT      4
6238 +
6239 +#define _PSB_FENCE_TYPE_EXE         (1 << _PSB_FENCE_EXE_SHIFT)
6240 +#define _PSB_FENCE_TYPE_FEEDBACK    (1 << _PSB_FENCE_FEEDBACK_SHIFT)
6241 +
6242 +#define PSB_NUM_ENGINES 6
6243 +
6244 +
6245 +#define PSB_FEEDBACK_OP_VISTEST (1 << 0)
6246 +
6247 +struct drm_psb_extension_rep {
6248 +       int32_t exists;
6249 +       uint32_t driver_ioctl_offset;
6250 +       uint32_t sarea_offset;
6251 +       uint32_t major;
6252 +       uint32_t minor;
6253 +       uint32_t pl;
6254 +};
6255 +
6256 +#define DRM_PSB_EXT_NAME_LEN 128
6257 +
6258 +union drm_psb_extension_arg {
6259 +       char extension[DRM_PSB_EXT_NAME_LEN];
6260 +       struct drm_psb_extension_rep rep;
6261 +};
6262 +
6263 +struct psb_validate_req {
6264 +       uint64_t set_flags;
6265 +       uint64_t clear_flags;
6266 +       uint64_t next;
6267 +       uint64_t presumed_gpu_offset;
6268 +       uint32_t buffer_handle;
6269 +       uint32_t presumed_flags;
6270 +       uint32_t group;
6271 +       uint32_t pad64;
6272 +};
6273 +
6274 +struct psb_validate_rep {
6275 +       uint64_t gpu_offset;
6276 +       uint32_t placement;
6277 +       uint32_t fence_type_mask;
6278 +};
6279 +
6280 +#define PSB_USE_PRESUMED     (1 << 0)
6281 +
6282 +struct psb_validate_arg {
6283 +       int handled;
6284 +       int ret;
6285 +       union {
6286 +               struct psb_validate_req req;
6287 +               struct psb_validate_rep rep;
6288 +       } d;
6289 +};
6290 +
6291 +
6292 +#define DRM_PSB_FENCE_NO_USER        (1 << 0)
6293 +
6294 +struct psb_ttm_fence_rep {
6295 +       uint32_t handle;
6296 +       uint32_t fence_class;
6297 +       uint32_t fence_type;
6298 +       uint32_t signaled_types;
6299 +       uint32_t error;
6300 +};
6301 +
6302 +typedef struct drm_psb_cmdbuf_arg {
6303 +       uint64_t buffer_list;   /* List of buffers to validate */
6304 +       uint64_t clip_rects;    /* See i915 counterpart */
6305 +       uint64_t scene_arg;
6306 +       uint64_t fence_arg;
6307 +
6308 +       uint32_t ta_flags;
6309 +
6310 +       uint32_t ta_handle;     /* TA reg-value pairs */
6311 +       uint32_t ta_offset;
6312 +       uint32_t ta_size;
6313 +
6314 +       uint32_t oom_handle;
6315 +       uint32_t oom_offset;
6316 +       uint32_t oom_size;
6317 +
6318 +       uint32_t cmdbuf_handle; /* 2D Command buffer object or, */
6319 +       uint32_t cmdbuf_offset; /* rasterizer reg-value pairs */
6320 +       uint32_t cmdbuf_size;
6321 +
6322 +       uint32_t reloc_handle;  /* Reloc buffer object */
6323 +       uint32_t reloc_offset;
6324 +       uint32_t num_relocs;
6325 +
6326 +       int32_t damage;         /* Damage front buffer with cliprects */
6327 +       /* Not implemented yet */
6328 +       uint32_t fence_flags;
6329 +       uint32_t engine;
6330 +
6331 +       /*
6332 +        * Feedback;
6333 +        */
6334 +
6335 +       uint32_t feedback_ops;
6336 +       uint32_t feedback_handle;
6337 +       uint32_t feedback_offset;
6338 +       uint32_t feedback_breakpoints;
6339 +       uint32_t feedback_size;
6340 +} drm_psb_cmdbuf_arg_t;
6341 +
6342 +typedef struct drm_psb_pageflip_arg {
6343 +       uint32_t flip_offset;
6344 +       uint32_t stride;
6345 +} drm_psb_pageflip_arg_t;
6346 +
6347 +typedef enum {
6348 +       LNC_VIDEO_DEVICE_INFO,
6349 +       LNC_VIDEO_GETPARAM_RAR_INFO,
6350 +       LNC_VIDEO_GETPARAM_CI_INFO,
6351 +       LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET,
6352 +       LNC_VIDEO_FRAME_SKIP
6353 +} lnc_getparam_key_t;
6354 +
6355 +struct drm_lnc_video_getparam_arg {
6356 +       lnc_getparam_key_t key;
6357 +       uint64_t arg;   /* argument pointer */
6358 +       uint64_t value; /* feed back pointer */
6359 +};
6360 +
6361 +
6362 +/*
6363 + * Feedback components:
6364 + */
6365 +
6366 +/*
6367 + * Vistest component. The number of these in the feedback buffer
6368 + * equals the number of vistest breakpoints + 1.
6369 + * This is currently the only feedback component.
6370 + */
6371 +
6372 +struct drm_psb_vistest {
6373 +       uint32_t vt[8];
6374 +};
6375 +
6376 +struct drm_psb_sizes_arg {
6377 +       uint32_t ta_mem_size;
6378 +       uint32_t mmu_size;
6379 +       uint32_t pds_size;
6380 +       uint32_t rastgeom_size;
6381 +       uint32_t tt_size;
6382 +       uint32_t vram_size;
6383 +};
6384 +
6385 +struct drm_psb_hist_status_arg {
6386 +       uint32_t buf[32];
6387 +};
6388 +
6389 +struct drm_psb_dpst_lut_arg {
6390 +       uint8_t lut[256];
6391 +       int output_id;
6392 +};
6393 +
6394 +struct mrst_timing_info {
6395 +       uint16_t pixel_clock;
6396 +       uint8_t hactive_lo;
6397 +       uint8_t hblank_lo;
6398 +       uint8_t hblank_hi:4;
6399 +       uint8_t hactive_hi:4;
6400 +       uint8_t vactive_lo;
6401 +       uint8_t vblank_lo;
6402 +       uint8_t vblank_hi:4;
6403 +       uint8_t vactive_hi:4;
6404 +       uint8_t hsync_offset_lo;
6405 +       uint8_t hsync_pulse_width_lo;
6406 +       uint8_t vsync_pulse_width_lo:4;
6407 +       uint8_t vsync_offset_lo:4;
6408 +       uint8_t vsync_pulse_width_hi:2;
6409 +       uint8_t vsync_offset_hi:2;
6410 +       uint8_t hsync_pulse_width_hi:2;
6411 +       uint8_t hsync_offset_hi:2;
6412 +       uint8_t width_mm_lo;
6413 +       uint8_t height_mm_lo;
6414 +       uint8_t height_mm_hi:4;
6415 +       uint8_t width_mm_hi:4;
6416 +       uint8_t hborder;
6417 +       uint8_t vborder;
6418 +       uint8_t unknown0:1;
6419 +       uint8_t hsync_positive:1;
6420 +       uint8_t vsync_positive:1;
6421 +       uint8_t separate_sync:2;
6422 +       uint8_t stereo:1;
6423 +       uint8_t unknown6:1;
6424 +       uint8_t interlaced:1;
6425 +} __attribute__((packed));
6426 +
6427 +struct mrst_panel_descriptor_v1{
6428 +       uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
6429 +                               /* 0x61190 if MIPI */
6430 +       uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
6431 +       uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
6432 +       uint32_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
6433 +                                               /* Register 0x61210 */
6434 +       struct mrst_timing_info DTD;/*18 bytes, Standard definition */
6435 +       uint16_t Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
6436 +                               /* Bit 0, Frequency, 15 bits,0 - 32767Hz */
6437 +                       /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
6438 +       uint16_t Panel_MIPI_Display_Descriptor;
6439 +                       /*16 bits, Defined as follows: */
6440 +                       /* if MIPI, 0x0000 if LVDS */
6441 +                       /* Bit 0, Type, 2 bits, */
6442 +                       /* 0: Type-1, */
6443 +                       /* 1: Type-2, */
6444 +                       /* 2: Type-3, */
6445 +                       /* 3: Type-4 */
6446 +                       /* Bit 2, Pixel Format, 4 bits */
6447 +                       /* Bit0: 16bpp (not supported in LNC), */
6448 +                       /* Bit1: 18bpp loosely packed, */
6449 +                       /* Bit2: 18bpp packed, */
6450 +                       /* Bit3: 24bpp */
6451 +                       /* Bit 6, Reserved, 2 bits, 00b */
6452 +               /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
6453 +                       /* Bit 14, Reserved, 2 bits, 00b */
6454 +} __attribute__ ((packed));
6455 +
6456 +struct mrst_panel_descriptor_v2{
6457 +       uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
6458 +                               /* 0x61190 if MIPI */
6459 +       uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
6460 +       uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
6461 +       uint8_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
6462 +                                               /* Register 0x61210 */
6463 +       struct mrst_timing_info DTD;/*18 bytes, Standard definition */
6464 +       uint16_t Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
6465 +                               /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
6466 +       uint8_t Panel_Initial_Brightness;/* [7:0] 0 - 100% */
6467 +                       /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
6468 +       uint16_t Panel_MIPI_Display_Descriptor;
6469 +                       /*16 bits, Defined as follows: */
6470 +                       /* if MIPI, 0x0000 if LVDS */
6471 +                       /* Bit 0, Type, 2 bits, */
6472 +                       /* 0: Type-1, */
6473 +                       /* 1: Type-2, */
6474 +                       /* 2: Type-3, */
6475 +                       /* 3: Type-4 */
6476 +                       /* Bit 2, Pixel Format, 4 bits */
6477 +                       /* Bit0: 16bpp (not supported in LNC), */
6478 +                       /* Bit1: 18bpp loosely packed, */
6479 +                       /* Bit2: 18bpp packed, */
6480 +                       /* Bit3: 24bpp */
6481 +                       /* Bit 6, Reserved, 2 bits, 00b */
6482 +               /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
6483 +                       /* Bit 14, Reserved, 2 bits, 00b */
6484 +} __attribute__ ((packed));
6485 +
6486 +union mrst_panel_rx{
6487 +       struct{
6488 +               uint16_t NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
6489 +                       /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
6490 +               uint16_t MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
6491 +               /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
6492 +               uint16_t SupportedVideoTransferMode:2; /*0: Non-burst only */
6493 +                                       /* 1: Burst and non-burst */
6494 +                                       /* 2/3: Reserved */
6495 +               uint16_t HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
6496 +               uint16_t DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
6497 +               uint16_t ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
6498 +               uint16_t BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
6499 +               uint16_t Rsvd:5;/*5 bits,00000b */
6500 +       } panelrx;
6501 +       uint16_t panel_receiver;
6502 +} __attribute__ ((packed));
6503 +
6504 +struct gct_ioctl_arg{
6505 +       uint8_t bpi; /* boot panel index, number of panel used during boot */
6506 +       uint8_t pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
6507 +       struct mrst_timing_info DTD; /* timing info for the selected panel */
6508 +       uint32_t Panel_Port_Control;
6509 +       uint32_t PP_On_Sequencing;/*1 dword,Register 0x61208,*/
6510 +       uint32_t PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
6511 +       uint32_t PP_Cycle_Delay;
6512 +       uint16_t Panel_Backlight_Inverter_Descriptor;
6513 +       uint16_t Panel_MIPI_Display_Descriptor;
6514 +} __attribute__ ((packed));
6515 +
6516 +struct mrst_vbt{
6517 +       char Signature[4]; /*4 bytes,"$GCT" */
6518 +       uint8_t Revision; /*1 byte */
6519 +       uint8_t Size; /*1 byte */
6520 +       uint8_t Checksum; /*1 byte,Calculated*/
6521 +       void *mrst_gct;
6522 +} __attribute__ ((packed));
6523 +
6524 +struct mrst_gct_v1{ /* expect this table to change per customer request*/
6525 +       union{ /*8 bits,Defined as follows: */
6526 +               struct{
6527 +                       uint8_t PanelType:4; /*4 bits, Bit field for panels*/
6528 +                                       /* 0 - 3: 0 = LVDS, 1 = MIPI*/
6529 +                                       /*2 bits,Specifies which of the*/
6530 +                       uint8_t BootPanelIndex:2;
6531 +                                       /* 4 panels to use by default*/
6532 +                       uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
6533 +                                       /* the 4 MIPI DSI receivers to use*/
6534 +                       } PD;
6535 +               uint8_t PanelDescriptor;
6536 +       };
6537 +       struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
6538 +       union mrst_panel_rx panelrx[4]; /* panel receivers*/
6539 +} __attribute__ ((packed));
6540 +
6541 +struct mrst_gct_v2{ /* expect this table to change per customer request*/
6542 +       union{ /*8 bits,Defined as follows: */
6543 +               struct{
6544 +                       uint8_t PanelType:4; /*4 bits, Bit field for panels*/
6545 +                                       /* 0 - 3: 0 = LVDS, 1 = MIPI*/
6546 +                                       /*2 bits,Specifies which of the*/
6547 +                       uint8_t BootPanelIndex:2;
6548 +                                       /* 4 panels to use by default*/
6549 +                       uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
6550 +                                       /* the 4 MIPI DSI receivers to use*/
6551 +                       } PD;
6552 +               uint8_t PanelDescriptor;
6553 +       };
6554 +       struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
6555 +       union mrst_panel_rx panelrx[4]; /* panel receivers*/
6556 +} __attribute__ ((packed));
6557 +
6558 +#define PSB_DC_CRTC_SAVE 0x01
6559 +#define PSB_DC_CRTC_RESTORE 0x02
6560 +#define PSB_DC_OUTPUT_SAVE 0x04
6561 +#define PSB_DC_OUTPUT_RESTORE 0x08
6562 +#define PSB_DC_CRTC_MASK 0x03
6563 +#define PSB_DC_OUTPUT_MASK 0x0C
6564 +
6565 +struct drm_psb_dc_state_arg {
6566 +       uint32_t flags;
6567 +       uint32_t obj_id;
6568 +};
6569 +
6570 +struct drm_psb_mode_operation_arg {
6571 +       uint32_t obj_id;
6572 +       uint16_t operation;
6573 +       struct drm_mode_modeinfo mode;
6574 +       void *data;
6575 +};
6576 +
6577 +struct drm_psb_stolen_memory_arg {
6578 +       uint32_t base;
6579 +       uint32_t size;
6580 +};
6581 +
6582 +/*Display Register Bits*/
6583 +#define REGRWBITS_PFIT_CONTROLS                        (1 << 0)
6584 +#define REGRWBITS_PFIT_AUTOSCALE_RATIOS                (1 << 1)
6585 +#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2)
6586 +#define REGRWBITS_PIPEASRC                     (1 << 3)
6587 +#define REGRWBITS_PIPEBSRC                     (1 << 4)
6588 +#define REGRWBITS_VTOTAL_A                     (1 << 5)
6589 +#define REGRWBITS_VTOTAL_B                     (1 << 6)
6590 +
6591 +/*Overlay Register Bits*/
6592 +#define OV_REGRWBITS_OVADD                     (1 << 0)
6593 +#define OV_REGRWBITS_OGAM_ALL                  (1 << 1)
6594 +
6595 +struct drm_psb_register_rw_arg {
6596 +       uint32_t b_force_hw_on;
6597 +
6598 +       uint32_t display_read_mask;
6599 +       uint32_t display_write_mask;
6600 +
6601 +       struct {
6602 +               uint32_t pfit_controls;
6603 +               uint32_t pfit_autoscale_ratios;
6604 +               uint32_t pfit_programmed_scale_ratios;
6605 +               uint32_t pipeasrc;
6606 +               uint32_t pipebsrc;
6607 +               uint32_t vtotal_a;
6608 +               uint32_t vtotal_b;
6609 +       } display;
6610 +
6611 +       uint32_t overlay_read_mask;
6612 +       uint32_t overlay_write_mask;
6613 +
6614 +       struct {
6615 +               uint32_t OVADD;
6616 +               uint32_t OGAMC0;
6617 +               uint32_t OGAMC1;
6618 +               uint32_t OGAMC2;
6619 +               uint32_t OGAMC3;
6620 +               uint32_t OGAMC4;
6621 +               uint32_t OGAMC5;
6622 +       } overlay;
6623 +
6624 +       uint32_t sprite_enable_mask;
6625 +       uint32_t sprite_disable_mask;
6626 +
6627 +       struct {
6628 +               uint32_t dspa_control;
6629 +               uint32_t dspa_key_value;
6630 +               uint32_t dspa_key_mask;
6631 +               uint32_t dspc_control;
6632 +               uint32_t dspc_stride;
6633 +               uint32_t dspc_position;
6634 +               uint32_t dspc_linear_offset;
6635 +               uint32_t dspc_size;
6636 +               uint32_t dspc_surface;
6637 +       } sprite;
6638 +};
6639 +
6640 +struct psb_gtt_mapping_arg {
6641 +       void *hKernelMemInfo;
6642 +       uint32_t offset_pages;
6643 +};
6644 +
6645 +struct drm_psb_getpageaddrs_arg {
6646 +       uint32_t handle;
6647 +       unsigned long *page_addrs;
6648 +       unsigned long gtt_offset;
6649 +};
6650 +
6651 +
6652 +/* Controlling the kernel modesetting buffers */
6653 +
6654 +#define DRM_PSB_KMS_OFF                0x00
6655 +#define DRM_PSB_KMS_ON         0x01
6656 +#define DRM_PSB_VT_LEAVE        0x02
6657 +#define DRM_PSB_VT_ENTER        0x03
6658 +#define DRM_PSB_EXTENSION       0x06
6659 +#define DRM_PSB_SIZES           0x07
6660 +#define DRM_PSB_FUSE_REG       0x08
6661 +#define DRM_PSB_VBT            0x09
6662 +#define DRM_PSB_DC_STATE       0x0A
6663 +#define DRM_PSB_ADB            0x0B
6664 +#define DRM_PSB_MODE_OPERATION 0x0C
6665 +#define DRM_PSB_STOLEN_MEMORY  0x0D
6666 +#define DRM_PSB_REGISTER_RW    0x0E
6667 +#define DRM_PSB_GTT_MAP         0x0F
6668 +#define DRM_PSB_GTT_UNMAP       0x10
6669 +#define DRM_PSB_GETPAGEADDRS   0x11
6670 +/**
6671 + * NOTE: Add new commands here, but increment
6672 + * the values below and increment their
6673 + * corresponding defines where they're
6674 + * defined elsewhere.
6675 + */
6676 +#define DRM_PVR_RESERVED1      0x12
6677 +#define DRM_PVR_RESERVED2      0x13
6678 +#define DRM_PVR_RESERVED3      0x14
6679 +#define DRM_PVR_RESERVED4      0x15
6680 +#define DRM_PVR_RESERVED5      0x16
6681 +
6682 +#define DRM_PSB_HIST_ENABLE    0x17
6683 +#define DRM_PSB_HIST_STATUS    0x18
6684 +#define DRM_PSB_UPDATE_GUARD   0x19
6685 +#define DRM_PSB_INIT_COMM      0x1A
6686 +#define DRM_PSB_DPST           0x1B
6687 +#define DRM_PSB_GAMMA          0x1C
6688 +#define DRM_PSB_DPST_BL                0x1D
6689 +
6690 +#define DRM_PVR_RESERVED6      0x1E
6691 +
6692 +#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
6693 +
6694 +struct drm_psb_dev_info_arg {
6695 +       uint32_t num_use_attribute_registers;
6696 +};
6697 +#define DRM_PSB_DEVINFO         0x01
6698 +
6699 +#define PSB_MODE_OPERATION_MODE_VALID  0x01
6700 +#define PSB_MODE_OPERATION_SET_DC_BASE  0x02
6701 +
6702 +struct drm_psb_get_pipe_from_crtc_id_arg {
6703 +       /** ID of CRTC being requested **/
6704 +       uint32_t crtc_id;
6705 +
6706 +       /** pipe of requested CRTC **/
6707 +       uint32_t pipe;
6708 +};
6709 +
6710 +#endif
6711 diff --git a/drivers/gpu/drm/mrst/drv/psb_drv.c b/drivers/gpu/drm/mrst/drv/psb_drv.c
6712 new file mode 100644
6713 index 0000000..dbc4327
6714 --- /dev/null
6715 +++ b/drivers/gpu/drm/mrst/drv/psb_drv.c
6716 @@ -0,0 +1,2218 @@
6717 +/**************************************************************************
6718 + * Copyright (c) 2007, Intel Corporation.
6719 + * All Rights Reserved.
6720 + * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
6721 + * All Rights Reserved.
6722 + *
6723 + * This program is free software; you can redistribute it and/or modify it
6724 + * under the terms and conditions of the GNU General Public License,
6725 + * version 2, as published by the Free Software Foundation.
6726 + *
6727 + * This program is distributed in the hope it will be useful, but WITHOUT
6728 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6729 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
6730 + * more details.
6731 + *
6732 + * You should have received a copy of the GNU General Public License along with
6733 + * this program; if not, write to the Free Software Foundation, Inc., 
6734 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6735 + *
6736 + **************************************************************************/
6737 +
6738 +#include <drm/drmP.h>
6739 +#include <drm/drm.h>
6740 +#include "psb_drm.h"
6741 +#include "psb_drv.h"
6742 +#include "psb_fb.h"
6743 +#include "psb_reg.h"
6744 +#include "psb_intel_reg.h"
6745 +#include "psb_intel_bios.h"
6746 +#include "psb_msvdx.h"
6747 +#include "lnc_topaz.h"
6748 +#include <drm/drm_pciids.h>
6749 +#include "ospm_power.h"
6750 +#include "pvr_drm_shared.h"
6751 +#include "img_types.h"
6752 +#include <linux/cpu.h>
6753 +#include <linux/notifier.h>
6754 +#include <linux/spinlock.h>
6755 +#include <linux/rar/rar_register.h>
6756 +#include <linux/rar/memrar.h>
6757 +
6758 +/*IMG headers*/
6759 +#include "pvr_drm_shared.h"
6760 +#include "img_types.h"
6761 +#include "pvr_bridge.h"
6762 +#include "linkage.h"
6763 +#include "sysirq.h"
6764 +
6765 +int drm_psb_debug;
6766 +EXPORT_SYMBOL(drm_psb_debug);
6767 +static int drm_psb_trap_pagefaults;
6768 +
6769 +int drm_psb_no_fb;
6770 +int drm_psb_force_pipeb;
6771 +int drm_idle_check_interval = 5;
6772 +int drm_msvdx_pmpolicy = PSB_PMPOLICY_POWERDOWN;
6773 +int drm_topaz_pmpolicy = PSB_PMPOLICY_NOPM;
6774 +int drm_topaz_sbuswa;
6775 +int drm_psb_ospm = 1;
6776 +
6777 +static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
6778 +
6779 +MODULE_PARM_DESC(debug, "Enable debug output");
6780 +MODULE_PARM_DESC(no_fb, "Disable FBdev");
6781 +MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
6782 +MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts");
6783 +MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb");
6784 +MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB");
6785 +MODULE_PARM_DESC(ospm, "switch for ospm support");
6786 +MODULE_PARM_DESC(msvdx_pmpolicy, "msvdx power management policy btw frames");
6787 +MODULE_PARM_DESC(topaz_pmpolicy, "topaz power managerment policy btw frames");
6788 +MODULE_PARM_DESC(topaz_sbuswa, "WA for topaz sysbus write");
6789 +module_param_named(debug, drm_psb_debug, int, 0600);
6790 +module_param_named(no_fb, drm_psb_no_fb, int, 0600);
6791 +module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
6792 +module_param_named(force_pipeb, drm_psb_force_pipeb, int, 0600);
6793 +module_param_named(msvdx_pmpolicy, drm_msvdx_pmpolicy, int, 0600);
6794 +module_param_named(topaz_pmpolicy, drm_topaz_pmpolicy, int, 0600);
6795 +module_param_named(topaz_sbuswa, drm_topaz_sbuswa, int, 0600);
6796 +module_param_named(ospm, drm_psb_ospm, int, 0600);
6797 +
6798 +#if 0
6799 +#ifndef CONFIG_X86_PAT
6800 +#warning "Don't build this driver without PAT support!!!"
6801 +#endif
6802 +#endif
6803 +#define psb_PCI_IDS \
6804 +    {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108}, \
6805 +    {0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109}, \
6806 +    {0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6807 +    {0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6808 +    {0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6809 +    {0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6810 +    {0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6811 +    {0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6812 +    {0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6813 +    {0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
6814 +    {0, 0, 0}
6815 +
6816 +static struct pci_device_id pciidlist[] = {
6817 +       psb_PCI_IDS
6818 +};
6819 +
6820 +/*
6821 + * Standard IOCTLs.
6822 + */
6823 +
6824 +#define DRM_IOCTL_PSB_KMS_OFF  \
6825 +               DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
6826 +#define DRM_IOCTL_PSB_KMS_ON   \
6827 +               DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
6828 +#define DRM_IOCTL_PSB_VT_LEAVE \
6829 +               DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE)
6830 +#define DRM_IOCTL_PSB_VT_ENTER \
6831 +               DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE)
6832 +#define DRM_IOCTL_PSB_EXTENSION        \
6833 +               DRM_IOWR(DRM_PSB_EXTENSION + DRM_COMMAND_BASE, \
6834 +                        union drm_psb_extension_arg)
6835 +#define DRM_IOCTL_PSB_SIZES    \
6836 +               DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
6837 +                       struct drm_psb_sizes_arg)
6838 +#define DRM_IOCTL_PSB_FUSE_REG \
6839 +               DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
6840 +#define DRM_IOCTL_PSB_VBT      \
6841 +               DRM_IOWR(DRM_PSB_VBT + DRM_COMMAND_BASE, \
6842 +                       struct gct_ioctl_arg)
6843 +#define DRM_IOCTL_PSB_DC_STATE \
6844 +               DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
6845 +                       struct drm_psb_dc_state_arg)
6846 +#define DRM_IOCTL_PSB_ADB      \
6847 +               DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
6848 +#define DRM_IOCTL_PSB_MODE_OPERATION   \
6849 +               DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
6850 +                        struct drm_psb_mode_operation_arg)
6851 +#define DRM_IOCTL_PSB_STOLEN_MEMORY    \
6852 +               DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
6853 +                        struct drm_psb_stolen_memory_arg)
6854 +#define DRM_IOCTL_PSB_REGISTER_RW      \
6855 +               DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
6856 +                        struct drm_psb_register_rw_arg)
6857 +#define DRM_IOCTL_PSB_GTT_MAP  \
6858 +               DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \
6859 +                        struct psb_gtt_mapping_arg)
6860 +#define DRM_IOCTL_PSB_GTT_UNMAP        \
6861 +               DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \
6862 +                       struct psb_gtt_mapping_arg)
6863 +#define DRM_IOCTL_PSB_GETPAGEADDRS     \
6864 +               DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\
6865 +                        struct drm_psb_getpageaddrs_arg)
6866 +#define DRM_IOCTL_PSB_HIST_ENABLE      \
6867 +               DRM_IOWR(DRM_PSB_HIST_ENABLE + DRM_COMMAND_BASE, \
6868 +                        uint32_t)
6869 +#define DRM_IOCTL_PSB_HIST_STATUS      \
6870 +               DRM_IOWR(DRM_PSB_HIST_STATUS + DRM_COMMAND_BASE, \
6871 +                        struct drm_psb_hist_status_arg)
6872 +#define DRM_IOCTL_PSB_UPDATE_GUARD     \
6873 +               DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \
6874 +                        uint32_t)
6875 +#define DRM_IOCTL_PSB_INIT_COMM        \
6876 +               DRM_IOWR(DRM_PSB_INIT_COMM + DRM_COMMAND_BASE, \
6877 +                        uint32_t)
6878 +#define DRM_IOCTL_PSB_DPST     \
6879 +               DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
6880 +                        uint32_t)
6881 +#define DRM_IOCTL_PSB_GAMMA    \
6882 +               DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
6883 +                        struct drm_psb_dpst_lut_arg)
6884 +#define DRM_IOCTL_PSB_DPST_BL  \
6885 +               DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
6886 +                        uint32_t)
6887 +#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID    \
6888 +               DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
6889 +                        struct drm_psb_get_pipe_from_crtc_id_arg)
6890 +
6891 +
6892 +/*pvr ioctls*/
6893 +#define PVR_DRM_SRVKM_IOCTL \
6894 +       DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_SRVKM_CMD, \
6895 +               PVRSRV_BRIDGE_PACKAGE)
6896 +#define PVR_DRM_DISP_IOCTL \
6897 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DISP_CMD)
6898 +#define PVR_DRM_BC_IOCTL \
6899 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_BC_CMD)
6900 +#define PVR_DRM_IS_MASTER_IOCTL \
6901 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_IS_MASTER_CMD)
6902 +#define PVR_DRM_UNPRIV_IOCTL \
6903 +       DRM_IOWR(DRM_COMMAND_BASE + PVR_DRM_UNPRIV_CMD, \
6904 +               IMG_UINT32)
6905 +#define PVR_DRM_DBGDRV_IOCTL \
6906 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD)
6907 +
6908 +/*
6909 + * TTM execbuf extension.
6910 + */
6911 +#if defined(PDUMP)
6912 +#define DRM_PSB_CMDBUF           (PVR_DRM_DBGDRV_CMD + 1)
6913 +#else
6914 +#define DRM_PSB_CMDBUF           (DRM_PSB_DPST_BL + 1)
6915 +#endif
6916 +
6917 +#define DRM_PSB_SCENE_UNREF      (DRM_PSB_CMDBUF + 1)
6918 +#define DRM_IOCTL_PSB_CMDBUF   \
6919 +               DRM_IOW(DRM_PSB_CMDBUF + DRM_COMMAND_BASE,      \
6920 +                       struct drm_psb_cmdbuf_arg)
6921 +#define DRM_IOCTL_PSB_SCENE_UNREF      \
6922 +               DRM_IOW(DRM_PSB_SCENE_UNREF + DRM_COMMAND_BASE, \
6923 +                       struct drm_psb_scene)
6924 +#define DRM_IOCTL_PSB_KMS_OFF    DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
6925 +#define DRM_IOCTL_PSB_KMS_ON     DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
6926 +#define DRM_IOCTL_PSB_EXTENSION        \
6927 +               DRM_IOWR(DRM_PSB_EXTENSION + DRM_COMMAND_BASE, \
6928 +                        union drm_psb_extension_arg)
6929 +/*
6930 + * TTM placement user extension.
6931 + */
6932 +
6933 +#define DRM_PSB_PLACEMENT_OFFSET   (DRM_PSB_SCENE_UNREF + 1)
6934 +
6935 +#define DRM_PSB_TTM_PL_CREATE   (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET)
6936 +#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET)
6937 +#define DRM_PSB_TTM_PL_UNREF    (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET)
6938 +#define DRM_PSB_TTM_PL_SYNCCPU  (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET)
6939 +#define DRM_PSB_TTM_PL_WAITIDLE  (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET)
6940 +#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET)
6941 +
6942 +/*
6943 + * TTM fence extension.
6944 + */
6945 +
6946 +#define DRM_PSB_FENCE_OFFSET      (DRM_PSB_TTM_PL_SETSTATUS + 1)
6947 +#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET)
6948 +#define DRM_PSB_TTM_FENCE_FINISH   (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET)
6949 +#define DRM_PSB_TTM_FENCE_UNREF    (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET)
6950 +
6951 +#define DRM_PSB_FLIP      (DRM_PSB_TTM_FENCE_UNREF + 1)        /*20*/
6952 +/* PSB video extension */
6953 +#define DRM_LNC_VIDEO_GETPARAM         (DRM_PSB_FLIP + 1)
6954 +
6955 +#define DRM_IOCTL_PSB_TTM_PL_CREATE    \
6956 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
6957 +                union ttm_pl_create_arg)
6958 +#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \
6959 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\
6960 +                union ttm_pl_reference_arg)
6961 +#define DRM_IOCTL_PSB_TTM_PL_UNREF    \
6962 +       DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\
6963 +               struct ttm_pl_reference_req)
6964 +#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU   \
6965 +       DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\
6966 +               struct ttm_pl_synccpu_arg)
6967 +#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE   \
6968 +       DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\
6969 +               struct ttm_pl_waitidle_arg)
6970 +#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \
6971 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\
6972 +                union ttm_pl_setstatus_arg)
6973 +#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \
6974 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED, \
6975 +                 union ttm_fence_signaled_arg)
6976 +#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \
6977 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH,   \
6978 +                union ttm_fence_finish_arg)
6979 +#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \
6980 +       DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF,     \
6981 +                struct ttm_fence_unref_arg)
6982 +#define DRM_IOCTL_PSB_FLIP \
6983 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_FLIP, \
6984 +                struct drm_psb_pageflip_arg)
6985 +#define DRM_IOCTL_LNC_VIDEO_GETPARAM \
6986 +       DRM_IOWR(DRM_COMMAND_BASE + DRM_LNC_VIDEO_GETPARAM, \
6987 +                struct drm_lnc_video_getparam_arg)
6988 +
6989 +static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
6990 +                             struct drm_file *file_priv);
6991 +static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
6992 +                             struct drm_file *file_priv);
6993 +static int psb_sizes_ioctl(struct drm_device *dev, void *data,
6994 +                          struct drm_file *file_priv);
6995 +static int psb_fuse_reg_ioctl(struct drm_device *dev, void *data,
6996 +                             struct drm_file *file_priv);
6997 +static int psb_vbt_ioctl(struct drm_device *dev, void *data,
6998 +                        struct drm_file *file_priv);
6999 +static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
7000 +                             struct drm_file *file_priv);
7001 +static int psb_adb_ioctl(struct drm_device *dev, void *data,
7002 +                        struct drm_file *file_priv);
7003 +static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
7004 +                                   struct drm_file *file_priv);
7005 +static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
7006 +                                  struct drm_file *file_priv);
7007 +static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
7008 +                                struct drm_file *file_priv);
7009 +static int psb_hist_enable_ioctl(struct drm_device *dev, void *data,
7010 +                                struct drm_file *file_priv);
7011 +static int psb_hist_status_ioctl(struct drm_device *dev, void *data,
7012 +                                struct drm_file *file_priv);
7013 +static int psb_update_guard_ioctl(struct drm_device *dev, void *data,
7014 +                              struct drm_file *file_priv);
7015 +static int psb_init_comm_ioctl(struct drm_device *dev, void *data,
7016 +                               struct drm_file *file_priv);
7017 +static int psb_dpst_ioctl(struct drm_device *dev, void *data,
7018 +                         struct drm_file *file_priv);
7019 +static int psb_gamma_ioctl(struct drm_device *dev, void *data,
7020 +                          struct drm_file *file_priv);
7021 +static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
7022 +                            struct drm_file *file_priv);
7023 +
7024 +#define PSB_IOCTL_DEF(ioctl, func, flags) \
7025 +       [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
7026 +
7027 +static struct drm_ioctl_desc psb_ioctls[] = {
7028 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_OFF, psbfb_kms_off_ioctl,
7029 +                     DRM_ROOT_ONLY),
7030 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
7031 +                       psbfb_kms_on_ioctl,
7032 +                       DRM_ROOT_ONLY),
7033 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl,
7034 +                     DRM_ROOT_ONLY),
7035 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER,
7036 +                       psb_vt_enter_ioctl,
7037 +                       DRM_ROOT_ONLY),
7038 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_EXTENSION, psb_extension_ioctl, DRM_AUTH),
7039 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
7040 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_FUSE_REG, psb_fuse_reg_ioctl, DRM_AUTH),
7041 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_VBT, psb_vbt_ioctl, DRM_AUTH),
7042 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
7043 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
7044 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
7045 +                     DRM_AUTH),
7046 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
7047 +                     DRM_AUTH),
7048 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
7049 +                     DRM_AUTH),
7050 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP,
7051 +                       psb_gtt_map_meminfo_ioctl,
7052 +                       DRM_AUTH),
7053 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP,
7054 +                       psb_gtt_unmap_meminfo_ioctl,
7055 +                       DRM_AUTH),
7056 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS,
7057 +                       psb_getpageaddrs_ioctl,
7058 +                       DRM_AUTH),
7059 +       PSB_IOCTL_DEF(PVR_DRM_SRVKM_IOCTL, PVRSRV_BridgeDispatchKM, 0),
7060 +       PSB_IOCTL_DEF(PVR_DRM_DISP_IOCTL, PVRDRM_Dummy_ioctl, 0),
7061 +       PSB_IOCTL_DEF(PVR_DRM_BC_IOCTL, PVRDRM_Dummy_ioctl, 0),
7062 +       PSB_IOCTL_DEF(PVR_DRM_IS_MASTER_IOCTL, PVRDRMIsMaster, DRM_MASTER),
7063 +       PSB_IOCTL_DEF(PVR_DRM_UNPRIV_IOCTL, PVRDRMUnprivCmd, 0),
7064 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_HIST_ENABLE,
7065 +                       psb_hist_enable_ioctl,
7066 +                       DRM_AUTH),
7067 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_HIST_STATUS,
7068 +                       psb_hist_status_ioctl,
7069 +                       DRM_AUTH),
7070 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_UPDATE_GUARD, psb_update_guard_ioctl, DRM_AUTH),
7071 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_INIT_COMM, psb_init_comm_ioctl, DRM_AUTH),
7072 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
7073 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
7074 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
7075 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, psb_intel_get_pipe_from_crtc_id, 0),
7076 +#if defined(PDUMP)
7077 +       PSB_IOCTL_DEF(PVR_DRM_DBGDRV_IOCTL, dbgdrv_ioctl, 0),
7078 +#endif
7079 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_CMDBUF, psb_cmdbuf_ioctl, DRM_AUTH),
7080 +       /*to be removed later*/
7081 +       /*PSB_IOCTL_DEF(DRM_IOCTL_PSB_SCENE_UNREF, drm_psb_scene_unref_ioctl,
7082 +                     DRM_AUTH),*/
7083 +
7084 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl,
7085 +                     DRM_AUTH),
7086 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl,
7087 +                     DRM_AUTH),
7088 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl,
7089 +                     DRM_AUTH),
7090 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl,
7091 +                     DRM_AUTH),
7092 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl,
7093 +                     DRM_AUTH),
7094 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl,
7095 +                     DRM_AUTH),
7096 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED,
7097 +                     psb_fence_signaled_ioctl, DRM_AUTH),
7098 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl,
7099 +                     DRM_AUTH),
7100 +       PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl,
7101 +                     DRM_AUTH),
7102 +       /*to be removed later */
7103 +       /*PSB_IOCTL_DEF(DRM_IOCTL_PSB_FLIP, psb_page_flip, DRM_AUTH),*/
7104 +       PSB_IOCTL_DEF(DRM_IOCTL_LNC_VIDEO_GETPARAM,
7105 +                       lnc_video_getparam, DRM_AUTH)
7106 +};
7107 +
7108 +static int psb_max_ioctl = DRM_ARRAY_SIZE(psb_ioctls);
7109 +
7110 +static void get_ci_info(struct drm_psb_private *dev_priv)
7111 +{
7112 +       struct pci_dev *pdev;
7113 +
7114 +       pdev = pci_get_subsys(0x8086, 0x080b, 0, 0, NULL);
7115 +       if (pdev == NULL) {
7116 +               /* IF no pci_device we set size & addr to 0, no ci
7117 +                * share buffer can be created */
7118 +               dev_priv->ci_region_start = 0;
7119 +               dev_priv->ci_region_size = 0;
7120 +               printk(KERN_ERR "can't find CI device, no ci share buffer\n");
7121 +               return;
7122 +       }
7123 +
7124 +       dev_priv->ci_region_start = pci_resource_start(pdev, 1);
7125 +       dev_priv->ci_region_size = pci_resource_len(pdev, 1);
7126 +
7127 +       printk(KERN_INFO "ci_region_start %x ci_region_size %d\n",
7128 +              dev_priv->ci_region_start, dev_priv->ci_region_size);
7129 +
7130 +       pci_dev_put(pdev);
7131 +
7132 +       return;
7133 +}
7134 +
7135 +static void get_rar_info(struct drm_psb_private *dev_priv)
7136 +{
7137 +#if defined(CONFIG_RAR_REGISTER)
7138 +       int ret;
7139 +       u32 start_addr, end_addr;
7140 +
7141 +       dev_priv->rar_region_start = 0;
7142 +       dev_priv->rar_region_size = 0;
7143 +       end_addr = 0;
7144 +       ret = 0;
7145 +
7146 +       ret = rar_get_address(RAR_TYPE_VIDEO, &start_addr,
7147 +                             &end_addr);
7148 +       if (ret) {
7149 +               printk(KERN_ERR "failed to get rar region info\n");
7150 +               return;
7151 +       }
7152 +        dev_priv->rar_region_start = (uint32_t) start_addr;
7153 +       if (!ret)
7154 +               dev_priv->rar_region_size =
7155 +                       end_addr - dev_priv->rar_region_start + 1;
7156 +
7157 +#endif
7158 +       return;
7159 +}
7160 +
7161 +static void psb_set_uopt(struct drm_psb_uopt *uopt)
7162 +{
7163 +       return;
7164 +}
7165 +
7166 +static void psb_lastclose(struct drm_device *dev)
7167 +{
7168 +       struct drm_psb_private *dev_priv =
7169 +           (struct drm_psb_private *) dev->dev_private;
7170 +
7171 +       return;
7172 +
7173 +       if (!dev->dev_private)
7174 +               return;
7175 +
7176 +       mutex_lock(&dev_priv->cmdbuf_mutex);
7177 +       if (dev_priv->context.buffers) {
7178 +               vfree(dev_priv->context.buffers);
7179 +               dev_priv->context.buffers = NULL;
7180 +       }
7181 +       mutex_unlock(&dev_priv->cmdbuf_mutex);
7182 +}
7183 +
7184 +static void psb_do_takedown(struct drm_device *dev)
7185 +{
7186 +       struct drm_psb_private *dev_priv =
7187 +           (struct drm_psb_private *) dev->dev_private;
7188 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
7189 +
7190 +
7191 +       if (dev_priv->have_mem_mmu) {
7192 +               ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU);
7193 +               dev_priv->have_mem_mmu = 0;
7194 +       }
7195 +
7196 +       if (dev_priv->have_tt) {
7197 +               ttm_bo_clean_mm(bdev, TTM_PL_TT);
7198 +               dev_priv->have_tt = 0;
7199 +       }
7200 +
7201 +       if (dev_priv->have_camera) {
7202 +               ttm_bo_clean_mm(bdev, TTM_PL_CI);
7203 +               dev_priv->have_camera = 0;
7204 +       }
7205 +       if (dev_priv->have_rar) {
7206 +               ttm_bo_clean_mm(bdev, TTM_PL_RAR);
7207 +               dev_priv->have_rar = 0;
7208 +       }
7209 +
7210 +       psb_msvdx_uninit(dev);
7211 +
7212 +       if (IS_MRST(dev))
7213 +               if (!dev_priv->topaz_disabled)
7214 +                       lnc_topaz_uninit(dev);
7215 +}
7216 +
7217 +#define FB_REG06 0xD0810600
7218 +#define FB_TOPAZ_DISABLE BIT0
7219 +#define PCI_ID_TOPAZ_DISABLED 0x4101
7220 +#define FB_MIPI_DISABLE  BIT11
7221 +#define FB_REG09 0xD0810900
7222 +#define FB_SKU_MASK  (BIT12|BIT13|BIT14)
7223 +#define FB_SKU_SHIFT 12
7224 +#define FB_SKU_100 0
7225 +#define FB_SKU_100L 1
7226 +#define FB_SKU_83 2
7227 +#if 1 /* FIXME remove it after PO */
7228 +#define FB_GFX_CLK_DIVIDE_MASK (BIT20|BIT21|BIT22)
7229 +#define FB_GFX_CLK_DIVIDE_SHIFT 20
7230 +#define FB_VED_CLK_DIVIDE_MASK (BIT23|BIT24)
7231 +#define FB_VED_CLK_DIVIDE_SHIFT 23
7232 +#define FB_VEC_CLK_DIVIDE_MASK (BIT25|BIT26)
7233 +#define FB_VEC_CLK_DIVIDE_SHIFT 25
7234 +#endif /* FIXME remove it after PO */
7235 +
7236 +
7237 +void mrst_get_fuse_settings(struct drm_psb_private *dev_priv)
7238 +{
7239 +       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
7240 +       uint32_t fuse_value = 0;
7241 +       uint32_t fuse_value_tmp = 0;
7242 +
7243 +       pci_write_config_dword(pci_root, 0xD0, FB_REG06);
7244 +       pci_read_config_dword(pci_root, 0xD4, &fuse_value);
7245 +
7246 +       dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
7247 +
7248 +       DRM_INFO("internal display is %s\n",
7249 +                dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
7250 +
7251 +       if (dev_priv->dev->pci_device == PCI_ID_TOPAZ_DISABLED)
7252 +               dev_priv->topaz_disabled = 1;
7253 +       else
7254 +               dev_priv->topaz_disabled = 0;
7255 +
7256 +       dev_priv->video_device_fuse = fuse_value;
7257 +
7258 +       DRM_INFO("topaz is %s\n",
7259 +                dev_priv->topaz_disabled ? "disabled" : "enabled");
7260 +
7261 +       pci_write_config_dword(pci_root, 0xD0, FB_REG09);
7262 +       pci_read_config_dword(pci_root, 0xD4, &fuse_value);
7263 +
7264 +       DRM_INFO("SKU values is 0x%x. \n", fuse_value);
7265 +       fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
7266 +
7267 +       dev_priv->fuse_reg_value = fuse_value;
7268 +
7269 +       switch (fuse_value_tmp) {
7270 +       case FB_SKU_100:
7271 +               DRM_INFO("SKU values is SKU_100. LNC core clk is 200MHz.\n");
7272 +               dev_priv->sku_100 = true;
7273 +               break;
7274 +       case FB_SKU_100L:
7275 +               DRM_INFO("SKU values is SKU_100L. LNC core clk is 100MHz.\n");
7276 +               dev_priv->sku_100L = true;
7277 +               break;
7278 +       case FB_SKU_83:
7279 +               DRM_INFO("SKU values is SKU_83. LNC core clk is 166MHz.\n");
7280 +               dev_priv->sku_83 = true;
7281 +               break;
7282 +       default:
7283 +               DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n",
7284 +                         fuse_value_tmp);
7285 +       }
7286 +
7287 +#if 1 /* FIXME remove it after PO */
7288 +       fuse_value_tmp =
7289 +         (fuse_value & FB_GFX_CLK_DIVIDE_MASK) >> FB_GFX_CLK_DIVIDE_SHIFT;
7290 +
7291 +       switch (fuse_value_tmp) {
7292 +       case 0:
7293 +               DRM_INFO("Gfx clk : core clk = 1:1. \n");
7294 +               break;
7295 +       case 1:
7296 +               DRM_INFO("Gfx clk : core clk = 4:3. \n");
7297 +               break;
7298 +       case 2:
7299 +               DRM_INFO("Gfx clk : core clk = 8:5. \n");
7300 +               break;
7301 +       case 3:
7302 +               DRM_INFO("Gfx clk : core clk = 2:1. \n");
7303 +               break;
7304 +       case 4:
7305 +               DRM_INFO("Gfx clk : core clk = 16:7. \n");
7306 +               break;
7307 +       case 5:
7308 +               DRM_INFO("Gfx clk : core clk = 8:3. \n");
7309 +               break;
7310 +       case 6:
7311 +               DRM_INFO("Gfx clk : core clk = 16:5. \n");
7312 +               break;
7313 +       case 7:
7314 +               DRM_INFO("Gfx clk : core clk = 4:1. \n");
7315 +               break;
7316 +       default:
7317 +               DRM_ERROR("Invalid GFX CLK DIVIDE values, value = 0x%08x\n",
7318 +                         fuse_value_tmp);
7319 +       }
7320 +
7321 +       fuse_value_tmp =
7322 +         (fuse_value & FB_VED_CLK_DIVIDE_MASK) >> FB_VED_CLK_DIVIDE_SHIFT;
7323 +
7324 +       switch (fuse_value_tmp) {
7325 +       case 0:
7326 +               DRM_INFO("Ved clk : core clk = 1:1. \n");
7327 +               break;
7328 +       case 1:
7329 +               DRM_INFO("Ved clk : core clk = 4:3. \n");
7330 +               break;
7331 +       case 2:
7332 +               DRM_INFO("Ved clk : core clk = 8:5. \n");
7333 +               break;
7334 +       case 3:
7335 +               DRM_INFO("Ved clk : core clk = 2:1. \n");
7336 +               break;
7337 +       default:
7338 +               DRM_ERROR("Invalid VED CLK DIVIDE values, value = 0x%08x\n",
7339 +                         fuse_value_tmp);
7340 +       }
7341 +
7342 +       fuse_value_tmp =
7343 +         (fuse_value & FB_VEC_CLK_DIVIDE_MASK) >> FB_VEC_CLK_DIVIDE_SHIFT;
7344 +
7345 +       switch (fuse_value_tmp) {
7346 +       case 0:
7347 +               DRM_INFO("Vec clk : core clk = 1:1. \n");
7348 +               break;
7349 +       case 1:
7350 +               DRM_INFO("Vec clk : core clk = 4:3. \n");
7351 +               break;
7352 +       case 2:
7353 +               DRM_INFO("Vec clk : core clk = 8:5. \n");
7354 +               break;
7355 +       case 3:
7356 +               DRM_INFO("Vec clk : core clk = 2:1. \n");
7357 +               break;
7358 +       default:
7359 +               DRM_ERROR("Invalid VEC CLK DIVIDE values, value = 0x%08x\n",
7360 +                         fuse_value_tmp);
7361 +       }
7362 +#endif /* FIXME remove it after PO */
7363 +
7364 +       return;
7365 +}
7366 +
7367 +bool mrst_get_vbt_data(struct drm_psb_private *dev_priv)
7368 +{
7369 +       struct mrst_vbt *pVBT = &dev_priv->vbt_data;
7370 +       u32 platform_config_address;
7371 +       u8 *pVBT_virtual;
7372 +       u8 bpi;
7373 +       void *pGCT;
7374 +       struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
7375 +
7376 +       /*get the address of the platform config vbt, B0:D2:F0;0xFC */
7377 +       pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address);
7378 +       DRM_INFO("drm platform config address is %x\n",
7379 +                       platform_config_address);
7380 +
7381 +       /* check for platform config address == 0. */
7382 +       /* this means fw doesn't support vbt */
7383 +
7384 +       if (platform_config_address == 0) {
7385 +               pVBT->Size = 0;
7386 +               return false;
7387 +       }
7388 +
7389 +       /* get the virtual address of the vbt */
7390 +       pVBT_virtual = ioremap(platform_config_address, sizeof(*pVBT));
7391 +
7392 +       memcpy(pVBT, pVBT_virtual, sizeof(*pVBT));
7393 +       iounmap(pVBT_virtual); /* Free virtual address space */
7394 +
7395 +       printk(KERN_ALERT "GCT Revision is %x\n", pVBT->Revision);
7396 +       pVBT->mrst_gct = NULL;
7397 +       pVBT->mrst_gct = ioremap(platform_config_address + sizeof(*pVBT) - 4,
7398 +                                        pVBT->Size - sizeof(*pVBT) + 4);
7399 +       pGCT = pVBT->mrst_gct;
7400 +
7401 +       switch (pVBT->Revision) {
7402 +       case 0:
7403 +               bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
7404 +               dev_priv->gct_data.bpi = bpi;
7405 +               dev_priv->gct_data.pt =
7406 +                       ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
7407 +               memcpy(&dev_priv->gct_data.DTD,
7408 +                       &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
7409 +                               sizeof(struct mrst_timing_info));
7410 +               dev_priv->gct_data.Panel_Port_Control =
7411 +                 ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
7412 +               dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
7413 +                 ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
7414 +               break;
7415 +       case 1:
7416 +               bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
7417 +               dev_priv->gct_data.bpi = bpi;
7418 +               dev_priv->gct_data.pt =
7419 +                       ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
7420 +               memcpy(&dev_priv->gct_data.DTD,
7421 +                       &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
7422 +                               sizeof(struct mrst_timing_info));
7423 +               dev_priv->gct_data.Panel_Port_Control =
7424 +                 ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
7425 +               dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
7426 +                 ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
7427 +               break;
7428 +       default:
7429 +               printk(KERN_ALERT "Unknown revision of GCT!\n");
7430 +               pVBT->Size = 0;
7431 +               return false;
7432 +       }
7433 +
7434 +       return true;
7435 +}
7436 +
7437 +static int psb_do_init(struct drm_device *dev)
7438 +{
7439 +       struct drm_psb_private *dev_priv =
7440 +           (struct drm_psb_private *) dev->dev_private;
7441 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
7442 +       struct psb_gtt *pg = dev_priv->pg;
7443 +
7444 +       uint32_t stolen_gtt;
7445 +       uint32_t tt_start;
7446 +       uint32_t tt_pages;
7447 +
7448 +       int ret = -ENOMEM;
7449 +
7450 +
7451 +       /*
7452 +        * Initialize sequence numbers for the different command
7453 +        * submission mechanisms.
7454 +        */
7455 +
7456 +       dev_priv->sequence[PSB_ENGINE_2D] = 0;
7457 +       dev_priv->sequence[PSB_ENGINE_VIDEO] = 0;
7458 +       dev_priv->sequence[LNC_ENGINE_ENCODE] = 0;
7459 +
7460 +       if (pg->mmu_gatt_start & 0x0FFFFFFF) {
7461 +               DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
7462 +               ret = -EINVAL;
7463 +               goto out_err;
7464 +       }
7465 +
7466 +       stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
7467 +       stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
7468 +       stolen_gtt =
7469 +           (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
7470 +
7471 +       dev_priv->gatt_free_offset = pg->mmu_gatt_start +
7472 +           (stolen_gtt << PAGE_SHIFT) * 1024;
7473 +
7474 +       if (1 || drm_debug) {
7475 +               uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
7476 +               uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
7477 +               DRM_INFO("SGX core id = 0x%08x\n", core_id);
7478 +               DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
7479 +                        (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
7480 +                        _PSB_CC_REVISION_MAJOR_SHIFT,
7481 +                        (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
7482 +                        _PSB_CC_REVISION_MINOR_SHIFT);
7483 +               DRM_INFO
7484 +                   ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
7485 +                    (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
7486 +                    _PSB_CC_REVISION_MAINTENANCE_SHIFT,
7487 +                    (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
7488 +                    _PSB_CC_REVISION_DESIGNER_SHIFT);
7489 +       }
7490 +
7491 +       spin_lock_init(&dev_priv->irqmask_lock);
7492 +
7493 +       tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
7494 +           pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
7495 +       tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
7496 +       tt_pages -= tt_start >> PAGE_SHIFT;
7497 +       dev_priv->sizes.ta_mem_size = 0;
7498 +
7499 +
7500 +       if (IS_MRST(dev) &&
7501 +           (dev_priv->ci_region_size != 0) &&
7502 +           !ttm_bo_init_mm(bdev, TTM_PL_CI, pg->ci_start >> PAGE_SHIFT,
7503 +                           dev_priv->ci_region_size >> PAGE_SHIFT)) {
7504 +               dev_priv->have_camera = 1;
7505 +       }
7506 +
7507 +       /* since there is always rar region for video, it is ok */
7508 +       if (IS_MRST(dev) &&
7509 +           (dev_priv->rar_region_size != 0) &&
7510 +           !ttm_bo_init_mm(bdev, TTM_PL_RAR, pg->rar_start >> PAGE_SHIFT,
7511 +                           dev_priv->rar_region_size >> PAGE_SHIFT)) {
7512 +               dev_priv->have_rar = 1;
7513 +       }
7514 +
7515 +       /* TT region managed by TTM. */
7516 +       if (!ttm_bo_init_mm(bdev, TTM_PL_TT,
7517 +               (pg->rar_start + dev_priv->rar_region_size) >> PAGE_SHIFT,
7518 +                       pg->gatt_pages -
7519 +                       (pg->ci_start >> PAGE_SHIFT) -
7520 +                       ((dev_priv->ci_region_size + dev_priv->rar_region_size)
7521 +                        >> PAGE_SHIFT))) {
7522 +
7523 +               dev_priv->have_tt = 1;
7524 +               dev_priv->sizes.tt_size =
7525 +                       (tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2;
7526 +       }
7527 +
7528 +       if (!ttm_bo_init_mm(bdev,
7529 +                       DRM_PSB_MEM_MMU,
7530 +                       0x00000000,
7531 +                       (pg->gatt_start - PSB_MEM_MMU_START) >> PAGE_SHIFT)) {
7532 +               dev_priv->have_mem_mmu = 1;
7533 +               dev_priv->sizes.mmu_size =
7534 +                       (pg->gatt_start - PSB_MEM_MMU_START) /
7535 +                       (1024*1024);
7536 +       }
7537 +
7538 +
7539 +       PSB_DEBUG_INIT("Init MSVDX\n");
7540 +       psb_msvdx_init(dev);
7541 +
7542 +       if (IS_MRST(dev)) {
7543 +               PSB_DEBUG_INIT("Init Topaz\n");
7544 +               /* for sku100L and sku100M, VEC is disabled in fuses */
7545 +               if (!dev_priv->topaz_disabled)
7546 +                       lnc_topaz_init(dev);
7547 +               else
7548 +                       ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
7549 +       }
7550 +
7551 +       return 0;
7552 +out_err:
7553 +       psb_do_takedown(dev);
7554 +       return ret;
7555 +}
7556 +
7557 +static int psb_intel_opregion_init(struct drm_device *dev)
7558 +{
7559 +       struct drm_psb_private *dev_priv = dev->dev_private;
7560 +       /*struct psb_intel_opregion * opregion = &dev_priv->opregion;*/
7561 +       u32 opregion_phy;
7562 +       void *base;
7563 +       u32 *lid_state;
7564 +
7565 +       dev_priv->lid_state = NULL;
7566 +
7567 +       pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
7568 +       if (opregion_phy == 0) {
7569 +               DRM_DEBUG("Opregion not supported, won't support lid-switch\n");
7570 +               return -ENOTSUPP;
7571 +       }
7572 +       DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy);
7573 +
7574 +       base = ioremap(opregion_phy, 8*1024);
7575 +       if (!base)
7576 +               return -ENOMEM;
7577 +
7578 +       lid_state = base + 0x01ac;
7579 +
7580 +       DRM_DEBUG("Lid switch state 0x%08x\n", *lid_state);
7581 +
7582 +       dev_priv->lid_state = lid_state;
7583 +       dev_priv->lid_last_state = *lid_state;
7584 +       return 0;
7585 +}
7586 +
7587 +static int psb_driver_unload(struct drm_device *dev)
7588 +{
7589 +       struct drm_psb_private *dev_priv =
7590 +           (struct drm_psb_private *) dev->dev_private;
7591 +
7592 +       /*Fristly, unload pvr driver*/
7593 +       PVRSRVDrmUnload(dev);
7594 +
7595 +       psb_backlight_exit(); /*writes minimum value to backlight HW reg */
7596 +
7597 +       if (drm_psb_no_fb == 0)
7598 +               psb_modeset_cleanup(dev);
7599 +
7600 +       if (dev_priv) {
7601 +               if (IS_POULSBO(dev))
7602 +                       psb_lid_timer_takedown(dev_priv);
7603 +
7604 +               /* psb_watchdog_takedown(dev_priv); */
7605 +               psb_do_takedown(dev);
7606 +
7607 +
7608 +               if (dev_priv->pf_pd) {
7609 +                       psb_mmu_free_pagedir(dev_priv->pf_pd);
7610 +                       dev_priv->pf_pd = NULL;
7611 +               }
7612 +               if (dev_priv->mmu) {
7613 +                       struct psb_gtt *pg = dev_priv->pg;
7614 +
7615 +                       down_read(&pg->sem);
7616 +                       psb_mmu_remove_pfn_sequence(
7617 +                                       psb_mmu_get_default_pd
7618 +                                       (dev_priv->mmu),
7619 +                                       pg->mmu_gatt_start,
7620 +                                       pg->vram_stolen_size >> PAGE_SHIFT);
7621 +                       if (pg->ci_stolen_size != 0)
7622 +                               psb_mmu_remove_pfn_sequence(
7623 +                                       psb_mmu_get_default_pd
7624 +                                       (dev_priv->mmu),
7625 +                                       pg->ci_start,
7626 +                                       pg->ci_stolen_size >> PAGE_SHIFT);
7627 +                       if (pg->rar_stolen_size != 0)
7628 +                               psb_mmu_remove_pfn_sequence(
7629 +                                       psb_mmu_get_default_pd
7630 +                                       (dev_priv->mmu),
7631 +                                       pg->rar_start,
7632 +                                       pg->rar_stolen_size >> PAGE_SHIFT);
7633 +                       up_read(&pg->sem);
7634 +                       psb_mmu_driver_takedown(dev_priv->mmu);
7635 +                       dev_priv->mmu = NULL;
7636 +               }
7637 +               psb_gtt_takedown(dev_priv->pg, 1);
7638 +               if (dev_priv->scratch_page) {
7639 +                       __free_page(dev_priv->scratch_page);
7640 +                       dev_priv->scratch_page = NULL;
7641 +               }
7642 +               if (dev_priv->has_bo_device) {
7643 +                       ttm_bo_device_release(&dev_priv->bdev);
7644 +                       dev_priv->has_bo_device = 0;
7645 +               }
7646 +               if (dev_priv->has_fence_device) {
7647 +                       ttm_fence_device_release(&dev_priv->fdev);
7648 +                       dev_priv->has_fence_device = 0;
7649 +               }
7650 +               if (dev_priv->vdc_reg) {
7651 +                       iounmap(dev_priv->vdc_reg);
7652 +                       dev_priv->vdc_reg = NULL;
7653 +               }
7654 +               if (dev_priv->sgx_reg) {
7655 +                       iounmap(dev_priv->sgx_reg);
7656 +                       dev_priv->sgx_reg = NULL;
7657 +               }
7658 +               if (dev_priv->msvdx_reg) {
7659 +                       iounmap(dev_priv->msvdx_reg);
7660 +                       dev_priv->msvdx_reg = NULL;
7661 +               }
7662 +
7663 +               if (IS_MRST(dev)) {
7664 +                       if (dev_priv->topaz_reg) {
7665 +                               iounmap(dev_priv->topaz_reg);
7666 +                               dev_priv->topaz_reg = NULL;
7667 +                       }
7668 +               }
7669 +
7670 +               if (dev_priv->tdev)
7671 +                       ttm_object_device_release(&dev_priv->tdev);
7672 +
7673 +               if (dev_priv->has_global)
7674 +                       psb_ttm_global_release(dev_priv);
7675 +
7676 +               kfree(dev_priv);
7677 +               dev->dev_private = NULL;
7678 +
7679 +               /*destory VBT data*/
7680 +               if (IS_POULSBO(dev))
7681 +                       psb_intel_destory_bios(dev);
7682 +       }
7683 +
7684 +       ospm_power_uninit();
7685 +
7686 +       return 0;
7687 +}
7688 +
7689 +
7690 +static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
7691 +{
7692 +       struct drm_psb_private *dev_priv;
7693 +       struct ttm_bo_device *bdev;
7694 +       unsigned long resource_start;
7695 +       struct psb_gtt *pg;
7696 +       int ret = -ENOMEM;
7697 +       uint32_t tt_pages;
7698 +
7699 +       DRM_INFO("psb - %s\n", PSB_PACKAGE_VERSION);
7700 +
7701 +       if (IS_MRST(dev))
7702 +               DRM_INFO("Run drivers on Moorestown platform!\n");
7703 +       else
7704 +               DRM_INFO("Run drivers on Poulsbo platform!\n");
7705 +
7706 +       dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
7707 +       if (dev_priv == NULL)
7708 +               return -ENOMEM;
7709 +
7710 +       /*init DPST umcomm to NULL*/
7711 +       dev_priv->psb_dpst_state = NULL;
7712 +       dev_priv->psb_hotplug_state = NULL;
7713 +
7714 +       dev_priv->dev = dev;
7715 +       bdev = &dev_priv->bdev;
7716 +
7717 +       ret = psb_ttm_global_init(dev_priv);
7718 +       if (unlikely(ret != 0))
7719 +               goto out_err;
7720 +       dev_priv->has_global = 1;
7721 +
7722 +       dev_priv->tdev = ttm_object_device_init
7723 +               (dev_priv->mem_global_ref.object, PSB_OBJECT_HASH_ORDER);
7724 +       if (unlikely(dev_priv->tdev == NULL))
7725 +               goto out_err;
7726 +
7727 +       mutex_init(&dev_priv->temp_mem);
7728 +       mutex_init(&dev_priv->cmdbuf_mutex);
7729 +       mutex_init(&dev_priv->reset_mutex);
7730 +       INIT_LIST_HEAD(&dev_priv->context.validate_list);
7731 +       INIT_LIST_HEAD(&dev_priv->context.kern_validate_list);
7732 +
7733 +
7734 +       spin_lock_init(&dev_priv->reloc_lock);
7735 +
7736 +       DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue);
7737 +
7738 +       dev->dev_private = (void *) dev_priv;
7739 +       dev_priv->chipset = chipset;
7740 +       psb_set_uopt(&dev_priv->uopt);
7741 +
7742 +       PSB_DEBUG_GENERAL("Init watchdog and scheduler\n");
7743 +       /* psb_watchdog_init(dev_priv); */
7744 +       psb_scheduler_init(dev, &dev_priv->scheduler);
7745 +
7746 +
7747 +       PSB_DEBUG_INIT("Mapping MMIO\n");
7748 +       resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
7749 +
7750 +       if (IS_MRST(dev))
7751 +               dev_priv->msvdx_reg =
7752 +                   ioremap(resource_start + MRST_MSVDX_OFFSET,
7753 +                           PSB_MSVDX_SIZE);
7754 +       else
7755 +               dev_priv->msvdx_reg =
7756 +                   ioremap(resource_start + PSB_MSVDX_OFFSET,
7757 +                           PSB_MSVDX_SIZE);
7758 +
7759 +       if (!dev_priv->msvdx_reg)
7760 +               goto out_err;
7761 +
7762 +       if (IS_MRST(dev) && !dev_priv->topaz_disabled) {
7763 +               dev_priv->topaz_reg =
7764 +                   ioremap(resource_start + LNC_TOPAZ_OFFSET,
7765 +                           LNC_TOPAZ_SIZE);
7766 +               if (!dev_priv->topaz_reg)
7767 +                       goto out_err;
7768 +       }
7769 +
7770 +       dev_priv->vdc_reg =
7771 +           ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
7772 +       if (!dev_priv->vdc_reg)
7773 +               goto out_err;
7774 +
7775 +       if (IS_MRST(dev))
7776 +               dev_priv->sgx_reg =
7777 +                   ioremap(resource_start + MRST_SGX_OFFSET,
7778 +                           PSB_SGX_SIZE);
7779 +       else
7780 +               dev_priv->sgx_reg =
7781 +                   ioremap(resource_start + PSB_SGX_OFFSET, PSB_SGX_SIZE);
7782 +
7783 +       if (!dev_priv->sgx_reg)
7784 +               goto out_err;
7785 +
7786 +       if (IS_MRST(dev)) {
7787 +               mrst_get_fuse_settings(dev_priv);
7788 +               mrst_get_vbt_data(dev_priv);
7789 +       } else {
7790 +               psb_intel_opregion_init(dev);
7791 +               psb_intel_init_bios(dev);
7792 +       }
7793 +
7794 +       PSB_DEBUG_INIT("Init TTM fence and BO driver\n");
7795 +
7796 +       if (IS_MRST(dev)) {
7797 +               get_ci_info(dev_priv);
7798 +               get_rar_info(dev_priv);
7799 +       }
7800 +
7801 +       /* Init OSPM support */
7802 +       ospm_power_init(dev);
7803 +
7804 +       ret = psb_ttm_fence_device_init(&dev_priv->fdev);
7805 +       if (unlikely(ret != 0))
7806 +               goto out_err;
7807 +
7808 +       dev_priv->has_fence_device = 1;
7809 +       ret = ttm_bo_device_init(bdev,
7810 +                                dev_priv->mem_global_ref.object,
7811 +                                &psb_ttm_bo_driver,
7812 +                                DRM_PSB_FILE_PAGE_OFFSET);
7813 +       if (unlikely(ret != 0))
7814 +               goto out_err;
7815 +       dev_priv->has_bo_device = 1;
7816 +       ttm_lock_init(&dev_priv->ttm_lock);
7817 +
7818 +       ret = -ENOMEM;
7819 +
7820 +       dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
7821 +       if (!dev_priv->scratch_page)
7822 +               goto out_err;
7823 +
7824 +       set_pages_uc(dev_priv->scratch_page, 1);
7825 +
7826 +       dev_priv->pg = psb_gtt_alloc(dev);
7827 +       if (!dev_priv->pg)
7828 +               goto out_err;
7829 +
7830 +       ret = psb_gtt_init(dev_priv->pg, 0);
7831 +       if (ret)
7832 +               goto out_err;
7833 +
7834 +       ret = psb_gtt_mm_init(dev_priv->pg);
7835 +       if (ret)
7836 +               goto out_err;
7837 +
7838 +       dev_priv->mmu = psb_mmu_driver_init((void *)0,
7839 +                                       drm_psb_trap_pagefaults, 0,
7840 +                                       dev_priv);
7841 +       if (!dev_priv->mmu)
7842 +               goto out_err;
7843 +
7844 +       pg = dev_priv->pg;
7845 +
7846 +       tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
7847 +               (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
7848 +
7849 +       /* CI/RAR use the lower half of TT. */
7850 +       pg->ci_start = (tt_pages / 2) << PAGE_SHIFT;
7851 +       pg->rar_start = pg->ci_start + pg->ci_stolen_size;
7852 +
7853 +
7854 +       /*
7855 +        * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area.
7856 +        */
7857 +       if (dev_priv->pg->ci_stolen_size != 0) {
7858 +               down_read(&pg->sem);
7859 +               ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd
7860 +                               (dev_priv->mmu),
7861 +                               dev_priv->ci_region_start >> PAGE_SHIFT,
7862 +                               pg->mmu_gatt_start + pg->ci_start,
7863 +                               pg->ci_stolen_size >> PAGE_SHIFT, 0);
7864 +               up_read(&pg->sem);
7865 +               if (ret)
7866 +                       goto out_err;
7867 +       }
7868 +
7869 +       /*
7870 +        * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area.
7871 +        */
7872 +       if (dev_priv->pg->rar_stolen_size != 0) {
7873 +               down_read(&pg->sem);
7874 +               ret = psb_mmu_insert_pfn_sequence(
7875 +                               psb_mmu_get_default_pd(dev_priv->mmu),
7876 +                               dev_priv->rar_region_start >> PAGE_SHIFT,
7877 +                               pg->mmu_gatt_start + pg->rar_start,
7878 +                               pg->rar_stolen_size >> PAGE_SHIFT, 0);
7879 +               up_read(&pg->sem);
7880 +               if (ret)
7881 +                       goto out_err;
7882 +       }
7883 +
7884 +       dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
7885 +       if (!dev_priv->pf_pd)
7886 +               goto out_err;
7887 +
7888 +       psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
7889 +       psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
7890 +
7891 +
7892 +       spin_lock_init(&dev_priv->sequence_lock);
7893 +
7894 +
7895 +       PSB_DEBUG_INIT("Begin to init SGX/MSVDX/Topaz\n");
7896 +
7897 +       ret = psb_do_init(dev);
7898 +       if (ret)
7899 +               return ret;
7900 +
7901 +       /**
7902 +        *  Init lid switch timer.
7903 +        *  NOTE: must do this after psb_intel_opregion_init
7904 +        *  and psb_backlight_init
7905 +        */
7906 +       if (IS_POULSBO(dev) && dev_priv->lid_state)
7907 +               psb_lid_timer_init(dev_priv);
7908 +
7909 +       /*initialize the MSI for MRST*/
7910 +       if (IS_MRST(dev)) {
7911 +               if (pci_enable_msi(dev->pdev)) {
7912 +                       DRM_ERROR("Enable MSI for MRST failed!\n");
7913 +               } else {
7914 +                       PSB_DEBUG_INIT("Enabled MSI IRQ (%d)\n",
7915 +                                      dev->pdev->irq);
7916 +                       /* pci_write_config_word(pdev, 0x04, 0x07); */
7917 +               }
7918 +       }
7919 +
7920 +
7921 +       if (drm_psb_no_fb == 0) {
7922 +               psb_modeset_init(dev);
7923 +               drm_helper_initial_config(dev);
7924 +       }
7925 +
7926 +       /*must be after mrst_get_fuse_settings()*/
7927 +       ret = psb_backlight_init(dev);
7928 +       if (ret)
7929 +               return ret;
7930 +
7931 +
7932 +       /*Intel drm driver load is done, continue doing pvr load*/
7933 +       DRM_DEBUG("Pvr driver load\n");
7934 +
7935 +       return PVRSRVDrmLoad(dev, chipset);
7936 +out_err:
7937 +       psb_driver_unload(dev);
7938 +       return ret;
7939 +}
7940 +
7941 +int psb_driver_device_is_agp(struct drm_device *dev)
7942 +{
7943 +       return 0;
7944 +}
7945 +
7946 +int psb_extension_ioctl(struct drm_device *dev, void *data,
7947 +                       struct drm_file *file_priv)
7948 +{
7949 +       union drm_psb_extension_arg *arg = data;
7950 +       struct drm_psb_extension_rep *rep = &arg->rep;
7951 +
7952 +       if (strcmp(arg->extension, "psb_ttm_placement_alphadrop") == 0) {
7953 +               rep->exists = 1;
7954 +               rep->driver_ioctl_offset = DRM_PSB_PLACEMENT_OFFSET;
7955 +               rep->sarea_offset = 0;
7956 +               rep->major = 1;
7957 +               rep->minor = 0;
7958 +               rep->pl = 0;
7959 +               return 0;
7960 +       }
7961 +       if (strcmp(arg->extension, "psb_ttm_fence_alphadrop") == 0) {
7962 +               rep->exists = 1;
7963 +               rep->driver_ioctl_offset = DRM_PSB_FENCE_OFFSET;
7964 +               rep->sarea_offset = 0;
7965 +               rep->major = 1;
7966 +               rep->minor = 0;
7967 +               rep->pl = 0;
7968 +               return 0;
7969 +       }
7970 +       if (strcmp(arg->extension, "psb_ttm_execbuf_alphadrop") == 0) {
7971 +               rep->exists = 1;
7972 +               rep->driver_ioctl_offset = DRM_PSB_CMDBUF;
7973 +               rep->sarea_offset = 0;
7974 +               rep->major = 1;
7975 +               rep->minor = 0;
7976 +               rep->pl = 0;
7977 +               return 0;
7978 +       }
7979 +
7980 +       /*return the page flipping ioctl offset*/
7981 +       if (strcmp(arg->extension, "psb_page_flipping_alphadrop") == 0) {
7982 +               rep->exists = 1;
7983 +               rep->driver_ioctl_offset = DRM_PSB_FLIP;
7984 +               rep->sarea_offset = 0;
7985 +               rep->major = 1;
7986 +               rep->minor = 0;
7987 +               rep->pl = 0;
7988 +               return 0;
7989 +       }
7990 +
7991 +       /* return the video rar offset */
7992 +       if (strcmp(arg->extension, "lnc_video_getparam") == 0) {
7993 +               rep->exists = 1;
7994 +               rep->driver_ioctl_offset = DRM_LNC_VIDEO_GETPARAM;
7995 +               rep->sarea_offset = 0;
7996 +               rep->major = 1;
7997 +               rep->minor = 0;
7998 +               rep->pl = 0;
7999 +               return 0;
8000 +       }
8001 +
8002 +       rep->exists = 0;
8003 +       return 0;
8004 +}
8005 +
8006 +static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
8007 +                             struct drm_file *file_priv)
8008 +{
8009 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8010 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
8011 +       struct ttm_mem_type_manager *man;
8012 +       int clean;
8013 +       int ret;
8014 +
8015 +       ret = ttm_write_lock(&dev_priv->ttm_lock, 1,
8016 +                            psb_fpriv(file_priv)->tfile);
8017 +       if (unlikely(ret != 0))
8018 +               return ret;
8019 +
8020 +       ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT);
8021 +       if (unlikely(ret != 0))
8022 +               goto out_unlock;
8023 +
8024 +       man = &bdev->man[TTM_PL_TT];
8025 +       spin_lock(&bdev->lru_lock);
8026 +       clean = drm_mm_clean(&man->manager);
8027 +       spin_unlock(&bdev->lru_lock);
8028 +       if (unlikely(!clean))
8029 +               DRM_INFO("Warning: GATT was not clean after VT switch.\n");
8030 +
8031 +       ttm_bo_swapout_all(&dev_priv->bdev);
8032 +
8033 +       return 0;
8034 +out_unlock:
8035 +       (void) ttm_write_unlock(&dev_priv->ttm_lock,
8036 +                               psb_fpriv(file_priv)->tfile);
8037 +       return ret;
8038 +}
8039 +
8040 +static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
8041 +                             struct drm_file *file_priv)
8042 +{
8043 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8044 +       return ttm_write_unlock(&dev_priv->ttm_lock,
8045 +                               psb_fpriv(file_priv)->tfile);
8046 +}
8047 +
8048 +static int psb_sizes_ioctl(struct drm_device *dev, void *data,
8049 +                          struct drm_file *file_priv)
8050 +{
8051 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8052 +       struct drm_psb_sizes_arg *arg =
8053 +               (struct drm_psb_sizes_arg *) data;
8054 +
8055 +       *arg = dev_priv->sizes;
8056 +       return 0;
8057 +}
8058 +
8059 +static int psb_fuse_reg_ioctl(struct drm_device *dev, void *data,
8060 +                             struct drm_file *file_priv)
8061 +{
8062 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8063 +       uint32_t *arg = data;
8064 +
8065 +       *arg = dev_priv->fuse_reg_value;
8066 +       return 0;
8067 +}
8068 +static int psb_vbt_ioctl(struct drm_device *dev, void *data,
8069 +                       struct drm_file *file_priv)
8070 +{
8071 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8072 +       struct gct_ioctl_arg *pGCT = data;
8073 +
8074 +       memcpy(pGCT, &dev_priv->gct_data, sizeof(*pGCT));
8075 +
8076 +       return 0;
8077 +}
8078 +
8079 +static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
8080 +                               struct drm_file *file_priv)
8081 +{
8082 +       uint32_t flags;
8083 +       uint32_t obj_id;
8084 +       struct drm_mode_object *obj;
8085 +       struct drm_connector *connector;
8086 +       struct drm_crtc *crtc;
8087 +       struct drm_psb_dc_state_arg *arg =
8088 +               (struct drm_psb_dc_state_arg *)data;
8089 +
8090 +       if (IS_MRST(dev))
8091 +               return 0;
8092 +
8093 +       flags = arg->flags;
8094 +       obj_id = arg->obj_id;
8095 +
8096 +       if (flags & PSB_DC_CRTC_MASK) {
8097 +               obj = drm_mode_object_find(dev, obj_id,
8098 +                               DRM_MODE_OBJECT_CRTC);
8099 +               if (!obj) {
8100 +                       DRM_DEBUG("Invalid CRTC object.\n");
8101 +                       return -EINVAL;
8102 +               }
8103 +
8104 +               crtc = obj_to_crtc(obj);
8105 +
8106 +               mutex_lock(&dev->mode_config.mutex);
8107 +               if (drm_helper_crtc_in_use(crtc)) {
8108 +                       if (flags & PSB_DC_CRTC_SAVE)
8109 +                               crtc->funcs->save(crtc);
8110 +                       else
8111 +                               crtc->funcs->restore(crtc);
8112 +               }
8113 +               mutex_unlock(&dev->mode_config.mutex);
8114 +
8115 +               return 0;
8116 +       } else if (flags & PSB_DC_OUTPUT_MASK) {
8117 +               obj = drm_mode_object_find(dev, obj_id,
8118 +                               DRM_MODE_OBJECT_CONNECTOR);
8119 +               if (!obj) {
8120 +                       DRM_DEBUG("Invalid connector id.\n");
8121 +                       return -EINVAL;
8122 +               }
8123 +
8124 +               connector = obj_to_connector(obj);
8125 +               if (flags & PSB_DC_OUTPUT_SAVE)
8126 +                       connector->funcs->save(connector);
8127 +               else
8128 +                       connector->funcs->restore(connector);
8129 +
8130 +               return 0;
8131 +       }
8132 +
8133 +       DRM_DEBUG("Bad flags 0x%x\n", flags);
8134 +       return -EINVAL;
8135 +}
8136 +
8137 +static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
8138 +                      struct drm_file *file_priv)
8139 +{
8140 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8141 +       uint32_t *arg = data;
8142 +       struct backlight_device bd;
8143 +       dev_priv->blc_adj2 = *arg;
8144 +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
8145 +       bd.props.brightness = psb_get_brightness(&bd);
8146 +       psb_set_brightness(&bd);
8147 +#endif
8148 +       return 0;
8149 +}
8150 +
8151 +static int psb_adb_ioctl(struct drm_device *dev, void *data,
8152 +                       struct drm_file *file_priv)
8153 +{
8154 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8155 +       uint32_t *arg = data;
8156 +       struct backlight_device bd;
8157 +       dev_priv->blc_adj1 = *arg;
8158 +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
8159 +       bd.props.brightness = psb_get_brightness(&bd);
8160 +       psb_set_brightness(&bd);
8161 +#endif
8162 +       return 0;
8163 +}
8164 +
8165 +static int psb_hist_enable_ioctl(struct drm_device *dev, void *data,
8166 +                               struct drm_file *file_priv)
8167 +{
8168 +       u32 irqCtrl = 0;
8169 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8170 +       struct dpst_guardband guardband_reg;
8171 +       struct dpst_ie_histogram_control ie_hist_cont_reg;
8172 +       uint32_t *enable = data;
8173 +
8174 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
8175 +           return 0;
8176 +       }
8177 +
8178 +       if (*enable == 1) {
8179 +               ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
8180 +               ie_hist_cont_reg.ie_pipe_assignment = 0;
8181 +               ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
8182 +               ie_hist_cont_reg.ie_histogram_enable = 1;
8183 +               PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
8184 +
8185 +               guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
8186 +               guardband_reg.interrupt_enable = 1;
8187 +               guardband_reg.interrupt_status = 1;
8188 +               PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
8189 +
8190 +               irqCtrl = PSB_RVDC32(PIPEASTAT);
8191 +               PSB_WVDC32(irqCtrl | PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
8192 +               /* Wait for two vblanks */
8193 +       } else {
8194 +               guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
8195 +               guardband_reg.interrupt_enable = 0;
8196 +               guardband_reg.interrupt_status = 1;
8197 +               PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
8198 +
8199 +               ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
8200 +               ie_hist_cont_reg.ie_histogram_enable = 0;
8201 +               PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
8202 +
8203 +               irqCtrl = PSB_RVDC32(PIPEASTAT);
8204 +               irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
8205 +               PSB_WVDC32(irqCtrl, PIPEASTAT);
8206 +       }
8207 +
8208 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8209 +
8210 +       return 0;
8211 +}
8212 +
8213 +static int psb_hist_status_ioctl(struct drm_device *dev, void *data,
8214 +                                struct drm_file *file_priv)
8215 +{
8216 +       struct drm_psb_private *dev_priv                = psb_priv(dev);
8217 +       struct drm_psb_hist_status_arg *hist_status     = data;
8218 +       uint32_t *arg                                   = hist_status->buf;
8219 +       u32 iedbr_reg_data                              = 0;
8220 +       struct dpst_ie_histogram_control ie_hist_cont_reg;
8221 +       u32 i;
8222 +       int dpst3_bin_threshold_count   = 0;
8223 +       uint32_t blm_hist_ctl           = HISTOGRAM_LOGIC_CONTROL;
8224 +       uint32_t iebdr_reg              = HISTOGRAM_BIN_DATA;
8225 +       uint32_t segvalue_max_22_bit    = 0x3fffff;
8226 +       uint32_t iedbr_busy_bit         = 0x80000000;
8227 +       int dpst3_bin_count             = 32;
8228 +
8229 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
8230 +           return 0;
8231 +       }
8232 +
8233 +       ie_hist_cont_reg.data                   = PSB_RVDC32(blm_hist_ctl);
8234 +       ie_hist_cont_reg.bin_reg_func_select    = dpst3_bin_threshold_count;
8235 +       ie_hist_cont_reg.bin_reg_index          = 0;
8236 +
8237 +       PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
8238 +
8239 +       for (i = 0; i < dpst3_bin_count; i++) {
8240 +               iedbr_reg_data = PSB_RVDC32(iebdr_reg);
8241 +
8242 +               if (!(iedbr_reg_data & iedbr_busy_bit)) {
8243 +                       arg[i] = iedbr_reg_data & segvalue_max_22_bit;
8244 +               } else {
8245 +                       i = 0;
8246 +                       ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
8247 +                       ie_hist_cont_reg.bin_reg_index = 0;
8248 +                       PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
8249 +               }
8250 +       }
8251 +
8252 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8253 +
8254 +       return 0;
8255 +}
8256 +
8257 +static int psb_init_comm_ioctl(struct drm_device *dev, void *data,
8258 +                               struct drm_file *file_priv)
8259 +{
8260 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8261 +       struct pci_dev *pdev = NULL;
8262 +       struct device *ddev = NULL;
8263 +       struct kobject *kobj = NULL;
8264 +       uint32_t *arg = data;
8265 +
8266 +       if (*arg == 1) {
8267 +               /*find handle to drm kboject*/
8268 +               pdev = dev->pdev;
8269 +               ddev = &pdev->dev;
8270 +               kobj = &ddev->kobj;
8271 +
8272 +               if (dev_priv->psb_dpst_state == NULL) {
8273 +                       /*init dpst kmum comms*/
8274 +                       dev_priv->psb_dpst_state = psb_dpst_init(kobj);
8275 +               } else {
8276 +                       printk(KERN_ALERT "DPST already initialized\n");
8277 +               }
8278 +
8279 +               sysirq_enable_dpst(dev);
8280 +               psb_dpst_notify_change_um(DPST_EVENT_INIT_COMPLETE,
8281 +                                         dev_priv->psb_dpst_state);
8282 +       } else {
8283 +               /*hotplug and dpst destroy examples*/
8284 +               sysirq_disable_dpst(dev);
8285 +               psb_dpst_notify_change_um(DPST_EVENT_TERMINATE,
8286 +                                         dev_priv->psb_dpst_state);
8287 +               psb_dpst_device_pool_destroy(dev_priv->psb_dpst_state);
8288 +               dev_priv->psb_dpst_state = NULL;
8289 +       }
8290 +       return 0;
8291 +}
8292 +
8293 +/* return the current mode to the dpst module */
8294 +static int psb_dpst_ioctl(struct drm_device *dev, void *data,
8295 +                         struct drm_file *file_priv)
8296 +{
8297 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8298 +       uint32_t *arg = data;
8299 +       uint32_t x;
8300 +       uint32_t y;
8301 +       uint32_t reg;
8302 +
8303 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
8304 +           return 0;
8305 +       }
8306 +
8307 +       reg = PSB_RVDC32(PIPEASRC);
8308 +
8309 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8310 +
8311 +       /* horizontal is the left 16 bits */
8312 +       x = reg >> 16;
8313 +       /* vertical is the right 16 bits */
8314 +       y = reg & 0x0000ffff;
8315 +
8316 +       /* the values are the image size minus one */
8317 +       x+=1;
8318 +       y+=1;
8319 +
8320 +       *arg = (x << 16) | y;
8321 +
8322 +       return 0;
8323 +}
8324 +static int psb_gamma_ioctl(struct drm_device *dev, void *data,
8325 +                          struct drm_file *file_priv)
8326 +{
8327 +       struct drm_psb_dpst_lut_arg *lut_arg = data;
8328 +       struct drm_mode_object *obj;
8329 +       struct drm_crtc *crtc;
8330 +       struct drm_connector *connector;
8331 +       struct psb_intel_crtc *psb_intel_crtc;
8332 +       int i = 0;
8333 +       int32_t obj_id;
8334 +
8335 +       obj_id = lut_arg->output_id;
8336 +       obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
8337 +       if (!obj) {
8338 +               DRM_DEBUG("Invalid Connector object.\n");
8339 +               return -EINVAL;
8340 +       }
8341 +
8342 +       connector = obj_to_connector(obj);
8343 +       crtc = connector->encoder->crtc;
8344 +       psb_intel_crtc = to_psb_intel_crtc(crtc);
8345 +
8346 +       for (i = 0; i < 256; i++)
8347 +               psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
8348 +
8349 +       psb_intel_crtc_load_lut(crtc);
8350 +
8351 +       return 0;
8352 +}
8353 +
8354 +static int psb_update_guard_ioctl(struct drm_device *dev, void *data,
8355 +                               struct drm_file *file_priv)
8356 +{
8357 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8358 +       struct dpst_guardband* input = (struct dpst_guardband*) data;
8359 +       struct dpst_guardband reg_data;
8360 +
8361 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
8362 +           return 0;
8363 +       }
8364 +
8365 +       reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
8366 +       reg_data.guardband = input->guardband;
8367 +       reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;
8368 +       /* printk(KERN_ALERT "guardband = %u\ninterrupt delay = %u\n", 
8369 +               reg_data.guardband, reg_data.guardband_interrupt_delay); */
8370 +       PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
8371 +       
8372 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8373 +
8374 +       return 0;
8375 +}
8376 +
8377 +static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
8378 +                               struct drm_file *file_priv)
8379 +{
8380 +       uint32_t obj_id;
8381 +       uint16_t op;
8382 +       struct drm_mode_modeinfo *umode;
8383 +       struct drm_display_mode *mode = NULL;
8384 +       struct drm_psb_mode_operation_arg *arg;
8385 +       struct drm_mode_object *obj;
8386 +       struct drm_connector *connector;
8387 +       struct drm_framebuffer * drm_fb;
8388 +       struct psb_framebuffer * psb_fb;
8389 +       struct drm_connector_helper_funcs *connector_funcs;
8390 +       int ret = 0;
8391 +       int resp = MODE_OK;
8392 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8393 +
8394 +       arg = (struct drm_psb_mode_operation_arg *)data;
8395 +        obj_id = arg->obj_id;
8396 +       op = arg->operation;
8397 +
8398 +       switch(op) {
8399 +       case PSB_MODE_OPERATION_SET_DC_BASE:
8400 +               obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
8401 +               if(!obj) {
8402 +                       DRM_ERROR("Invalid FB id %d\n", obj_id);
8403 +                       return -EINVAL;
8404 +               }
8405 +
8406 +               drm_fb = obj_to_fb(obj);
8407 +               psb_fb = to_psb_fb(drm_fb);
8408 +                       
8409 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
8410 +                                             OSPM_UHB_ONLY_IF_ON)) {
8411 +                       REG_WRITE(DSPASURF, psb_fb->offset);
8412 +                       REG_READ(DSPASURF);
8413 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8414 +               } else {
8415 +                       dev_priv->saveDSPASURF = psb_fb->offset;
8416 +               }
8417 +               
8418 +               return 0;
8419 +       case PSB_MODE_OPERATION_MODE_VALID:
8420 +               umode = &arg->mode;
8421 +
8422 +               mutex_lock(&dev->mode_config.mutex);
8423 +
8424 +               obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
8425 +               if (!obj) {
8426 +                       ret = -EINVAL;
8427 +                       goto mode_op_out;
8428 +               }
8429 +
8430 +               connector = obj_to_connector(obj);
8431 +
8432 +               mode = drm_mode_create(dev);
8433 +               if (!mode) {
8434 +                       ret = -ENOMEM;
8435 +                       goto mode_op_out;
8436 +               }
8437 +
8438 +               /* drm_crtc_convert_umode(mode, umode); */
8439 +               {
8440 +                       mode->clock = umode->clock;
8441 +                       mode->hdisplay = umode->hdisplay;
8442 +                       mode->hsync_start = umode->hsync_start;
8443 +                       mode->hsync_end = umode->hsync_end;
8444 +                       mode->htotal = umode->htotal;
8445 +                       mode->hskew = umode->hskew;
8446 +                       mode->vdisplay = umode->vdisplay;
8447 +                       mode->vsync_start = umode->vsync_start;
8448 +                       mode->vsync_end = umode->vsync_end;
8449 +                       mode->vtotal = umode->vtotal;
8450 +                       mode->vscan = umode->vscan;
8451 +                       mode->vrefresh = umode->vrefresh;
8452 +                       mode->flags = umode->flags;
8453 +                       mode->type = umode->type;
8454 +                       strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
8455 +                       mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
8456 +               }
8457 +
8458 +               connector_funcs = (struct drm_connector_helper_funcs *)
8459 +                                  connector->helper_private;
8460 +
8461 +               if (connector_funcs->mode_valid) {
8462 +                       resp = connector_funcs->mode_valid(connector, mode);
8463 +                       arg->data = (void *)resp;
8464 +               }
8465 +
8466 +               /*do some clean up work*/
8467 +               if(mode) {
8468 +                       drm_mode_destroy(dev, mode);
8469 +               }
8470 +mode_op_out:
8471 +               mutex_unlock(&dev->mode_config.mutex);
8472 +               return ret;
8473 +
8474 +       default:
8475 +               DRM_DEBUG("Unsupported psb mode operation");
8476 +               return -EOPNOTSUPP;
8477 +       }
8478 +
8479 +       return 0;
8480 +}
8481 +
8482 +static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
8483 +                                  struct drm_file *file_priv)
8484 +{
8485 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8486 +       struct drm_psb_stolen_memory_arg *arg = data;
8487 +
8488 +       arg->base = dev_priv->pg->stolen_base;
8489 +       arg->size = dev_priv->pg->vram_stolen_size;
8490 +
8491 +       return 0;
8492 +}
8493 +
8494 +static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
8495 +                                struct drm_file *file_priv)
8496 +{
8497 +       struct drm_psb_private *dev_priv = psb_priv(dev);
8498 +       struct drm_psb_register_rw_arg *arg = data;
8499 +       UHBUsage usage =
8500 +         arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON;
8501 +
8502 +       if (arg->display_write_mask != 0) {
8503 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8504 +                       if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
8505 +                               PSB_WVDC32(arg->display.pfit_controls,
8506 +                                          PFIT_CONTROL);
8507 +                       if (arg->display_write_mask &
8508 +                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
8509 +                               PSB_WVDC32(arg->display.pfit_autoscale_ratios,
8510 +                                          PFIT_AUTO_RATIOS);
8511 +                       if (arg->display_write_mask &
8512 +                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
8513 +                               PSB_WVDC32(
8514 +                                  arg->display.pfit_programmed_scale_ratios,
8515 +                                  PFIT_PGM_RATIOS);
8516 +                       if (arg->display_write_mask & REGRWBITS_PIPEASRC)
8517 +                               PSB_WVDC32(arg->display.pipeasrc,
8518 +                                          PIPEASRC);
8519 +                       if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
8520 +                               PSB_WVDC32(arg->display.pipebsrc,
8521 +                                          PIPEBSRC);
8522 +                       if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
8523 +                               PSB_WVDC32(arg->display.vtotal_a,
8524 +                                          VTOTAL_A);
8525 +                       if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
8526 +                               PSB_WVDC32(arg->display.vtotal_b,
8527 +                                          VTOTAL_B);
8528 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8529 +               } else {
8530 +                       if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
8531 +                               dev_priv->savePFIT_CONTROL =
8532 +                                               arg->display.pfit_controls;
8533 +                       if (arg->display_write_mask &
8534 +                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
8535 +                               dev_priv->savePFIT_AUTO_RATIOS =
8536 +                                       arg->display.pfit_autoscale_ratios;
8537 +                       if (arg->display_write_mask &
8538 +                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
8539 +                               dev_priv->savePFIT_PGM_RATIOS =
8540 +                                  arg->display.pfit_programmed_scale_ratios;
8541 +                       if (arg->display_write_mask & REGRWBITS_PIPEASRC)
8542 +                               dev_priv->savePIPEASRC = arg->display.pipeasrc;
8543 +                       if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
8544 +                               dev_priv->savePIPEBSRC = arg->display.pipebsrc;
8545 +                       if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
8546 +                               dev_priv->saveVTOTAL_A = arg->display.vtotal_a;
8547 +                       if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
8548 +                               dev_priv->saveVTOTAL_B = arg->display.vtotal_b;
8549 +               }
8550 +       }
8551 +
8552 +       if (arg->display_read_mask != 0) {
8553 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8554 +                       if (arg->display_read_mask &
8555 +                           REGRWBITS_PFIT_CONTROLS)
8556 +                               arg->display.pfit_controls =
8557 +                                               PSB_RVDC32(PFIT_CONTROL);
8558 +                       if (arg->display_read_mask &
8559 +                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
8560 +                               arg->display.pfit_autoscale_ratios =
8561 +                                               PSB_RVDC32(PFIT_AUTO_RATIOS);
8562 +                       if (arg->display_read_mask &
8563 +                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
8564 +                               arg->display.pfit_programmed_scale_ratios =
8565 +                                               PSB_RVDC32(PFIT_PGM_RATIOS);
8566 +                       if (arg->display_read_mask & REGRWBITS_PIPEASRC)
8567 +                               arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
8568 +                       if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
8569 +                               arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
8570 +                       if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
8571 +                               arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
8572 +                       if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
8573 +                               arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
8574 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8575 +               } else {
8576 +                       if (arg->display_read_mask &
8577 +                           REGRWBITS_PFIT_CONTROLS)
8578 +                               arg->display.pfit_controls =
8579 +                                               dev_priv->savePFIT_CONTROL;
8580 +                       if (arg->display_read_mask &
8581 +                           REGRWBITS_PFIT_AUTOSCALE_RATIOS)
8582 +                               arg->display.pfit_autoscale_ratios =
8583 +                                               dev_priv->savePFIT_AUTO_RATIOS;
8584 +                       if (arg->display_read_mask &
8585 +                           REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
8586 +                               arg->display.pfit_programmed_scale_ratios =
8587 +                                               dev_priv->savePFIT_PGM_RATIOS;
8588 +                       if (arg->display_read_mask & REGRWBITS_PIPEASRC)
8589 +                               arg->display.pipeasrc = dev_priv->savePIPEASRC;
8590 +                       if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
8591 +                               arg->display.pipebsrc = dev_priv->savePIPEBSRC;
8592 +                       if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
8593 +                               arg->display.vtotal_a = dev_priv->saveVTOTAL_A;
8594 +                       if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
8595 +                               arg->display.vtotal_b = dev_priv->saveVTOTAL_B;
8596 +               }
8597 +       }
8598 +
8599 +       if (arg->overlay_write_mask != 0) {
8600 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8601 +                       if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
8602 +                               PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
8603 +                               PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
8604 +                               PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
8605 +                               PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
8606 +                               PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
8607 +                               PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
8608 +                       }
8609 +
8610 +                       if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
8611 +                               PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
8612 +
8613 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8614 +               } else {
8615 +                       if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
8616 +                               dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
8617 +                               dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4;
8618 +                               dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3;
8619 +                               dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2;
8620 +                               dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1;
8621 +                               dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0;
8622 +                       }
8623 +                       if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
8624 +                               dev_priv->saveOV_OVADD = arg->overlay.OVADD;
8625 +               }
8626 +       }
8627 +
8628 +       if (arg->overlay_read_mask != 0) {
8629 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8630 +                       if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
8631 +                               arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
8632 +                               arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
8633 +                               arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
8634 +                               arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
8635 +                               arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
8636 +                               arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
8637 +                       }
8638 +                       if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
8639 +                               arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
8640 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8641 +               } else {
8642 +                       if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
8643 +                               arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
8644 +                               arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4;
8645 +                               arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3;
8646 +                               arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2;
8647 +                               arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1;
8648 +                               arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0;
8649 +                       }
8650 +                       if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
8651 +                               arg->overlay.OVADD = dev_priv->saveOV_OVADD;
8652 +               }
8653 +       }
8654 +
8655 +       if (arg->sprite_enable_mask != 0) {
8656 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8657 +                       PSB_WVDC32(0x1F3E, DSPARB);
8658 +                       PSB_WVDC32(arg->sprite.dspa_control | PSB_RVDC32(DSPACNTR), DSPACNTR);
8659 +                       PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
8660 +                       PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
8661 +                       PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
8662 +                       PSB_RVDC32(DSPASURF);
8663 +                       PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
8664 +                       PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
8665 +                       PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
8666 +                       PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
8667 +                       PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
8668 +                       PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
8669 +                       PSB_RVDC32(DSPCSURF);
8670 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8671 +               }
8672 +       }
8673 +
8674 +       if (arg->sprite_disable_mask != 0) {
8675 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
8676 +                       PSB_WVDC32(0x3F3E, DSPARB);
8677 +                       PSB_WVDC32(0x0, DSPCCNTR);
8678 +                       PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
8679 +                       PSB_RVDC32(DSPCSURF);
8680 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
8681 +               }
8682 +       }
8683 +
8684 +
8685 +       return 0;
8686 +}
8687 +
8688 +/* always available as we are SIGIO'd */
8689 +static unsigned int psb_poll(struct file *filp,
8690 +                            struct poll_table_struct *wait)
8691 +{
8692 +       return POLLIN | POLLRDNORM;
8693 +}
8694 +
8695 +int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
8696 +{
8697 +       DRM_DEBUG("\n");
8698 +       return PVRSRVOpen(dev, priv);
8699 +}
8700 +
8701 +static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
8702 +                              unsigned long arg)
8703 +{
8704 +       struct drm_file *file_priv = filp->private_data;
8705 +       struct drm_device *dev = file_priv->minor->dev;
8706 +       unsigned int nr = DRM_IOCTL_NR(cmd);
8707 +       long ret;
8708 +
8709 +       DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr);
8710 +
8711 +       /*
8712 +        * The driver private ioctls and TTM ioctls should be
8713 +        * thread-safe.
8714 +        */
8715 +
8716 +       if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
8717 +            && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
8718 +               struct drm_ioctl_desc *ioctl =
8719 +                                       &psb_ioctls[nr - DRM_COMMAND_BASE];
8720 +
8721 +               if (unlikely(ioctl->cmd != cmd)) {
8722 +                       DRM_ERROR(
8723 +                               "Invalid drm cmnd %d ioctl->cmd %x, cmd %x\n",
8724 +                               nr - DRM_COMMAND_BASE, ioctl->cmd, cmd);
8725 +                       return -EINVAL;
8726 +               }
8727 +
8728 +               return drm_unlocked_ioctl(filp, cmd, arg);
8729 +       }
8730 +       /*
8731 +        * Not all old drm ioctls are thread-safe.
8732 +        */
8733 +
8734 +       lock_kernel();
8735 +       ret = drm_unlocked_ioctl(filp, cmd, arg);
8736 +       unlock_kernel();
8737 +       return ret;
8738 +}
8739 +
8740 +static int psb_blc_read(char *buf, char **start, off_t offset, int request,
8741 +                       int *eof, void *data)
8742 +{
8743 +       struct drm_minor *minor = (struct drm_minor *) data;
8744 +       struct drm_device *dev = minor->dev;
8745 +       struct drm_psb_private *dev_priv =
8746 +           (struct drm_psb_private *) dev->dev_private;
8747 +       struct backlight_device bd;
8748 +       int user_brightness = 0;
8749 +       int final_brightness = 0;
8750 +       int len = 0;
8751 +
8752 +       *start = &buf[offset];
8753 +       *eof = 0;
8754 +
8755 +       user_brightness = psb_get_brightness(&bd);
8756 +       final_brightness = (user_brightness * dev_priv->blc_adj1) / 100;
8757 +       final_brightness = (final_brightness * dev_priv->blc_adj2) / 100;
8758 +
8759 +       DRM_INFO("%i\n", final_brightness);
8760 +
8761 +       if (len > request + offset)
8762 +               return request;
8763 +       *eof = 1;
8764 +       return len - offset;
8765 +}
8766 +
8767 +static int psb_ospm_read(char *buf, char **start, off_t offset, int request,
8768 +                        int *eof, void *data)
8769 +{
8770 +       struct drm_minor *minor = (struct drm_minor *) data;
8771 +       struct drm_device *dev = minor->dev;
8772 +       struct drm_psb_private *dev_priv =
8773 +           (struct drm_psb_private *) dev->dev_private;
8774 +       int len = 0;
8775 +#ifdef OSPM_STAT
8776 +       unsigned long on_time = 0;
8777 +       unsigned long off_time = 0;
8778 +#endif
8779 +
8780 +       *start = &buf[offset];
8781 +       *eof = 0;
8782 +
8783 +#ifdef SUPPORT_ACTIVE_POWER_MANAGEMENT
8784 +    DRM_INFO("GFX D0i3: enabled              ");
8785 +#else
8786 +    DRM_INFO("GFX D0i3: disabled             ");
8787 +#endif
8788 +
8789 +#ifdef OSPM_STAT
8790 +       switch (dev_priv->graphics_state) {
8791 +       case PSB_PWR_STATE_ON:
8792 +               DRM_INFO("GFX state:%s\n", "on");
8793 +               break;
8794 +       case PSB_PWR_STATE_OFF:
8795 +               DRM_INFO("GFX state:%s\n", "off");
8796 +               break;
8797 +       default:
8798 +               DRM_INFO("GFX state:%s\n", "unknown");
8799 +       }
8800 +
8801 +       on_time = dev_priv->gfx_on_time * 1000 / HZ;
8802 +       off_time = dev_priv->gfx_off_time * 1000 / HZ;
8803 +       switch (dev_priv->graphics_state) {
8804 +       case PSB_PWR_STATE_ON:
8805 +               on_time += (jiffies - dev_priv->gfx_last_mode_change) * \
8806 +                           1000 / HZ;
8807 +               break;
8808 +       case PSB_PWR_STATE_OFF:
8809 +               off_time += (jiffies - dev_priv->gfx_last_mode_change) * \
8810 +                            1000 / HZ;
8811 +               break;
8812 +       }
8813 +       DRM_INFO("GFX(count/ms):\n");
8814 +       DRM_INFO("on:%lu/%lu, off:%lu/%lu \n",
8815 +               dev_priv->gfx_on_cnt, on_time, dev_priv->gfx_off_cnt, off_time);
8816 +#endif
8817 +       if (len > request + offset)
8818 +               return request;
8819 +       *eof = 1;
8820 +       return len - offset;
8821 +}
8822 +
8823 +/* When a client dies:
8824 + *    - Check for and clean up flipped page state
8825 + */
8826 +void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
8827 +{
8828 +}
8829 +
8830 +static void psb_remove(struct pci_dev *pdev)
8831 +{
8832 +       struct drm_device *dev = pci_get_drvdata(pdev);
8833 +       drm_put_dev(dev);
8834 +}
8835 +
8836 +static int psb_proc_init(struct drm_minor *minor)
8837 +{
8838 +       struct proc_dir_entry *ent;
8839 +       struct proc_dir_entry *ent1;
8840 +       ent = create_proc_read_entry(OSPM_PROC_ENTRY, 0, minor->proc_root,
8841 +               psb_ospm_read, minor);
8842 +       ent1 = create_proc_read_entry(BLC_PROC_ENTRY, 0, minor->proc_root,
8843 +               psb_blc_read, minor);
8844 +
8845 +       if (!ent || !ent1)
8846 +               return -1;
8847 +
8848 +       return 0;
8849 +}
8850 +
8851 +static void psb_proc_cleanup(struct drm_minor *minor)
8852 +{
8853 +       remove_proc_entry(OSPM_PROC_ENTRY, minor->proc_root);
8854 +       remove_proc_entry(BLC_PROC_ENTRY, minor->proc_root);
8855 +       return;
8856 +}
8857 +
8858 +static struct drm_driver driver = {
8859 +       .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
8860 +                          DRIVER_IRQ_VBL | DRIVER_MODESET,
8861 +       .load = psb_driver_load,
8862 +       .unload = psb_driver_unload,
8863 +
8864 +       .ioctls = psb_ioctls,
8865 +       .device_is_agp = psb_driver_device_is_agp,
8866 +       .irq_preinstall = sysirq_preinstall,
8867 +       .irq_postinstall = sysirq_postinstall,
8868 +       .irq_uninstall = sysirq_uninstall,
8869 +       .irq_handler = sysirq_handler,
8870 +       .enable_vblank = sysirq_enable_vblank,
8871 +       .disable_vblank = sysirq_disable_vblank,
8872 +       .get_vblank_counter = sysirq_get_vblank_counter,
8873 +       .firstopen = NULL,
8874 +       .lastclose = psb_lastclose,
8875 +       .open = psb_driver_open,
8876 +       .postclose = PVRSRVDrmPostClose,
8877 +       .suspend = PVRSRVDriverSuspend,
8878 +       .resume = PVRSRVDriverResume,
8879 +       .get_map_ofs = drm_core_get_map_ofs,
8880 +       .get_reg_ofs = drm_core_get_reg_ofs,
8881 +       .proc_init = psb_proc_init,
8882 +       .proc_cleanup = psb_proc_cleanup,
8883 +       .preclose = psb_driver_preclose,
8884 +       .fops = {
8885 +                .owner = THIS_MODULE,
8886 +                .open = psb_open,
8887 +                .release = psb_release,
8888 +                .unlocked_ioctl = psb_unlocked_ioctl,
8889 +                .mmap = psb_mmap,
8890 +                .poll = psb_poll,
8891 +                .fasync = drm_fasync,
8892 +                .read = drm_read,
8893 +                },
8894 +       .pci_driver = {
8895 +                      .name = DRIVER_NAME,
8896 +                      .id_table = pciidlist,
8897 +                      .resume = ospm_power_resume,
8898 +                      .suspend = ospm_power_suspend,
8899 +                      .probe = psb_probe,
8900 +                      .remove = psb_remove,
8901 +                      },
8902 +       .name = DRIVER_NAME,
8903 +       .desc = DRIVER_DESC,
8904 +       .date = PSB_DRM_DRIVER_DATE,
8905 +       .major = PSB_DRM_DRIVER_MAJOR,
8906 +       .minor = PSB_DRM_DRIVER_MINOR,
8907 +       .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
8908 +};
8909 +
8910 +static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
8911 +{
8912 +       return drm_get_dev(pdev, ent, &driver);
8913 +}
8914 +
8915 +static int __init psb_init(void)
8916 +{
8917 +       driver.num_ioctls = psb_max_ioctl;
8918 +
8919 +       PVRDPFInit();
8920 +
8921 +       return drm_init(&driver);
8922 +}
8923 +
8924 +static void __exit psb_exit(void)
8925 +{
8926 +       drm_exit(&driver);
8927 +}
8928 +
8929 +late_initcall(psb_init);
8930 +module_exit(psb_exit);
8931 +
8932 +MODULE_AUTHOR(DRIVER_AUTHOR);
8933 +MODULE_DESCRIPTION(DRIVER_DESC);
8934 +MODULE_LICENSE("GPL");
8935 diff --git a/drivers/gpu/drm/mrst/drv/psb_drv.h b/drivers/gpu/drm/mrst/drv/psb_drv.h
8936 new file mode 100644
8937 index 0000000..2ac7934
8938 --- /dev/null
8939 +++ b/drivers/gpu/drm/mrst/drv/psb_drv.h
8940 @@ -0,0 +1,1025 @@
8941 +/**************************************************************************
8942 + * Copyright (c) 2007-2008, Intel Corporation.
8943 + * All Rights Reserved.
8944 + *
8945 + * This program is free software; you can redistribute it and/or modify it
8946 + * under the terms and conditions of the GNU General Public License,
8947 + * version 2, as published by the Free Software Foundation.
8948 + *
8949 + * This program is distributed in the hope it will be useful, but WITHOUT
8950 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8951 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
8952 + * more details.
8953 + *
8954 + * You should have received a copy of the GNU General Public License along with
8955 + * this program; if not, write to the Free Software Foundation, Inc., 
8956 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
8957 + *
8958 + **************************************************************************/
8959 +
8960 +#ifndef _PSB_DRV_H_
8961 +#define _PSB_DRV_H_
8962 +
8963 +#include <drm/drmP.h>
8964 +#include "psb_drm.h"
8965 +#include "psb_reg.h"
8966 +#include "psb_schedule.h"
8967 +#include "psb_intel_drv.h"
8968 +#include "psb_hotplug.h"
8969 +#include "psb_dpst.h"
8970 +#include "psb_gtt.h"
8971 +#include "ttm/ttm_object.h"
8972 +#include "ttm/ttm_fence_driver.h"
8973 +#include "ttm/ttm_bo_driver.h"
8974 +#include "ttm/ttm_lock.h"
8975 +
8976 +/*IMG headers*/
8977 +#include "private_data.h"
8978 +#include "pvr_drm.h"
8979 +
8980 +extern struct ttm_bo_driver psb_ttm_bo_driver;
8981 +
8982 +enum {
8983 +       CHIP_PSB_8108 = 0,
8984 +       CHIP_PSB_8109 = 1,
8985 +       CHIP_MRST_4100 = 2
8986 +};
8987 +
8988 +/*
8989 + *Hardware bugfixes
8990 + */
8991 +
8992 +#define FIX_TG_16
8993 +#define FIX_TG_2D_CLOCKGATE
8994 +#define OSPM_STAT
8995 +
8996 +#define DRIVER_NAME "pvrsrvkm"
8997 +#define DRIVER_DESC "drm driver for the Intel GMA500"
8998 +#define DRIVER_AUTHOR "Tungsten Graphics Inc."
8999 +#define OSPM_PROC_ENTRY "ospm"
9000 +#define BLC_PROC_ENTRY "mrst_blc"
9001 +
9002 +#define PSB_DRM_DRIVER_DATE "2009-03-10"
9003 +#define PSB_DRM_DRIVER_MAJOR 8
9004 +#define PSB_DRM_DRIVER_MINOR 1
9005 +#define PSB_DRM_DRIVER_PATCHLEVEL 0
9006 +
9007 +/*
9008 + *TTM driver private offsets.
9009 + */
9010 +
9011 +#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
9012 +
9013 +#define PSB_OBJECT_HASH_ORDER 13
9014 +#define PSB_FILE_OBJECT_HASH_ORDER 12
9015 +#define PSB_BO_HASH_ORDER 12
9016 +
9017 +#define PSB_VDC_OFFSET          0x00000000
9018 +#define PSB_VDC_SIZE            0x000080000
9019 +#define MRST_MMIO_SIZE          0x0000C0000
9020 +#define PSB_SGX_SIZE            0x8000
9021 +#define PSB_SGX_OFFSET          0x00040000
9022 +#define MRST_SGX_OFFSET                 0x00080000
9023 +#define PSB_MMIO_RESOURCE       0
9024 +#define PSB_GATT_RESOURCE       2
9025 +#define PSB_GTT_RESOURCE        3
9026 +#define PSB_GMCH_CTRL           0x52
9027 +#define PSB_BSM                         0x5C
9028 +#define _PSB_GMCH_ENABLED       0x4
9029 +#define PSB_PGETBL_CTL          0x2020
9030 +#define _PSB_PGETBL_ENABLED     0x00000001
9031 +#define PSB_SGX_2D_SLAVE_PORT   0x4000
9032 +#define PSB_TT_PRIV0_LIMIT      (256*1024*1024)
9033 +#define PSB_TT_PRIV0_PLIMIT     (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
9034 +#define PSB_NUM_VALIDATE_BUFFERS 2048
9035 +
9036 +#define PSB_MEM_MMU_START       0x40000000
9037 +
9038 +/*
9039 + *Flags for external memory type field.
9040 + */
9041 +
9042 +#define MRST_MSVDX_OFFSET      0x90000 /*MSVDX Base offset */
9043 +#define PSB_MSVDX_OFFSET       0x50000 /*MSVDX Base offset */
9044 +/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */
9045 +#define PSB_MSVDX_SIZE         0x10000
9046 +
9047 +#define LNC_TOPAZ_OFFSET       0xA0000
9048 +#define LNC_TOPAZ_SIZE         0x10000
9049 +
9050 +#define PSB_MMU_CACHED_MEMORY    0x0001        /* Bind to MMU only */
9051 +#define PSB_MMU_RO_MEMORY        0x0002        /* MMU RO memory */
9052 +#define PSB_MMU_WO_MEMORY        0x0004        /* MMU WO memory */
9053 +
9054 +/*
9055 + *PTE's and PDE's
9056 + */
9057 +
9058 +#define PSB_PDE_MASK             0x003FFFFF
9059 +#define PSB_PDE_SHIFT            22
9060 +#define PSB_PTE_SHIFT            12
9061 +
9062 +#define PSB_PTE_VALID            0x0001        /* PTE / PDE valid */
9063 +#define PSB_PTE_WO               0x0002        /* Write only */
9064 +#define PSB_PTE_RO               0x0004        /* Read only */
9065 +#define PSB_PTE_CACHED           0x0008        /* CPU cache coherent */
9066 +
9067 +/*
9068 + *VDC registers and bits
9069 + */
9070 +#define PSB_MSVDX_CLOCKGATING    0x2064
9071 +#define PSB_TOPAZ_CLOCKGATING    0x2068
9072 +#define PSB_HWSTAM               0x2098
9073 +#define PSB_INSTPM               0x20C0
9074 +#define _PSB_VSYNC_PIPEB_FLAG    (1<<5)
9075 +#define _PSB_VSYNC_PIPEA_FLAG    (1<<7)
9076 +#define _PSB_DPST_PIPEA_FLAG     (1<<6)
9077 +#define _PSB_DPST_PIPEB_FLAG     (1<<4)
9078 +#define _PSB_IRQ_SGX_FLAG        (1<<18)
9079 +#define _PSB_IRQ_MSVDX_FLAG      (1<<19)
9080 +#define _LNC_IRQ_TOPAZ_FLAG      (1<<20)
9081 +#define PSB_INT_IDENTITY_R       0x20A4
9082 +#define PSB_INT_MASK_R           0x20A8
9083 +#define PSB_INT_ENABLE_R         0x20A0
9084 +
9085 +#define _PSB_MMU_ER_MASK      0x0001FF00
9086 +#define _PSB_MMU_ER_HOST      (1 << 16)
9087 +#define GPIOA                  0x5010
9088 +#define GPIOB                  0x5014
9089 +#define GPIOC                  0x5018
9090 +#define GPIOD                  0x501c
9091 +#define GPIOE                  0x5020
9092 +#define GPIOF                  0x5024
9093 +#define GPIOG                  0x5028
9094 +#define GPIOH                  0x502c
9095 +#define GPIO_CLOCK_DIR_MASK            (1 << 0)
9096 +#define GPIO_CLOCK_DIR_IN              (0 << 1)
9097 +#define GPIO_CLOCK_DIR_OUT             (1 << 1)
9098 +#define GPIO_CLOCK_VAL_MASK            (1 << 2)
9099 +#define GPIO_CLOCK_VAL_OUT             (1 << 3)
9100 +#define GPIO_CLOCK_VAL_IN              (1 << 4)
9101 +#define GPIO_CLOCK_PULLUP_DISABLE      (1 << 5)
9102 +#define GPIO_DATA_DIR_MASK             (1 << 8)
9103 +#define GPIO_DATA_DIR_IN               (0 << 9)
9104 +#define GPIO_DATA_DIR_OUT              (1 << 9)
9105 +#define GPIO_DATA_VAL_MASK             (1 << 10)
9106 +#define GPIO_DATA_VAL_OUT              (1 << 11)
9107 +#define GPIO_DATA_VAL_IN               (1 << 12)
9108 +#define GPIO_DATA_PULLUP_DISABLE       (1 << 13)
9109 +
9110 +#define VCLK_DIVISOR_VGA0   0x6000
9111 +#define VCLK_DIVISOR_VGA1   0x6004
9112 +#define VCLK_POST_DIV      0x6010
9113 +
9114 +#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
9115 +#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
9116 +#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
9117 +#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
9118 +#define PSB_COMM_USER_IRQ (1024 >> 2)
9119 +#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
9120 +#define PSB_COMM_FW (2048 >> 2)
9121 +
9122 +#define PSB_UIRQ_VISTEST              1
9123 +#define PSB_UIRQ_OOM_REPLY            2
9124 +#define PSB_UIRQ_FIRE_TA_REPLY        3
9125 +#define PSB_UIRQ_FIRE_RASTER_REPLY     4
9126 +
9127 +#define PSB_2D_SIZE (256*1024*1024)
9128 +#define PSB_MAX_RELOC_PAGES 1024
9129 +
9130 +#define PSB_LOW_REG_OFFS 0x0204
9131 +#define PSB_HIGH_REG_OFFS 0x0600
9132 +
9133 +#define PSB_NUM_VBLANKS 2
9134 +
9135 +
9136 +#define PSB_2D_SIZE (256*1024*1024)
9137 +#define PSB_MAX_RELOC_PAGES 1024
9138 +
9139 +#define PSB_LOW_REG_OFFS 0x0204
9140 +#define PSB_HIGH_REG_OFFS 0x0600
9141 +
9142 +#define PSB_NUM_VBLANKS 2
9143 +#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
9144 +#define PSB_LID_DELAY (DRM_HZ / 10)
9145 +
9146 +#define PSB_PWR_STATE_ON               1
9147 +#define PSB_PWR_STATE_OFF              2
9148 +
9149 +#define PSB_PMPOLICY_NOPM              0
9150 +#define PSB_PMPOLICY_POWERDOWN         2
9151 +
9152 +#define PSB_PMSTATE_POWERUP            0
9153 +#define PSB_PMSTATE_POWERDOWN          2
9154 +
9155 +/*
9156 + *User options.
9157 + */
9158 +
9159 +struct drm_psb_uopt {
9160 +       int pad; /*keep it here in case we use it in future*/
9161 +};
9162 +
9163 +/**
9164 + *struct psb_context
9165 + *
9166 + *@buffers:     array of pre-allocated validate buffers.
9167 + *@used_buffers: number of buffers in @buffers array currently in use.
9168 + *@validate_buffer: buffers validated from user-space.
9169 + *@kern_validate_buffers : buffers validated from kernel-space.
9170 + *@fence_flags : Fence flags to be used for fence creation.
9171 + *
9172 + *This structure is used during execbuf validation.
9173 + */
9174 +
9175 +struct psb_context {
9176 +       struct psb_validate_buffer *buffers;
9177 +       uint32_t used_buffers;
9178 +       struct list_head validate_list;
9179 +       struct list_head kern_validate_list;
9180 +       uint32_t fence_types;
9181 +       uint32_t val_seq;
9182 +};
9183 +
9184 +struct psb_validate_buffer;
9185 +
9186 +struct psb_msvdx_cmd_queue {
9187 +       struct list_head head;
9188 +       void *cmd;
9189 +       unsigned long cmd_size;
9190 +       uint32_t sequence;
9191 +};
9192 +
9193 +struct drm_psb_private {
9194 +
9195 +       /*
9196 +        *TTM Glue.
9197 +        */
9198 +
9199 +       struct drm_global_reference mem_global_ref;
9200 +       int has_global;
9201 +
9202 +       struct drm_device *dev;
9203 +       struct ttm_object_device *tdev;
9204 +       struct ttm_fence_device fdev;
9205 +       struct ttm_bo_device bdev;
9206 +       struct ttm_lock ttm_lock;
9207 +       struct vm_operations_struct *ttm_vm_ops;
9208 +       int has_fence_device;
9209 +       int has_bo_device;
9210 +
9211 +       unsigned long chipset;
9212 +
9213 +       struct drm_psb_dev_info_arg dev_info;
9214 +       struct drm_psb_uopt uopt;
9215 +
9216 +       struct psb_gtt *pg;
9217 +
9218 +       /*GTT Memory manager*/
9219 +       struct psb_gtt_mm *gtt_mm;
9220 +
9221 +       struct page *scratch_page;
9222 +       uint32_t sequence[PSB_NUM_ENGINES];
9223 +       uint32_t last_sequence[PSB_NUM_ENGINES];
9224 +       uint32_t last_submitted_seq[PSB_NUM_ENGINES];
9225 +
9226 +       struct psb_mmu_driver *mmu;
9227 +       struct psb_mmu_pd *pf_pd;
9228 +
9229 +       uint8_t *sgx_reg;
9230 +       uint8_t *vdc_reg;
9231 +       uint32_t gatt_free_offset;
9232 +
9233 +       /*
9234 +        *MSVDX
9235 +        */
9236 +       uint8_t *msvdx_reg;
9237 +       atomic_t msvdx_mmu_invaldc;
9238 +       void *msvdx_private;
9239 +
9240 +       /*
9241 +        *TOPAZ
9242 +        */
9243 +       uint8_t *topaz_reg;
9244 +       void *topaz_private;
9245 +       uint8_t topaz_disabled;
9246 +       uint32_t video_device_fuse;
9247 +       atomic_t topaz_mmu_invaldc;
9248 +
9249 +       /*
9250 +        *Fencing / irq.
9251 +        */
9252 +
9253 +       uint32_t vdc_irq_mask;
9254 +       u32 pipestat[2];
9255 +       bool vblanksEnabledForFlips;
9256 +
9257 +       spinlock_t irqmask_lock;
9258 +       spinlock_t sequence_lock;
9259 +
9260 +       /*
9261 +        *Modesetting
9262 +        */
9263 +       struct psb_intel_mode_device mode_dev;
9264 +
9265 +       struct drm_crtc *plane_to_crtc_mapping[2];
9266 +       struct drm_crtc *pipe_to_crtc_mapping[2];
9267 +
9268 +       /*
9269 +        * CI share buffer
9270 +        */
9271 +       unsigned int ci_region_start;
9272 +       unsigned int ci_region_size;
9273 +
9274 +       /*
9275 +        * RAR share buffer;
9276 +        */
9277 +       unsigned int rar_region_start;
9278 +       unsigned int rar_region_size;
9279 +
9280 +       /*
9281 +        *Memory managers
9282 +        */
9283 +
9284 +       int have_camera;
9285 +       int have_rar;
9286 +       int have_tt;
9287 +       int have_mem_mmu;
9288 +       struct mutex temp_mem;
9289 +
9290 +       /*
9291 +        *Relocation buffer mapping.
9292 +        */
9293 +
9294 +       spinlock_t reloc_lock;
9295 +       unsigned int rel_mapped_pages;
9296 +       wait_queue_head_t rel_mapped_queue;
9297 +
9298 +       /*
9299 +        *SAREA
9300 +        */
9301 +       struct drm_psb_sarea *sarea_priv;
9302 +
9303 +       /*
9304 +       *OSPM info
9305 +       */
9306 +       uint32_t ospm_base;
9307 +
9308 +       /*
9309 +        * Sizes info
9310 +        */
9311 +
9312 +       struct drm_psb_sizes_arg sizes;
9313 +
9314 +       uint32_t fuse_reg_value;
9315 +
9316 +       /* vbt (gct) header information*/
9317 +       struct mrst_vbt vbt_data;
9318 +       /* info that is stored from the gct */
9319 +       struct gct_ioctl_arg gct_data;
9320 +
9321 +       /*
9322 +        *LVDS info
9323 +        */
9324 +       int backlight_duty_cycle;       /* restore backlight to this value */
9325 +       bool panel_wants_dither;
9326 +       struct drm_display_mode *panel_fixed_mode;
9327 +       struct drm_display_mode *lfp_lvds_vbt_mode;
9328 +       struct drm_display_mode *sdvo_lvds_vbt_mode;
9329 +
9330 +       struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/
9331 +       struct psb_intel_i2c_chan *lvds_i2c_bus;
9332 +
9333 +       /* Feature bits from the VBIOS*/
9334 +       unsigned int int_tv_support:1;
9335 +       unsigned int lvds_dither:1;
9336 +       unsigned int lvds_vbt:1;
9337 +       unsigned int int_crt_support:1;
9338 +       unsigned int lvds_use_ssc:1;
9339 +       int lvds_ssc_freq;
9340 +
9341 +/* MRST private date start */
9342 +/*FIXME JLIU7 need to revisit */
9343 +       bool sku_83;
9344 +       bool sku_100;
9345 +       bool sku_100L;
9346 +       bool sku_bypass;
9347 +       uint32_t iLVDS_enable;
9348 +
9349 +       /* pipe config register value */
9350 +       uint32_t pipeconf;
9351 +
9352 +       /* plane control register value */
9353 +       uint32_t dspcntr;
9354 +
9355 +/* MRST_DSI private date start */
9356 +       /*
9357 +        *MRST DSI info
9358 +        */
9359 +       /* The DSI device ready */
9360 +       bool dsi_device_ready;
9361 +
9362 +       /* The DPI panel power on */
9363 +       bool dpi_panel_on;
9364 +
9365 +       /* The DBI panel power on */
9366 +       bool dbi_panel_on;
9367 +
9368 +       /* The DPI display */
9369 +       bool dpi;
9370 +
9371 +       enum mipi_panel_type panel_make;
9372 +
9373 +       /* status */
9374 +       uint32_t videoModeFormat:2;
9375 +       uint32_t laneCount:3;
9376 +       uint32_t status_reserved:27;
9377 +
9378 +       /* dual display - DPI & DBI */
9379 +       bool dual_display;
9380 +
9381 +       /* HS or LP transmission */
9382 +       bool lp_transmission;
9383 +
9384 +       /* configuration phase */
9385 +       bool config_phase;
9386 +
9387 +       /* DSI clock */
9388 +       uint32_t RRate;
9389 +       uint32_t DDR_Clock;
9390 +       uint32_t DDR_Clock_Calculated;
9391 +       uint32_t ClockBits;
9392 +
9393 +       /* DBI Buffer pointer */
9394 +       u8 *p_DBI_commandBuffer_orig;
9395 +       u8 *p_DBI_commandBuffer;
9396 +       uint32_t DBI_CB_pointer;
9397 +       u8 *p_DBI_dataBuffer_orig;
9398 +       u8 *p_DBI_dataBuffer;
9399 +       uint32_t DBI_DB_pointer;
9400 +
9401 +       /* DPI panel spec */
9402 +       uint32_t pixelClock;
9403 +       uint32_t HsyncWidth;
9404 +       uint32_t HbackPorch;
9405 +       uint32_t HfrontPorch;
9406 +       uint32_t HactiveArea;
9407 +       uint32_t VsyncWidth;
9408 +       uint32_t VbackPorch;
9409 +       uint32_t VfrontPorch;
9410 +       uint32_t VactiveArea;
9411 +       uint32_t bpp:5;
9412 +       uint32_t Reserved:27;
9413 +
9414 +       /* DBI panel spec */
9415 +       uint32_t dbi_pixelClock;
9416 +       uint32_t dbi_HsyncWidth;
9417 +       uint32_t dbi_HbackPorch;
9418 +       uint32_t dbi_HfrontPorch;
9419 +       uint32_t dbi_HactiveArea;
9420 +       uint32_t dbi_VsyncWidth;
9421 +       uint32_t dbi_VbackPorch;
9422 +       uint32_t dbi_VfrontPorch;
9423 +       uint32_t dbi_VactiveArea;
9424 +       uint32_t dbi_bpp:5;
9425 +       uint32_t dbi_Reserved:27;
9426 +
9427 +/* MRST_DSI private date end */
9428 +
9429 +       /*
9430 +        *Register state
9431 +        */
9432 +       uint32_t saveDSPACNTR;
9433 +       uint32_t saveDSPBCNTR;
9434 +       uint32_t savePIPEACONF;
9435 +       uint32_t savePIPEBCONF;
9436 +       uint32_t savePIPEASRC;
9437 +       uint32_t savePIPEBSRC;
9438 +       uint32_t saveFPA0;
9439 +       uint32_t saveFPA1;
9440 +       uint32_t saveDPLL_A;
9441 +       uint32_t saveDPLL_A_MD;
9442 +       uint32_t saveHTOTAL_A;
9443 +       uint32_t saveHBLANK_A;
9444 +       uint32_t saveHSYNC_A;
9445 +       uint32_t saveVTOTAL_A;
9446 +       uint32_t saveVBLANK_A;
9447 +       uint32_t saveVSYNC_A;
9448 +       uint32_t saveDSPASTRIDE;
9449 +       uint32_t saveDSPASIZE;
9450 +       uint32_t saveDSPAPOS;
9451 +       uint32_t saveDSPABASE;
9452 +       uint32_t saveDSPASURF;
9453 +       uint32_t saveFPB0;
9454 +       uint32_t saveFPB1;
9455 +       uint32_t saveDPLL_B;
9456 +       uint32_t saveDPLL_B_MD;
9457 +       uint32_t saveHTOTAL_B;
9458 +       uint32_t saveHBLANK_B;
9459 +       uint32_t saveHSYNC_B;
9460 +       uint32_t saveVTOTAL_B;
9461 +       uint32_t saveVBLANK_B;
9462 +       uint32_t saveVSYNC_B;
9463 +       uint32_t saveDSPBSTRIDE;
9464 +       uint32_t saveDSPBSIZE;
9465 +       uint32_t saveDSPBPOS;
9466 +       uint32_t saveDSPBBASE;
9467 +       uint32_t saveDSPBSURF;
9468 +       uint32_t saveVCLK_DIVISOR_VGA0;
9469 +       uint32_t saveVCLK_DIVISOR_VGA1;
9470 +       uint32_t saveVCLK_POST_DIV;
9471 +       uint32_t saveVGACNTRL;
9472 +       uint32_t saveADPA;
9473 +       uint32_t saveLVDS;
9474 +       uint32_t saveDVOA;
9475 +       uint32_t saveDVOB;
9476 +       uint32_t saveDVOC;
9477 +       uint32_t savePP_ON;
9478 +       uint32_t savePP_OFF;
9479 +       uint32_t savePP_CONTROL;
9480 +       uint32_t savePP_CYCLE;
9481 +       uint32_t savePFIT_CONTROL;
9482 +       uint32_t savePaletteA[256];
9483 +       uint32_t savePaletteB[256];
9484 +       uint32_t saveBLC_PWM_CTL2;
9485 +       uint32_t saveBLC_PWM_CTL;
9486 +       uint32_t saveCLOCKGATING;
9487 +       uint32_t saveDSPARB;
9488 +       uint32_t saveDSPATILEOFF;
9489 +       uint32_t saveDSPBTILEOFF;
9490 +       uint32_t saveDSPAADDR;
9491 +       uint32_t saveDSPBADDR;
9492 +       uint32_t savePFIT_AUTO_RATIOS;
9493 +       uint32_t savePFIT_PGM_RATIOS;
9494 +       uint32_t savePP_ON_DELAYS;
9495 +       uint32_t savePP_OFF_DELAYS;
9496 +       uint32_t savePP_DIVISOR;
9497 +       uint32_t saveBCLRPAT_A;
9498 +       uint32_t saveBCLRPAT_B;
9499 +       uint32_t saveDSPALINOFF;
9500 +       uint32_t saveDSPBLINOFF;
9501 +       uint32_t savePERF_MODE;
9502 +       uint32_t saveDSPFW1;
9503 +       uint32_t saveDSPFW2;
9504 +       uint32_t saveDSPFW3;
9505 +       uint32_t saveDSPFW4;
9506 +       uint32_t saveDSPFW5;
9507 +       uint32_t saveDSPFW6;
9508 +       uint32_t saveCHICKENBIT;
9509 +       uint32_t saveDSPACURSOR_CTRL;
9510 +       uint32_t saveDSPBCURSOR_CTRL;
9511 +       uint32_t saveDSPACURSOR_BASE;
9512 +       uint32_t saveDSPBCURSOR_BASE;
9513 +       uint32_t saveDSPACURSOR_POS;
9514 +       uint32_t saveDSPBCURSOR_POS;
9515 +       uint32_t save_palette_a[256];
9516 +       uint32_t save_palette_b[256];
9517 +       uint32_t saveOV_OVADD;
9518 +       uint32_t saveOV_OGAMC0;
9519 +       uint32_t saveOV_OGAMC1;
9520 +       uint32_t saveOV_OGAMC2;
9521 +       uint32_t saveOV_OGAMC3;
9522 +       uint32_t saveOV_OGAMC4;
9523 +       uint32_t saveOV_OGAMC5;
9524 +
9525 +       /* DSI reg save */
9526 +       uint32_t saveDEVICE_READY_REG;
9527 +       uint32_t saveINTR_EN_REG;
9528 +       uint32_t saveDSI_FUNC_PRG_REG;
9529 +       uint32_t saveHS_TX_TIMEOUT_REG;
9530 +       uint32_t saveLP_RX_TIMEOUT_REG;
9531 +       uint32_t saveTURN_AROUND_TIMEOUT_REG;
9532 +       uint32_t saveDEVICE_RESET_REG;
9533 +       uint32_t saveDPI_RESOLUTION_REG;
9534 +       uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
9535 +       uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
9536 +       uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
9537 +       uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
9538 +       uint32_t saveVERT_SYNC_PAD_COUNT_REG;
9539 +       uint32_t saveVERT_BACK_PORCH_COUNT_REG;
9540 +       uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
9541 +       uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
9542 +       uint32_t saveINIT_COUNT_REG;
9543 +       uint32_t saveMAX_RET_PAK_REG;
9544 +       uint32_t saveVIDEO_FMT_REG;
9545 +       uint32_t saveEOT_DISABLE_REG;
9546 +       uint32_t saveLP_BYTECLK_REG;
9547 +       uint32_t saveHS_LS_DBI_ENABLE_REG;
9548 +       uint32_t saveTXCLKESC_REG;
9549 +       uint32_t saveDPHY_PARAM_REG;
9550 +       uint32_t saveMIPI_CONTROL_REG;
9551 +       uint32_t saveMIPI;
9552 +       void (*init_drvIC)(struct drm_device *dev);
9553 +
9554 +       /* DPST Register Save */
9555 +       uint32_t saveHISTOGRAM_INT_CONTROL_REG;
9556 +       uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
9557 +
9558 +       /*
9559 +        *Scheduling.
9560 +        */
9561 +
9562 +       struct mutex reset_mutex;
9563 +       struct psb_scheduler scheduler;
9564 +       struct mutex cmdbuf_mutex;
9565 +       /*uint32_t ta_mem_pages;
9566 +       struct psb_ta_mem *ta_mem;
9567 +       int force_ta_mem_load;*/
9568 +       atomic_t val_seq;
9569 +
9570 +       /*
9571 +        *TODO: change this to be per drm-context.
9572 +        */
9573 +
9574 +       struct psb_context context;
9575 +
9576 +       /*
9577 +        * LID-Switch
9578 +        */
9579 +       spinlock_t lid_lock;
9580 +       struct timer_list lid_timer;
9581 +       struct psb_intel_opregion opregion;
9582 +       u32 *lid_state;
9583 +       u32 lid_last_state;
9584 +
9585 +       /*
9586 +        *Watchdog
9587 +        */
9588 +
9589 +       spinlock_t watchdog_lock;
9590 +       struct timer_list watchdog_timer;
9591 +       struct work_struct watchdog_wq;
9592 +       struct work_struct msvdx_watchdog_wq;
9593 +       struct work_struct topaz_watchdog_wq;
9594 +       int timer_available;
9595 +
9596 +       uint32_t apm_reg;
9597 +       uint16_t apm_base;
9598 +#ifdef OSPM_STAT
9599 +       unsigned char graphics_state;
9600 +       unsigned long gfx_on_time;
9601 +       unsigned long gfx_off_time;
9602 +       unsigned long gfx_last_mode_change;
9603 +       unsigned long gfx_on_cnt;
9604 +       unsigned long gfx_off_cnt;
9605 +#endif
9606 +
9607 +       /*to be removed later*/
9608 +       /*int dri_page_flipping;
9609 +       int current_page;
9610 +       int pipe_active[2];
9611 +       int saved_start[2];
9612 +       int saved_offset[2];
9613 +       int saved_stride[2];
9614 +
9615 +       int flip_start[2];
9616 +       int flip_offset[2];
9617 +       int flip_stride[2];*/
9618 +
9619 +
9620 +       /*
9621 +        * Used for modifying backlight from
9622 +        * xrandr -- consider removing and using HAL instead
9623 +        */
9624 +       struct drm_property *backlight_property;
9625 +       uint32_t blc_adj1;
9626 +       uint32_t blc_adj2;
9627 +
9628 +       /*
9629 +        * DPST and Hotplug state
9630 +        */
9631 +
9632 +       struct dpst_state *psb_dpst_state;
9633 +       struct hotplug_state *psb_hotplug_state;
9634 +
9635 +};
9636 +
9637 +struct psb_fpriv {
9638 +       struct ttm_object_file *tfile;
9639 +};
9640 +
9641 +struct psb_mmu_driver;
9642 +
9643 +extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
9644 +extern int drm_pick_crtcs(struct drm_device *dev);
9645 +
9646 +
9647 +static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
9648 +{
9649 +       PVRSRV_FILE_PRIVATE_DATA *pvr_file_priv
9650 +                       = (PVRSRV_FILE_PRIVATE_DATA *)file_priv->driver_priv;
9651 +       return (struct psb_fpriv *) pvr_file_priv->pPriv;
9652 +}
9653 +
9654 +static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
9655 +{
9656 +       return (struct drm_psb_private *) dev->dev_private;
9657 +}
9658 +
9659 +/*
9660 + *TTM glue. psb_ttm_glue.c
9661 + */
9662 +
9663 +extern int psb_open(struct inode *inode, struct file *filp);
9664 +extern int psb_release(struct inode *inode, struct file *filp);
9665 +extern int psb_mmap(struct file *filp, struct vm_area_struct *vma);
9666 +
9667 +extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
9668 +                                   struct drm_file *file_priv);
9669 +extern int psb_verify_access(struct ttm_buffer_object *bo,
9670 +                            struct file *filp);
9671 +extern ssize_t psb_ttm_read(struct file *filp, char __user *buf,
9672 +                           size_t count, loff_t *f_pos);
9673 +extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
9674 +                           size_t count, loff_t *f_pos);
9675 +extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
9676 +                                 struct drm_file *file_priv);
9677 +extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
9678 +                                struct drm_file *file_priv);
9679 +extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
9680 +                                struct drm_file *file_priv);
9681 +extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
9682 +                                 struct drm_file *file_priv);
9683 +extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
9684 +                               struct drm_file *file_priv);
9685 +extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
9686 +                             struct drm_file *file_priv);
9687 +extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
9688 +                                 struct drm_file *file_priv);
9689 +extern int psb_pl_create_ioctl(struct drm_device *dev, void *data,
9690 +                              struct drm_file *file_priv);
9691 +extern int psb_extension_ioctl(struct drm_device *dev, void *data,
9692 +                              struct drm_file *file_priv);
9693 +extern int psb_ttm_global_init(struct drm_psb_private *dev_priv);
9694 +extern void psb_ttm_global_release(struct drm_psb_private *dev_priv);
9695 +extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
9696 +                               struct drm_file *file_priv);
9697 +/*
9698 + *MMU stuff.
9699 + */
9700 +
9701 +extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
9702 +                                       int trap_pagefaults,
9703 +                                       int invalid_type,
9704 +                                       struct drm_psb_private *dev_priv);
9705 +extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
9706 +extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver
9707 +                                                *driver);
9708 +extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
9709 +                              uint32_t gtt_start, uint32_t gtt_pages);
9710 +extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
9711 +                                          int trap_pagefaults,
9712 +                                          int invalid_type);
9713 +extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
9714 +extern void psb_mmu_flush(struct psb_mmu_driver *driver);
9715 +extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
9716 +                                       unsigned long address,
9717 +                                       uint32_t num_pages);
9718 +extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
9719 +                                      uint32_t start_pfn,
9720 +                                      unsigned long address,
9721 +                                      uint32_t num_pages, int type);
9722 +extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
9723 +                                 unsigned long *pfn);
9724 +
9725 +/*
9726 + *Enable / disable MMU for different requestors.
9727 + */
9728 +
9729 +
9730 +extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
9731 +extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
9732 +                               unsigned long address, uint32_t num_pages,
9733 +                               uint32_t desired_tile_stride,
9734 +                               uint32_t hw_tile_stride, int type);
9735 +extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
9736 +                                unsigned long address, uint32_t num_pages,
9737 +                                uint32_t desired_tile_stride,
9738 +                                uint32_t hw_tile_stride);
9739 +/*
9740 + *psb_sgx.c
9741 + */
9742 +
9743 +
9744 +
9745 +extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
9746 +                           struct drm_file *file_priv);
9747 +extern int psb_reg_submit(struct drm_psb_private *dev_priv,
9748 +                         uint32_t *regs, unsigned int cmds);
9749 +
9750 +
9751 +extern void psb_fence_or_sync(struct drm_file *file_priv,
9752 +                             uint32_t engine,
9753 +                             uint32_t fence_types,
9754 +                             uint32_t fence_flags,
9755 +                             struct list_head *list,
9756 +                             struct psb_ttm_fence_rep *fence_arg,
9757 +                             struct ttm_fence_object **fence_p);
9758 +extern int psb_validate_kernel_buffer(struct psb_context *context,
9759 +                                     struct ttm_buffer_object *bo,
9760 +                                     uint32_t fence_class,
9761 +                                     uint64_t set_flags,
9762 +                                     uint64_t clr_flags);
9763 +
9764 +
9765 +/*
9766 + *psb_fence.c
9767 + */
9768 +
9769 +extern void psb_fence_handler(struct drm_device *dev, uint32_t class);
9770 +
9771 +extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
9772 +                                  uint32_t fence_class,
9773 +                                  uint32_t flags, uint32_t *sequence,
9774 +                                  unsigned long *timeout_jiffies);
9775 +extern void psb_fence_error(struct drm_device *dev,
9776 +                           uint32_t class,
9777 +                           uint32_t sequence, uint32_t type, int error);
9778 +extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev);
9779 +
9780 +/* MSVDX/Topaz stuff */
9781 +extern int lnc_video_frameskip(struct drm_device *dev,
9782 +                              uint64_t user_pointer);
9783 +extern int lnc_video_getparam(struct drm_device *dev, void *data,
9784 +                             struct drm_file *file_priv);
9785 +extern int psb_try_power_down_topaz(struct drm_device *dev);
9786 +extern int psb_try_power_down_msvdx(struct drm_device *dev);
9787 +
9788 +
9789 +/*
9790 + *psb_fb.c
9791 + */
9792 +extern int psbfb_probed(struct drm_device *dev);
9793 +extern int psbfb_remove(struct drm_device *dev,
9794 +                       struct drm_framebuffer *fb);
9795 +extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
9796 +                              struct drm_file *file_priv);
9797 +extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
9798 +                             struct drm_file *file_priv);
9799 +
9800 +/*
9801 + *psb_reset.c
9802 + */
9803 +
9804 +extern void psb_schedule_watchdog(struct drm_psb_private *dev_priv);
9805 +extern void psb_watchdog_init(struct drm_psb_private *dev_priv);
9806 +extern void psb_watchdog_takedown(struct drm_psb_private *dev_priv);
9807 +extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
9808 +extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
9809 +extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
9810 +
9811 +
9812 +
9813 +/* modesetting */
9814 +extern void psb_modeset_init(struct drm_device *dev);
9815 +extern void psb_modeset_cleanup(struct drm_device *dev);
9816 +
9817 +/* psb_bl.c */
9818 +int psb_backlight_init(struct drm_device *dev);
9819 +void psb_backlight_exit(void);
9820 +int psb_set_brightness(struct backlight_device *bd);
9821 +int psb_get_brightness(struct backlight_device *bd);
9822 +
9823 +/*
9824 + *Utilities
9825 + */
9826 +#define DRM_DRIVER_PRIVATE_T struct drm_psb_private
9827 +
9828 +static inline u32 MSG_READ32(uint port, uint offset)
9829 +{
9830 +       int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
9831 +       outl(0x800000D0, 0xCF8);
9832 +       outl(mcr, 0xCFC);
9833 +       outl(0x800000D4, 0xCF8);
9834 +       return inl(0xcfc);
9835 +}
9836 +static inline void MSG_WRITE32(uint port, uint offset, u32 value)
9837 +{
9838 +       int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
9839 +       outl(0x800000D4, 0xCF8);
9840 +       outl(value, 0xcfc);
9841 +       outl(0x800000D0, 0xCF8);
9842 +       outl(mcr, 0xCFC);
9843 +}
9844 +
9845 +static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
9846 +{
9847 +       struct drm_psb_private *dev_priv = dev->dev_private;
9848 +
9849 +       return ioread32(dev_priv->vdc_reg + (reg));
9850 +}
9851 +
9852 +#define REG_READ(reg)         REGISTER_READ(dev, (reg))
9853 +static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
9854 +                                     uint32_t val)
9855 +{
9856 +       struct drm_psb_private *dev_priv = dev->dev_private;
9857 +
9858 +       iowrite32((val), dev_priv->vdc_reg + (reg));
9859 +}
9860 +
9861 +#define REG_WRITE(reg, val)    REGISTER_WRITE(dev, (reg), (val))
9862 +
9863 +static inline void REGISTER_WRITE16(struct drm_device *dev,
9864 +                                       uint32_t reg, uint32_t val)
9865 +{
9866 +       struct drm_psb_private *dev_priv = dev->dev_private;
9867 +
9868 +       iowrite16((val), dev_priv->vdc_reg + (reg));
9869 +}
9870 +
9871 +#define REG_WRITE16(reg, val)    REGISTER_WRITE16(dev, (reg), (val))
9872 +
9873 +static inline void REGISTER_WRITE8(struct drm_device *dev,
9874 +                                      uint32_t reg, uint32_t val)
9875 +{
9876 +       struct drm_psb_private *dev_priv = dev->dev_private;
9877 +
9878 +       iowrite8((val), dev_priv->vdc_reg + (reg));
9879 +}
9880 +
9881 +#define REG_WRITE8(reg, val)    REGISTER_WRITE8(dev, (reg), (val))
9882 +
9883 +#define PSB_ALIGN_TO(_val, _align) \
9884 +  (((_val) + ((_align) - 1)) & ~((_align) - 1))
9885 +#define PSB_WVDC32(_val, _offs) \
9886 +  iowrite32(_val, dev_priv->vdc_reg + (_offs))
9887 +#define PSB_RVDC32(_offs) \
9888 +  ioread32(dev_priv->vdc_reg + (_offs))
9889 +
9890 +/* #define TRAP_SGX_PM_FAULT 1 */
9891 +#ifdef TRAP_SGX_PM_FAULT
9892 +#define PSB_RSGX32(_offs)                                      \
9893 +({                                                             \
9894 +    if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) {         \
9895 +       printk(KERN_ERR "access sgx when it's off!! (READ) %s, %d\n", \
9896 +              __FILE__, __LINE__);                             \
9897 +       mdelay(1000);                                           \
9898 +    }                                                          \
9899 +    ioread32(dev_priv->sgx_reg + (_offs));                     \
9900 +})
9901 +#else
9902 +#define PSB_RSGX32(_offs)                                      \
9903 +  ioread32(dev_priv->sgx_reg + (_offs))
9904 +#endif
9905 +
9906 +#define PSB_WMSVDX32(_val, _offs) \
9907 +  iowrite32(_val, dev_priv->msvdx_reg + (_offs))
9908 +#define PSB_RMSVDX32(_offs) \
9909 +  ioread32(dev_priv->msvdx_reg + (_offs))
9910 +
9911 +#define PSB_ALPL(_val, _base)                  \
9912 +  (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT))
9913 +#define PSB_ALPLM(_val, _base)                 \
9914 +  ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK))
9915 +
9916 +#define PSB_D_RENDER  (1 << 16)
9917 +
9918 +#define PSB_D_GENERAL (1 << 0)
9919 +#define PSB_D_INIT    (1 << 1)
9920 +#define PSB_D_IRQ     (1 << 2)
9921 +#define PSB_D_FW      (1 << 3)
9922 +#define PSB_D_PERF    (1 << 4)
9923 +#define PSB_D_TMP    (1 << 5)
9924 +#define PSB_D_PM      (1 << 6)
9925 +
9926 +extern int drm_psb_debug;
9927 +extern int drm_psb_no_fb;
9928 +extern int drm_idle_check_interval;
9929 +extern int drm_topaz_sbuswa;
9930 +
9931 +#define PSB_DEBUG_FW(_fmt, _arg...) \
9932 +       PSB_DEBUG(PSB_D_FW, _fmt, ##_arg)
9933 +#define PSB_DEBUG_GENERAL(_fmt, _arg...) \
9934 +       PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg)
9935 +#define PSB_DEBUG_INIT(_fmt, _arg...) \
9936 +       PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg)
9937 +#define PSB_DEBUG_IRQ(_fmt, _arg...) \
9938 +       PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg)
9939 +#define PSB_DEBUG_RENDER(_fmt, _arg...) \
9940 +       PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg)
9941 +#define PSB_DEBUG_PERF(_fmt, _arg...) \
9942 +       PSB_DEBUG(PSB_D_PERF, _fmt, ##_arg)
9943 +#define PSB_DEBUG_TMP(_fmt, _arg...) \
9944 +       PSB_DEBUG(PSB_D_TMP, _fmt, ##_arg)
9945 +#define PSB_DEBUG_PM(_fmt, _arg...) \
9946 +       PSB_DEBUG(PSB_D_PM, _fmt, ##_arg)
9947 +
9948 +#if DRM_DEBUG_CODE
9949 +#define PSB_DEBUG(_flag, _fmt, _arg...)                                        \
9950 +       do {                                                            \
9951 +               if (unlikely((_flag) & drm_psb_debug))                  \
9952 +                       printk(KERN_DEBUG                               \
9953 +                              "[psb:0x%02x:%s] " _fmt , _flag,         \
9954 +                              __func__ , ##_arg);                      \
9955 +       } while (0)
9956 +#else
9957 +#define PSB_DEBUG(_fmt, _arg...)     do { } while (0)
9958 +#endif
9959 +
9960 +#define IS_POULSBO(dev) (((dev)->pci_device == 0x8108) || \
9961 +                        ((dev)->pci_device == 0x8109))
9962 +
9963 +#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
9964 +
9965 +#endif
9966 diff --git a/drivers/gpu/drm/mrst/drv/psb_fb.c b/drivers/gpu/drm/mrst/drv/psb_fb.c
9967 new file mode 100644
9968 index 0000000..addec23
9969 --- /dev/null
9970 +++ b/drivers/gpu/drm/mrst/drv/psb_fb.c
9971 @@ -0,0 +1,1817 @@
9972 +/**************************************************************************
9973 + * Copyright (c) 2007, Intel Corporation.
9974 + * All Rights Reserved.
9975 + *
9976 + * This program is free software; you can redistribute it and/or modify it
9977 + * under the terms and conditions of the GNU General Public License,
9978 + * version 2, as published by the Free Software Foundation.
9979 + *
9980 + * This program is distributed in the hope it will be useful, but WITHOUT
9981 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9982 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
9983 + * more details.
9984 + *
9985 + * You should have received a copy of the GNU General Public License along with
9986 + * this program; if not, write to the Free Software Foundation, Inc., 
9987 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9988 + *
9989 + **************************************************************************/
9990 +
9991 +#include <linux/module.h>
9992 +#include <linux/kernel.h>
9993 +#include <linux/errno.h>
9994 +#include <linux/string.h>
9995 +#include <linux/mm.h>
9996 +#include <linux/tty.h>
9997 +#include <linux/slab.h>
9998 +#include <linux/delay.h>
9999 +#include <linux/fb.h>
10000 +#include <linux/init.h>
10001 +#include <linux/console.h>
10002 +
10003 +#include <drm/drmP.h>
10004 +#include <drm/drm.h>
10005 +#include <drm/drm_crtc.h>
10006 +
10007 +#include "psb_drv.h"
10008 +#include "psb_intel_reg.h"
10009 +#include "psb_intel_drv.h"
10010 +#include "ttm/ttm_userobj_api.h"
10011 +#include "psb_fb.h"
10012 +#include "psb_sgx.h"
10013 +#include "psb_pvr_glue.h"
10014 +
10015 +static int fill_fb_bitfield(struct fb_var_screeninfo *var, int depth)
10016 +{
10017 +       switch (depth) {
10018 +       case 8:
10019 +               var->red.offset = 0;
10020 +               var->green.offset = 0;
10021 +               var->blue.offset = 0;
10022 +               var->red.length = 8;
10023 +               var->green.length = 8;
10024 +               var->blue.length = 8;
10025 +               var->transp.length = 0;
10026 +               var->transp.offset = 0;
10027 +               break;
10028 +       case 15:
10029 +               var->red.offset = 10;
10030 +               var->green.offset = 5;
10031 +               var->blue.offset = 0;
10032 +               var->red.length = 5;
10033 +               var->green.length = 5;
10034 +               var->blue.length = 5;
10035 +               var->transp.length = 1;
10036 +               var->transp.offset = 15;
10037 +               break;
10038 +       case 16:
10039 +               var->red.offset = 11;
10040 +               var->green.offset = 5;
10041 +               var->blue.offset = 0;
10042 +               var->red.length = 5;
10043 +               var->green.length = 6;
10044 +               var->blue.length = 5;
10045 +               var->transp.length = 0;
10046 +               var->transp.offset = 0;
10047 +               break;
10048 +       case 24:
10049 +               var->red.offset = 16;
10050 +               var->green.offset = 8;
10051 +               var->blue.offset = 0;
10052 +               var->red.length = 8;
10053 +               var->green.length = 8;
10054 +               var->blue.length = 8;
10055 +               var->transp.length = 0;
10056 +               var->transp.offset = 0;
10057 +               break;
10058 +       case 32:
10059 +               var->red.offset = 16;
10060 +               var->green.offset = 8;
10061 +               var->blue.offset = 0;
10062 +               var->red.length = 8;
10063 +               var->green.length = 8;
10064 +               var->blue.length = 8;
10065 +               var->transp.length = 8;
10066 +               var->transp.offset = 24;
10067 +               break;
10068 +       default:
10069 +               return -EINVAL;
10070 +       }
10071 +
10072 +       return 0;
10073 +}
10074 +
10075 +static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
10076 +static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
10077 +                                             struct drm_file *file_priv,
10078 +                                             unsigned int *handle);
10079 +
10080 +static const struct drm_framebuffer_funcs psb_fb_funcs = {
10081 +       .destroy = psb_user_framebuffer_destroy,
10082 +       .create_handle = psb_user_framebuffer_create_handle,
10083 +};
10084 +
10085 +struct psbfb_par {
10086 +       struct drm_device *dev;
10087 +       struct psb_framebuffer *psbfb;
10088 +
10089 +       int dpms_state;
10090 +
10091 +       int crtc_count;
10092 +       /* crtc currently bound to this */
10093 +       uint32_t crtc_ids[2];
10094 +};
10095 +
10096 +#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
10097 +
10098 +void *psbfb_vdc_reg(struct drm_device *dev)
10099 +{
10100 +       struct drm_psb_private *dev_priv;
10101 +       dev_priv = (struct drm_psb_private *) dev->dev_private;
10102 +       return dev_priv->vdc_reg;
10103 +}
10104 +EXPORT_SYMBOL(psbfb_vdc_reg);
10105 +
10106 +static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
10107 +                          unsigned blue, unsigned transp,
10108 +                          struct fb_info *info)
10109 +{
10110 +       struct psbfb_par *par = info->par;
10111 +       struct drm_framebuffer *fb = &par->psbfb->base;
10112 +       uint32_t v;
10113 +
10114 +       if (!fb)
10115 +               return -ENOMEM;
10116 +
10117 +       if (regno > 255)
10118 +               return 1;
10119 +
10120 +#if 0                          /* JB: not drop, check that this works */
10121 +       if (fb->bits_per_pixel == 8) {
10122 +               list_for_each_entry(crtc, &dev->mode_config.crtc_list,
10123 +                                   head) {
10124 +                       for (i = 0; i < par->crtc_count; i++)
10125 +                               if (crtc->base.id == par->crtc_ids[i])
10126 +                                       break;
10127 +
10128 +                       if (i == par->crtc_count)
10129 +                               continue;
10130 +
10131 +                       if (crtc->funcs->gamma_set)
10132 +                               crtc->funcs->gamma_set(crtc, red, green,
10133 +                                                      blue, regno);
10134 +               }
10135 +               return 0;
10136 +       }
10137 +#endif
10138 +
10139 +       red = CMAP_TOHW(red, info->var.red.length);
10140 +       blue = CMAP_TOHW(blue, info->var.blue.length);
10141 +       green = CMAP_TOHW(green, info->var.green.length);
10142 +       transp = CMAP_TOHW(transp, info->var.transp.length);
10143 +
10144 +       v = (red << info->var.red.offset) |
10145 +           (green << info->var.green.offset) |
10146 +           (blue << info->var.blue.offset) |
10147 +           (transp << info->var.transp.offset);
10148 +
10149 +       if (regno < 16) {
10150 +               switch (fb->bits_per_pixel) {
10151 +               case 16:
10152 +                       ((uint32_t *) info->pseudo_palette)[regno] = v;
10153 +                       break;
10154 +               case 24:
10155 +               case 32:
10156 +                       ((uint32_t *) info->pseudo_palette)[regno] = v;
10157 +                       break;
10158 +               }
10159 +       }
10160 +
10161 +       return 0;
10162 +}
10163 +
10164 +static struct drm_display_mode *psbfb_find_first_mode(struct
10165 +                                                     fb_var_screeninfo
10166 +                                                     *var,
10167 +                                                     struct fb_info *info,
10168 +                                                     struct drm_crtc
10169 +                                                     *crtc)
10170 +{
10171 +       struct psbfb_par *par = info->par;
10172 +       struct drm_device *dev = par->dev;
10173 +       struct drm_display_mode *drm_mode;
10174 +       struct drm_display_mode *preferred_mode = NULL;
10175 +       struct drm_display_mode *last_mode = NULL;
10176 +       struct drm_connector *connector;
10177 +       int found;
10178 +
10179 +       found = 0;
10180 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
10181 +                           head) {
10182 +               if (connector->encoder && connector->encoder->crtc == crtc) {
10183 +                       found = 1;
10184 +                       break;
10185 +               }
10186 +       }
10187 +
10188 +       /* found no connector, bail */
10189 +       if (!found)
10190 +               return NULL;
10191 +
10192 +       found = 0;
10193 +       list_for_each_entry(drm_mode, &connector->modes, head) {
10194 +               if (drm_mode->hdisplay == var->xres &&
10195 +                   drm_mode->vdisplay == var->yres
10196 +                   && drm_mode->clock != 0) {
10197 +                       found = 1;
10198 +                       last_mode = drm_mode;
10199 +                       if (IS_POULSBO(dev)) {
10200 +                               if (last_mode->type & DRM_MODE_TYPE_PREFERRED)
10201 +                                       preferred_mode = last_mode;
10202 +                       }
10203 +               }
10204 +       }
10205 +
10206 +       /* No mode matching mode found */
10207 +       if (!found)
10208 +               return NULL;
10209 +
10210 +       if (IS_POULSBO(dev)) {
10211 +               if (preferred_mode)
10212 +                       return preferred_mode;
10213 +               else
10214 +                       return last_mode;
10215 +       } else {
10216 +               return last_mode;
10217 +       }
10218 +}
10219 +
10220 +static int psbfb_check_var(struct fb_var_screeninfo *var,
10221 +                          struct fb_info *info)
10222 +{
10223 +       struct psbfb_par *par = info->par;
10224 +       struct psb_framebuffer *psbfb = par->psbfb;
10225 +       struct drm_device *dev = par->dev;
10226 +       int ret;
10227 +       int depth;
10228 +       int pitch;
10229 +       int bpp = var->bits_per_pixel;
10230 +
10231 +       if (!psbfb)
10232 +               return -ENOMEM;
10233 +
10234 +       if (!var->pixclock)
10235 +               return -EINVAL;
10236 +
10237 +       /* don't support virtuals for now */
10238 +       if (var->xres_virtual > var->xres)
10239 +               return -EINVAL;
10240 +
10241 +       if (var->yres_virtual > var->yres)
10242 +               return -EINVAL;
10243 +
10244 +       switch (bpp) {
10245 +#if 0                          /* JB: for now only support true color */
10246 +       case 8:
10247 +               depth = 8;
10248 +               break;
10249 +#endif
10250 +       case 16:
10251 +               depth = (var->green.length == 6) ? 16 : 15;
10252 +               break;
10253 +       case 24:                /* assume this is 32bpp / depth 24 */
10254 +               bpp = 32;
10255 +               /* fallthrough */
10256 +       case 32:
10257 +               depth = (var->transp.length > 0) ? 32 : 24;
10258 +               break;
10259 +       default:
10260 +               return -EINVAL;
10261 +       }
10262 +
10263 +       pitch = ((var->xres * ((bpp + 1) / 8)) + 0x3f) & ~0x3f;
10264 +
10265 +       /* Check that we can resize */
10266 +       if ((pitch * var->yres) > psbfb->size) {
10267 +#if 1
10268 +               /* Need to resize the fb object.
10269 +                * But the generic fbdev code doesn't really understand
10270 +                * that we can do this. So disable for now.
10271 +                */
10272 +               DRM_INFO("Can't support requested size, too big!\n");
10273 +               return -EINVAL;
10274 +#endif
10275 +       }
10276 +
10277 +       ret = fill_fb_bitfield(var, depth);
10278 +       if (ret)
10279 +               return ret;
10280 +
10281 +#if 1
10282 +       /* Here we walk the output mode list and look for modes. If we haven't
10283 +        * got it, then bail. Not very nice, so this is disabled.
10284 +        * In the set_par code, we create our mode based on the incoming
10285 +        * parameters. Nicer, but may not be desired by some.
10286 +        */
10287 +       {
10288 +               struct drm_crtc *crtc;
10289 +               int i;
10290 +
10291 +               list_for_each_entry(crtc, &dev->mode_config.crtc_list,
10292 +                                   head) {
10293 +                       struct psb_intel_crtc *psb_intel_crtc =
10294 +                           to_psb_intel_crtc(crtc);
10295 +
10296 +                       for (i = 0; i < par->crtc_count; i++)
10297 +                               if (crtc->base.id == par->crtc_ids[i])
10298 +                                       break;
10299 +
10300 +                       if (i == par->crtc_count)
10301 +                               continue;
10302 +
10303 +                       if (psb_intel_crtc->mode_set.num_connectors == 0)
10304 +                               continue;
10305 +
10306 +                       if (!psbfb_find_first_mode(&info->var, info, crtc))
10307 +                               return -EINVAL;
10308 +               }
10309 +       }
10310 +#else
10311 +       (void) i;
10312 +       (void) dev;             /* silence warnings */
10313 +       (void) crtc;
10314 +       (void) drm_mode;
10315 +       (void) connector;
10316 +#endif
10317 +
10318 +       return 0;
10319 +}
10320 +
10321 +/* this will let fbcon do the mode init */
10322 +static int psbfb_set_par(struct fb_info *info)
10323 +{
10324 +       struct psbfb_par *par = info->par;
10325 +       struct psb_framebuffer *psbfb = par->psbfb;
10326 +       struct drm_framebuffer *fb = &psbfb->base;
10327 +       struct drm_device *dev = par->dev;
10328 +       struct fb_var_screeninfo *var = &info->var;
10329 +       /* struct drm_psb_private *dev_priv = dev->dev_private; */
10330 +       struct drm_display_mode *drm_mode;
10331 +       int pitch;
10332 +       int depth;
10333 +       int bpp = var->bits_per_pixel;
10334 +
10335 +       if (!fb)
10336 +               return -ENOMEM;
10337 +
10338 +       switch (bpp) {
10339 +       case 8:
10340 +               depth = 8;
10341 +               break;
10342 +       case 16:
10343 +               depth = (var->green.length == 6) ? 16 : 15;
10344 +               break;
10345 +       case 24:                /* assume this is 32bpp / depth 24 */
10346 +               bpp = 32;
10347 +               /* fallthrough */
10348 +       case 32:
10349 +               depth = (var->transp.length > 0) ? 32 : 24;
10350 +               break;
10351 +       default:
10352 +               DRM_ERROR("Illegal BPP\n");
10353 +               return -EINVAL;
10354 +       }
10355 +
10356 +       pitch = ((var->xres * ((bpp + 1) / 8)) + 0x3f) & ~0x3f;
10357 +
10358 +       if ((pitch * var->yres) > (psbfb->size)) {
10359 +#if 1
10360 +               /* Need to resize the fb object.
10361 +                * But the generic fbdev code doesn't really understand
10362 +                * that we can do this. So disable for now.
10363 +                */
10364 +               DRM_INFO("Can't support requested size, too big!\n");
10365 +               return -EINVAL;
10366 +#endif
10367 +       }
10368 +
10369 +       psbfb->offset = 0;
10370 +       fb->width = var->xres;
10371 +       fb->height = var->yres;
10372 +       fb->bits_per_pixel = bpp;
10373 +       fb->pitch = pitch;
10374 +       fb->depth = depth;
10375 +
10376 +       info->fix.line_length = psbfb->base.pitch;
10377 +       info->fix.visual =
10378 +           (psbfb->base.depth ==
10379 +            8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
10380 +
10381 +       /* some fbdev's apps don't want these to change */
10382 +       info->fix.smem_start = dev->mode_config.fb_base + psbfb->offset;
10383 +
10384 +#if 0
10385 +       /* relates to resize - disable */
10386 +       info->fix.smem_len = info->fix.line_length * var->yres;
10387 +       info->screen_size = info->fix.smem_len; /* ??? */
10388 +#endif
10389 +
10390 +       /* Should we walk the output's modelist or just create our own ???
10391 +        * For now, we create and destroy a mode based on the incoming
10392 +        * parameters. But there's commented out code below which scans
10393 +        * the output list too.
10394 +        */
10395 +#if 1
10396 +       /* This code is now in the for loop futher down. */
10397 +#endif
10398 +
10399 +       {
10400 +               struct drm_crtc *crtc;
10401 +               int ret;
10402 +               int i;
10403 +
10404 +               list_for_each_entry(crtc, &dev->mode_config.crtc_list,
10405 +                                   head) {
10406 +                       struct psb_intel_crtc *psb_intel_crtc =
10407 +                           to_psb_intel_crtc(crtc);
10408 +
10409 +                       for (i = 0; i < par->crtc_count; i++)
10410 +                               if (crtc->base.id == par->crtc_ids[i])
10411 +                                       break;
10412 +
10413 +                       if (i == par->crtc_count)
10414 +                               continue;
10415 +
10416 +                       if (psb_intel_crtc->mode_set.num_connectors == 0)
10417 +                               continue;
10418 +
10419 +#if 1
10420 +                       drm_mode =
10421 +                           psbfb_find_first_mode(&info->var, info, crtc);
10422 +                       if (!drm_mode)
10423 +                               DRM_ERROR("No matching mode found\n");
10424 +                       psb_intel_crtc->mode_set.mode = drm_mode;
10425 +#endif
10426 +
10427 +#if 0                          /* FIXME: TH */
10428 +                       if (crtc->fb == psb_intel_crtc->mode_set.fb) {
10429 +#endif
10430 +                               DRM_DEBUG
10431 +                                   ("setting mode on crtc %p with id %u\n",
10432 +                                    crtc, crtc->base.id);
10433 +                               ret =
10434 +                                   crtc->funcs->
10435 +                                   set_config(&psb_intel_crtc->mode_set);
10436 +                               if (ret) {
10437 +                                       DRM_ERROR("Failed setting mode\n");
10438 +                                       return ret;
10439 +                               }
10440 +#if 0
10441 +                       }
10442 +#endif
10443 +               }
10444 +               DRM_DEBUG("Set par returned OK.\n");
10445 +               return 0;
10446 +       }
10447 +
10448 +       return 0;
10449 +}
10450 +#if 0
10451 +static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
10452 +                          unsigned size)
10453 +{
10454 +       int ret = 0;
10455 +       int i;
10456 +       unsigned submit_size;
10457 +
10458 +       while (size > 0) {
10459 +               submit_size = (size < 0x60) ? size : 0x60;
10460 +               size -= submit_size;
10461 +               ret = psb_2d_wait_available(dev_priv, submit_size);
10462 +               if (ret)
10463 +                       return ret;
10464 +
10465 +               submit_size <<= 2;
10466 +               for (i = 0; i < submit_size; i += 4)
10467 +                       PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
10468 +
10469 +               (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
10470 +       }
10471 +       return 0;
10472 +}
10473 +
10474 +static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv,
10475 +                                uint32_t dst_offset, uint32_t dst_stride,
10476 +                                uint32_t dst_format, uint16_t dst_x,
10477 +                                uint16_t dst_y, uint16_t size_x,
10478 +                                uint16_t size_y, uint32_t fill)
10479 +{
10480 +       uint32_t buffer[10];
10481 +       uint32_t *buf;
10482 +
10483 +       buf = buffer;
10484 +
10485 +       *buf++ = PSB_2D_FENCE_BH;
10486 +
10487 +       *buf++ =
10488 +           PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
10489 +                                              PSB_2D_DST_STRIDE_SHIFT);
10490 +       *buf++ = dst_offset;
10491 +
10492 +       *buf++ =
10493 +           PSB_2D_BLIT_BH |
10494 +           PSB_2D_ROT_NONE |
10495 +           PSB_2D_COPYORDER_TL2BR |
10496 +           PSB_2D_DSTCK_DISABLE |
10497 +           PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY;
10498 +
10499 +       *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT;
10500 +       *buf++ =
10501 +           (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
10502 +                                                 PSB_2D_DST_YSTART_SHIFT);
10503 +       *buf++ =
10504 +           (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
10505 +                                                 PSB_2D_DST_YSIZE_SHIFT);
10506 +       *buf++ = PSB_2D_FLUSH_BH;
10507 +
10508 +       return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
10509 +}
10510 +
10511 +static void psbfb_fillrect_accel(struct fb_info *info,
10512 +                                const struct fb_fillrect *r)
10513 +{
10514 +       struct psbfb_par *par = info->par;
10515 +       struct psb_framebuffer *psbfb = par->psbfb;
10516 +       struct drm_framebuffer *fb = &psbfb->base;
10517 +       struct drm_psb_private *dev_priv = par->dev->dev_private;
10518 +       uint32_t offset;
10519 +       uint32_t stride;
10520 +       uint32_t format;
10521 +
10522 +       if (!fb)
10523 +               return;
10524 +
10525 +       offset = psbfb->offset;
10526 +       stride = fb->pitch;
10527 +
10528 +       switch (fb->depth) {
10529 +       case 8:
10530 +               format = PSB_2D_DST_332RGB;
10531 +               break;
10532 +       case 15:
10533 +               format = PSB_2D_DST_555RGB;
10534 +               break;
10535 +       case 16:
10536 +               format = PSB_2D_DST_565RGB;
10537 +               break;
10538 +       case 24:
10539 +       case 32:
10540 +               /* this is wrong but since we don't do blending its okay */
10541 +               format = PSB_2D_DST_8888ARGB;
10542 +               break;
10543 +       default:
10544 +               /* software fallback */
10545 +               cfb_fillrect(info, r);
10546 +               return;
10547 +       }
10548 +
10549 +       psb_accel_2d_fillrect(dev_priv,
10550 +                             offset, stride, format,
10551 +                             r->dx, r->dy, r->width, r->height, r->color);
10552 +}
10553 +
10554 +static void psbfb_fillrect(struct fb_info *info,
10555 +                          const struct fb_fillrect *rect)
10556 +{
10557 +       struct psbfb_par *par = info->par;
10558 +       struct drm_device *dev = par->dev;
10559 +       struct drm_psb_private *dev_priv = dev->dev_private;
10560 +
10561 +       if (unlikely(info->state != FBINFO_STATE_RUNNING))
10562 +               return;
10563 +
10564 +       if (info->flags & FBINFO_HWACCEL_DISABLED)
10565 +               return cfb_fillrect(info, rect);
10566 +       /*
10567 +        * psbfb_fillrect is atomic so need to do instantaneous check of
10568 +        * power on
10569 +        */
10570 +       if (powermgmt_is_suspend_in_progress(PSB_GRAPHICS_ISLAND) ||
10571 +           powermgmt_is_resume_in_progress(PSB_GRAPHICS_ISLAND) ||
10572 +           !powermgmt_is_hw_on(dev->pdev, PSB_GRAPHICS_ISLAND))
10573 +               return cfb_fillrect(info, rect);
10574 +
10575 +       if (psb_2d_trylock(dev_priv)) {
10576 +               psbfb_fillrect_accel(info, rect);
10577 +               psb_2d_unlock(dev_priv);
10578 +               schedule_delayed_work(&dev_priv->scheduler.wq, 1);
10579 +       } else
10580 +               cfb_fillrect(info, rect);
10581 +}
10582 +
10583 +uint32_t psb_accel_2d_copy_direction(int xdir, int ydir)
10584 +{
10585 +       if (xdir < 0)
10586 +               return (ydir <
10587 +                        0) ? PSB_2D_COPYORDER_BR2TL :
10588 +                       PSB_2D_COPYORDER_TR2BL;
10589 +       else
10590 +               return (ydir <
10591 +                        0) ? PSB_2D_COPYORDER_BL2TR :
10592 +                       PSB_2D_COPYORDER_TL2BR;
10593 +}
10594 +
10595 +/*
10596 + * @srcOffset in bytes
10597 + * @srcStride in bytes
10598 + * @srcFormat psb 2D format defines
10599 + * @dstOffset in bytes
10600 + * @dstStride in bytes
10601 + * @dstFormat psb 2D format defines
10602 + * @srcX offset in pixels
10603 + * @srcY offset in pixels
10604 + * @dstX offset in pixels
10605 + * @dstY offset in pixels
10606 + * @sizeX of the copied area
10607 + * @sizeY of the copied area
10608 + */
10609 +static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
10610 +                            uint32_t src_offset, uint32_t src_stride,
10611 +                            uint32_t src_format, uint32_t dst_offset,
10612 +                            uint32_t dst_stride, uint32_t dst_format,
10613 +                            uint16_t src_x, uint16_t src_y,
10614 +                            uint16_t dst_x, uint16_t dst_y,
10615 +                            uint16_t size_x, uint16_t size_y)
10616 +{
10617 +       uint32_t blit_cmd;
10618 +       uint32_t buffer[10];
10619 +       uint32_t *buf;
10620 +       uint32_t direction;
10621 +
10622 +       buf = buffer;
10623 +
10624 +       direction =
10625 +           psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
10626 +
10627 +       if (direction == PSB_2D_COPYORDER_BR2TL ||
10628 +           direction == PSB_2D_COPYORDER_TR2BL) {
10629 +               src_x += size_x - 1;
10630 +               dst_x += size_x - 1;
10631 +       }
10632 +       if (direction == PSB_2D_COPYORDER_BR2TL ||
10633 +           direction == PSB_2D_COPYORDER_BL2TR) {
10634 +               src_y += size_y - 1;
10635 +               dst_y += size_y - 1;
10636 +       }
10637 +
10638 +       blit_cmd =
10639 +           PSB_2D_BLIT_BH |
10640 +           PSB_2D_ROT_NONE |
10641 +           PSB_2D_DSTCK_DISABLE |
10642 +           PSB_2D_SRCCK_DISABLE |
10643 +           PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
10644 +
10645 +       *buf++ = PSB_2D_FENCE_BH;
10646 +       *buf++ =
10647 +           PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
10648 +                                              PSB_2D_DST_STRIDE_SHIFT);
10649 +       *buf++ = dst_offset;
10650 +       *buf++ =
10651 +           PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
10652 +                                              PSB_2D_SRC_STRIDE_SHIFT);
10653 +       *buf++ = src_offset;
10654 +       *buf++ =
10655 +           PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) |
10656 +           (src_y << PSB_2D_SRCOFF_YSTART_SHIFT);
10657 +       *buf++ = blit_cmd;
10658 +       *buf++ =
10659 +           (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
10660 +                                                 PSB_2D_DST_YSTART_SHIFT);
10661 +       *buf++ =
10662 +           (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
10663 +                                                 PSB_2D_DST_YSIZE_SHIFT);
10664 +       *buf++ = PSB_2D_FLUSH_BH;
10665 +
10666 +       return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
10667 +}
10668 +
10669 +static void psbfb_copyarea_accel(struct fb_info *info,
10670 +                                const struct fb_copyarea *a)
10671 +{
10672 +       struct psbfb_par *par = info->par;
10673 +       struct psb_framebuffer *psbfb = par->psbfb;
10674 +       struct drm_framebuffer *fb = &psbfb->base;
10675 +       struct drm_psb_private *dev_priv = par->dev->dev_private;
10676 +       uint32_t offset;
10677 +       uint32_t stride;
10678 +       uint32_t src_format;
10679 +       uint32_t dst_format;
10680 +
10681 +       if (!fb)
10682 +               return;
10683 +
10684 +       offset = psbfb->offset;
10685 +       stride = fb->pitch;
10686 +
10687 +       switch (fb->depth) {
10688 +       case 8:
10689 +               src_format = PSB_2D_SRC_332RGB;
10690 +               dst_format = PSB_2D_DST_332RGB;
10691 +               break;
10692 +       case 15:
10693 +               src_format = PSB_2D_SRC_555RGB;
10694 +               dst_format = PSB_2D_DST_555RGB;
10695 +               break;
10696 +       case 16:
10697 +               src_format = PSB_2D_SRC_565RGB;
10698 +               dst_format = PSB_2D_DST_565RGB;
10699 +               break;
10700 +       case 24:
10701 +       case 32:
10702 +               /* this is wrong but since we don't do blending its okay */
10703 +               src_format = PSB_2D_SRC_8888ARGB;
10704 +               dst_format = PSB_2D_DST_8888ARGB;
10705 +               break;
10706 +       default:
10707 +               /* software fallback */
10708 +               cfb_copyarea(info, a);
10709 +               return;
10710 +       }
10711 +
10712 +       psb_accel_2d_copy(dev_priv,
10713 +                         offset, stride, src_format,
10714 +                         offset, stride, dst_format,
10715 +                         a->sx, a->sy, a->dx, a->dy, a->width, a->height);
10716 +}
10717 +
10718 +static void psbfb_copyarea(struct fb_info *info,
10719 +                          const struct fb_copyarea *region)
10720 +{
10721 +       struct psbfb_par *par = info->par;
10722 +       struct drm_device *dev = par->dev;
10723 +       struct drm_psb_private *dev_priv = dev->dev_private;
10724 +
10725 +       if (unlikely(info->state != FBINFO_STATE_RUNNING))
10726 +               return;
10727 +
10728 +       if (info->flags & FBINFO_HWACCEL_DISABLED)
10729 +               return cfb_copyarea(info, region);
10730 +       /*
10731 +        * psbfb_copyarea is atomic so need to do instantaneous check of
10732 +        * power on
10733 +        */
10734 +       if (powermgmt_is_suspend_in_progress(PSB_GRAPHICS_ISLAND) ||
10735 +           powermgmt_is_resume_in_progress(PSB_GRAPHICS_ISLAND) ||
10736 +           !powermgmt_is_hw_on(dev->pdev, PSB_GRAPHICS_ISLAND))
10737 +               return cfb_copyarea(info, region);
10738 +
10739 +       if (psb_2d_trylock(dev_priv)) {
10740 +               psbfb_copyarea_accel(info, region);
10741 +               psb_2d_unlock(dev_priv);
10742 +               schedule_delayed_work(&dev_priv->scheduler.wq, 1);
10743 +       } else
10744 +               cfb_copyarea(info, region);
10745 +}
10746 +#endif
10747 +void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
10748 +{
10749 +       if (unlikely(info->state != FBINFO_STATE_RUNNING))
10750 +               return;
10751 +
10752 +       cfb_imageblit(info, image);
10753 +}
10754 +
10755 +static void psbfb_onoff(struct fb_info *info, int dpms_mode)
10756 +{
10757 +       struct psbfb_par *par = info->par;
10758 +       struct drm_device *dev = par->dev;
10759 +       struct drm_crtc *crtc;
10760 +       struct drm_encoder *encoder;
10761 +       int i;
10762 +
10763 +       /*
10764 +        * For each CRTC in this fb, find all associated encoders
10765 +        * and turn them off, then turn off the CRTC.
10766 +        */
10767 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
10768 +               struct drm_crtc_helper_funcs *crtc_funcs =
10769 +                   crtc->helper_private;
10770 +
10771 +               for (i = 0; i < par->crtc_count; i++)
10772 +                       if (crtc->base.id == par->crtc_ids[i])
10773 +                               break;
10774 +
10775 +               if (i == par->crtc_count)
10776 +                       continue;
10777 +
10778 +               if (dpms_mode == DRM_MODE_DPMS_ON)
10779 +                       crtc_funcs->dpms(crtc, dpms_mode);
10780 +
10781 +               /* Found a CRTC on this fb, now find encoders */
10782 +               list_for_each_entry(encoder,
10783 +                                   &dev->mode_config.encoder_list, head) {
10784 +                       if (encoder->crtc == crtc) {
10785 +                               struct drm_encoder_helper_funcs
10786 +                               *encoder_funcs;
10787 +                               encoder_funcs = encoder->helper_private;
10788 +                               encoder_funcs->dpms(encoder, dpms_mode);
10789 +                       }
10790 +               }
10791 +
10792 +               if (dpms_mode == DRM_MODE_DPMS_OFF)
10793 +                       crtc_funcs->dpms(crtc, dpms_mode);
10794 +       }
10795 +}
10796 +
10797 +static int psbfb_blank(int blank_mode, struct fb_info *info)
10798 +{
10799 +       struct psbfb_par *par = info->par;
10800 +
10801 +       par->dpms_state = blank_mode;
10802 +       PSB_DEBUG_PM("psbfb_blank \n");
10803 +       switch (blank_mode) {
10804 +       case FB_BLANK_UNBLANK:
10805 +               psbfb_onoff(info, DRM_MODE_DPMS_ON);
10806 +               break;
10807 +       case FB_BLANK_NORMAL:
10808 +               psbfb_onoff(info, DRM_MODE_DPMS_STANDBY);
10809 +               break;
10810 +       case FB_BLANK_HSYNC_SUSPEND:
10811 +               psbfb_onoff(info, DRM_MODE_DPMS_STANDBY);
10812 +               break;
10813 +       case FB_BLANK_VSYNC_SUSPEND:
10814 +               psbfb_onoff(info, DRM_MODE_DPMS_SUSPEND);
10815 +               break;
10816 +       case FB_BLANK_POWERDOWN:
10817 +               psbfb_onoff(info, DRM_MODE_DPMS_OFF);
10818 +               break;
10819 +       }
10820 +
10821 +       return 0;
10822 +}
10823 +
10824 +
10825 +static int psbfb_kms_off(struct drm_device *dev, int suspend)
10826 +{
10827 +       struct drm_framebuffer *fb = 0;
10828 +       DRM_DEBUG("psbfb_kms_off_ioctl\n");
10829 +
10830 +       mutex_lock(&dev->mode_config.mutex);
10831 +       list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
10832 +               struct fb_info *info = fb->fbdev;
10833 +
10834 +               if (suspend) {
10835 +                       fb_set_suspend(info, 1);
10836 +                       psbfb_blank(FB_BLANK_POWERDOWN, info);
10837 +               }
10838 +       }
10839 +       mutex_unlock(&dev->mode_config.mutex);
10840 +       return 0;
10841 +}
10842 +
10843 +int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
10844 +                       struct drm_file *file_priv)
10845 +{
10846 +       int ret;
10847 +
10848 +       if (drm_psb_no_fb)
10849 +               return 0;
10850 +       acquire_console_sem();
10851 +       ret = psbfb_kms_off(dev, 0);
10852 +       release_console_sem();
10853 +
10854 +       return ret;
10855 +}
10856 +
10857 +static int psbfb_kms_on(struct drm_device *dev, int resume)
10858 +{
10859 +       struct drm_framebuffer *fb = 0;
10860 +
10861 +       DRM_DEBUG("psbfb_kms_on_ioctl\n");
10862 +
10863 +       mutex_lock(&dev->mode_config.mutex);
10864 +       list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
10865 +               struct fb_info *info = fb->fbdev;
10866 +
10867 +               if (resume) {
10868 +                       fb_set_suspend(info, 0);
10869 +                       psbfb_blank(FB_BLANK_UNBLANK, info);
10870 +               }
10871 +
10872 +       }
10873 +       mutex_unlock(&dev->mode_config.mutex);
10874 +
10875 +       return 0;
10876 +}
10877 +
10878 +int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
10879 +                      struct drm_file *file_priv)
10880 +{
10881 +       int ret;
10882 +
10883 +       if (drm_psb_no_fb)
10884 +               return 0;
10885 +       acquire_console_sem();
10886 +       ret = psbfb_kms_on(dev, 0);
10887 +       release_console_sem();
10888 +       drm_helper_disable_unused_functions(dev);
10889 +       return ret;
10890 +}
10891 +
10892 +void psbfb_suspend(struct drm_device *dev)
10893 +{
10894 +       acquire_console_sem();
10895 +       psbfb_kms_off(dev, 1);
10896 +       release_console_sem();
10897 +}
10898 +
10899 +void psbfb_resume(struct drm_device *dev)
10900 +{
10901 +       acquire_console_sem();
10902 +       psbfb_kms_on(dev, 1);
10903 +       release_console_sem();
10904 +       drm_helper_disable_unused_functions(dev);
10905 +}
10906 +
10907 +static int psbfb_vm_fault(struct vm_area_struct * vma, struct vm_fault * vmf)
10908 +{
10909 +       int page_num = 0;
10910 +       int i;
10911 +       unsigned long address = 0;
10912 +       int ret;
10913 +       unsigned long pfn;
10914 +       struct psb_framebuffer *psbfb = (struct psb_framebuffer *)vma->vm_private_data;
10915 +       struct drm_device * dev = psbfb->base.dev;
10916 +        struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
10917 +       struct psb_gtt *pg = dev_priv->pg;
10918 +       unsigned long phys_addr = (unsigned long)pg->stolen_base;;
10919 +
10920 +       page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
10921 +
10922 +       address = (unsigned long)vmf->virtual_address;
10923 +
10924 +       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
10925 +
10926 +       for(i=0; i<page_num; i++) {
10927 +               pfn = (phys_addr >> PAGE_SHIFT); //phys_to_pfn(phys_addr);
10928 +
10929 +               ret = vm_insert_mixed(vma, address, pfn);
10930 +               if(unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
10931 +                       break;
10932 +               else if(unlikely(ret != 0)) {
10933 +                       ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
10934 +                       return ret;
10935 +               }
10936 +
10937 +               address += PAGE_SIZE;
10938 +               phys_addr += PAGE_SIZE;
10939 +       }
10940 +       
10941 +       return VM_FAULT_NOPAGE;
10942 +}
10943 +
10944 +static void psbfb_vm_open(struct vm_area_struct * vma)
10945 +{
10946 +       DRM_DEBUG("vm_open\n");
10947 +}
10948 +
10949 +static void psbfb_vm_close(struct vm_area_struct * vma)
10950 +{
10951 +       DRM_DEBUG("vm_close\n");
10952 +}
10953 +
10954 +static struct vm_operations_struct psbfb_vm_ops = {
10955 +       .fault  = psbfb_vm_fault,
10956 +       .open   = psbfb_vm_open,
10957 +       .close  = psbfb_vm_close
10958 +};
10959 +
10960 +static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
10961 +{
10962 +       struct psbfb_par *par = info->par;
10963 +       struct psb_framebuffer *psbfb = par->psbfb;
10964 +       char * fb_screen_base = NULL;
10965 +       struct drm_device * dev = psbfb->base.dev;
10966 +       struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
10967 +       struct psb_gtt *pg = dev_priv->pg;
10968 +
10969 +       if (vma->vm_pgoff != 0)
10970 +               return -EINVAL;
10971 +       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
10972 +               return -EINVAL;
10973 +
10974 +       if (!psbfb->addr_space)
10975 +               psbfb->addr_space = vma->vm_file->f_mapping;
10976 +
10977 +       fb_screen_base = (char *)info->screen_base;
10978 +
10979 +       DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n", vma->vm_pgoff, fb_screen_base, pg->vram_addr);
10980 +
10981 +       /*if using stolen memory, */
10982 +       if(fb_screen_base == pg->vram_addr) {
10983 +               vma->vm_ops = &psbfb_vm_ops;
10984 +               vma->vm_private_data = (void *)psbfb;
10985 +               vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
10986 +       } else {
10987 +       /*using IMG meminfo, can I use pvrmmap to map it?*/
10988 +       
10989 +
10990 +       }
10991 +
10992 +       return 0;
10993 +}
10994 +
10995 +
10996 +static struct fb_ops psbfb_ops = {
10997 +       .owner = THIS_MODULE,
10998 +       .fb_check_var = psbfb_check_var,
10999 +       .fb_set_par = psbfb_set_par,
11000 +       .fb_setcolreg = psbfb_setcolreg,
11001 +       .fb_fillrect = cfb_fillrect,
11002 +       .fb_copyarea = cfb_copyarea,
11003 +       .fb_imageblit = cfb_imageblit,
11004 +       .fb_mmap = psbfb_mmap,
11005 +       .fb_blank = psbfb_blank,
11006 +};
11007 +
11008 +static struct drm_mode_set panic_mode;
11009 +
11010 +int psbfb_panic(struct notifier_block *n, unsigned long ununsed,
11011 +               void *panic_str)
11012 +{
11013 +       DRM_ERROR("panic occurred, switching back to text console\n");
11014 +       drm_crtc_helper_set_config(&panic_mode);
11015 +
11016 +       return 0;
11017 +}
11018 +EXPORT_SYMBOL(psbfb_panic);
11019 +
11020 +static struct notifier_block paniced = {
11021 +       .notifier_call = psbfb_panic,
11022 +};
11023 +
11024 +
11025 +static struct drm_framebuffer *psb_framebuffer_create
11026 +                       (struct drm_device *dev, struct drm_mode_fb_cmd *r,
11027 +                        void *mm_private)
11028 +{
11029 +       struct psb_framebuffer *fb;
11030 +       int ret;
11031 +
11032 +       fb = kzalloc(sizeof(*fb), GFP_KERNEL);
11033 +       if (!fb)
11034 +               return NULL;
11035 +
11036 +       ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
11037 +
11038 +       if (ret)
11039 +               goto err;
11040 +
11041 +       drm_helper_mode_fill_fb_struct(&fb->base, r);
11042 +
11043 +       fb->pvrBO = mm_private;
11044 +
11045 +       return &fb->base;
11046 +
11047 +err:
11048 +       kfree(fb);
11049 +       return NULL;
11050 +}
11051 +
11052 +static struct drm_framebuffer *psb_user_framebuffer_create
11053 +                       (struct drm_device *dev, struct drm_file *filp,
11054 +                        struct drm_mode_fb_cmd *r)
11055 +{
11056 +       struct psb_framebuffer *psbfb;
11057 +       struct drm_framebuffer *fb;
11058 +       struct fb_info *info;
11059 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
11060 +       IMG_HANDLE hKernelMemInfo = (IMG_HANDLE)r->handle;
11061 +       struct drm_psb_private *dev_priv
11062 +               = (struct drm_psb_private *) dev->dev_private;
11063 +       struct psb_gtt *pg = dev_priv->pg;
11064 +       int ret;
11065 +       uint32_t offset;
11066 +       uint64_t size;
11067 +
11068 +       ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
11069 +       if (ret) {
11070 +               DRM_ERROR("Cannot get meminfo for handle %lx\n",
11071 +                         (IMG_UINT32)hKernelMemInfo);
11072 +
11073 +               return NULL;
11074 +       }
11075 +
11076 +       DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
11077 +                 (IMG_UINT32)hKernelMemInfo);
11078 +
11079 +       /* JB: TODO not drop, make smarter */
11080 +       size = psKernelMemInfo->ui32AllocSize;
11081 +       if (size < r->height * r->pitch)
11082 +               return NULL;
11083 +
11084 +       /* JB: TODO not drop, refcount buffer */
11085 +       /* return psb_framebuffer_create(dev, r, bo); */
11086 +
11087 +       fb = psb_framebuffer_create(dev, r, (void *)psKernelMemInfo);
11088 +       if (!fb) {
11089 +               DRM_ERROR("failed to allocate fb.\n");
11090 +               return NULL;
11091 +       }
11092 +
11093 +       psbfb = to_psb_fb(fb);
11094 +       psbfb->size = size;
11095 +       psbfb->hKernelMemInfo = hKernelMemInfo;
11096 +
11097 +       DRM_DEBUG("Mapping to gtt..., KernelMemInfo %p\n", psKernelMemInfo);
11098 +
11099 +       /*if not VRAM, map it into tt aperture*/
11100 +       if (psKernelMemInfo->pvLinAddrKM != pg->vram_addr) {
11101 +               ret = psb_gtt_map_meminfo(dev, hKernelMemInfo, &offset);
11102 +               if (ret) {
11103 +                       DRM_ERROR("map meminfo for %lx failed\n",
11104 +                                 (IMG_UINT32)hKernelMemInfo);
11105 +                       return NULL;
11106 +               }
11107 +               psbfb->offset = (offset << PAGE_SHIFT);
11108 +       } else {
11109 +               psbfb->offset = 0;
11110 +       }
11111 +
11112 +       info = framebuffer_alloc(sizeof(struct psbfb_par), &dev->pdev->dev);
11113 +       if (!info)
11114 +               return NULL;
11115 +
11116 +       strcpy(info->fix.id, "psbfb");
11117 +       info->fix.type = FB_TYPE_PACKED_PIXELS;
11118 +       info->fix.visual = FB_VISUAL_TRUECOLOR;
11119 +       info->fix.type_aux = 0;
11120 +       info->fix.xpanstep = 1; /* doing it in hw */
11121 +       info->fix.ypanstep = 1; /* doing it in hw */
11122 +       info->fix.ywrapstep = 0;
11123 +       info->fix.accel = FB_ACCEL_I830;
11124 +       info->fix.type_aux = 0;
11125 +
11126 +       info->flags = FBINFO_DEFAULT;
11127 +
11128 +       info->fbops = &psbfb_ops;
11129 +
11130 +       info->fix.line_length = fb->pitch;
11131 +       info->fix.smem_start = dev->mode_config.fb_base;
11132 +       info->fix.smem_len = size;
11133 +
11134 +       info->flags = FBINFO_DEFAULT;
11135 +
11136 +       info->screen_base = psKernelMemInfo->pvLinAddrKM;
11137 +       info->screen_size = size;
11138 +
11139 +       /* it is called for kms flip, the back buffer has been rendered,
11140 +        * then we should not clear it*/
11141 +#if 0
11142 +       if (is_iomem)
11143 +               memset_io(info->screen_base, 0, size);
11144 +       else
11145 +               memset(info->screen_base, 0, size);
11146 +#endif
11147 +       info->pseudo_palette = fb->pseudo_palette;
11148 +       info->var.xres_virtual = fb->width;
11149 +       info->var.yres_virtual = fb->height;
11150 +       info->var.bits_per_pixel = fb->bits_per_pixel;
11151 +       info->var.xoffset = 0;
11152 +       info->var.yoffset = 0;
11153 +       info->var.activate = FB_ACTIVATE_NOW;
11154 +       info->var.height = -1;
11155 +       info->var.width = -1;
11156 +
11157 +       info->var.xres = r->width;
11158 +       info->var.yres = r->height;
11159 +
11160 +       info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
11161 +       info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
11162 +
11163 +       info->pixmap.size = 64 * 1024;
11164 +       info->pixmap.buf_align = 8;
11165 +       info->pixmap.access_align = 32;
11166 +       info->pixmap.flags = FB_PIXMAP_SYSTEM;
11167 +       info->pixmap.scan_align = 1;
11168 +
11169 +       fill_fb_bitfield(&info->var, fb->depth);
11170 +
11171 +       register_framebuffer(info);
11172 +
11173 +       fb->fbdev = info;
11174 +
11175 +       return fb;
11176 +}
11177 +
11178 +int psbfb_create(struct drm_device *dev, uint32_t fb_width,
11179 +                uint32_t fb_height, uint32_t surface_width,
11180 +                uint32_t surface_height, struct psb_framebuffer **psbfb_p)
11181 +{
11182 +       struct fb_info *info;
11183 +       struct psbfb_par *par;
11184 +       struct drm_framebuffer *fb;
11185 +       struct psb_framebuffer *psbfb;
11186 +       struct drm_mode_fb_cmd mode_cmd;
11187 +       struct device *device = &dev->pdev->dev;
11188 +       struct drm_psb_private *dev_priv
11189 +                       = (struct drm_psb_private *)dev->dev_private;
11190 +       struct psb_gtt *pg = dev_priv->pg;
11191 +       int size, aligned_size, ret;
11192 +
11193 +       mode_cmd.width = surface_width; /* crtc->desired_mode->hdisplay; */
11194 +       mode_cmd.height = surface_height; /* crtc->desired_mode->vdisplay; */
11195 +
11196 +       mode_cmd.bpp = 32;
11197 +       //HW requires pitch to be 64 byte aligned
11198 +       mode_cmd.pitch =  ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
11199 +       mode_cmd.depth = 24;
11200 +
11201 +       size = mode_cmd.pitch * mode_cmd.height;
11202 +       aligned_size = ALIGN(size, PAGE_SIZE);
11203 +
11204 +       mutex_lock(&dev->struct_mutex);
11205 +       fb = psb_framebuffer_create(dev, &mode_cmd, NULL);
11206 +       if (!fb) {
11207 +
11208 +               DRM_ERROR("failed to allocate fb.\n");
11209 +               ret = -ENOMEM;
11210 +               goto out_err0;
11211 +       }
11212 +       psbfb = to_psb_fb(fb);
11213 +       psbfb->size = size;
11214 +
11215 +       list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
11216 +       info = framebuffer_alloc(sizeof(struct psbfb_par), device);
11217 +       if (!info) {
11218 +               ret = -ENOMEM;
11219 +               goto out_err1;
11220 +       }
11221 +
11222 +       par = info->par;
11223 +       par->psbfb = psbfb;
11224 +
11225 +       strcpy(info->fix.id, "psbfb");
11226 +       info->fix.type = FB_TYPE_PACKED_PIXELS;
11227 +       info->fix.visual = FB_VISUAL_TRUECOLOR;
11228 +       info->fix.type_aux = 0;
11229 +       info->fix.xpanstep = 1; /* doing it in hw */
11230 +       info->fix.ypanstep = 1; /* doing it in hw */
11231 +       info->fix.ywrapstep = 0;
11232 +       info->fix.accel = FB_ACCEL_I830;
11233 +       info->fix.type_aux = 0;
11234 +
11235 +       info->flags = FBINFO_DEFAULT;
11236 +
11237 +       info->fbops = &psbfb_ops;
11238 +
11239 +       info->fix.line_length = fb->pitch;
11240 +       info->fix.smem_start = dev->mode_config.fb_base;
11241 +       info->fix.smem_len = size;
11242 +       info->flags = FBINFO_DEFAULT;
11243 +       info->screen_base = (char *)pg->vram_addr;
11244 +       info->screen_size = size;
11245 +       memset(info->screen_base, 0, size);
11246 +
11247 +       info->pseudo_palette = fb->pseudo_palette;
11248 +       info->var.xres_virtual = fb->width;
11249 +       info->var.yres_virtual = fb->height;
11250 +       info->var.bits_per_pixel = fb->bits_per_pixel;
11251 +       info->var.xoffset = 0;
11252 +       info->var.yoffset = 0;
11253 +       info->var.activate = FB_ACTIVATE_NOW;
11254 +       info->var.height = -1;
11255 +       info->var.width = -1;
11256 +
11257 +       info->var.xres = fb_width;
11258 +       info->var.yres = fb_height;
11259 +
11260 +       info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
11261 +       info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
11262 +
11263 +       info->pixmap.size = 64 * 1024;
11264 +       info->pixmap.buf_align = 8;
11265 +       info->pixmap.access_align = 32;
11266 +       info->pixmap.flags = FB_PIXMAP_SYSTEM;
11267 +       info->pixmap.scan_align = 1;
11268 +
11269 +       DRM_DEBUG("fb depth is %d\n", fb->depth);
11270 +       DRM_DEBUG("   pitch is %d\n", fb->pitch);
11271 +       fill_fb_bitfield(&info->var, fb->depth);
11272 +
11273 +       fb->fbdev = info;
11274 +
11275 +       par->dev = dev;
11276 +
11277 +       /* To allow resizing without swapping buffers */
11278 +       printk(KERN_INFO"allocated %dx%d fb\n",
11279 +              psbfb->base.width,
11280 +              psbfb->base.height);
11281 +
11282 +       if (psbfb_p)
11283 +               *psbfb_p = psbfb;
11284 +
11285 +       mutex_unlock(&dev->struct_mutex);
11286 +
11287 +       return 0;
11288 +out_err1:
11289 +       fb->funcs->destroy(fb);
11290 +out_err0:
11291 +       mutex_unlock(&dev->struct_mutex);
11292 +       return ret;
11293 +}
11294 +
11295 +static int psbfb_multi_fb_probe_crtc(struct drm_device *dev,
11296 +                                    struct drm_crtc *crtc)
11297 +{
11298 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
11299 +       struct drm_framebuffer *fb = crtc->fb;
11300 +       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
11301 +       struct drm_connector *connector;
11302 +       struct fb_info *info;
11303 +       struct psbfb_par *par;
11304 +       struct drm_mode_set *modeset;
11305 +       unsigned int width, height;
11306 +       int new_fb = 0;
11307 +       int ret, i, conn_count;
11308 +
11309 +       if (!drm_helper_crtc_in_use(crtc))
11310 +               return 0;
11311 +
11312 +       if (!crtc->desired_mode)
11313 +               return 0;
11314 +
11315 +       width = crtc->desired_mode->hdisplay;
11316 +       height = crtc->desired_mode->vdisplay;
11317 +
11318 +       /* is there an fb bound to this crtc already */
11319 +       if (!psb_intel_crtc->mode_set.fb) {
11320 +               ret =
11321 +                   psbfb_create(dev, width, height, width, height,
11322 +                                &psbfb);
11323 +               if (ret)
11324 +                       return -EINVAL;
11325 +               new_fb = 1;
11326 +       } else {
11327 +               fb = psb_intel_crtc->mode_set.fb;
11328 +               if ((fb->width < width) || (fb->height < height))
11329 +                       return -EINVAL;
11330 +       }
11331 +
11332 +       info = fb->fbdev;
11333 +       par = info->par;
11334 +
11335 +       modeset = &psb_intel_crtc->mode_set;
11336 +       modeset->fb = fb;
11337 +       conn_count = 0;
11338 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
11339 +                           head) {
11340 +               if (connector->encoder)
11341 +                       if (connector->encoder->crtc == modeset->crtc) {
11342 +                               modeset->connectors[conn_count] =
11343 +                                   connector;
11344 +                               conn_count++;
11345 +                               if (conn_count > INTELFB_CONN_LIMIT)
11346 +                                       BUG();
11347 +                       }
11348 +       }
11349 +
11350 +       for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
11351 +               modeset->connectors[i] = NULL;
11352 +
11353 +       par->crtc_ids[0] = crtc->base.id;
11354 +
11355 +       modeset->num_connectors = conn_count;
11356 +       if (modeset->mode != modeset->crtc->desired_mode)
11357 +               modeset->mode = modeset->crtc->desired_mode;
11358 +
11359 +       par->crtc_count = 1;
11360 +
11361 +       if (new_fb) {
11362 +               info->var.pixclock = -1;
11363 +               if (register_framebuffer(info) < 0)
11364 +                       return -EINVAL;
11365 +       } else
11366 +               psbfb_set_par(info);
11367 +
11368 +       printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
11369 +              info->fix.id);
11370 +
11371 +       /* Switch back to kernel console on panic */
11372 +       panic_mode = *modeset;
11373 +       atomic_notifier_chain_register(&panic_notifier_list, &paniced);
11374 +       printk(KERN_INFO "registered panic notifier\n");
11375 +
11376 +       return 0;
11377 +}
11378 +
11379 +static int psbfb_multi_fb_probe(struct drm_device *dev)
11380 +{
11381 +
11382 +       struct drm_crtc *crtc;
11383 +       int ret = 0;
11384 +
11385 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
11386 +               ret = psbfb_multi_fb_probe_crtc(dev, crtc);
11387 +               if (ret)
11388 +                       return ret;
11389 +       }
11390 +       return ret;
11391 +}
11392 +
11393 +static int psbfb_single_fb_probe(struct drm_device *dev)
11394 +{
11395 +       struct drm_crtc *crtc;
11396 +       struct drm_connector *connector;
11397 +       unsigned int fb_width = (unsigned) -1, fb_height = (unsigned) -1;
11398 +       unsigned int surface_width = 0, surface_height = 0;
11399 +       int new_fb = 0;
11400 +       int crtc_count = 0;
11401 +       int ret, i, conn_count = 0;
11402 +       struct fb_info *info;
11403 +       struct psbfb_par *par;
11404 +       struct drm_mode_set *modeset = NULL;
11405 +       struct drm_framebuffer *fb = NULL;
11406 +       struct psb_framebuffer *psbfb = NULL;
11407 +
11408 +       /* first up get a count of crtcs now in use and
11409 +        * new min/maxes width/heights */
11410 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
11411 +               if (drm_helper_crtc_in_use(crtc)) {
11412 +                       if (crtc->desired_mode) {
11413 +                               fb = crtc->fb;
11414 +                               if (crtc->desired_mode->hdisplay <
11415 +                                   fb_width)
11416 +                                       fb_width =
11417 +                                           crtc->desired_mode->hdisplay;
11418 +
11419 +                               if (crtc->desired_mode->vdisplay <
11420 +                                   fb_height)
11421 +                                       fb_height =
11422 +                                           crtc->desired_mode->vdisplay;
11423 +
11424 +                               if (crtc->desired_mode->hdisplay >
11425 +                                   surface_width)
11426 +                                       surface_width =
11427 +                                           crtc->desired_mode->hdisplay;
11428 +
11429 +                               if (crtc->desired_mode->vdisplay >
11430 +                                   surface_height)
11431 +                                       surface_height =
11432 +                                           crtc->desired_mode->vdisplay;
11433 +
11434 +                       }
11435 +                       crtc_count++;
11436 +               }
11437 +       }
11438 +
11439 +       if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
11440 +               /* hmm everyone went away - assume VGA cable just fell out
11441 +                  and will come back later. */
11442 +               return 0;
11443 +       }
11444 +
11445 +       /* do we have an fb already? */
11446 +       if (list_empty(&dev->mode_config.fb_kernel_list)) {
11447 +               /* create an fb if we don't have one */
11448 +               ret =
11449 +                   psbfb_create(dev, fb_width, fb_height, surface_width,
11450 +                                surface_height, &psbfb);
11451 +               if (ret)
11452 +                       return -EINVAL;
11453 +               new_fb = 1;
11454 +               fb = &psbfb->base;
11455 +       } else {
11456 +               fb = list_first_entry(&dev->mode_config.fb_kernel_list,
11457 +                                     struct drm_framebuffer, filp_head);
11458 +
11459 +               /* if someone hotplugs something bigger than we have already
11460 +                * allocated, we are pwned. As really we can't resize an
11461 +                * fbdev that is in the wild currently due to fbdev not really
11462 +                * being designed for the lower layers moving stuff around
11463 +                * under it. - so in the grand style of things - punt. */
11464 +               if ((fb->width < surface_width)
11465 +                   || (fb->height < surface_height)) {
11466 +                       DRM_ERROR
11467 +                       ("Framebuffer not large enough to scale"
11468 +                        " console onto.\n");
11469 +                       return -EINVAL;
11470 +               }
11471 +       }
11472 +
11473 +       info = fb->fbdev;
11474 +       par = info->par;
11475 +
11476 +       crtc_count = 0;
11477 +       /* okay we need to setup new connector sets in the crtcs */
11478 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
11479 +               struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
11480 +               modeset = &psb_intel_crtc->mode_set;
11481 +               modeset->fb = fb;
11482 +               conn_count = 0;
11483 +               list_for_each_entry(connector,
11484 +                                   &dev->mode_config.connector_list,
11485 +                                   head) {
11486 +                       if (connector->encoder)
11487 +                               if (connector->encoder->crtc ==
11488 +                                   modeset->crtc) {
11489 +                                       modeset->connectors[conn_count] =
11490 +                                           connector;
11491 +                                       conn_count++;
11492 +                                       if (conn_count >
11493 +                                           INTELFB_CONN_LIMIT)
11494 +                                               BUG();
11495 +                               }
11496 +               }
11497 +
11498 +               for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
11499 +                       modeset->connectors[i] = NULL;
11500 +
11501 +               par->crtc_ids[crtc_count++] = crtc->base.id;
11502 +
11503 +               modeset->num_connectors = conn_count;
11504 +               if (modeset->mode != modeset->crtc->desired_mode)
11505 +                       modeset->mode = modeset->crtc->desired_mode;
11506 +       }
11507 +       par->crtc_count = crtc_count;
11508 +
11509 +       if (new_fb) {
11510 +               info->var.pixclock = -1;
11511 +               if (register_framebuffer(info) < 0)
11512 +                       return -EINVAL;
11513 +       } else
11514 +               psbfb_set_par(info);
11515 +
11516 +       printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
11517 +              info->fix.id);
11518 +
11519 +       /* Switch back to kernel console on panic */
11520 +       panic_mode = *modeset;
11521 +       atomic_notifier_chain_register(&panic_notifier_list, &paniced);
11522 +       printk(KERN_INFO "registered panic notifier\n");
11523 +
11524 +       return 0;
11525 +}
11526 +
11527 +int psbfb_probe(struct drm_device *dev)
11528 +{
11529 +       int ret = 0;
11530 +
11531 +       DRM_DEBUG("\n");
11532 +
11533 +       /* something has changed in the lower levels of hell - deal with it
11534 +          here */
11535 +
11536 +       /* two modes : a) 1 fb to rule all crtcs.
11537 +          b) one fb per crtc.
11538 +          two actions 1) new connected device
11539 +          2) device removed.
11540 +          case a/1 : if the fb surface isn't big enough -
11541 +          resize the surface fb.
11542 +          if the fb size isn't big enough - resize fb into surface.
11543 +          if everything big enough configure the new crtc/etc.
11544 +          case a/2 : undo the configuration
11545 +          possibly resize down the fb to fit the new configuration.
11546 +          case b/1 : see if it is on a new crtc - setup a new fb and add it.
11547 +          case b/2 : teardown the new fb.
11548 +        */
11549 +
11550 +       /* mode a first */
11551 +       /* search for an fb */
11552 +       if (0 /*i915_fbpercrtc == 1 */)
11553 +               ret = psbfb_multi_fb_probe(dev);
11554 +       else
11555 +               ret = psbfb_single_fb_probe(dev);
11556 +
11557 +       return ret;
11558 +}
11559 +EXPORT_SYMBOL(psbfb_probe);
11560 +
11561 +int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
11562 +{
11563 +       struct fb_info *info;
11564 +
11565 +       if (drm_psb_no_fb)
11566 +               return 0;
11567 +
11568 +       info = fb->fbdev;
11569 +
11570 +       if (info) {
11571 +               unregister_framebuffer(info);
11572 +               framebuffer_release(info);
11573 +       }
11574 +
11575 +       atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
11576 +       memset(&panic_mode, 0, sizeof(struct drm_mode_set));
11577 +       return 0;
11578 +}
11579 +EXPORT_SYMBOL(psbfb_remove);
11580 +
11581 +static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
11582 +                                             struct drm_file *file_priv,
11583 +                                             unsigned int *handle)
11584 +{
11585 +       /* JB: TODO currently we can't go from a bo to a handle with ttm */
11586 +       (void) file_priv;
11587 +       *handle = 0;
11588 +       return 0;
11589 +}
11590 +
11591 +static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
11592 +{
11593 +       struct drm_device *dev = fb->dev;
11594 +       struct psb_framebuffer *psbfb = to_psb_fb(fb);
11595 +
11596 +       /*ummap gtt pages*/
11597 +       psb_gtt_unmap_meminfo(dev, psbfb->hKernelMemInfo);
11598 +
11599 +       if (fb->fbdev)
11600 +               psbfb_remove(dev, fb);
11601 +
11602 +       /* JB: TODO not drop, refcount buffer */
11603 +       drm_framebuffer_cleanup(fb);
11604 +
11605 +       kfree(fb);
11606 +}
11607 +
11608 +static const struct drm_mode_config_funcs psb_mode_funcs = {
11609 +       .fb_create = psb_user_framebuffer_create,
11610 +       .fb_changed = psbfb_probe,
11611 +};
11612 +
11613 +static int psb_create_backlight_property(struct drm_device *dev)
11614 +{
11615 +       struct drm_psb_private *dev_priv
11616 +                               = (struct drm_psb_private *) dev->dev_private;
11617 +       struct drm_property *backlight;
11618 +
11619 +       if (dev_priv->backlight_property)
11620 +               return 0;
11621 +
11622 +       backlight = drm_property_create(dev,
11623 +                                       DRM_MODE_PROP_RANGE,
11624 +                                       "backlight",
11625 +                                       2);
11626 +       backlight->values[0] = 0;
11627 +       backlight->values[1] = 100;
11628 +
11629 +       dev_priv->backlight_property = backlight;
11630 +
11631 +       return 0;
11632 +}
11633 +
11634 +static void psb_setup_outputs(struct drm_device *dev)
11635 +{
11636 +       struct drm_psb_private *dev_priv =
11637 +           (struct drm_psb_private *) dev->dev_private;
11638 +       struct drm_connector *connector;
11639 +
11640 +       drm_mode_create_scaling_mode_property(dev);
11641 +
11642 +       psb_create_backlight_property(dev);
11643 +
11644 +       if (IS_MRST(dev)) {
11645 +               if (dev_priv->iLVDS_enable)
11646 +                       /* Set up integrated LVDS for MRST */
11647 +                       mrst_lvds_init(dev, &dev_priv->mode_dev);
11648 +               else {
11649 +                       /* Set up integrated MIPI for MRST */
11650 +                       mrst_dsi_init(dev, &dev_priv->mode_dev);
11651 +               }
11652 +       } else {
11653 +               psb_intel_lvds_init(dev, &dev_priv->mode_dev);
11654 +               psb_intel_sdvo_init(dev, SDVOB);
11655 +       }
11656 +
11657 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
11658 +                           head) {
11659 +               struct psb_intel_output *psb_intel_output =
11660 +                   to_psb_intel_output(connector);
11661 +               struct drm_encoder *encoder = &psb_intel_output->enc;
11662 +               int crtc_mask = 0, clone_mask = 0;
11663 +
11664 +               /* valid crtcs */
11665 +               switch (psb_intel_output->type) {
11666 +               case INTEL_OUTPUT_SDVO:
11667 +                       crtc_mask = ((1 << 0) | (1 << 1));
11668 +                       clone_mask = (1 << INTEL_OUTPUT_SDVO);
11669 +                       break;
11670 +               case INTEL_OUTPUT_LVDS:
11671 +                       if (IS_MRST(dev))
11672 +                               crtc_mask = (1 << 0);
11673 +                       else
11674 +                               crtc_mask = (1 << 1);
11675 +
11676 +                       clone_mask = (1 << INTEL_OUTPUT_LVDS);
11677 +                       break;
11678 +               case INTEL_OUTPUT_MIPI:
11679 +                       crtc_mask = (1 << 0);
11680 +                       clone_mask = (1 << INTEL_OUTPUT_MIPI);
11681 +                       break;
11682 +               }
11683 +               encoder->possible_crtcs = crtc_mask;
11684 +               encoder->possible_clones =
11685 +                   psb_intel_connector_clones(dev, clone_mask);
11686 +       }
11687 +}
11688 +
11689 +static void *psb_bo_from_handle(struct drm_device *dev,
11690 +                               struct drm_file *file_priv,
11691 +                               unsigned int handle)
11692 +{
11693 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
11694 +       IMG_HANDLE hKernelMemInfo = (IMG_HANDLE)handle;
11695 +       int ret;
11696 +
11697 +       ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
11698 +       if (ret) {
11699 +               DRM_ERROR("Cannot get meminfo for handle %lx\n",
11700 +                         (IMG_UINT32)hKernelMemInfo);
11701 +               return NULL;
11702 +       }
11703 +
11704 +       return (void *)psKernelMemInfo;
11705 +}
11706 +
11707 +static size_t psb_bo_size(struct drm_device *dev, void *bof)
11708 +{
11709 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO *)bof;
11710 +       return (size_t)psKernelMemInfo->ui32AllocSize;
11711 +}
11712 +
11713 +static size_t psb_bo_offset(struct drm_device *dev, void *bof)
11714 +{
11715 +       struct psb_framebuffer *psbfb
11716 +               = (struct psb_framebuffer *)bof;
11717 +
11718 +       return (size_t)psbfb->offset;
11719 +}
11720 +
11721 +static int psb_bo_pin_for_scanout(struct drm_device *dev, void *bo)
11722 +{
11723 +#if 0                          /* JB: Not used for the drop */
11724 +       struct ttm_buffer_object *bo = bof;
11725 +               We should do things like check if
11726 +               the buffer is in a scanout : able
11727 +                   place.And make sure that its pinned.
11728 +#endif
11729 +                return 0;
11730 +               }
11731 +
11732 +       static int psb_bo_unpin_for_scanout(struct drm_device *dev,
11733 +                                                   void *bo) {
11734 +#if 0                          /* JB: Not used for the drop */
11735 +               struct ttm_buffer_object *bo = bof;
11736 +#endif
11737 +               return 0;
11738 +       }
11739 +
11740 +       void psb_modeset_init(struct drm_device *dev)
11741 +       {
11742 +               struct drm_psb_private *dev_priv =
11743 +                   (struct drm_psb_private *) dev->dev_private;
11744 +               struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
11745 +               int i;
11746 +               int num_pipe;
11747 +
11748 +               /* Init mm functions */
11749 +               mode_dev->bo_from_handle = psb_bo_from_handle;
11750 +               mode_dev->bo_size = psb_bo_size;
11751 +               mode_dev->bo_offset = psb_bo_offset;
11752 +               mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout;
11753 +               mode_dev->bo_unpin_for_scanout = psb_bo_unpin_for_scanout;
11754 +
11755 +               drm_mode_config_init(dev);
11756 +
11757 +               dev->mode_config.min_width = 0;
11758 +               dev->mode_config.min_height = 0;
11759 +
11760 +               dev->mode_config.funcs = (void *) &psb_mode_funcs;
11761 +
11762 +               dev->mode_config.max_width = 2048;
11763 +               dev->mode_config.max_height = 2048;
11764 +
11765 +               /* set memory base */
11766 +               /* MRST and PSB should use BAR 2*/
11767 +               dev->mode_config.fb_base =
11768 +                   pci_resource_start(dev->pdev, 2);
11769 +
11770 +               if (IS_MRST(dev))
11771 +                       num_pipe = 1;
11772 +               else
11773 +                       num_pipe = 2;
11774 +
11775 +
11776 +               for (i = 0; i < num_pipe; i++)
11777 +                       psb_intel_crtc_init(dev, i, mode_dev);
11778 +
11779 +               psb_setup_outputs(dev);
11780 +
11781 +               /* setup fbs */
11782 +               /* drm_initial_config(dev); */
11783 +       }
11784 +
11785 +       void psb_modeset_cleanup(struct drm_device *dev)
11786 +       {
11787 +               drm_mode_config_cleanup(dev);
11788 +       }
11789 diff --git a/drivers/gpu/drm/mrst/drv/psb_fb.h b/drivers/gpu/drm/mrst/drv/psb_fb.h
11790 new file mode 100644
11791 index 0000000..1986eca
11792 --- /dev/null
11793 +++ b/drivers/gpu/drm/mrst/drv/psb_fb.h
11794 @@ -0,0 +1,49 @@
11795 +/*
11796 + * Copyright (c) 2008, Intel Corporation
11797 + *
11798 + * This program is free software; you can redistribute it and/or modify it
11799 + * under the terms and conditions of the GNU General Public License,
11800 + * version 2, as published by the Free Software Foundation.
11801 + *
11802 + * This program is distributed in the hope it will be useful, but WITHOUT
11803 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11804 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11805 + * more details.
11806 + *
11807 + * You should have received a copy of the GNU General Public License along with
11808 + * this program; if not, write to the Free Software Foundation, Inc., 
11809 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11810 + *
11811 + * Authors:
11812 + *      Eric Anholt <eric@anholt.net>
11813 + *
11814 + */
11815 +
11816 +#ifndef _PSB_FB_H_
11817 +#define _PSB_FB_H_
11818 +
11819 +#include <drm/drmP.h>
11820 +#include "psb_drv.h"
11821 +
11822 +/*IMG Headers*/
11823 +#include "servicesint.h"
11824 +
11825 +struct psb_framebuffer {
11826 +       struct drm_framebuffer base;
11827 +       struct address_space *addr_space;
11828 +       struct ttm_buffer_object *bo;
11829 +       /* struct ttm_bo_kmap_obj kmap; */
11830 +       PVRSRV_KERNEL_MEM_INFO *pvrBO;
11831 +       IMG_HANDLE hKernelMemInfo;
11832 +       uint32_t size;
11833 +       uint32_t offset;
11834 +};
11835 +
11836 +#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
11837 +
11838 +
11839 +extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
11840 +
11841 +
11842 +#endif
11843 +
11844 diff --git a/drivers/gpu/drm/mrst/drv/psb_fence.c b/drivers/gpu/drm/mrst/drv/psb_fence.c
11845 new file mode 100644
11846 index 0000000..b630fc2
11847 --- /dev/null
11848 +++ b/drivers/gpu/drm/mrst/drv/psb_fence.c
11849 @@ -0,0 +1,158 @@
11850 +/*
11851 + * Copyright (c) 2007, Intel Corporation.
11852 + * All Rights Reserved.
11853 + *
11854 + * This program is free software; you can redistribute it and/or modify it
11855 + * under the terms and conditions of the GNU General Public License,
11856 + * version 2, as published by the Free Software Foundation.
11857 + *
11858 + * This program is distributed in the hope it will be useful, but WITHOUT
11859 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11860 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11861 + * more details.
11862 + *
11863 + * You should have received a copy of the GNU General Public License along with
11864 + * this program; if not, write to the Free Software Foundation, Inc., 
11865 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11866 + *
11867 + *
11868 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
11869 + */
11870 +
11871 +#include <drm/drmP.h>
11872 +#include "psb_drv.h"
11873 +#include "psb_msvdx.h"
11874 +#include "lnc_topaz.h"
11875 +
11876 +static void psb_fence_poll(struct ttm_fence_device *fdev,
11877 +                          uint32_t fence_class, uint32_t waiting_types)
11878 +{
11879 +       struct drm_psb_private *dev_priv =
11880 +           container_of(fdev, struct drm_psb_private, fdev);
11881 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
11882 +       struct topaz_private *topaz_priv = dev_priv->topaz_private;
11883 +       uint32_t sequence = 0;
11884 +
11885 +       if (unlikely(!dev_priv))
11886 +               return;
11887 +
11888 +       if (waiting_types) {
11889 +               switch (fence_class) {
11890 +               case PSB_ENGINE_VIDEO:
11891 +                       sequence = msvdx_priv->msvdx_current_sequence;
11892 +                       break;
11893 +               case LNC_ENGINE_ENCODE:
11894 +                       sequence = *((uint32_t *)topaz_priv->topaz_sync_addr);
11895 +                       break;
11896 +               default:
11897 +                       break;
11898 +               }
11899 +
11900 +               ttm_fence_handler(fdev, fence_class, sequence,
11901 +                                 _PSB_FENCE_TYPE_EXE, 0);
11902 +
11903 +       }
11904 +}
11905 +
11906 +void psb_fence_error(struct drm_device *dev,
11907 +                    uint32_t fence_class,
11908 +                    uint32_t sequence, uint32_t type, int error)
11909 +{
11910 +       struct drm_psb_private *dev_priv = psb_priv(dev);
11911 +       struct ttm_fence_device *fdev = &dev_priv->fdev;
11912 +       unsigned long irq_flags;
11913 +       struct ttm_fence_class_manager *fc =
11914 +           &fdev->fence_class[fence_class];
11915 +
11916 +       BUG_ON(fence_class >= PSB_NUM_ENGINES);
11917 +       write_lock_irqsave(&fc->lock, irq_flags);
11918 +       ttm_fence_handler(fdev, fence_class, sequence, type, error);
11919 +       write_unlock_irqrestore(&fc->lock, irq_flags);
11920 +}
11921 +
11922 +int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
11923 +                           uint32_t fence_class,
11924 +                           uint32_t flags, uint32_t *sequence,
11925 +                           unsigned long *timeout_jiffies)
11926 +{
11927 +       struct drm_psb_private *dev_priv =
11928 +           container_of(fdev, struct drm_psb_private, fdev);
11929 +       uint32_t seq = 0;
11930 +
11931 +       if (!dev_priv)
11932 +               return -EINVAL;
11933 +
11934 +       if (fence_class >= PSB_NUM_ENGINES)
11935 +               return -EINVAL;
11936 +
11937 +       spin_lock(&dev_priv->sequence_lock);
11938 +       seq = dev_priv->sequence[fence_class]++;
11939 +       spin_unlock(&dev_priv->sequence_lock);
11940 +
11941 +       *sequence = seq;
11942 +       *timeout_jiffies = jiffies + DRM_HZ * 3;
11943 +
11944 +       return 0;
11945 +}
11946 +
11947 +static void psb_fence_lockup(struct ttm_fence_object *fence,
11948 +                            uint32_t fence_types)
11949 +{
11950 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
11951 +
11952 +       if (fence->fence_class == LNC_ENGINE_ENCODE) {
11953 +               DRM_ERROR("TOPAZ timeout (probable lockup)\n");
11954 +
11955 +               write_lock(&fc->lock);
11956 +               lnc_topaz_handle_timeout(fence->fdev);
11957 +               ttm_fence_handler(fence->fdev, fence->fence_class,
11958 +                                 fence->sequence, fence_types, -EBUSY);
11959 +               write_unlock(&fc->lock);
11960 +       } else {
11961 +               DRM_ERROR("MSVDX timeout (probable lockup)\n");
11962 +               write_lock(&fc->lock);
11963 +               ttm_fence_handler(fence->fdev, fence->fence_class,
11964 +                                 fence->sequence, fence_types, -EBUSY);
11965 +               write_unlock(&fc->lock);
11966 +       }
11967 +}
11968 +
11969 +void psb_fence_handler(struct drm_device *dev, uint32_t fence_class)
11970 +{
11971 +       struct drm_psb_private *dev_priv = psb_priv(dev);
11972 +       struct ttm_fence_device *fdev = &dev_priv->fdev;
11973 +       struct ttm_fence_class_manager *fc =
11974 +           &fdev->fence_class[fence_class];
11975 +       unsigned long irq_flags;
11976 +
11977 +       write_lock_irqsave(&fc->lock, irq_flags);
11978 +       psb_fence_poll(fdev, fence_class, fc->waiting_types);
11979 +       write_unlock_irqrestore(&fc->lock, irq_flags);
11980 +}
11981 +
11982 +
11983 +static struct ttm_fence_driver psb_ttm_fence_driver = {
11984 +       .has_irq = NULL,
11985 +       .emit = psb_fence_emit_sequence,
11986 +       .flush = NULL,
11987 +       .poll = psb_fence_poll,
11988 +       .needed_flush = NULL,
11989 +       .wait = NULL,
11990 +       .signaled = NULL,
11991 +       .lockup = psb_fence_lockup,
11992 +};
11993 +
11994 +int psb_ttm_fence_device_init(struct ttm_fence_device *fdev)
11995 +{
11996 +       struct drm_psb_private *dev_priv =
11997 +               container_of(fdev, struct drm_psb_private, fdev);
11998 +       struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30),
11999 +               .flush_diff = (1 << 29),
12000 +               .sequence_mask = 0xFFFFFFFF
12001 +       };
12002 +
12003 +       return ttm_fence_device_init(PSB_NUM_ENGINES,
12004 +                                    dev_priv->mem_global_ref.object,
12005 +                                    fdev, &fci, 1,
12006 +                                    &psb_ttm_fence_driver);
12007 +}
12008 diff --git a/drivers/gpu/drm/mrst/drv/psb_gtt.c b/drivers/gpu/drm/mrst/drv/psb_gtt.c
12009 new file mode 100644
12010 index 0000000..5f66e75
12011 --- /dev/null
12012 +++ b/drivers/gpu/drm/mrst/drv/psb_gtt.c
12013 @@ -0,0 +1,1040 @@
12014 +/*
12015 + * Copyright (c) 2007, Intel Corporation.
12016 + * All Rights Reserved.
12017 + *
12018 + * This program is free software; you can redistribute it and/or modify it
12019 + * under the terms and conditions of the GNU General Public License,
12020 + * version 2, as published by the Free Software Foundation.
12021 + *
12022 + * This program is distributed in the hope it will be useful, but WITHOUT
12023 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12024 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12025 + * more details.
12026 + *
12027 + * You should have received a copy of the GNU General Public License along with
12028 + * this program; if not, write to the Free Software Foundation, Inc., 
12029 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
12030 + *
12031 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
12032 + */
12033 +
12034 +#include <drm/drmP.h>
12035 +#include "psb_drv.h"
12036 +#include "psb_pvr_glue.h"
12037 +
12038 +static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
12039 +{
12040 +       uint32_t mask = PSB_PTE_VALID;
12041 +
12042 +       if (type & PSB_MMU_CACHED_MEMORY)
12043 +               mask |= PSB_PTE_CACHED;
12044 +       if (type & PSB_MMU_RO_MEMORY)
12045 +               mask |= PSB_PTE_RO;
12046 +       if (type & PSB_MMU_WO_MEMORY)
12047 +               mask |= PSB_PTE_WO;
12048 +
12049 +       return (pfn << PAGE_SHIFT) | mask;
12050 +}
12051 +
12052 +struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
12053 +{
12054 +       struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
12055 +
12056 +       if (!tmp)
12057 +               return NULL;
12058 +
12059 +       init_rwsem(&tmp->sem);
12060 +       tmp->dev = dev;
12061 +
12062 +       return tmp;
12063 +}
12064 +
12065 +void psb_gtt_takedown(struct psb_gtt *pg, int free)
12066 +{
12067 +       struct drm_psb_private *dev_priv = pg->dev->dev_private;
12068 +
12069 +       if (!pg)
12070 +               return;
12071 +
12072 +       if (pg->gtt_map) {
12073 +               iounmap(pg->gtt_map);
12074 +               pg->gtt_map = NULL;
12075 +       }
12076 +       if (pg->initialized) {
12077 +               pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
12078 +                                     pg->gmch_ctrl);
12079 +               PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
12080 +               (void) PSB_RVDC32(PSB_PGETBL_CTL);
12081 +       }
12082 +       if (free)
12083 +               kfree(pg);
12084 +}
12085 +
12086 +int psb_gtt_init(struct psb_gtt *pg, int resume)
12087 +{
12088 +       struct drm_device *dev = pg->dev;
12089 +       struct drm_psb_private *dev_priv = dev->dev_private;
12090 +       unsigned gtt_pages;
12091 +       unsigned long stolen_size, vram_stolen_size, ci_stolen_size;
12092 +       unsigned long rar_stolen_size;
12093 +       unsigned i, num_pages;
12094 +       unsigned pfn_base;
12095 +       uint32_t ci_pages, vram_pages;
12096 +       uint32_t tt_pages;
12097 +       uint32_t *ttm_gtt_map;
12098 +       uint32_t dvmt_mode = 0;
12099 +
12100 +       int ret = 0;
12101 +       uint32_t pte;
12102 +
12103 +       pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
12104 +       pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
12105 +                             pg->gmch_ctrl | _PSB_GMCH_ENABLED);
12106 +
12107 +       pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
12108 +       PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
12109 +       (void) PSB_RVDC32(PSB_PGETBL_CTL);
12110 +
12111 +       pg->initialized = 1;
12112 +
12113 +       pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK;
12114 +
12115 +       pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
12116 +       /* fix me: video mmu has hw bug to access 0x0D0000000,
12117 +        * then make gatt start at 0x0e000,0000 */
12118 +       pg->mmu_gatt_start = 0xE0000000;
12119 +       pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
12120 +       gtt_pages =
12121 +           pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
12122 +       pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
12123 +           >> PAGE_SHIFT;
12124 +
12125 +       pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
12126 +       vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
12127 +
12128 +       /* CI is not included in the stolen size since the TOPAZ MMU bug */
12129 +       ci_stolen_size = dev_priv->ci_region_size;
12130 +       /* Don't add CI & RAR share buffer space
12131 +        * managed by TTM to stolen_size */
12132 +       stolen_size = vram_stolen_size;
12133 +
12134 +       rar_stolen_size = dev_priv->rar_region_size;
12135 +
12136 +       printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
12137 +               pg->gatt_start, pg->gatt_pages/256);
12138 +       printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
12139 +               pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
12140 +       printk(KERN_INFO"Stole memory information \n");
12141 +       printk(KERN_INFO"      base in RAM: 0x%x \n", pg->stolen_base);
12142 +       printk(KERN_INFO"      size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
12143 +               vram_stolen_size/1024);
12144 +       dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7;
12145 +       printk(KERN_INFO"      the correct size should be: %dM(dvmt mode=%d) \n",
12146 +               (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
12147 +
12148 +       if (ci_stolen_size > 0)
12149 +               printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M \n",
12150 +                               dev_priv->ci_region_start,
12151 +                               ci_stolen_size / 1024 / 1024);
12152 +       if (rar_stolen_size > 0)
12153 +               printk(KERN_INFO"RAR Stole memory: RAM base = 0x%08x, size = %lu M \n",
12154 +                               dev_priv->rar_region_start,
12155 +                               rar_stolen_size / 1024 / 1024);
12156 +
12157 +       if (resume && (gtt_pages != pg->gtt_pages) &&
12158 +           (stolen_size != pg->stolen_size)) {
12159 +               DRM_ERROR("GTT resume error.\n");
12160 +               ret = -EINVAL;
12161 +               goto out_err;
12162 +       }
12163 +
12164 +       pg->gtt_pages = gtt_pages;
12165 +       pg->stolen_size = stolen_size;
12166 +       pg->vram_stolen_size = vram_stolen_size;
12167 +       pg->ci_stolen_size = ci_stolen_size;
12168 +       pg->rar_stolen_size = rar_stolen_size;
12169 +       pg->gtt_map =
12170 +           ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
12171 +       if (!pg->gtt_map) {
12172 +               DRM_ERROR("Failure to map gtt.\n");
12173 +               ret = -ENOMEM;
12174 +               goto out_err;
12175 +       }
12176 +
12177 +       pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size);
12178 +       if (!pg->vram_addr) {
12179 +               DRM_ERROR("Failure to map stolen base.\n");
12180 +               ret = -ENOMEM;
12181 +               goto out_err;
12182 +       }
12183 +
12184 +       DRM_DEBUG("%s: vram kernel virtual address %p\n", pg->vram_addr);
12185 +
12186 +       tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
12187 +               (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
12188 +
12189 +       ttm_gtt_map = pg->gtt_map + tt_pages / 2;
12190 +
12191 +       /*
12192 +        * insert vram stolen pages.
12193 +        */
12194 +
12195 +       pfn_base = pg->stolen_base >> PAGE_SHIFT;
12196 +       vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
12197 +       printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
12198 +               num_pages, pfn_base, 0);
12199 +       for (i = 0; i < num_pages; ++i) {
12200 +               pte = psb_gtt_mask_pte(pfn_base + i, 0);
12201 +               iowrite32(pte, pg->gtt_map + i);
12202 +       }
12203 +
12204 +       /*
12205 +        * Init rest of gtt managed by IMG.
12206 +        */
12207 +       pfn_base = page_to_pfn(dev_priv->scratch_page);
12208 +       pte = psb_gtt_mask_pte(pfn_base, 0);
12209 +       for (; i < tt_pages / 2 - 1; ++i)
12210 +               iowrite32(pte, pg->gtt_map + i);
12211 +
12212 +       /*
12213 +        * insert CI stolen pages
12214 +        */
12215 +
12216 +       pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT;
12217 +       ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT;
12218 +       printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n",
12219 +              num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4);
12220 +       for (i = 0; i < num_pages; ++i) {
12221 +               pte = psb_gtt_mask_pte(pfn_base + i, 0);
12222 +               iowrite32(pte, ttm_gtt_map + i);
12223 +       }
12224 +
12225 +       /*
12226 +        * insert RAR stolen pages
12227 +        */
12228 +       if (rar_stolen_size != 0) {
12229 +               pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT;
12230 +               num_pages = rar_stolen_size >> PAGE_SHIFT;
12231 +               printk(KERN_INFO"Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n",
12232 +                       num_pages, pfn_base,
12233 +                       (ttm_gtt_map - pg->gtt_map + i) * 4);
12234 +               for (; i < num_pages + ci_pages; ++i) {
12235 +                       pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0);
12236 +                       iowrite32(pte, ttm_gtt_map + i);
12237 +               }
12238 +       }
12239 +       /*
12240 +        * Init rest of gtt managed by TTM.
12241 +        */
12242 +
12243 +       pfn_base = page_to_pfn(dev_priv->scratch_page);
12244 +       pte = psb_gtt_mask_pte(pfn_base, 0);
12245 +       PSB_DEBUG_INIT("Initializing the rest of a total "
12246 +                      "of %d gtt pages.\n", pg->gatt_pages);
12247 +
12248 +       for (; i < pg->gatt_pages - tt_pages / 2; ++i)
12249 +               iowrite32(pte, ttm_gtt_map + i);
12250 +       (void) ioread32(pg->gtt_map + i - 1);
12251 +
12252 +       return 0;
12253 +
12254 +out_err:
12255 +       psb_gtt_takedown(pg, 0);
12256 +       return ret;
12257 +}
12258 +
12259 +int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
12260 +                        unsigned offset_pages, unsigned num_pages,
12261 +                        unsigned desired_tile_stride,
12262 +                        unsigned hw_tile_stride, int type)
12263 +{
12264 +       unsigned rows = 1;
12265 +       unsigned add;
12266 +       unsigned row_add;
12267 +       unsigned i;
12268 +       unsigned j;
12269 +       uint32_t *cur_page = NULL;
12270 +       uint32_t pte;
12271 +
12272 +       if (hw_tile_stride)
12273 +               rows = num_pages / desired_tile_stride;
12274 +       else
12275 +               desired_tile_stride = num_pages;
12276 +
12277 +       add = desired_tile_stride;
12278 +       row_add = hw_tile_stride;
12279 +
12280 +       down_read(&pg->sem);
12281 +       for (i = 0; i < rows; ++i) {
12282 +               cur_page = pg->gtt_map + offset_pages;
12283 +               for (j = 0; j < desired_tile_stride; ++j) {
12284 +                       pte =
12285 +                           psb_gtt_mask_pte(page_to_pfn(*pages++), type);
12286 +                       iowrite32(pte, cur_page++);
12287 +               }
12288 +               offset_pages += add;
12289 +       }
12290 +       (void) ioread32(cur_page - 1);
12291 +       up_read(&pg->sem);
12292 +
12293 +       return 0;
12294 +}
12295 +
12296 +int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, IMG_CPU_PHYADDR *pPhysFrames,
12297 +                                                                  unsigned offset_pages, unsigned num_pages, int type)
12298 +{
12299 +        unsigned j;
12300 +        uint32_t *cur_page = NULL;
12301 +        uint32_t pte;
12302 +
12303 +        //printk("Allocatng IMG GTT mem at %x (pages %d)\n",offset_pages,num_pages);
12304 +        down_read(&pg->sem);
12305 +
12306 +        cur_page = pg->gtt_map + offset_pages;
12307 +        for (j = 0; j < num_pages; ++j)
12308 +        {
12309 +                pte =  psb_gtt_mask_pte( (pPhysFrames++)->uiAddr >> PAGE_SHIFT, type);
12310 +                iowrite32(pte, cur_page++);
12311 +                //printk("PTE %d: %x/%x\n",j,(pPhysFrames-1)->uiAddr,pte);
12312 +        }
12313 +        (void) ioread32(cur_page - 1);
12314 +
12315 +        up_read(&pg->sem);
12316 +
12317 +        return 0;
12318 +}
12319 +
12320 +int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
12321 +                        unsigned num_pages, unsigned desired_tile_stride,
12322 +                        unsigned hw_tile_stride)
12323 +{
12324 +       struct drm_psb_private *dev_priv = pg->dev->dev_private;
12325 +       unsigned rows = 1;
12326 +       unsigned add;
12327 +       unsigned row_add;
12328 +       unsigned i;
12329 +       unsigned j;
12330 +       uint32_t *cur_page = NULL;
12331 +       unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
12332 +       uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
12333 +
12334 +       if (hw_tile_stride)
12335 +               rows = num_pages / desired_tile_stride;
12336 +       else
12337 +               desired_tile_stride = num_pages;
12338 +
12339 +       add = desired_tile_stride;
12340 +       row_add = hw_tile_stride;
12341 +
12342 +       down_read(&pg->sem);
12343 +       for (i = 0; i < rows; ++i) {
12344 +               cur_page = pg->gtt_map + offset_pages;
12345 +               for (j = 0; j < desired_tile_stride; ++j)
12346 +                       iowrite32(pte, cur_page++);
12347 +
12348 +               offset_pages += add;
12349 +       }
12350 +       (void) ioread32(cur_page - 1);
12351 +       up_read(&pg->sem);
12352 +
12353 +       return 0;
12354 +}
12355 +
12356 +int psb_gtt_mm_init(struct psb_gtt *pg)
12357 +{
12358 +       struct psb_gtt_mm *gtt_mm;
12359 +       struct drm_psb_private *dev_priv = pg->dev->dev_private;
12360 +       struct drm_open_hash *ht;
12361 +       struct drm_mm *mm;
12362 +       int ret;
12363 +       uint32_t tt_start;
12364 +       uint32_t tt_size;
12365 +
12366 +       if (!pg || !pg->initialized) {
12367 +               DRM_DEBUG("Invalid gtt struct\n");
12368 +               return -EINVAL;
12369 +       }
12370 +
12371 +       gtt_mm =  kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL);
12372 +       if (!gtt_mm)
12373 +               return -ENOMEM;
12374 +
12375 +       spin_lock_init(&gtt_mm->lock);
12376 +
12377 +       ht = &gtt_mm->hash;
12378 +       ret = drm_ht_create(ht, 20);
12379 +       if (ret) {
12380 +               DRM_DEBUG("Create hash table failed(%d)\n", ret);
12381 +               goto err_free;
12382 +       }
12383 +
12384 +       tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
12385 +       tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages;
12386 +       tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
12387 +                       (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
12388 +
12389 +       mm = &gtt_mm->base;
12390 +
12391 +       /*will use tt_start ~ 128M for IMG TT buffers*/
12392 +       ret = drm_mm_init(mm, tt_start, ((tt_size / 2) - tt_start));
12393 +       if (ret) {
12394 +               DRM_DEBUG("drm_mm_int error(%d)\n", ret);
12395 +               goto err_mm_init;
12396 +       }
12397 +
12398 +       gtt_mm->count = 0;
12399 +
12400 +       dev_priv->gtt_mm = gtt_mm;
12401 +
12402 +       DRM_INFO("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n",
12403 +               (unsigned long)tt_start,
12404 +               (unsigned long)((tt_size / 2) - tt_start));
12405 +       return 0;
12406 +err_mm_init:
12407 +       drm_ht_remove(ht);
12408 +
12409 +err_free:
12410 +       kfree(gtt_mm);
12411 +       return ret;
12412 +}
12413 +
12414 +/**
12415 + * Delete all hash entries;
12416 + */
12417 +void psb_gtt_mm_takedown(void)
12418 +{
12419 +       return;
12420 +}
12421 +
12422 +static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm,
12423 +                                   u32 tgid,
12424 +                                   struct psb_gtt_hash_entry **hentry)
12425 +{
12426 +       struct drm_hash_item *entry;
12427 +       struct psb_gtt_hash_entry *psb_entry;
12428 +       int ret;
12429 +
12430 +       ret = drm_ht_find_item(&mm->hash, tgid, &entry);
12431 +       if (ret) {
12432 +               DRM_DEBUG("Cannot find entry pid=%ld\n", tgid);
12433 +               return ret;
12434 +       }
12435 +
12436 +       psb_entry = container_of(entry, struct psb_gtt_hash_entry, item);
12437 +       if (!psb_entry) {
12438 +               DRM_DEBUG("Invalid entry");
12439 +               return -EINVAL;
12440 +       }
12441 +
12442 +       *hentry = psb_entry;
12443 +       return 0;
12444 +}
12445 +
12446 +
12447 +static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm,
12448 +                                      u32 tgid,
12449 +                                      struct psb_gtt_hash_entry *hentry)
12450 +{
12451 +       struct drm_hash_item *item;
12452 +       int ret;
12453 +
12454 +       if (!hentry) {
12455 +               DRM_DEBUG("Invalid parameters\n");
12456 +               return -EINVAL;
12457 +       }
12458 +
12459 +       item = &hentry->item;
12460 +       item->key = tgid;
12461 +
12462 +       /**
12463 +        * NOTE: drm_ht_insert_item will perform such a check
12464 +       ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp);
12465 +       if (!ret) {
12466 +               DRM_DEBUG("Entry already exists for pid %ld\n", tgid);
12467 +               return -EAGAIN;
12468 +       }
12469 +       */
12470 +
12471 +       /*Insert the given entry*/
12472 +       ret = drm_ht_insert_item(&mm->hash, item);
12473 +       if (ret) {
12474 +               DRM_DEBUG("Insert failure\n");
12475 +               return ret;
12476 +       }
12477 +
12478 +       mm->count++;
12479 +
12480 +       return 0;
12481 +}
12482 +
12483 +static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm,
12484 +                                     u32 tgid,
12485 +                                     struct psb_gtt_hash_entry **entry)
12486 +{
12487 +       struct psb_gtt_hash_entry *hentry;
12488 +       int ret;
12489 +
12490 +       /*if the hentry for this tgid exists, just get it and return*/
12491 +       spin_lock(&mm->lock);
12492 +       ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
12493 +       if (!ret) {
12494 +               DRM_DEBUG("Entry for tgid %ld exist, hentry %p\n",
12495 +                         tgid, hentry);
12496 +               *entry = hentry;
12497 +               spin_unlock(&mm->lock);
12498 +               return 0;
12499 +       }
12500 +       spin_unlock(&mm->lock);
12501 +
12502 +       DRM_DEBUG("Entry for tgid %ld doesn't exist, will create it\n", tgid);
12503 +
12504 +       hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL);
12505 +       if (!hentry) {
12506 +               DRM_DEBUG("Kmalloc failled\n");
12507 +               return -ENOMEM;
12508 +       }
12509 +
12510 +       ret = drm_ht_create(&hentry->ht, 20);
12511 +       if (ret) {
12512 +               DRM_DEBUG("Create hash table failed\n");
12513 +               return ret;
12514 +       }
12515 +
12516 +       spin_lock(&mm->lock);
12517 +       ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry);
12518 +       spin_unlock(&mm->lock);
12519 +
12520 +       if (!ret)
12521 +               *entry = hentry;
12522 +
12523 +       return ret;
12524 +}
12525 +
12526 +static struct psb_gtt_hash_entry *
12527 +psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
12528 +{
12529 +       struct psb_gtt_hash_entry *tmp;
12530 +       int ret;
12531 +
12532 +       ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp);
12533 +       if (ret) {
12534 +               DRM_DEBUG("Cannot find entry pid %ld\n", tgid);
12535 +               return NULL;
12536 +       }
12537 +
12538 +       /*remove it from ht*/
12539 +       drm_ht_remove_item(&mm->hash, &tmp->item);
12540 +
12541 +       mm->count--;
12542 +
12543 +       return tmp;
12544 +}
12545 +
12546 +static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
12547 +{
12548 +       struct psb_gtt_hash_entry *entry;
12549 +
12550 +       entry = psb_gtt_mm_remove_ht_locked(mm, tgid);
12551 +
12552 +       if (!entry) {
12553 +               DRM_DEBUG("Invalid entry");
12554 +               return -EINVAL;
12555 +       }
12556 +
12557 +       /*delete ht*/
12558 +       drm_ht_remove(&entry->ht);
12559 +
12560 +       /*free this entry*/
12561 +       kfree(entry);
12562 +       return 0;
12563 +}
12564 +
12565 +static int
12566 +psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht,
12567 +                          u32 key,
12568 +                          struct psb_gtt_mem_mapping **hentry)
12569 +{
12570 +       struct drm_hash_item *entry;
12571 +       struct psb_gtt_mem_mapping *mapping;
12572 +       int ret;
12573 +
12574 +       ret = drm_ht_find_item(ht, key, &entry);
12575 +       if (ret) {
12576 +               DRM_DEBUG("Cannot find key %ld\n", key);
12577 +               return ret;
12578 +       }
12579 +
12580 +       mapping =  container_of(entry, struct psb_gtt_mem_mapping, item);
12581 +       if (!mapping) {
12582 +               DRM_DEBUG("Invalid entry\n");
12583 +               return -EINVAL;
12584 +       }
12585 +
12586 +       *hentry = mapping;
12587 +       return 0;
12588 +}
12589 +
12590 +static int
12591 +psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht,
12592 +                             u32 key,
12593 +                             struct psb_gtt_mem_mapping *hentry)
12594 +{
12595 +       struct drm_hash_item *item;
12596 +       struct psb_gtt_hash_entry *entry;
12597 +       int ret;
12598 +
12599 +       if (!hentry) {
12600 +               DRM_DEBUG("hentry is NULL\n");
12601 +               return -EINVAL;
12602 +       }
12603 +
12604 +       item = &hentry->item;
12605 +       item->key = key;
12606 +
12607 +       ret = drm_ht_insert_item(ht, item);
12608 +       if (ret) {
12609 +               DRM_DEBUG("insert_item failed\n");
12610 +               return ret;
12611 +       }
12612 +
12613 +       entry = container_of(ht, struct psb_gtt_hash_entry, ht);
12614 +       if (entry)
12615 +               entry->count++;
12616 +
12617 +       return 0;
12618 +}
12619 +
12620 +static int
12621 +psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm,
12622 +                                   struct drm_open_hash *ht,
12623 +                                   u32 key,
12624 +                                   struct drm_mm_node *node,
12625 +                                   struct psb_gtt_mem_mapping **entry)
12626 +{
12627 +       struct psb_gtt_mem_mapping *mapping;
12628 +       int ret;
12629 +
12630 +       if (!node || !ht) {
12631 +               DRM_DEBUG("parameter error\n");
12632 +               return -EINVAL;
12633 +       }
12634 +
12635 +       /*try to get this mem_map */
12636 +       spin_lock(&mm->lock);
12637 +       ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping);
12638 +       if (!ret) {
12639 +               DRM_DEBUG("mapping entry for key %ld exists, entry %p\n",
12640 +                         key, mapping);
12641 +               *entry = mapping;
12642 +               spin_unlock(&mm->lock);
12643 +               return 0;
12644 +       }
12645 +       spin_unlock(&mm->lock);
12646 +
12647 +       DRM_DEBUG("Mapping entry for key %ld doesn't exist, will create it\n",
12648 +                 key);
12649 +
12650 +       mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL);
12651 +       if (!mapping) {
12652 +               DRM_DEBUG("kmalloc failed\n");
12653 +               return -ENOMEM;
12654 +       }
12655 +
12656 +       mapping->node = node;
12657 +
12658 +       spin_lock(&mm->lock);
12659 +       ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping);
12660 +       spin_unlock(&mm->lock);
12661 +
12662 +       if (!ret)
12663 +               *entry = mapping;
12664 +
12665 +       return ret;
12666 +}
12667 +
12668 +static struct psb_gtt_mem_mapping *
12669 +psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key)
12670 +{
12671 +       struct psb_gtt_mem_mapping *tmp;
12672 +       struct psb_gtt_hash_entry *entry;
12673 +       int ret;
12674 +
12675 +       ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp);
12676 +       if (ret) {
12677 +               DRM_DEBUG("Cannot find key %ld\n", key);
12678 +               return NULL;
12679 +       }
12680 +
12681 +       drm_ht_remove_item(ht, &tmp->item);
12682 +
12683 +       entry = container_of(ht, struct psb_gtt_hash_entry, ht);
12684 +       if (entry)
12685 +               entry->count--;
12686 +
12687 +       return tmp;
12688 +}
12689 +
12690 +static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht,
12691 +                                             u32 key,
12692 +                                             struct drm_mm_node **node)
12693 +{
12694 +       struct psb_gtt_mem_mapping *entry;
12695 +
12696 +       entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key);
12697 +       if (!entry) {
12698 +               DRM_DEBUG("entry is NULL\n");
12699 +               return -EINVAL;
12700 +       }
12701 +
12702 +       *node = entry->node;
12703 +
12704 +       kfree(entry);
12705 +       return 0;
12706 +}
12707 +
12708 +static int psb_gtt_add_node(struct psb_gtt_mm *mm,
12709 +                           u32 tgid,
12710 +                           u32 key,
12711 +                           struct drm_mm_node *node,
12712 +                           struct psb_gtt_mem_mapping **entry)
12713 +{
12714 +       struct psb_gtt_hash_entry *hentry;
12715 +       struct psb_gtt_mem_mapping *mapping;
12716 +       int ret;
12717 +
12718 +       ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry);
12719 +       if (ret) {
12720 +               DRM_DEBUG("alloc_insert failed\n");
12721 +               return ret;
12722 +       }
12723 +
12724 +       ret = psb_gtt_mm_alloc_insert_mem_mapping(mm,
12725 +                                                 &hentry->ht,
12726 +                                                 key,
12727 +                                                 node,
12728 +                                                 &mapping);
12729 +       if (ret) {
12730 +               DRM_DEBUG("mapping alloc_insert failed\n");
12731 +               return ret;
12732 +       }
12733 +
12734 +       *entry = mapping;
12735 +
12736 +       return 0;
12737 +}
12738 +
12739 +static int psb_gtt_remove_node(struct psb_gtt_mm *mm,
12740 +                              u32 tgid,
12741 +                              u32 key,
12742 +                              struct drm_mm_node **node)
12743 +{
12744 +       struct psb_gtt_hash_entry *hentry;
12745 +       struct drm_mm_node *tmp;
12746 +       int ret;
12747 +
12748 +       spin_lock(&mm->lock);
12749 +       ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
12750 +       if (ret) {
12751 +               DRM_DEBUG("Cannot find entry for pid %ld\n", tgid);
12752 +               spin_unlock(&mm->lock);
12753 +               return ret;
12754 +       }
12755 +       spin_unlock(&mm->lock);
12756 +
12757 +       /*remove mapping entry*/
12758 +       spin_lock(&mm->lock);
12759 +       ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht,
12760 +                                                       key,
12761 +                                                       &tmp);
12762 +       if (ret) {
12763 +               DRM_DEBUG("remove_free failed\n");
12764 +               spin_unlock(&mm->lock);
12765 +               return ret;
12766 +       }
12767 +
12768 +       *node = tmp;
12769 +
12770 +       /*check the count of mapping entry*/
12771 +       if (!hentry->count) {
12772 +               DRM_DEBUG("count of mapping entry is zero, tgid=%ld\n", tgid);
12773 +               psb_gtt_mm_remove_free_ht_locked(mm, tgid);
12774 +       }
12775 +
12776 +       spin_unlock(&mm->lock);
12777 +
12778 +       return 0;
12779 +}
12780 +
12781 +static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm,
12782 +                               uint32_t pages,
12783 +                               uint32_t align,
12784 +                               struct drm_mm_node **node)
12785 +{
12786 +       struct drm_mm_node *tmp_node;
12787 +       int ret;
12788 +
12789 +       do {
12790 +               ret = drm_mm_pre_get(&mm->base);
12791 +               if (unlikely(ret)) {
12792 +                       DRM_DEBUG("drm_mm_pre_get error\n");
12793 +                       return ret;
12794 +               }
12795 +
12796 +               spin_lock(&mm->lock);
12797 +               tmp_node = drm_mm_search_free(&mm->base, pages, align, 1);
12798 +               if (unlikely(!tmp_node)) {
12799 +                       DRM_DEBUG("No free node found\n");
12800 +                       spin_unlock(&mm->lock);
12801 +                       break;
12802 +               }
12803 +
12804 +               tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align);
12805 +               spin_unlock(&mm->lock);
12806 +       } while (!tmp_node);
12807 +
12808 +       if (!tmp_node) {
12809 +               DRM_DEBUG("Node allocation failed\n");
12810 +               return -ENOMEM;
12811 +       }
12812 +
12813 +       *node = tmp_node;
12814 +       return 0;
12815 +}
12816 +
12817 +static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node)
12818 +{
12819 +       spin_lock(&mm->lock);
12820 +       drm_mm_put_block(node);
12821 +       spin_unlock(&mm->lock);
12822 +}
12823 +
12824 +int psb_gtt_map_meminfo(struct drm_device *dev,
12825 +                       IMG_HANDLE hKernelMemInfo,
12826 +                       uint32_t *offset)
12827 +{
12828 +       struct drm_psb_private *dev_priv
12829 +              = (struct drm_psb_private *)dev->dev_private;
12830 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
12831 +       struct psb_gtt_mm *mm = dev_priv->gtt_mm;
12832 +       struct psb_gtt *pg = dev_priv->pg;
12833 +       uint32_t size, pages, offset_pages;
12834 +       void *kmem;
12835 +       struct drm_mm_node *node;
12836 +       struct page **page_list;
12837 +       struct psb_gtt_mem_mapping *mapping = NULL;
12838 +       int ret;
12839 +
12840 +       ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
12841 +       if (ret) {
12842 +               DRM_DEBUG("Cannot find kernelMemInfo handle %ld\n",
12843 +                         hKernelMemInfo);
12844 +               return -EINVAL;
12845 +       }
12846 +
12847 +       DRM_DEBUG("Got psKernelMemInfo %p for handle %lx\n",
12848 +                 psKernelMemInfo, (u32)hKernelMemInfo);
12849 +
12850 +       size = psKernelMemInfo->ui32AllocSize;
12851 +       kmem = psKernelMemInfo->pvLinAddrKM;
12852 +       pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
12853 +
12854 +       DRM_DEBUG("KerMemInfo size %ld, cpuVadr %lx, pages %ld, osMemHdl %lx\n",
12855 +                 size, kmem, pages, psKernelMemInfo->sMemBlk.hOSMemHandle);
12856 +
12857 +       if (!kmem)
12858 +               DRM_DEBUG("kmem is NULL");
12859 +
12860 +       /*get pages*/
12861 +       ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle,
12862 +                                         &page_list);
12863 +       if (ret) {
12864 +               DRM_DEBUG("get pages error\n");
12865 +               return ret;
12866 +       }
12867 +
12868 +       DRM_DEBUG("get %ld pages\n", pages);
12869 +
12870 +       /*alloc memory in TT apeture*/
12871 +       ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node);
12872 +       if (ret) {
12873 +               DRM_DEBUG("alloc TT memory error\n");
12874 +               goto failed_pages_alloc;
12875 +       }
12876 +
12877 +       /*update psb_gtt_mm*/
12878 +       ret = psb_gtt_add_node(mm,
12879 +                              (u32)psb_get_tgid(),
12880 +                              (u32)hKernelMemInfo,
12881 +                              node,
12882 +                              &mapping);
12883 +       if (ret) {
12884 +               DRM_DEBUG("add_node failed");
12885 +               goto failed_add_node;
12886 +       }
12887 +
12888 +       node = mapping->node;
12889 +       offset_pages = node->start;
12890 +
12891 +       DRM_DEBUG("get free node for %ld pages, offset %ld pages",
12892 +                 pages, offset_pages);
12893 +
12894 +       /*update gtt*/
12895 +       psb_gtt_insert_pages(pg, page_list,
12896 +                            (unsigned)offset_pages,
12897 +                            (unsigned)pages,
12898 +                            0,
12899 +                            0,
12900 +                            0);
12901 +
12902 +       *offset = offset_pages;
12903 +       return 0;
12904 +
12905 +failed_add_node:
12906 +       psb_gtt_mm_free_mem(mm, node);
12907 +failed_pages_alloc:
12908 +       kfree(page_list);
12909 +       return ret;
12910 +}
12911 +
12912 +int psb_gtt_unmap_meminfo(struct drm_device *dev, IMG_HANDLE hKernelMemInfo)
12913 +{
12914 +       struct drm_psb_private *dev_priv
12915 +              = (struct drm_psb_private *)dev->dev_private;
12916 +       struct psb_gtt_mm *mm = dev_priv->gtt_mm;
12917 +       struct psb_gtt *pg = dev_priv->pg;
12918 +       uint32_t pages, offset_pages;
12919 +       struct drm_mm_node *node;
12920 +       int ret;
12921 +
12922 +       ret = psb_gtt_remove_node(mm,
12923 +                                 (u32)psb_get_tgid(),
12924 +                                 (u32)hKernelMemInfo,
12925 +                                 &node);
12926 +       if (ret) {
12927 +               DRM_DEBUG("remove node failed\n");
12928 +               return ret;
12929 +       }
12930 +
12931 +       /*remove gtt entries*/
12932 +       offset_pages = node->start;
12933 +       pages = node->size;
12934 +
12935 +       psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0);
12936 +
12937 +
12938 +       /*free tt node*/
12939 +
12940 +       psb_gtt_mm_free_mem(mm, node);
12941 +       return 0;
12942 +}
12943 +
12944 +int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
12945 +                              struct drm_file *file_priv)
12946 +{
12947 +       struct psb_gtt_mapping_arg *arg
12948 +              = (struct psb_gtt_mapping_arg *)data;
12949 +       uint32_t *offset_pages = &arg->offset_pages;
12950 +
12951 +       DRM_DEBUG("\n");
12952 +
12953 +       return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages);
12954 +}
12955 +
12956 +int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
12957 +                               struct drm_file *file_priv)
12958 +{
12959 +
12960 +       struct psb_gtt_mapping_arg *arg
12961 +              = (struct psb_gtt_mapping_arg *)data;
12962 +
12963 +       DRM_DEBUG("\n");
12964 +
12965 +       return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo);
12966 +}
12967 +
12968 +int psb_gtt_map_pvr_memory(struct drm_device *dev, 
12969 +                                                                unsigned int hHandle,
12970 +                                                            unsigned int ui32TaskId,
12971 +                                                                IMG_CPU_PHYADDR *pPages,
12972 +                                                                unsigned int ui32PagesNum,
12973 +                                                                unsigned int *ui32Offset) 
12974 +{
12975 +       struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private; 
12976 +       struct psb_gtt_mm * mm = dev_priv->gtt_mm;
12977 +       struct psb_gtt * pg = dev_priv->pg;
12978 +       
12979 +       uint32_t size, pages, offset_pages;
12980 +       struct drm_mm_node * node = NULL;
12981 +       struct psb_gtt_mem_mapping * mapping = NULL;
12982 +       int ret;
12983 +
12984 +       size = ui32PagesNum * PAGE_SIZE;
12985 +       pages = 0;   
12986 +
12987 +       /*alloc memory in TT apeture*/
12988 +       ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node);
12989 +       if(ret) 
12990 +       {
12991 +               DRM_DEBUG("alloc TT memory error\n");
12992 +               goto failed_pages_alloc;
12993 +       }
12994 +
12995 +   /*update psb_gtt_mm*/
12996 +       ret = psb_gtt_add_node(mm,
12997 +                                                  (u32)ui32TaskId,
12998 +                                                  (u32)hHandle,
12999 +                                                  node,
13000 +                                                  &mapping);
13001 +       if(ret) 
13002 +       {
13003 +               DRM_DEBUG("add_node failed");
13004 +               goto failed_add_node;
13005 +       }
13006 +
13007 +       node = mapping->node;
13008 +       offset_pages = node->start;
13009 +
13010 +       DRM_DEBUG("get free node for %ld pages, offset %ld pages", pages, offset_pages);
13011 +
13012 +       /*update gtt*/
13013 +       psb_gtt_insert_phys_addresses( pg, pPages, (unsigned)offset_pages, (unsigned)ui32PagesNum, 0 );
13014 +
13015 +       *ui32Offset = offset_pages;
13016 +       return 0;
13017 +
13018 +failed_add_node:
13019 +       psb_gtt_mm_free_mem(mm, node);
13020 +failed_pages_alloc:
13021 +       return ret;     
13022 +}
13023 +
13024 +
13025 +int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle, unsigned int ui32TaskId) 
13026 +{
13027 +       struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
13028 +       struct psb_gtt_mm * mm = dev_priv->gtt_mm;
13029 +       struct psb_gtt * pg = dev_priv->pg;
13030 +       uint32_t pages, offset_pages;
13031 +       struct drm_mm_node * node;
13032 +       int ret;
13033 +
13034 +       ret = psb_gtt_remove_node(mm,
13035 +                                                         (u32)ui32TaskId,
13036 +                                                         (u32)hHandle,
13037 +                              &node);
13038 +       if(ret)
13039 +       {
13040 +               printk("remove node failed\n");
13041 +               return ret;
13042 +       }
13043 +
13044 +       /*remove gtt entries*/
13045 +       offset_pages = node->start;
13046 +       pages = node->size;
13047 +
13048 +       psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0);
13049 +
13050 +       /*free tt node*/
13051 +       psb_gtt_mm_free_mem(mm, node);
13052 +       return 0;
13053 +}
13054 diff --git a/drivers/gpu/drm/mrst/drv/psb_gtt.h b/drivers/gpu/drm/mrst/drv/psb_gtt.h
13055 new file mode 100644
13056 index 0000000..ab19989
13057 --- /dev/null
13058 +++ b/drivers/gpu/drm/mrst/drv/psb_gtt.h
13059 @@ -0,0 +1,111 @@
13060 +/**************************************************************************
13061 + * Copyright (c) 2007-2008, Intel Corporation.
13062 + * All Rights Reserved.
13063 + *
13064 + * This program is free software; you can redistribute it and/or modify it
13065 + * under the terms and conditions of the GNU General Public License,
13066 + * version 2, as published by the Free Software Foundation.
13067 + *
13068 + * This program is distributed in the hope it will be useful, but WITHOUT
13069 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13070 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13071 + * more details.
13072 + *
13073 + * You should have received a copy of the GNU General Public License along with
13074 + * this program; if not, write to the Free Software Foundation, Inc., 
13075 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13076 + *
13077 + **************************************************************************/
13078 +
13079 +#ifndef _PSB_GTT_H_
13080 +#define _PSB_GTT_H_
13081 +
13082 +#include <drm/drmP.h>
13083 +
13084 +#include "img_types.h"
13085 +
13086 +struct psb_gtt {
13087 +       struct drm_device *dev;
13088 +       int initialized;
13089 +       uint32_t gatt_start;
13090 +       uint32_t mmu_gatt_start;
13091 +       uint32_t ci_start;
13092 +       uint32_t rar_start;
13093 +       uint32_t gtt_start;
13094 +       uint32_t gtt_phys_start;
13095 +       unsigned gtt_pages;
13096 +       unsigned gatt_pages;
13097 +       uint32_t stolen_base;
13098 +       void *vram_addr;
13099 +       uint32_t pge_ctl;
13100 +       u16 gmch_ctrl;
13101 +       unsigned long stolen_size;
13102 +       unsigned long vram_stolen_size;
13103 +       unsigned long ci_stolen_size;
13104 +       unsigned long rar_stolen_size;
13105 +       uint32_t *gtt_map;
13106 +       struct rw_semaphore sem;
13107 +};
13108 +
13109 +struct psb_gtt_mm {
13110 +       struct drm_mm base;
13111 +       struct drm_open_hash hash;
13112 +       uint32_t count;
13113 +       spinlock_t lock;
13114 +};
13115 +
13116 +struct psb_gtt_hash_entry {
13117 +       struct drm_open_hash ht;
13118 +       uint32_t count;
13119 +       struct drm_hash_item item;
13120 +};
13121 +
13122 +struct psb_gtt_mem_mapping {
13123 +       struct drm_mm_node *node;
13124 +       struct drm_hash_item item;
13125 +};
13126 +
13127 +#if 0
13128 +/*Ioctl args*/
13129 +struct psb_gtt_mapping_arg {
13130 +       IMG_HANDLE hKernelMemInfo;
13131 +};
13132 +#endif
13133 +
13134 +/*Exported functions*/
13135 +extern int psb_gtt_init(struct psb_gtt *pg, int resume);
13136 +extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
13137 +                               unsigned offset_pages, unsigned num_pages,
13138 +                               unsigned desired_tile_stride,
13139 +                               unsigned hw_tile_stride, int type);
13140 +extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
13141 +                               unsigned num_pages,
13142 +                               unsigned desired_tile_stride,
13143 +                               unsigned hw_tile_stride);
13144 +
13145 +extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
13146 +extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
13147 +extern int psb_gtt_map_meminfo(struct drm_device *dev,
13148 +                               IMG_HANDLE hKernelMemInfo,
13149 +                               uint32_t *offset);
13150 +extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
13151 +                                IMG_HANDLE hKernelMemInfo);
13152 +extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
13153 +                                    struct drm_file *file_priv);
13154 +extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
13155 +                                      struct drm_file *file_priv);
13156 +extern int psb_gtt_mm_init(struct psb_gtt *pg);
13157 +extern void psb_gtt_mm_takedown(void);
13158 +
13159 +extern int psb_gtt_map_pvr_memory(struct drm_device *dev,
13160 +                                                                  unsigned int hHandle,
13161 +                                                                  unsigned int ui32TaskId,
13162 +                                                                  IMG_CPU_PHYADDR *pPages,
13163 +                                                                  unsigned int ui32PagesNum,
13164 +                                                                  unsigned int *ui32Offset);
13165 +
13166 +extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev,
13167 +                                                                        unsigned int hHandle,
13168 +                                                                        unsigned int ui32TaskId);
13169 +
13170 +#endif
13171 diff --git a/drivers/gpu/drm/mrst/drv/psb_hotplug.c b/drivers/gpu/drm/mrst/drv/psb_hotplug.c
13172 new file mode 100644
13173 index 0000000..d50fd83
13174 --- /dev/null
13175 +++ b/drivers/gpu/drm/mrst/drv/psb_hotplug.c
13176 @@ -0,0 +1,425 @@
13177 +/*
13178 + * Copyright Â© 2009 Intel Corporation
13179 + *
13180 + * This program is free software; you can redistribute it and/or modify it
13181 + * under the terms and conditions of the GNU General Public License,
13182 + * version 2, as published by the Free Software Foundation.
13183 + *
13184 + * This program is distributed in the hope it will be useful, but WITHOUT
13185 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13186 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13187 + * more details.
13188 + *
13189 + * You should have received a copy of the GNU General Public License along with
13190 + * this program; if not, write to the Free Software Foundation, Inc., 
13191 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13192 + *
13193 + * Authors:
13194 + *    James C. Gualario <james.c.gualario@intel.com>
13195 + *
13196 + */
13197 +
13198 +#include "psb_umevents.h"
13199 +#include "psb_hotplug.h"
13200 +/**
13201 + * inform the kernel of the work to be performed and related function.
13202 + *
13203 + */
13204 +DECLARE_WORK(hotplug_dev_create_work, &psb_hotplug_dev_create_wq);
13205 +DECLARE_WORK(hotplug_dev_remove_work, &psb_hotplug_dev_remove_wq);
13206 +DECLARE_WORK(hotplug_dev_change_work, &psb_hotplug_dev_change_wq);
13207 +/**
13208 + * psb_hotplug_notify_change_um - notify user mode of hotplug changes
13209 + *
13210 + * @name: name of event to notify user mode of change to
13211 + * @state: hotplug state to search for event object in
13212 + *
13213 + */
13214 +int psb_hotplug_notify_change_um(const char *name,
13215 +                            struct hotplug_state *state)
13216 +{
13217 +       strcpy(&(state->hotplug_change_wq_data.dev_name_arry
13218 +                [state->hotplug_change_wq_data.dev_name_write][0]), name);
13219 +       state->hotplug_change_wq_data.dev_name_arry_rw_status
13220 +               [state->hotplug_change_wq_data.dev_name_write] =
13221 +               DRM_HOTPLUG_READY_TO_READ;
13222 +       if (state->hotplug_change_wq_data.dev_name_read_write_wrap_ack == 1)
13223 +               state->hotplug_change_wq_data.dev_name_read_write_wrap_ack = 0;
13224 +       state->hotplug_change_wq_data.dev_name_write++;
13225 +       if (state->hotplug_change_wq_data.dev_name_write ==
13226 +          state->hotplug_change_wq_data.dev_name_read) {
13227 +               state->hotplug_change_wq_data.dev_name_write--;
13228 +               return IRQ_NONE;
13229 +       }
13230 +       if (state->hotplug_change_wq_data.dev_name_write >
13231 +          DRM_HOTPLUG_RING_DEPTH_MAX) {
13232 +               state->hotplug_change_wq_data.dev_name_write = 0;
13233 +               state->hotplug_change_wq_data.dev_name_write_wrap = 1;
13234 +       }
13235 +       state->hotplug_change_wq_data.hotplug_dev_list = state->list;
13236 +       queue_work(state->hotplug_wq, &(state->hotplug_change_wq_data.work));
13237 +       return IRQ_HANDLED;
13238 +}
13239 +/**
13240 + *
13241 + * psb_hotplug_create_and_notify_um - create and notify user mode of new dev
13242 + *
13243 + * @name: name to give for new event / device
13244 + * @state: hotplug state to track new event /device in
13245 + *
13246 + */
13247 +int psb_hotplug_create_and_notify_um(const char *name,
13248 +                                struct hotplug_state *state)
13249 +{
13250 +       strcpy(&(state->hotplug_create_wq_data.dev_name_arry
13251 +                [state->hotplug_create_wq_data.dev_name_write][0]), name);
13252 +       state->hotplug_create_wq_data.dev_name_arry_rw_status
13253 +               [state->hotplug_create_wq_data.dev_name_write] =
13254 +               DRM_HOTPLUG_READY_TO_READ;
13255 +       if (state->hotplug_create_wq_data.dev_name_read_write_wrap_ack == 1)
13256 +               state->hotplug_create_wq_data.dev_name_read_write_wrap_ack = 0;
13257 +       state->hotplug_create_wq_data.dev_name_write++;
13258 +       if (state->hotplug_create_wq_data.dev_name_write ==
13259 +          state->hotplug_create_wq_data.dev_name_read) {
13260 +               state->hotplug_create_wq_data.dev_name_write--;
13261 +               return IRQ_NONE;
13262 +       }
13263 +       if (state->hotplug_create_wq_data.dev_name_write >
13264 +          DRM_HOTPLUG_RING_DEPTH_MAX) {
13265 +               state->hotplug_create_wq_data.dev_name_write = 0;
13266 +               state->hotplug_create_wq_data.dev_name_write_wrap = 1;
13267 +       }
13268 +       state->hotplug_create_wq_data.hotplug_dev_list = state->list;
13269 +       queue_work(state->hotplug_wq, &(state->hotplug_create_wq_data.work));
13270 +       return IRQ_HANDLED;
13271 +}
13272 +EXPORT_SYMBOL(psb_hotplug_create_and_notify_um);
13273 +/**
13274 + * psb_hotplug_remove_and_notify_um - remove device and notify user mode
13275 + *
13276 + * @name: name of event / device to remove
13277 + * @state: hotplug state to remove event / device from
13278 + *
13279 + */
13280 +int psb_hotplug_remove_and_notify_um(const char *name,
13281 +                                struct hotplug_state *state)
13282 +{
13283 +       strcpy(&(state->hotplug_remove_wq_data.dev_name_arry
13284 +                [state->hotplug_remove_wq_data.dev_name_write][0]), name);
13285 +       state->hotplug_remove_wq_data.dev_name_arry_rw_status
13286 +               [state->hotplug_remove_wq_data.dev_name_write] =
13287 +               DRM_HOTPLUG_READY_TO_READ;
13288 +       if (state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack == 1)
13289 +               state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack = 0;
13290 +       state->hotplug_remove_wq_data.dev_name_write++;
13291 +       if (state->hotplug_remove_wq_data.dev_name_write ==
13292 +          state->hotplug_remove_wq_data.dev_name_read) {
13293 +               state->hotplug_remove_wq_data.dev_name_write--;
13294 +               return IRQ_NONE;
13295 +       }
13296 +       if (state->hotplug_remove_wq_data.dev_name_write >
13297 +          DRM_HOTPLUG_RING_DEPTH_MAX) {
13298 +               state->hotplug_remove_wq_data.dev_name_write = 0;
13299 +               state->hotplug_remove_wq_data.dev_name_write_wrap = 1;
13300 +       }
13301 +       state->hotplug_remove_wq_data.hotplug_dev_list = state->list;
13302 +       queue_work(state->hotplug_wq, &(state->hotplug_remove_wq_data.work));
13303 +       return IRQ_HANDLED;
13304 +}
13305 +EXPORT_SYMBOL(psb_hotplug_remove_and_notify_um);
13306 +/**
13307 + * psb_hotplug_device_pool_create_and_init - make new hotplug device pool
13308 + *
13309 + * @parent_kobj: parent kobject to associate hotplug kset with
13310 + * @state: hotplug state to assocaite workqueues with
13311 + *
13312 + */
13313 +struct umevent_list *psb_hotplug_device_pool_create_and_init(
13314 +                                    struct kobject *parent_kobj,
13315 +                                    struct hotplug_state *state)
13316 +{
13317 +       struct umevent_list *new_hotplug_dev_list = NULL;
13318 +
13319 +       new_hotplug_dev_list = psb_umevent_create_list();
13320 +       if (new_hotplug_dev_list)
13321 +               psb_umevent_init(parent_kobj, new_hotplug_dev_list,
13322 +                                "psb_hotplug");
13323 +
13324 +       state->hotplug_wq = create_singlethread_workqueue("hotplug-wq");
13325 +       if (!state->hotplug_wq)
13326 +               return NULL;
13327 +
13328 +       INIT_WORK(&state->hotplug_create_wq_data.work,
13329 +                 psb_hotplug_dev_create_wq);
13330 +       INIT_WORK(&state->hotplug_remove_wq_data.work,
13331 +                 psb_hotplug_dev_remove_wq);
13332 +       INIT_WORK(&state->hotplug_change_wq_data.work,
13333 +                 psb_hotplug_dev_change_wq);
13334 +
13335 +       state->hotplug_create_wq_data.dev_name_read = 0;
13336 +       state->hotplug_create_wq_data.dev_name_write = 0;
13337 +       state->hotplug_create_wq_data.dev_name_write_wrap = 0;
13338 +       state->hotplug_create_wq_data.dev_name_read_write_wrap_ack = 0;
13339 +       memset(&(state->hotplug_create_wq_data.dev_name_arry_rw_status[0]),
13340 +              0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
13341 +
13342 +       state->hotplug_remove_wq_data.dev_name_read = 0;
13343 +       state->hotplug_remove_wq_data.dev_name_write = 0;
13344 +       state->hotplug_remove_wq_data.dev_name_write_wrap = 0;
13345 +       state->hotplug_remove_wq_data.dev_name_read_write_wrap_ack = 0;
13346 +       memset(&(state->hotplug_remove_wq_data.dev_name_arry_rw_status[0]),
13347 +              0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
13348 +
13349 +       state->hotplug_change_wq_data.dev_name_read = 0;
13350 +       state->hotplug_change_wq_data.dev_name_write = 0;
13351 +       state->hotplug_change_wq_data.dev_name_write_wrap = 0;
13352 +       state->hotplug_change_wq_data.dev_name_read_write_wrap_ack = 0;
13353 +       memset(&(state->hotplug_change_wq_data.dev_name_arry_rw_status[0]),
13354 +              0, sizeof(int)*DRM_HOTPLUG_RING_DEPTH);
13355 +
13356 +       return new_hotplug_dev_list;
13357 +}
13358 +EXPORT_SYMBOL(psb_hotplug_device_pool_create_and_init);
13359 +/**
13360 + *
13361 + * psb_hotplug_init - init hotplug subsystem
13362 + *
13363 + * @parent_kobj: parent kobject to associate hotplug state with
13364 + *
13365 + */
13366 +struct hotplug_state *psb_hotplug_init(struct kobject *parent_kobj)
13367 +{
13368 +       struct hotplug_state *state;
13369 +       state = kzalloc(sizeof(struct hotplug_state), GFP_KERNEL);
13370 +       state->list = NULL;
13371 +       state->list = psb_hotplug_device_pool_create_and_init(
13372 +                                                     parent_kobj,
13373 +                                                     state);
13374 +       return state;
13375 +}
13376 +/**
13377 + * psb_hotplug_device_pool_destroy - destroy all hotplug related resources
13378 + *
13379 + * @state: hotplug state to destroy
13380 + *
13381 + */
13382 +void psb_hotplug_device_pool_destroy(struct hotplug_state *state)
13383 +{
13384 +       flush_workqueue(state->hotplug_wq);
13385 +       destroy_workqueue(state->hotplug_wq);
13386 +       psb_umevent_cleanup(state->list);
13387 +       kfree(state);
13388 +}
13389 +EXPORT_SYMBOL(psb_hotplug_device_pool_destroy);
13390 +/**
13391 + * psb_hotplug_dev_create_wq - create workqueue implementation
13392 + *
13393 + * @work: work struct to use for kernel scheduling
13394 + *
13395 + */
13396 +void psb_hotplug_dev_create_wq(struct work_struct *work)
13397 +{
13398 +       struct hotplug_disp_workqueue_data *wq_data;
13399 +       struct umevent_obj *wq_working_hotplug_disp_obj;
13400 +       wq_data = to_hotplug_disp_workqueue_data(work);
13401 +       if (wq_data->dev_name_write_wrap == 1) {
13402 +               wq_data->dev_name_read_write_wrap_ack = 1;
13403 +               wq_data->dev_name_write_wrap = 0;
13404 +               while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
13405 +                       if (wq_data->dev_name_arry_rw_status
13406 +                          [wq_data->dev_name_read] ==
13407 +                          DRM_HOTPLUG_READY_TO_READ) {
13408 +                               wq_working_hotplug_disp_obj =
13409 +                               psb_create_umevent_obj(
13410 +                                       &wq_data->dev_name_arry
13411 +                                       [wq_data->dev_name_read][0],
13412 +                                       wq_data->hotplug_dev_list);
13413 +                               wq_data->dev_name_arry_rw_status
13414 +                                       [wq_data->dev_name_read] =
13415 +                                       DRM_HOTPLUG_READ_COMPLETE;
13416 +                               psb_umevent_notify
13417 +                                       (wq_working_hotplug_disp_obj);
13418 +                       }
13419 +                       wq_data->dev_name_read++;
13420 +               }
13421 +               wq_data->dev_name_read = 0;
13422 +               while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
13423 +                       if (wq_data->dev_name_arry_rw_status
13424 +                          [wq_data->dev_name_read] ==
13425 +                          DRM_HOTPLUG_READY_TO_READ) {
13426 +                               wq_working_hotplug_disp_obj =
13427 +                               psb_create_umevent_obj(
13428 +                                       &wq_data->dev_name_arry
13429 +                                       [wq_data->dev_name_read][0],
13430 +                                       wq_data->hotplug_dev_list);
13431 +                               wq_data->dev_name_arry_rw_status
13432 +                                       [wq_data->dev_name_read] =
13433 +                                       DRM_HOTPLUG_READ_COMPLETE;
13434 +                               psb_umevent_notify
13435 +                                       (wq_working_hotplug_disp_obj);
13436 +                       }
13437 +                       wq_data->dev_name_read++;
13438 +               }
13439 +       } else {
13440 +               while (wq_data->dev_name_read < wq_data->dev_name_write) {
13441 +                       if (wq_data->dev_name_arry_rw_status
13442 +                          [wq_data->dev_name_read] ==
13443 +                          DRM_HOTPLUG_READY_TO_READ) {
13444 +                               wq_working_hotplug_disp_obj =
13445 +                               psb_create_umevent_obj(
13446 +                               &wq_data->dev_name_arry
13447 +                                       [wq_data->dev_name_read][0],
13448 +                                       wq_data->hotplug_dev_list);
13449 +                               wq_data->dev_name_arry_rw_status
13450 +                                       [wq_data->dev_name_read] =
13451 +                                       DRM_HOTPLUG_READ_COMPLETE;
13452 +                               psb_umevent_notify
13453 +                                       (wq_working_hotplug_disp_obj);
13454 +                       }
13455 +                       wq_data->dev_name_read++;
13456 +               }
13457 +       }
13458 +       if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
13459 +               wq_data->dev_name_read = 0;
13460 +}
13461 +EXPORT_SYMBOL(psb_hotplug_dev_create_wq);
13462 +/**
13463 + * psb_hotplug_dev_remove_wq - remove workqueue implementation
13464 + *
13465 + * @work: work struct to use for kernel scheduling
13466 + *
13467 + */
13468 +void psb_hotplug_dev_remove_wq(struct work_struct *work)
13469 +{
13470 +       struct hotplug_disp_workqueue_data *wq_data;
13471 +       wq_data = to_hotplug_disp_workqueue_data(work);
13472 +       if (wq_data->dev_name_write_wrap == 1) {
13473 +               wq_data->dev_name_read_write_wrap_ack = 1;
13474 +               wq_data->dev_name_write_wrap = 0;
13475 +               while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
13476 +                       if (wq_data->dev_name_arry_rw_status
13477 +                          [wq_data->dev_name_read] ==
13478 +                          DRM_HOTPLUG_READY_TO_READ) {
13479 +                               psb_umevent_remove_from_list(
13480 +                               wq_data->hotplug_dev_list,
13481 +                               &wq_data->dev_name_arry
13482 +                               [wq_data->dev_name_read][0]);
13483 +                               wq_data->dev_name_arry_rw_status
13484 +                               [wq_data->dev_name_read] =
13485 +                               DRM_HOTPLUG_READ_COMPLETE;
13486 +                       }
13487 +                       wq_data->dev_name_read++;
13488 +               }
13489 +               wq_data->dev_name_read = 0;
13490 +               while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
13491 +                       if (wq_data->dev_name_arry_rw_status
13492 +                          [wq_data->dev_name_read] ==
13493 +                          DRM_HOTPLUG_READY_TO_READ) {
13494 +                               psb_umevent_remove_from_list(
13495 +                               wq_data->hotplug_dev_list,
13496 +                               &wq_data->dev_name_arry
13497 +                               [wq_data->dev_name_read][0]);
13498 +                               wq_data->dev_name_arry_rw_status
13499 +                               [wq_data->dev_name_read] =
13500 +                               DRM_HOTPLUG_READ_COMPLETE;
13501 +                       }
13502 +                       wq_data->dev_name_read++;
13503 +               }
13504 +       } else {
13505 +               while (wq_data->dev_name_read < wq_data->dev_name_write) {
13506 +                       if (wq_data->dev_name_arry_rw_status
13507 +                          [wq_data->dev_name_read] ==
13508 +                          DRM_HOTPLUG_READY_TO_READ) {
13509 +                               psb_umevent_remove_from_list(
13510 +                               wq_data->hotplug_dev_list,
13511 +                               &wq_data->dev_name_arry
13512 +                               [wq_data->dev_name_read][0]);
13513 +                               wq_data->dev_name_arry_rw_status
13514 +                               [wq_data->dev_name_read] =
13515 +                               DRM_HOTPLUG_READ_COMPLETE;
13516 +                       }
13517 +                       wq_data->dev_name_read++;
13518 +               }
13519 +       }
13520 +       if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
13521 +               wq_data->dev_name_read = 0;
13522 +}
13523 +EXPORT_SYMBOL(psb_hotplug_dev_remove_wq);
13524 +/**
13525 + * psb_hotplug_dev_change_wq - change workqueue implementation
13526 + *
13527 + * @work: work struct to use for kernel scheduling
13528 + *
13529 + */
13530 +void psb_hotplug_dev_change_wq(struct work_struct *work)
13531 +{
13532 +       struct hotplug_disp_workqueue_data *wq_data;
13533 +       struct umevent_obj *wq_working_hotplug_disp_obj;
13534 +       wq_data = to_hotplug_disp_workqueue_data(work);
13535 +       if (wq_data->dev_name_write_wrap == 1) {
13536 +               wq_data->dev_name_read_write_wrap_ack = 1;
13537 +               wq_data->dev_name_write_wrap = 0;
13538 +               while (wq_data->dev_name_read != DRM_HOTPLUG_RING_DEPTH_MAX) {
13539 +                       if (wq_data->dev_name_arry_rw_status
13540 +                          [wq_data->dev_name_read] ==
13541 +                          DRM_HOTPLUG_READY_TO_READ) {
13542 +                               wq_data->dev_name_arry_rw_status
13543 +                               [wq_data->dev_name_read] =
13544 +                               DRM_HOTPLUG_READ_COMPLETE;
13545 +
13546 +                               wq_working_hotplug_disp_obj =
13547 +                                       psb_umevent_find_obj(
13548 +                                            &wq_data->dev_name_arry
13549 +                                            [wq_data->dev_name_read][0],
13550 +                                             wq_data->hotplug_dev_list);
13551 +                               psb_umevent_notify_change_gfxsock
13552 +                                       (wq_working_hotplug_disp_obj,
13553 +                                        DRM_HOTPLUG_SOCKET_GROUP_ID);
13554 +                       }
13555 +                       wq_data->dev_name_read++;
13556 +               }
13557 +               wq_data->dev_name_read = 0;
13558 +               while (wq_data->dev_name_read < wq_data->dev_name_write-1) {
13559 +                       if (wq_data->dev_name_arry_rw_status
13560 +                          [wq_data->dev_name_read] ==
13561 +                          DRM_HOTPLUG_READY_TO_READ) {
13562 +                               wq_data->dev_name_arry_rw_status
13563 +                               [wq_data->dev_name_read] =
13564 +                               DRM_HOTPLUG_READ_COMPLETE;
13565 +
13566 +                               wq_working_hotplug_disp_obj =
13567 +                                       psb_umevent_find_obj(
13568 +                                            &wq_data->dev_name_arry
13569 +                                            [wq_data->dev_name_read][0],
13570 +                                             wq_data->hotplug_dev_list);
13571 +                               psb_umevent_notify_change_gfxsock
13572 +                                       (wq_working_hotplug_disp_obj,
13573 +                                        DRM_HOTPLUG_SOCKET_GROUP_ID);
13574 +                       }
13575 +                       wq_data->dev_name_read++;
13576 +               }
13577 +       } else {
13578 +               while (wq_data->dev_name_read < wq_data->dev_name_write) {
13579 +                       if (wq_data->dev_name_arry_rw_status
13580 +                          [wq_data->dev_name_read] ==
13581 +                          DRM_HOTPLUG_READY_TO_READ) {
13582 +                               wq_data->dev_name_arry_rw_status
13583 +                               [wq_data->dev_name_read] =
13584 +                                       DRM_HOTPLUG_READ_COMPLETE;
13585 +
13586 +                               wq_working_hotplug_disp_obj =
13587 +                                       psb_umevent_find_obj(
13588 +                                            &wq_data->dev_name_arry
13589 +                                            [wq_data->dev_name_read][0],
13590 +                                             wq_data->hotplug_dev_list);
13591 +                               psb_umevent_notify_change_gfxsock
13592 +                                       (wq_working_hotplug_disp_obj,
13593 +                                        DRM_HOTPLUG_SOCKET_GROUP_ID);
13594 +                       }
13595 +                       wq_data->dev_name_read++;
13596 +               }
13597 +       }
13598 +       if (wq_data->dev_name_read > DRM_HOTPLUG_RING_DEPTH_MAX)
13599 +               wq_data->dev_name_read = 0;
13600 +}
13601 +EXPORT_SYMBOL(psb_hotplug_dev_change_wq);
13602 diff --git a/drivers/gpu/drm/mrst/drv/psb_hotplug.h b/drivers/gpu/drm/mrst/drv/psb_hotplug.h
13603 new file mode 100644
13604 index 0000000..b6e42a4
13605 --- /dev/null
13606 +++ b/drivers/gpu/drm/mrst/drv/psb_hotplug.h
13607 @@ -0,0 +1,90 @@
13608 +/*
13609 + * Copyright Â© 2009 Intel Corporation
13610 + *
13611 + * This program is free software; you can redistribute it and/or modify it
13612 + * under the terms and conditions of the GNU General Public License,
13613 + * version 2, as published by the Free Software Foundation.
13614 + *
13615 + * This program is distributed in the hope it will be useful, but WITHOUT
13616 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13617 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13618 + * more details.
13619 + *
13620 + * You should have received a copy of the GNU General Public License along with
13621 + * this program; if not, write to the Free Software Foundation, Inc., 
13622 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13623 + *
13624 + * Authors:
13625 + *    James C. Gualario <james.c.gualario@intel.com>
13626 + *
13627 + */
13628 +#ifndef _PSB_HOTPLUG_H_
13629 +#define _PSB_HOTPLUG_H_
13630 +/**
13631 + * required includes
13632 + *
13633 + */
13634 +#include "psb_umevents.h"
13635 +/**
13636 + * hotplug specific defines
13637 + *
13638 + */
13639 +#define DRM_HOTPLUG_RING_DEPTH 256
13640 +#define DRM_HOTPLUG_RING_DEPTH_MAX (DRM_HOTPLUG_RING_DEPTH-1)
13641 +#define DRM_HOTPLUG_READY_TO_READ 1
13642 +#define DRM_HOTPLUG_READ_COMPLETE 2
13643 +/**
13644 + * hotplug workqueue data struct.
13645 + */
13646 +struct hotplug_disp_workqueue_data {
13647 +       struct work_struct work;
13648 +       const char *dev_name;
13649 +       int dev_name_write;
13650 +       int dev_name_read;
13651 +       int dev_name_write_wrap;
13652 +       int dev_name_read_write_wrap_ack;
13653 +       char dev_name_arry[DRM_HOTPLUG_RING_DEPTH][24];
13654 +       int dev_name_arry_rw_status[DRM_HOTPLUG_RING_DEPTH];
13655 +       struct umevent_list *hotplug_dev_list;
13656 +};
13657 +/**
13658 + * hotplug state structure
13659 + *
13660 + */
13661 +struct hotplug_state {
13662 +       struct workqueue_struct *hotplug_wq;
13663 +       struct hotplug_disp_workqueue_data hotplug_remove_wq_data;
13664 +       struct hotplug_disp_workqueue_data hotplug_create_wq_data;
13665 +       struct hotplug_disp_workqueue_data hotplug_change_wq_data;
13666 +       struct umevent_list *list;
13667 +};
13668 +/**
13669 + * main interface function prototytpes for hotplug support.
13670 + *
13671 + */
13672 +struct hotplug_state *psb_hotplug_init(struct kobject *parent_kobj);
13673 +extern int psb_hotplug_notify_change_um(const char *name,
13674 +                                   struct hotplug_state *state);
13675 +extern int psb_hotplug_create_and_notify_um(const char *name,
13676 +                                       struct hotplug_state *state);
13677 +extern int psb_hotplug_remove_and_notify_um(const char *name,
13678 +                                       struct hotplug_state *state);
13679 +extern struct umevent_list *psb_hotplug_device_pool_create_and_init(
13680 +                                           struct kobject *parent_kobj,
13681 +                                           struct hotplug_state *state);
13682 +extern void psb_hotplug_device_pool_destroy(struct hotplug_state *state);
13683 +/**
13684 + * to go back and forth between work strauct and workqueue data
13685 + *
13686 + */
13687 +#define to_hotplug_disp_workqueue_data(x) \
13688 +       container_of(x, struct hotplug_disp_workqueue_data, work)
13689 +
13690 +/**
13691 + * function prototypes for workqueue implementation
13692 + *
13693 + */
13694 +extern void psb_hotplug_dev_create_wq(struct work_struct *work);
13695 +extern void psb_hotplug_dev_remove_wq(struct work_struct *work);
13696 +extern void psb_hotplug_dev_change_wq(struct work_struct *work);
13697 +#endif
13698 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_bios.c b/drivers/gpu/drm/mrst/drv/psb_intel_bios.c
13699 new file mode 100644
13700 index 0000000..e752bde
13701 --- /dev/null
13702 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_bios.c
13703 @@ -0,0 +1,305 @@
13704 +/*
13705 + * Copyright (c) 2006 Intel Corporation
13706 + *
13707 + * This program is free software; you can redistribute it and/or modify it
13708 + * under the terms and conditions of the GNU General Public License,
13709 + * version 2, as published by the Free Software Foundation.
13710 + *
13711 + * This program is distributed in the hope it will be useful, but WITHOUT
13712 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13713 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13714 + * more details.
13715 + *
13716 + * You should have received a copy of the GNU General Public License along with
13717 + * this program; if not, write to the Free Software Foundation, Inc., 
13718 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
13719 + *
13720 + * Authors:
13721 + *    Eric Anholt <eric@anholt.net>
13722 + *
13723 + */
13724 +#include <drm/drmP.h>
13725 +#include <drm/drm.h>
13726 +#include "psb_drm.h"
13727 +#include "psb_drv.h"
13728 +#include "psb_intel_drv.h"
13729 +#include "psb_intel_reg.h"
13730 +#include "psb_intel_bios.h"
13731 +
13732 +
13733 +static void *find_section(struct bdb_header *bdb, int section_id)
13734 +{
13735 +       u8 *base = (u8 *)bdb;
13736 +       int index = 0;
13737 +       u16 total, current_size;
13738 +       u8 current_id;
13739 +
13740 +       /* skip to first section */
13741 +       index += bdb->header_size;
13742 +       total = bdb->bdb_size;
13743 +
13744 +       /* walk the sections looking for section_id */
13745 +       while (index < total) {
13746 +               current_id = *(base + index);
13747 +               index++;
13748 +               current_size = *((u16 *)(base + index));
13749 +               index += 2;
13750 +               if (current_id == section_id)
13751 +                       return base + index;
13752 +               index += current_size;
13753 +       }
13754 +
13755 +       return NULL;
13756 +}
13757 +
13758 +static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
13759 +                       struct lvds_dvo_timing *dvo_timing)
13760 +{
13761 +       panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
13762 +               dvo_timing->hactive_lo;
13763 +       panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
13764 +               ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
13765 +       panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
13766 +               dvo_timing->hsync_pulse_width;
13767 +       panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
13768 +               ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
13769 +
13770 +       panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
13771 +               dvo_timing->vactive_lo;
13772 +       panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
13773 +               dvo_timing->vsync_off;
13774 +       panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
13775 +               dvo_timing->vsync_pulse_width;
13776 +       panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
13777 +               ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
13778 +       panel_fixed_mode->clock = dvo_timing->clock * 10;
13779 +       panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
13780 +
13781 +       /* Some VBTs have bogus h/vtotal values */
13782 +       if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
13783 +               panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
13784 +       if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
13785 +               panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
13786 +
13787 +       drm_mode_set_name(panel_fixed_mode);
13788 +}
13789 +
13790 +static void parse_backlight_data(struct drm_psb_private *dev_priv,
13791 +                               struct bdb_header *bdb)
13792 +{
13793 +       struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
13794 +       struct bdb_lvds_backlight *lvds_bl;
13795 +       u8 p_type = 0;
13796 +       void *bl_start = NULL;
13797 +       struct bdb_lvds_options *lvds_opts
13798 +                               = find_section(bdb, BDB_LVDS_OPTIONS);
13799 +
13800 +       dev_priv->lvds_bl = NULL;
13801 +
13802 +       if (lvds_opts) {
13803 +               DRM_DEBUG("lvds_options found at %p\n", lvds_opts);
13804 +               p_type = lvds_opts->panel_type;
13805 +       } else {
13806 +               DRM_DEBUG("no lvds_options\n");
13807 +               return;
13808 +       }
13809 +
13810 +       bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
13811 +       vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
13812 +
13813 +       lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
13814 +       if (!lvds_bl) {
13815 +               DRM_DEBUG("No memory\n");
13816 +               return;
13817 +       }
13818 +
13819 +       memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
13820 +
13821 +       dev_priv->lvds_bl = lvds_bl;
13822 +}
13823 +
13824 +/* Try to find integrated panel data */
13825 +static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
13826 +                           struct bdb_header *bdb)
13827 +{
13828 +       struct bdb_lvds_options *lvds_options;
13829 +       struct bdb_lvds_lfp_data *lvds_lfp_data;
13830 +       struct bdb_lvds_lfp_data_entry *entry;
13831 +       struct lvds_dvo_timing *dvo_timing;
13832 +       struct drm_display_mode *panel_fixed_mode;
13833 +
13834 +       /* Defaults if we can't find VBT info */
13835 +       dev_priv->lvds_dither = 0;
13836 +       dev_priv->lvds_vbt = 0;
13837 +
13838 +       lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
13839 +       if (!lvds_options)
13840 +               return;
13841 +
13842 +       dev_priv->lvds_dither = lvds_options->pixel_dither;
13843 +       if (lvds_options->panel_type == 0xff)
13844 +               return;
13845 +
13846 +       lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
13847 +       if (!lvds_lfp_data)
13848 +               return;
13849 +
13850 +       dev_priv->lvds_vbt = 1;
13851 +
13852 +       entry = &lvds_lfp_data->data[lvds_options->panel_type];
13853 +       dvo_timing = &entry->dvo_timing;
13854 +
13855 +       panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
13856 +                                     GFP_KERNEL);
13857 +
13858 +       fill_detail_timing_data(panel_fixed_mode, dvo_timing);
13859 +
13860 +       dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
13861 +
13862 +       DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
13863 +       drm_mode_debug_printmodeline(panel_fixed_mode);
13864 +
13865 +       return;
13866 +}
13867 +
13868 +/* Try to find sdvo panel data */
13869 +static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
13870 +                     struct bdb_header *bdb)
13871 +{
13872 +       struct bdb_sdvo_lvds_options *sdvo_lvds_options;
13873 +       struct lvds_dvo_timing *dvo_timing;
13874 +       struct drm_display_mode *panel_fixed_mode;
13875 +
13876 +       dev_priv->sdvo_lvds_vbt_mode = NULL;
13877 +
13878 +       sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
13879 +       if (!sdvo_lvds_options)
13880 +               return;
13881 +
13882 +       dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
13883 +       if (!dvo_timing)
13884 +               return;
13885 +
13886 +       panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
13887 +
13888 +       if (!panel_fixed_mode)
13889 +               return;
13890 +
13891 +       fill_detail_timing_data(panel_fixed_mode,
13892 +                       dvo_timing + sdvo_lvds_options->panel_type);
13893 +
13894 +       dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
13895 +
13896 +       return;
13897 +}
13898 +
13899 +static void parse_general_features(struct drm_psb_private *dev_priv,
13900 +                      struct bdb_header *bdb)
13901 +{
13902 +       struct bdb_general_features *general;
13903 +
13904 +       /* Set sensible defaults in case we can't find the general block */
13905 +       dev_priv->int_tv_support = 1;
13906 +       dev_priv->int_crt_support = 1;
13907 +
13908 +       general = find_section(bdb, BDB_GENERAL_FEATURES);
13909 +       if (general) {
13910 +               dev_priv->int_tv_support = general->int_tv_support;
13911 +               dev_priv->int_crt_support = general->int_crt_support;
13912 +               dev_priv->lvds_use_ssc = general->enable_ssc;
13913 +
13914 +               if (dev_priv->lvds_use_ssc) {
13915 +                       if (IS_I855(dev_priv->dev))
13916 +                               dev_priv->lvds_ssc_freq
13917 +                                       = general->ssc_freq ? 66 : 48;
13918 +                       else
13919 +                               dev_priv->lvds_ssc_freq
13920 +                                       = general->ssc_freq ? 100 : 96;
13921 +               }
13922 +       }
13923 +}
13924 +
13925 +/**
13926 + * psb_intel_init_bios - initialize VBIOS settings & find VBT
13927 + * @dev: DRM device
13928 + *
13929 + * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
13930 + * to appropriate values.
13931 + *
13932 + * VBT existence is a sanity check that is relied on by other i830_bios.c code.
13933 + * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
13934 + * feed an updated VBT back through that, compared to what we'll fetch using
13935 + * this method of groping around in the BIOS data.
13936 + *
13937 + * Returns 0 on success, nonzero on failure.
13938 + */
13939 +bool psb_intel_init_bios(struct drm_device *dev)
13940 +{
13941 +       struct drm_psb_private *dev_priv = dev->dev_private;
13942 +       struct pci_dev *pdev = dev->pdev;
13943 +       struct vbt_header *vbt = NULL;
13944 +       struct bdb_header *bdb;
13945 +       u8 __iomem *bios;
13946 +       size_t size;
13947 +       int i;
13948 +
13949 +       bios = pci_map_rom(pdev, &size);
13950 +       if (!bios)
13951 +               return -1;
13952 +
13953 +       /* Scour memory looking for the VBT signature */
13954 +       for (i = 0; i + 4 < size; i++) {
13955 +               if (!memcmp(bios + i, "$VBT", 4)) {
13956 +                       vbt = (struct vbt_header *)(bios + i);
13957 +                       break;
13958 +               }
13959 +       }
13960 +
13961 +       if (!vbt) {
13962 +               DRM_ERROR("VBT signature missing\n");
13963 +               pci_unmap_rom(pdev, bios);
13964 +               return -1;
13965 +       }
13966 +
13967 +       bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
13968 +
13969 +       /* Grab useful general definitions */
13970 +       parse_general_features(dev_priv, bdb);
13971 +       parse_lfp_panel_data(dev_priv, bdb);
13972 +       parse_sdvo_panel_data(dev_priv, bdb);
13973 +       parse_backlight_data(dev_priv, bdb);
13974 +
13975 +       pci_unmap_rom(pdev, bios);
13976 +
13977 +       return 0;
13978 +}
13979 +
13980 +/**
13981 + * Destory and free VBT data
13982 + */
13983 +void psb_intel_destory_bios(struct drm_device *dev)
13984 +{
13985 +       struct drm_psb_private *dev_priv = dev->dev_private;
13986 +       struct drm_display_mode *sdvo_lvds_vbt_mode =
13987 +                               dev_priv->sdvo_lvds_vbt_mode;
13988 +       struct drm_display_mode *lfp_lvds_vbt_mode =
13989 +                               dev_priv->lfp_lvds_vbt_mode;
13990 +       struct bdb_lvds_backlight *lvds_bl =
13991 +                               dev_priv->lvds_bl;
13992 +
13993 +       /*free sdvo panel mode*/
13994 +       if (sdvo_lvds_vbt_mode) {
13995 +               dev_priv->sdvo_lvds_vbt_mode = NULL;
13996 +               kfree(sdvo_lvds_vbt_mode);
13997 +       }
13998 +
13999 +       if (lfp_lvds_vbt_mode) {
14000 +               dev_priv->lfp_lvds_vbt_mode = NULL;
14001 +               kfree(lfp_lvds_vbt_mode);
14002 +       }
14003 +
14004 +       if (lvds_bl) {
14005 +               dev_priv->lvds_bl = NULL;
14006 +               kfree(lvds_bl);
14007 +       }
14008 +}
14009 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_bios.h b/drivers/gpu/drm/mrst/drv/psb_intel_bios.h
14010 new file mode 100644
14011 index 0000000..dfcae62
14012 --- /dev/null
14013 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_bios.h
14014 @@ -0,0 +1,430 @@
14015 +/*
14016 + * Copyright (c) 2006 Intel Corporation
14017 + *
14018 + * This program is free software; you can redistribute it and/or modify it
14019 + * under the terms and conditions of the GNU General Public License,
14020 + * version 2, as published by the Free Software Foundation.
14021 + *
14022 + * This program is distributed in the hope it will be useful, but WITHOUT
14023 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14024 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14025 + * more details.
14026 + *
14027 + * You should have received a copy of the GNU General Public License along with
14028 + * this program; if not, write to the Free Software Foundation, Inc., 
14029 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
14030 + *
14031 + * Authors:
14032 + *    Eric Anholt <eric@anholt.net>
14033 + *
14034 + */
14035 +
14036 +#ifndef _I830_BIOS_H_
14037 +#define _I830_BIOS_H_
14038 +
14039 +#include <drm/drmP.h>
14040 +
14041 +struct vbt_header {
14042 +       u8 signature[20];               /**< Always starts with 'VBT$' */
14043 +       u16 version;                    /**< decimal */
14044 +       u16 header_size;                /**< in bytes */
14045 +       u16 vbt_size;                   /**< in bytes */
14046 +       u8 vbt_checksum;
14047 +       u8 reserved0;
14048 +       u32 bdb_offset;                 /**< from beginning of VBT */
14049 +       u32 aim_offset[4];              /**< from beginning of VBT */
14050 +} __attribute__((packed));
14051 +
14052 +
14053 +struct bdb_header {
14054 +       u8 signature[16];               /**< Always 'BIOS_DATA_BLOCK' */
14055 +       u16 version;                    /**< decimal */
14056 +       u16 header_size;                /**< in bytes */
14057 +       u16 bdb_size;                   /**< in bytes */
14058 +};
14059 +
14060 +/* strictly speaking, this is a "skip" block, but it has interesting info */
14061 +struct vbios_data {
14062 +       u8 type; /* 0 == desktop, 1 == mobile */
14063 +       u8 relstage;
14064 +       u8 chipset;
14065 +       u8 lvds_present:1;
14066 +       u8 tv_present:1;
14067 +       u8 rsvd2:6; /* finish byte */
14068 +       u8 rsvd3[4];
14069 +       u8 signon[155];
14070 +       u8 copyright[61];
14071 +       u16 code_segment;
14072 +       u8 dos_boot_mode;
14073 +       u8 bandwidth_percent;
14074 +       u8 rsvd4; /* popup memory size */
14075 +       u8 resize_pci_bios;
14076 +       u8 rsvd5; /* is crt already on ddc2 */
14077 +} __attribute__((packed));
14078 +
14079 +/*
14080 + * There are several types of BIOS data blocks (BDBs), each block has
14081 + * an ID and size in the first 3 bytes (ID in first, size in next 2).
14082 + * Known types are listed below.
14083 + */
14084 +#define BDB_GENERAL_FEATURES     1
14085 +#define BDB_GENERAL_DEFINITIONS          2
14086 +#define BDB_OLD_TOGGLE_LIST      3
14087 +#define BDB_MODE_SUPPORT_LIST    4
14088 +#define BDB_GENERIC_MODE_TABLE   5
14089 +#define BDB_EXT_MMIO_REGS        6
14090 +#define BDB_SWF_IO               7
14091 +#define BDB_SWF_MMIO             8
14092 +#define BDB_DOT_CLOCK_TABLE      9
14093 +#define BDB_MODE_REMOVAL_TABLE  10
14094 +#define BDB_CHILD_DEVICE_TABLE  11
14095 +#define BDB_DRIVER_FEATURES     12
14096 +#define BDB_DRIVER_PERSISTENCE  13
14097 +#define BDB_EXT_TABLE_PTRS      14
14098 +#define BDB_DOT_CLOCK_OVERRIDE  15
14099 +#define BDB_DISPLAY_SELECT      16
14100 +/* 17 rsvd */
14101 +#define BDB_DRIVER_ROTATION     18
14102 +#define BDB_DISPLAY_REMOVE      19
14103 +#define BDB_OEM_CUSTOM          20
14104 +#define BDB_EFP_LIST            21 /* workarounds for VGA hsync/vsync */
14105 +#define BDB_SDVO_LVDS_OPTIONS   22
14106 +#define BDB_SDVO_PANEL_DTDS     23
14107 +#define BDB_SDVO_LVDS_PNP_IDS   24
14108 +#define BDB_SDVO_LVDS_POWER_SEQ         25
14109 +#define BDB_TV_OPTIONS          26
14110 +#define BDB_LVDS_OPTIONS        40
14111 +#define BDB_LVDS_LFP_DATA_PTRS  41
14112 +#define BDB_LVDS_LFP_DATA       42
14113 +#define BDB_LVDS_BACKLIGHT      43
14114 +#define BDB_LVDS_POWER          44
14115 +#define BDB_SKIP               254 /* VBIOS private block, ignore */
14116 +
14117 +struct bdb_general_features {
14118 +       /* bits 1 */
14119 +       u8 panel_fitting:2;
14120 +       u8 flexaim:1;
14121 +       u8 msg_enable:1;
14122 +       u8 clear_screen:3;
14123 +       u8 color_flip:1;
14124 +
14125 +       /* bits 2 */
14126 +       u8 download_ext_vbt:1;
14127 +       u8 enable_ssc:1;
14128 +       u8 ssc_freq:1;
14129 +       u8 enable_lfp_on_override:1;
14130 +       u8 disable_ssc_ddt:1;
14131 +       u8 rsvd8:3; /* finish byte */
14132 +
14133 +       /* bits 3 */
14134 +       u8 disable_smooth_vision:1;
14135 +       u8 single_dvi:1;
14136 +       u8 rsvd9:6; /* finish byte */
14137 +
14138 +       /* bits 4 */
14139 +       u8 legacy_monitor_detect;
14140 +
14141 +       /* bits 5 */
14142 +       u8 int_crt_support:1;
14143 +       u8 int_tv_support:1;
14144 +       u8 rsvd11:6; /* finish byte */
14145 +} __attribute__((packed));
14146 +
14147 +struct bdb_general_definitions {
14148 +       /* DDC GPIO */
14149 +       u8 crt_ddc_gmbus_pin;
14150 +
14151 +       /* DPMS bits */
14152 +       u8 dpms_acpi:1;
14153 +       u8 skip_boot_crt_detect:1;
14154 +       u8 dpms_aim:1;
14155 +       u8 rsvd1:5; /* finish byte */
14156 +
14157 +       /* boot device bits */
14158 +       u8 boot_display[2];
14159 +       u8 child_dev_size;
14160 +
14161 +       /* device info */
14162 +       u8 tv_or_lvds_info[33];
14163 +       u8 dev1[33];
14164 +       u8 dev2[33];
14165 +       u8 dev3[33];
14166 +       u8 dev4[33];
14167 +       /* may be another device block here on some platforms */
14168 +};
14169 +
14170 +struct bdb_lvds_options {
14171 +       u8 panel_type;
14172 +       u8 rsvd1;
14173 +       /* LVDS capabilities, stored in a dword */
14174 +       u8 pfit_mode:2;
14175 +       u8 pfit_text_mode_enhanced:1;
14176 +       u8 pfit_gfx_mode_enhanced:1;
14177 +       u8 pfit_ratio_auto:1;
14178 +       u8 pixel_dither:1;
14179 +       u8 lvds_edid:1;
14180 +       u8 rsvd2:1;
14181 +       u8 rsvd4;
14182 +} __attribute__((packed));
14183 +
14184 +struct bdb_lvds_backlight {
14185 +       u8 type:2;
14186 +       u8 pol:1;
14187 +       u8 gpio:3;
14188 +       u8 gmbus:2;
14189 +       u16 freq;
14190 +       u8 minbrightness;
14191 +       u8 i2caddr;
14192 +       u8 brightnesscmd;
14193 +       /*FIXME: more...*/
14194 +} __attribute__((packed));
14195 +
14196 +/* LFP pointer table contains entries to the struct below */
14197 +struct bdb_lvds_lfp_data_ptr {
14198 +       u16 fp_timing_offset; /* offsets are from start of bdb */
14199 +       u8 fp_table_size;
14200 +       u16 dvo_timing_offset;
14201 +       u8 dvo_table_size;
14202 +       u16 panel_pnp_id_offset;
14203 +       u8 pnp_table_size;
14204 +} __attribute__((packed));
14205 +
14206 +struct bdb_lvds_lfp_data_ptrs {
14207 +       u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
14208 +       struct bdb_lvds_lfp_data_ptr ptr[16];
14209 +} __attribute__((packed));
14210 +
14211 +/* LFP data has 3 blocks per entry */
14212 +struct lvds_fp_timing {
14213 +       u16 x_res;
14214 +       u16 y_res;
14215 +       u32 lvds_reg;
14216 +       u32 lvds_reg_val;
14217 +       u32 pp_on_reg;
14218 +       u32 pp_on_reg_val;
14219 +       u32 pp_off_reg;
14220 +       u32 pp_off_reg_val;
14221 +       u32 pp_cycle_reg;
14222 +       u32 pp_cycle_reg_val;
14223 +       u32 pfit_reg;
14224 +       u32 pfit_reg_val;
14225 +       u16 terminator;
14226 +} __attribute__((packed));
14227 +
14228 +struct lvds_dvo_timing {
14229 +       u16 clock;              /**< In 10khz */
14230 +       u8 hactive_lo;
14231 +       u8 hblank_lo;
14232 +       u8 hblank_hi:4;
14233 +       u8 hactive_hi:4;
14234 +       u8 vactive_lo;
14235 +       u8 vblank_lo;
14236 +       u8 vblank_hi:4;
14237 +       u8 vactive_hi:4;
14238 +       u8 hsync_off_lo;
14239 +       u8 hsync_pulse_width;
14240 +       u8 vsync_pulse_width:4;
14241 +       u8 vsync_off:4;
14242 +       u8 rsvd0:6;
14243 +       u8 hsync_off_hi:2;
14244 +       u8 h_image;
14245 +       u8 v_image;
14246 +       u8 max_hv;
14247 +       u8 h_border;
14248 +       u8 v_border;
14249 +       u8 rsvd1:3;
14250 +       u8 digital:2;
14251 +       u8 vsync_positive:1;
14252 +       u8 hsync_positive:1;
14253 +       u8 rsvd2:1;
14254 +} __attribute__((packed));
14255 +
14256 +struct lvds_pnp_id {
14257 +       u16 mfg_name;
14258 +       u16 product_code;
14259 +       u32 serial;
14260 +       u8 mfg_week;
14261 +       u8 mfg_year;
14262 +} __attribute__((packed));
14263 +
14264 +struct bdb_lvds_lfp_data_entry {
14265 +       struct lvds_fp_timing fp_timing;
14266 +       struct lvds_dvo_timing dvo_timing;
14267 +       struct lvds_pnp_id pnp_id;
14268 +} __attribute__((packed));
14269 +
14270 +struct bdb_lvds_lfp_data {
14271 +       struct bdb_lvds_lfp_data_entry data[16];
14272 +} __attribute__((packed));
14273 +
14274 +struct aimdb_header {
14275 +       char signature[16];
14276 +       char oem_device[20];
14277 +       u16 aimdb_version;
14278 +       u16 aimdb_header_size;
14279 +       u16 aimdb_size;
14280 +} __attribute__((packed));
14281 +
14282 +struct aimdb_block {
14283 +       u8 aimdb_id;
14284 +       u16 aimdb_size;
14285 +} __attribute__((packed));
14286 +
14287 +struct vch_panel_data {
14288 +       u16 fp_timing_offset;
14289 +       u8 fp_timing_size;
14290 +       u16 dvo_timing_offset;
14291 +       u8 dvo_timing_size;
14292 +       u16 text_fitting_offset;
14293 +       u8 text_fitting_size;
14294 +       u16 graphics_fitting_offset;
14295 +       u8 graphics_fitting_size;
14296 +} __attribute__((packed));
14297 +
14298 +struct vch_bdb_22 {
14299 +       struct aimdb_block aimdb_block;
14300 +       struct vch_panel_data panels[16];
14301 +} __attribute__((packed));
14302 +
14303 +struct bdb_sdvo_lvds_options {
14304 +       u8 panel_backlight;
14305 +       u8 h40_set_panel_type;
14306 +       u8 panel_type;
14307 +       u8 ssc_clk_freq;
14308 +       u16 als_low_trip;
14309 +       u16 als_high_trip;
14310 +       u8 sclalarcoeff_tab_row_num;
14311 +       u8 sclalarcoeff_tab_row_size;
14312 +       u8 coefficient[8];
14313 +       u8 panel_misc_bits_1;
14314 +       u8 panel_misc_bits_2;
14315 +       u8 panel_misc_bits_3;
14316 +       u8 panel_misc_bits_4;
14317 +} __attribute__((packed));
14318 +
14319 +
14320 +extern bool psb_intel_init_bios(struct drm_device *dev);
14321 +extern void psb_intel_destory_bios(struct drm_device *dev);
14322 +
14323 +/*
14324 + * Driver<->VBIOS interaction occurs through scratch bits in
14325 + * GR18 & SWF*.
14326 + */
14327 +
14328 +/* GR18 bits are set on display switch and hotkey events */
14329 +#define GR18_DRIVER_SWITCH_EN  (1<<7) /* 0: VBIOS control, 1: driver control */
14330 +#define GR18_HOTKEY_MASK       0x78 /* See also SWF4 15:0 */
14331 +#define   GR18_HK_NONE         (0x0<<3)
14332 +#define   GR18_HK_LFP_STRETCH  (0x1<<3)
14333 +#define   GR18_HK_TOGGLE_DISP  (0x2<<3)
14334 +#define   GR18_HK_DISP_SWITCH  (0x4<<3) /* see SWF14 15:0 for what to enable */
14335 +#define   GR18_HK_POPUP_DISABLED (0x6<<3)
14336 +#define   GR18_HK_POPUP_ENABLED        (0x7<<3)
14337 +#define   GR18_HK_PFIT         (0x8<<3)
14338 +#define   GR18_HK_APM_CHANGE   (0xa<<3)
14339 +#define   GR18_HK_MULTIPLE     (0xc<<3)
14340 +#define GR18_USER_INT_EN       (1<<2)
14341 +#define GR18_A0000_FLUSH_EN    (1<<1)
14342 +#define GR18_SMM_EN            (1<<0)
14343 +
14344 +/* Set by driver, cleared by VBIOS */
14345 +#define SWF00_YRES_SHIFT       16
14346 +#define SWF00_XRES_SHIFT       0
14347 +#define SWF00_RES_MASK         0xffff
14348 +
14349 +/* Set by VBIOS at boot time and driver at runtime */
14350 +#define SWF01_TV2_FORMAT_SHIFT 8
14351 +#define SWF01_TV1_FORMAT_SHIFT 0
14352 +#define SWF01_TV_FORMAT_MASK   0xffff
14353 +
14354 +#define SWF10_VBIOS_BLC_I2C_EN (1<<29)
14355 +#define SWF10_GTT_OVERRIDE_EN  (1<<28)
14356 +#define SWF10_LFP_DPMS_OVR     (1<<27) /* override DPMS on display switch */
14357 +#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
14358 +#define   SWF10_OLD_TOGGLE     0x0
14359 +#define   SWF10_TOGGLE_LIST_1  0x1
14360 +#define   SWF10_TOGGLE_LIST_2  0x2
14361 +#define   SWF10_TOGGLE_LIST_3  0x3
14362 +#define   SWF10_TOGGLE_LIST_4  0x4
14363 +#define SWF10_PANNING_EN       (1<<23)
14364 +#define SWF10_DRIVER_LOADED    (1<<22)
14365 +#define SWF10_EXTENDED_DESKTOP (1<<21)
14366 +#define SWF10_EXCLUSIVE_MODE   (1<<20)
14367 +#define SWF10_OVERLAY_EN       (1<<19)
14368 +#define SWF10_PLANEB_HOLDOFF   (1<<18)
14369 +#define SWF10_PLANEA_HOLDOFF   (1<<17)
14370 +#define SWF10_VGA_HOLDOFF      (1<<16)
14371 +#define SWF10_ACTIVE_DISP_MASK 0xffff
14372 +#define   SWF10_PIPEB_LFP2     (1<<15)
14373 +#define   SWF10_PIPEB_EFP2     (1<<14)
14374 +#define   SWF10_PIPEB_TV2      (1<<13)
14375 +#define   SWF10_PIPEB_CRT2     (1<<12)
14376 +#define   SWF10_PIPEB_LFP      (1<<11)
14377 +#define   SWF10_PIPEB_EFP      (1<<10)
14378 +#define   SWF10_PIPEB_TV       (1<<9)
14379 +#define   SWF10_PIPEB_CRT      (1<<8)
14380 +#define   SWF10_PIPEA_LFP2     (1<<7)
14381 +#define   SWF10_PIPEA_EFP2     (1<<6)
14382 +#define   SWF10_PIPEA_TV2      (1<<5)
14383 +#define   SWF10_PIPEA_CRT2     (1<<4)
14384 +#define   SWF10_PIPEA_LFP      (1<<3)
14385 +#define   SWF10_PIPEA_EFP      (1<<2)
14386 +#define   SWF10_PIPEA_TV       (1<<1)
14387 +#define   SWF10_PIPEA_CRT      (1<<0)
14388 +
14389 +#define SWF11_MEMORY_SIZE_SHIFT        16
14390 +#define SWF11_SV_TEST_EN       (1<<15)
14391 +#define SWF11_IS_AGP           (1<<14)
14392 +#define SWF11_DISPLAY_HOLDOFF  (1<<13)
14393 +#define SWF11_DPMS_REDUCED     (1<<12)
14394 +#define SWF11_IS_VBE_MODE      (1<<11)
14395 +#define SWF11_PIPEB_ACCESS     (1<<10) /* 0 here means pipe a */
14396 +#define SWF11_DPMS_MASK                0x07
14397 +#define   SWF11_DPMS_OFF       (1<<2)
14398 +#define   SWF11_DPMS_SUSPEND   (1<<1)
14399 +#define   SWF11_DPMS_STANDBY   (1<<0)
14400 +#define   SWF11_DPMS_ON                0
14401 +
14402 +#define SWF14_GFX_PFIT_EN      (1<<31)
14403 +#define SWF14_TEXT_PFIT_EN     (1<<30)
14404 +#define SWF14_LID_STATUS_CLOSED        (1<<29) /* 0 here means open */
14405 +#define SWF14_POPUP_EN         (1<<28)
14406 +#define SWF14_DISPLAY_HOLDOFF  (1<<27)
14407 +#define SWF14_DISP_DETECT_EN   (1<<26)
14408 +#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
14409 +#define SWF14_DRIVER_STATUS    (1<<24)
14410 +#define SWF14_OS_TYPE_WIN9X    (1<<23)
14411 +#define SWF14_OS_TYPE_WINNT    (1<<22)
14412 +/* 21:19 rsvd */
14413 +#define SWF14_PM_TYPE_MASK     0x00070000
14414 +#define   SWF14_PM_ACPI_VIDEO  (0x4 << 16)
14415 +#define   SWF14_PM_ACPI                (0x3 << 16)
14416 +#define   SWF14_PM_APM_12      (0x2 << 16)
14417 +#define   SWF14_PM_APM_11      (0x1 << 16)
14418 +#define SWF14_HK_REQUEST_MASK  0x0000ffff /* see GR18 6:3 for event type */
14419 +         /* if GR18 indicates a display switch */
14420 +#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
14421 +#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
14422 +#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
14423 +#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
14424 +#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
14425 +#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
14426 +#define   SWF14_DS_PIPEB_TV_EN  (1<<9)
14427 +#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
14428 +#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
14429 +#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
14430 +#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
14431 +#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
14432 +#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
14433 +#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
14434 +#define   SWF14_DS_PIPEA_TV_EN  (1<<1)
14435 +#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
14436 +         /* if GR18 indicates a panel fitting request */
14437 +#define   SWF14_PFIT_EN                (1<<0) /* 0 means disable */
14438 +         /* if GR18 indicates an APM change request */
14439 +#define   SWF14_APM_HIBERNATE  0x4
14440 +#define   SWF14_APM_SUSPEND    0x3
14441 +#define   SWF14_APM_STANDBY    0x1
14442 +#define   SWF14_APM_RESTORE    0x0
14443 +
14444 +#endif /* _I830_BIOS_H_ */
14445 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_display.c b/drivers/gpu/drm/mrst/drv/psb_intel_display.c
14446 new file mode 100644
14447 index 0000000..10c6dec
14448 --- /dev/null
14449 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_display.c
14450 @@ -0,0 +1,2538 @@
14451 +/*
14452 + * Copyright Ã‚© 2006-2007 Intel Corporation
14453 + *
14454 + * This program is free software; you can redistribute it and/or modify it
14455 + * under the terms and conditions of the GNU General Public License,
14456 + * version 2, as published by the Free Software Foundation.
14457 + *
14458 + * This program is distributed in the hope it will be useful, but WITHOUT
14459 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14460 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14461 + * more details.
14462 + *
14463 + * You should have received a copy of the GNU General Public License along with
14464 + * this program; if not, write to the Free Software Foundation, Inc., 
14465 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
14466 + *
14467 + * Authors:
14468 + *     Eric Anholt <eric@anholt.net>
14469 + */
14470 +
14471 +#include <linux/i2c.h>
14472 +
14473 +#include <drm/drmP.h>
14474 +#include "psb_fb.h"
14475 +#include "psb_drv.h"
14476 +#include "psb_intel_drv.h"
14477 +#include "psb_intel_reg.h"
14478 +#include "psb_intel_display.h"
14479 +#include "ospm_power.h"
14480 +
14481 +struct psb_intel_clock_t {
14482 +       /* given values */
14483 +       int n;
14484 +       int m1, m2;
14485 +       int p1, p2;
14486 +       /* derived values */
14487 +       int dot;
14488 +       int vco;
14489 +       int m;
14490 +       int p;
14491 +};
14492 +
14493 +struct psb_intel_range_t {
14494 +       int min, max;
14495 +};
14496 +
14497 +struct psb_intel_p2_t {
14498 +       int dot_limit;
14499 +       int p2_slow, p2_fast;
14500 +};
14501 +
14502 +#define INTEL_P2_NUM                 2
14503 +
14504 +struct psb_intel_limit_t {
14505 +       struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
14506 +       struct psb_intel_p2_t p2;
14507 +};
14508 +
14509 +#define I8XX_DOT_MIN             25000
14510 +#define I8XX_DOT_MAX            350000
14511 +#define I8XX_VCO_MIN            930000
14512 +#define I8XX_VCO_MAX           1400000
14513 +#define I8XX_N_MIN                   3
14514 +#define I8XX_N_MAX                  16
14515 +#define I8XX_M_MIN                  96
14516 +#define I8XX_M_MAX                 140
14517 +#define I8XX_M1_MIN                 18
14518 +#define I8XX_M1_MAX                 26
14519 +#define I8XX_M2_MIN                  6
14520 +#define I8XX_M2_MAX                 16
14521 +#define I8XX_P_MIN                   4
14522 +#define I8XX_P_MAX                 128
14523 +#define I8XX_P1_MIN                  2
14524 +#define I8XX_P1_MAX                 33
14525 +#define I8XX_P1_LVDS_MIN             1
14526 +#define I8XX_P1_LVDS_MAX             6
14527 +#define I8XX_P2_SLOW                 4
14528 +#define I8XX_P2_FAST                 2
14529 +#define I8XX_P2_LVDS_SLOW            14
14530 +#define I8XX_P2_LVDS_FAST            14        /* No fast option */
14531 +#define I8XX_P2_SLOW_LIMIT      165000
14532 +
14533 +#define I9XX_DOT_MIN             20000
14534 +#define I9XX_DOT_MAX            400000
14535 +#define I9XX_VCO_MIN           1400000
14536 +#define I9XX_VCO_MAX           2800000
14537 +#define I9XX_N_MIN                   3
14538 +#define I9XX_N_MAX                   8
14539 +#define I9XX_M_MIN                  70
14540 +#define I9XX_M_MAX                 120
14541 +#define I9XX_M1_MIN                 10
14542 +#define I9XX_M1_MAX                 20
14543 +#define I9XX_M2_MIN                  5
14544 +#define I9XX_M2_MAX                  9
14545 +#define I9XX_P_SDVO_DAC_MIN          5
14546 +#define I9XX_P_SDVO_DAC_MAX         80
14547 +#define I9XX_P_LVDS_MIN                      7
14548 +#define I9XX_P_LVDS_MAX                     98
14549 +#define I9XX_P1_MIN                  1
14550 +#define I9XX_P1_MAX                  8
14551 +#define I9XX_P2_SDVO_DAC_SLOW               10
14552 +#define I9XX_P2_SDVO_DAC_FAST                5
14553 +#define I9XX_P2_SDVO_DAC_SLOW_LIMIT     200000
14554 +#define I9XX_P2_LVDS_SLOW                   14
14555 +#define I9XX_P2_LVDS_FAST                    7
14556 +#define I9XX_P2_LVDS_SLOW_LIMIT                 112000
14557 +
14558 +#define INTEL_LIMIT_I8XX_DVO_DAC    0
14559 +#define INTEL_LIMIT_I8XX_LVDS      1
14560 +#define INTEL_LIMIT_I9XX_SDVO_DAC   2
14561 +#define INTEL_LIMIT_I9XX_LVDS      3
14562 +
14563 +static const struct psb_intel_limit_t psb_intel_limits[] = {
14564 +       {                       /* INTEL_LIMIT_I8XX_DVO_DAC */
14565 +        .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
14566 +        .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
14567 +        .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
14568 +        .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
14569 +        .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
14570 +        .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
14571 +        .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
14572 +        .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
14573 +        .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
14574 +               .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
14575 +        },
14576 +       {                       /* INTEL_LIMIT_I8XX_LVDS */
14577 +        .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
14578 +        .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
14579 +        .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
14580 +        .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
14581 +        .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
14582 +        .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
14583 +        .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
14584 +        .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
14585 +        .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
14586 +               .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
14587 +        },
14588 +       {                       /* INTEL_LIMIT_I9XX_SDVO_DAC */
14589 +        .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
14590 +        .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
14591 +        .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
14592 +        .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
14593 +        .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
14594 +        .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
14595 +        .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX},
14596 +        .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
14597 +        .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
14598 +               .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast =
14599 +               I9XX_P2_SDVO_DAC_FAST},
14600 +        },
14601 +       {                       /* INTEL_LIMIT_I9XX_LVDS */
14602 +        .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
14603 +        .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
14604 +        .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
14605 +        .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
14606 +        .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
14607 +        .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
14608 +        .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX},
14609 +        .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
14610 +        /* The single-channel range is 25-112Mhz, and dual-channel
14611 +         * is 80-224Mhz.  Prefer single channel as much as possible.
14612 +         */
14613 +        .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
14614 +               .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST},
14615 +        },
14616 +};
14617 +
14618 +static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
14619 +{
14620 +       struct drm_device *dev = crtc->dev;
14621 +       const struct psb_intel_limit_t *limit;
14622 +
14623 +       if (IS_I9XX(dev)) {
14624 +               if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
14625 +                       limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS];
14626 +               else
14627 +                       limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
14628 +       } else {
14629 +               if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
14630 +                       limit = &psb_intel_limits[INTEL_LIMIT_I8XX_LVDS];
14631 +               else
14632 +                       limit = &psb_intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
14633 +       }
14634 +       return limit;
14635 +}
14636 +
14637 +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
14638 +
14639 +static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
14640 +{
14641 +       clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
14642 +       clock->p = clock->p1 * clock->p2;
14643 +       clock->vco = refclk * clock->m / (clock->n + 2);
14644 +       clock->dot = clock->vco / clock->p;
14645 +}
14646 +
14647 +/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
14648 +
14649 +static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
14650 +{
14651 +       clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
14652 +       clock->p = clock->p1 * clock->p2;
14653 +       clock->vco = refclk * clock->m / (clock->n + 2);
14654 +       clock->dot = clock->vco / clock->p;
14655 +}
14656 +
14657 +static void psb_intel_clock(struct drm_device *dev, int refclk,
14658 +                       struct psb_intel_clock_t *clock)
14659 +{
14660 +       if (IS_I9XX(dev))
14661 +               return i9xx_clock(refclk, clock);
14662 +       else
14663 +               return i8xx_clock(refclk, clock);
14664 +}
14665 +
14666 +/**
14667 + * Returns whether any output on the specified pipe is of the specified type
14668 + */
14669 +bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
14670 +{
14671 +       struct drm_device *dev = crtc->dev;
14672 +       struct drm_mode_config *mode_config = &dev->mode_config;
14673 +       struct drm_connector *l_entry;
14674 +
14675 +       list_for_each_entry(l_entry, &mode_config->connector_list, head) {
14676 +               if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
14677 +                       struct psb_intel_output *psb_intel_output =
14678 +                           to_psb_intel_output(l_entry);
14679 +                       if (psb_intel_output->type == type)
14680 +                               return true;
14681 +               }
14682 +       }
14683 +       return false;
14684 +}
14685 +
14686 +#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
14687 +/**
14688 + * Returns whether the given set of divisors are valid for a given refclk with
14689 + * the given connectors.
14690 + */
14691 +
14692 +static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc,
14693 +                              struct psb_intel_clock_t *clock)
14694 +{
14695 +       const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
14696 +
14697 +       if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
14698 +               INTELPllInvalid("p1 out of range\n");
14699 +       if (clock->p < limit->p.min || limit->p.max < clock->p)
14700 +               INTELPllInvalid("p out of range\n");
14701 +       if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
14702 +               INTELPllInvalid("m2 out of range\n");
14703 +       if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
14704 +               INTELPllInvalid("m1 out of range\n");
14705 +       if (clock->m1 <= clock->m2)
14706 +               INTELPllInvalid("m1 <= m2\n");
14707 +       if (clock->m < limit->m.min || limit->m.max < clock->m)
14708 +               INTELPllInvalid("m out of range\n");
14709 +       if (clock->n < limit->n.min || limit->n.max < clock->n)
14710 +               INTELPllInvalid("n out of range\n");
14711 +       if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
14712 +               INTELPllInvalid("vco out of range\n");
14713 +       /* XXX: We may need to be checking "Dot clock"
14714 +        * depending on the multiplier, connector, etc.,
14715 +        * rather than just a single range.
14716 +        */
14717 +       if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
14718 +               INTELPllInvalid("dot out of range\n");
14719 +
14720 +       return true;
14721 +}
14722 +
14723 +/**
14724 + * Returns a set of divisors for the desired target clock with the given
14725 + * refclk, or FALSE.  The returned values represent the clock equation:
14726 + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
14727 + */
14728 +static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
14729 +                               int refclk,
14730 +                               struct psb_intel_clock_t *best_clock)
14731 +{
14732 +       struct drm_device *dev = crtc->dev;
14733 +       struct psb_intel_clock_t clock;
14734 +       const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
14735 +       int err = target;
14736 +
14737 +       if (IS_I9XX(dev) && psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
14738 +           (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
14739 +               /*
14740 +                * For LVDS, if the panel is on, just rely on its current
14741 +                * settings for dual-channel.  We haven't figured out how to
14742 +                * reliably set up different single/dual channel state, if we
14743 +                * even can.
14744 +                */
14745 +               if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
14746 +                   LVDS_CLKB_POWER_UP)
14747 +                       clock.p2 = limit->p2.p2_fast;
14748 +               else
14749 +                       clock.p2 = limit->p2.p2_slow;
14750 +       } else {
14751 +               if (target < limit->p2.dot_limit)
14752 +                       clock.p2 = limit->p2.p2_slow;
14753 +               else
14754 +                       clock.p2 = limit->p2.p2_fast;
14755 +       }
14756 +
14757 +       memset(best_clock, 0, sizeof(*best_clock));
14758 +
14759 +       for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
14760 +            clock.m1++) {
14761 +               for (clock.m2 = limit->m2.min;
14762 +                    clock.m2 < clock.m1 && clock.m2 <= limit->m2.max;
14763 +                    clock.m2++) {
14764 +                       for (clock.n = limit->n.min;
14765 +                            clock.n <= limit->n.max; clock.n++) {
14766 +                               for (clock.p1 = limit->p1.min;
14767 +                                    clock.p1 <= limit->p1.max;
14768 +                                    clock.p1++) {
14769 +                                       int this_err;
14770 +
14771 +                                       psb_intel_clock(dev, refclk, &clock);
14772 +
14773 +                                       if (!psb_intel_PLL_is_valid
14774 +                                           (crtc, &clock))
14775 +                                               continue;
14776 +
14777 +                                       this_err = abs(clock.dot - target);
14778 +                                       if (this_err < err) {
14779 +                                               *best_clock = clock;
14780 +                                               err = this_err;
14781 +                                       }
14782 +                               }
14783 +                       }
14784 +               }
14785 +       }
14786 +
14787 +       return err != target;
14788 +}
14789 +
14790 +void psb_intel_wait_for_vblank(struct drm_device *dev)
14791 +{
14792 +       /* Wait for 20ms, i.e. one cycle at 50hz. */
14793 +       udelay(20000);
14794 +}
14795 +
14796 +int psb_intel_pipe_set_base(struct drm_crtc *crtc,
14797 +                           int x, int y, struct drm_framebuffer *old_fb)
14798 +{
14799 +       struct drm_device *dev = crtc->dev;
14800 +       /* struct drm_i915_master_private *master_priv; */
14801 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
14802 +       struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
14803 +       struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
14804 +       int pipe = psb_intel_crtc->pipe;
14805 +       unsigned long Start, Offset;
14806 +       int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
14807 +       int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
14808 +       int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
14809 +       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
14810 +       u32 dspcntr;
14811 +       int ret = 0;
14812 +
14813 +       /* no fb bound */
14814 +       if (!crtc->fb) {
14815 +               DRM_DEBUG("No FB bound\n");
14816 +               return 0;
14817 +       }
14818 +
14819 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
14820 +                                      OSPM_UHB_FORCE_POWER_ON))
14821 +               return 0;
14822 +
14823 +       if (IS_MRST(dev) && (pipe == 0))
14824 +               dspbase = MRST_DSPABASE;
14825 +
14826 +       Start = mode_dev->bo_offset(dev, psbfb);
14827 +       Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
14828 +
14829 +       REG_WRITE(dspstride, crtc->fb->pitch);
14830 +
14831 +       dspcntr = REG_READ(dspcntr_reg);
14832 +       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
14833 +
14834 +       switch (crtc->fb->bits_per_pixel) {
14835 +       case 8:
14836 +               dspcntr |= DISPPLANE_8BPP;
14837 +               break;
14838 +       case 16:
14839 +               if (crtc->fb->depth == 15)
14840 +                       dspcntr |= DISPPLANE_15_16BPP;
14841 +               else
14842 +                       dspcntr |= DISPPLANE_16BPP;
14843 +               break;
14844 +       case 24:
14845 +       case 32:
14846 +               dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
14847 +               break;
14848 +       default:
14849 +               DRM_ERROR("Unknown color depth\n");
14850 +               ret = -EINVAL;
14851 +               goto psb_intel_pipe_set_base_exit;
14852 +       }
14853 +       REG_WRITE(dspcntr_reg, dspcntr);
14854 +
14855 +       DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
14856 +       if (IS_I965G(dev) || IS_MRST(dev)) {
14857 +               REG_WRITE(dspbase, Offset);
14858 +               REG_READ(dspbase);
14859 +               REG_WRITE(dspsurf, Start);
14860 +               REG_READ(dspsurf);
14861 +       } else {
14862 +               REG_WRITE(dspbase, Start + Offset);
14863 +               REG_READ(dspbase);
14864 +       }
14865 +
14866 +psb_intel_pipe_set_base_exit:
14867 +
14868 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
14869 +
14870 +       return ret;
14871 +}
14872 +
14873 +/**
14874 + * Sets the power management mode of the pipe and plane.
14875 + *
14876 + * This code should probably grow support for turning the cursor off and back
14877 + * on appropriately at the same time as we're turning the pipe off/on.
14878 + */
14879 +static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
14880 +{
14881 +       struct drm_device *dev = crtc->dev;
14882 +       /* struct drm_i915_master_private *master_priv; */
14883 +       /* struct drm_i915_private *dev_priv = dev->dev_private; */
14884 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
14885 +       int pipe = psb_intel_crtc->pipe;
14886 +       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
14887 +       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
14888 +       int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
14889 +       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
14890 +       u32 temp;
14891 +       bool enabled;
14892 +
14893 +       /* XXX: When our outputs are all unaware of DPMS modes other than off
14894 +        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
14895 +        */
14896 +       switch (mode) {
14897 +       case DRM_MODE_DPMS_ON:
14898 +       case DRM_MODE_DPMS_STANDBY:
14899 +       case DRM_MODE_DPMS_SUSPEND:
14900 +               /* Enable the DPLL */
14901 +               temp = REG_READ(dpll_reg);
14902 +               if ((temp & DPLL_VCO_ENABLE) == 0) {
14903 +                       REG_WRITE(dpll_reg, temp);
14904 +                       REG_READ(dpll_reg);
14905 +                       /* Wait for the clocks to stabilize. */
14906 +                       udelay(150);
14907 +                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
14908 +                       REG_READ(dpll_reg);
14909 +                       /* Wait for the clocks to stabilize. */
14910 +                       udelay(150);
14911 +                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
14912 +                       REG_READ(dpll_reg);
14913 +                       /* Wait for the clocks to stabilize. */
14914 +                       udelay(150);
14915 +               }
14916 +
14917 +               /* Enable the pipe */
14918 +               temp = REG_READ(pipeconf_reg);
14919 +               if ((temp & PIPEACONF_ENABLE) == 0)
14920 +                       REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
14921 +
14922 +               /* Enable the plane */
14923 +               temp = REG_READ(dspcntr_reg);
14924 +               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
14925 +                       REG_WRITE(dspcntr_reg,
14926 +                                 temp | DISPLAY_PLANE_ENABLE);
14927 +                       /* Flush the plane changes */
14928 +                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
14929 +               }
14930 +
14931 +               psb_intel_crtc_load_lut(crtc);
14932 +
14933 +               /* Give the overlay scaler a chance to enable
14934 +                * if it's on this pipe */
14935 +               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
14936 +               break;
14937 +       case DRM_MODE_DPMS_OFF:
14938 +               /* Give the overlay scaler a chance to disable
14939 +                * if it's on this pipe */
14940 +               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
14941 +
14942 +               /* Disable the VGA plane that we never use */
14943 +               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
14944 +
14945 +               /* Disable display plane */
14946 +               temp = REG_READ(dspcntr_reg);
14947 +               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
14948 +                       REG_WRITE(dspcntr_reg,
14949 +                                 temp & ~DISPLAY_PLANE_ENABLE);
14950 +                       /* Flush the plane changes */
14951 +                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
14952 +                       REG_READ(dspbase_reg);
14953 +               }
14954 +
14955 +               if (!IS_I9XX(dev)) {
14956 +                       /* Wait for vblank for the disable to take effect */
14957 +                       psb_intel_wait_for_vblank(dev);
14958 +               }
14959 +
14960 +               /* Next, disable display pipes */
14961 +               temp = REG_READ(pipeconf_reg);
14962 +               if ((temp & PIPEACONF_ENABLE) != 0) {
14963 +                       REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
14964 +                       REG_READ(pipeconf_reg);
14965 +               }
14966 +
14967 +               /* Wait for vblank for the disable to take effect. */
14968 +               psb_intel_wait_for_vblank(dev);
14969 +
14970 +               temp = REG_READ(dpll_reg);
14971 +               if ((temp & DPLL_VCO_ENABLE) != 0) {
14972 +                       REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
14973 +                       REG_READ(dpll_reg);
14974 +               }
14975 +
14976 +               /* Wait for the clocks to turn off. */
14977 +               udelay(150);
14978 +               break;
14979 +       }
14980 +
14981 +       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
14982 +
14983 +#if 0                          /* JB: Add vblank support later */
14984 +       if (enabled)
14985 +               dev_priv->vblank_pipe |= (1 << pipe);
14986 +       else
14987 +               dev_priv->vblank_pipe &= ~(1 << pipe);
14988 +#endif
14989 +
14990 +#if 0                          /* JB: Add sarea support later */
14991 +       if (!dev->primary->master)
14992 +               return 0;
14993 +
14994 +       master_priv = dev->primary->master->driver_priv;
14995 +       if (!master_priv->sarea_priv)
14996 +               return 0;
14997 +
14998 +       switch (pipe) {
14999 +       case 0:
15000 +               master_priv->sarea_priv->planeA_w =
15001 +                   enabled ? crtc->mode.hdisplay : 0;
15002 +               master_priv->sarea_priv->planeA_h =
15003 +                   enabled ? crtc->mode.vdisplay : 0;
15004 +               break;
15005 +       case 1:
15006 +               master_priv->sarea_priv->planeB_w =
15007 +                   enabled ? crtc->mode.hdisplay : 0;
15008 +               master_priv->sarea_priv->planeB_h =
15009 +                   enabled ? crtc->mode.vdisplay : 0;
15010 +               break;
15011 +       default:
15012 +               DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
15013 +               break;
15014 +       }
15015 +#endif
15016 +
15017 +       /*Set FIFO Watermarks*/
15018 +       REG_WRITE(DSPARB, 0x3F3E);
15019 +}
15020 +
15021 +static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
15022 +{
15023 +       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
15024 +       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
15025 +}
15026 +
15027 +static void psb_intel_crtc_commit(struct drm_crtc *crtc)
15028 +{
15029 +       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
15030 +       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
15031 +}
15032 +
15033 +void psb_intel_encoder_prepare(struct drm_encoder *encoder)
15034 +{
15035 +       struct drm_encoder_helper_funcs *encoder_funcs =
15036 +           encoder->helper_private;
15037 +       /* lvds has its own version of prepare see psb_intel_lvds_prepare */
15038 +       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
15039 +}
15040 +
15041 +void psb_intel_encoder_commit(struct drm_encoder *encoder)
15042 +{
15043 +       struct drm_encoder_helper_funcs *encoder_funcs =
15044 +           encoder->helper_private;
15045 +       /* lvds has its own version of commit see psb_intel_lvds_commit */
15046 +       encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
15047 +}
15048 +
15049 +static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
15050 +                                 struct drm_display_mode *mode,
15051 +                                 struct drm_display_mode *adjusted_mode)
15052 +{
15053 +       return true;
15054 +}
15055 +
15056 +
15057 +/**
15058 + * Return the pipe currently connected to the panel fitter,
15059 + * or -1 if the panel fitter is not present or not in use
15060 + */
15061 +static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
15062 +{
15063 +       u32 pfit_control;
15064 +
15065 +       /* i830 doesn't have a panel fitter */
15066 +       if (IS_I830(dev))
15067 +               return -1;
15068 +
15069 +       pfit_control = REG_READ(PFIT_CONTROL);
15070 +
15071 +       /* See if the panel fitter is in use */
15072 +       if ((pfit_control & PFIT_ENABLE) == 0)
15073 +               return -1;
15074 +
15075 +       /* 965 can place panel fitter on either pipe */
15076 +       if (IS_I965G(dev) || IS_MRST(dev))
15077 +               return (pfit_control >> 29) & 0x3;
15078 +
15079 +       /* older chips can only use pipe 1 */
15080 +       return 1;
15081 +}
15082 +
15083 +static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
15084 +                              struct drm_display_mode *mode,
15085 +                              struct drm_display_mode *adjusted_mode,
15086 +                              int x, int y,
15087 +                              struct drm_framebuffer *old_fb)
15088 +{
15089 +       struct drm_device *dev = crtc->dev;
15090 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15091 +       int pipe = psb_intel_crtc->pipe;
15092 +       int fp_reg = (pipe == 0) ? FPA0 : FPB0;
15093 +       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
15094 +       int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
15095 +       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
15096 +       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
15097 +       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
15098 +       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
15099 +       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
15100 +       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
15101 +       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
15102 +       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
15103 +       int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
15104 +       int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
15105 +       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
15106 +       int refclk;
15107 +       struct psb_intel_clock_t clock;
15108 +       u32 dpll = 0, fp = 0, dspcntr, pipeconf;
15109 +       bool ok, is_sdvo = false, is_dvo = false;
15110 +       bool is_crt = false, is_lvds = false, is_tv = false;
15111 +       struct drm_mode_config *mode_config = &dev->mode_config;
15112 +       struct drm_connector *connector;
15113 +
15114 +       list_for_each_entry(connector, &mode_config->connector_list, head) {
15115 +               struct psb_intel_output *psb_intel_output =
15116 +                   to_psb_intel_output(connector);
15117 +
15118 +               if (!connector->encoder
15119 +                   || connector->encoder->crtc != crtc)
15120 +                       continue;
15121 +
15122 +               switch (psb_intel_output->type) {
15123 +               case INTEL_OUTPUT_LVDS:
15124 +                       is_lvds = true;
15125 +                       break;
15126 +               case INTEL_OUTPUT_SDVO:
15127 +                       is_sdvo = true;
15128 +                       break;
15129 +               case INTEL_OUTPUT_DVO:
15130 +                       is_dvo = true;
15131 +                       break;
15132 +               case INTEL_OUTPUT_TVOUT:
15133 +                       is_tv = true;
15134 +                       break;
15135 +               case INTEL_OUTPUT_ANALOG:
15136 +                       is_crt = true;
15137 +                       break;
15138 +               }
15139 +       }
15140 +
15141 +       if (IS_I9XX(dev))
15142 +               refclk = 96000;
15143 +       else
15144 +               refclk = 48000;
15145 +
15146 +       ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
15147 +                                &clock);
15148 +       if (!ok) {
15149 +               DRM_ERROR("Couldn't find PLL settings for mode!\n");
15150 +               return 0;
15151 +       }
15152 +
15153 +       fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
15154 +
15155 +       dpll = DPLL_VGA_MODE_DIS;
15156 +       if (IS_I9XX(dev)) {
15157 +               if (is_lvds) {
15158 +                       dpll |= DPLLB_MODE_LVDS;
15159 +                       if (IS_POULSBO(dev))
15160 +                               dpll |= DPLL_DVO_HIGH_SPEED;
15161 +               } else
15162 +                       dpll |= DPLLB_MODE_DAC_SERIAL;
15163 +               if (is_sdvo) {
15164 +                       dpll |= DPLL_DVO_HIGH_SPEED;
15165 +                       if (IS_I945G(dev) ||
15166 +                           IS_I945GM(dev) ||
15167 +                           IS_POULSBO(dev)) {
15168 +                               int sdvo_pixel_multiply =
15169 +                                   adjusted_mode->clock / mode->clock;
15170 +                               dpll |=
15171 +                                   (sdvo_pixel_multiply -
15172 +                                    1) << SDVO_MULTIPLIER_SHIFT_HIRES;
15173 +                       }
15174 +               }
15175 +
15176 +               /* compute bitmask from p1 value */
15177 +               dpll |= (1 << (clock.p1 - 1)) << 16;
15178 +               switch (clock.p2) {
15179 +               case 5:
15180 +                       dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
15181 +                       break;
15182 +               case 7:
15183 +                       dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
15184 +                       break;
15185 +               case 10:
15186 +                       dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
15187 +                       break;
15188 +               case 14:
15189 +                       dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
15190 +                       break;
15191 +               }
15192 +               if (IS_I965G(dev))
15193 +                       dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
15194 +       } else {
15195 +               if (is_lvds) {
15196 +                       dpll |=
15197 +                           (1 << (clock.p1 - 1)) <<
15198 +                           DPLL_FPA01_P1_POST_DIV_SHIFT;
15199 +               } else {
15200 +                       if (clock.p1 == 2)
15201 +                               dpll |= PLL_P1_DIVIDE_BY_TWO;
15202 +                       else
15203 +                               dpll |=
15204 +                                   (clock.p1 -
15205 +                                    2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
15206 +                       if (clock.p2 == 4)
15207 +                               dpll |= PLL_P2_DIVIDE_BY_4;
15208 +               }
15209 +       }
15210 +
15211 +       if (is_tv) {
15212 +               /* XXX: just matching BIOS for now */
15213 +/*     dpll |= PLL_REF_INPUT_TVCLKINBC; */
15214 +               dpll |= 3;
15215 +       }
15216 +#if 0
15217 +       else if (is_lvds)
15218 +               dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
15219 +#endif
15220 +       else
15221 +               dpll |= PLL_REF_INPUT_DREFCLK;
15222 +
15223 +       /* setup pipeconf */
15224 +       pipeconf = REG_READ(pipeconf_reg);
15225 +
15226 +       /* Set up the display plane register */
15227 +       dspcntr = DISPPLANE_GAMMA_ENABLE;
15228 +
15229 +       if (pipe == 0)
15230 +               dspcntr |= DISPPLANE_SEL_PIPE_A;
15231 +       else
15232 +               dspcntr |= DISPPLANE_SEL_PIPE_B;
15233 +
15234 +       dspcntr |= DISPLAY_PLANE_ENABLE;
15235 +       pipeconf |= PIPEACONF_ENABLE;
15236 +       dpll |= DPLL_VCO_ENABLE;
15237 +
15238 +
15239 +       /* Disable the panel fitter if it was on our pipe */
15240 +       if (psb_intel_panel_fitter_pipe(dev) == pipe)
15241 +               REG_WRITE(PFIT_CONTROL, 0);
15242 +
15243 +       DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
15244 +       drm_mode_debug_printmodeline(mode);
15245 +
15246 +       if (dpll & DPLL_VCO_ENABLE) {
15247 +               REG_WRITE(fp_reg, fp);
15248 +               REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
15249 +               REG_READ(dpll_reg);
15250 +               udelay(150);
15251 +       }
15252 +
15253 +       /* The LVDS pin pair needs to be on before the DPLLs are enabled.
15254 +        * This is an exception to the general rule that mode_set doesn't turn
15255 +        * things on.
15256 +        */
15257 +       if (is_lvds) {
15258 +               u32 lvds = REG_READ(LVDS);
15259 +
15260 +               lvds |=
15261 +                   LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
15262 +                   LVDS_PIPEB_SELECT;
15263 +               /* Set the B0-B3 data pairs corresponding to
15264 +                * whether we're going to
15265 +                * set the DPLLs for dual-channel mode or not.
15266 +                */
15267 +               if (clock.p2 == 7)
15268 +                       lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
15269 +               else
15270 +                       lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
15271 +
15272 +               /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
15273 +                * appropriately here, but we need to look more
15274 +                * thoroughly into how panels behave in the two modes.
15275 +                */
15276 +
15277 +               REG_WRITE(LVDS, lvds);
15278 +               REG_READ(LVDS);
15279 +       }
15280 +
15281 +       REG_WRITE(fp_reg, fp);
15282 +       REG_WRITE(dpll_reg, dpll);
15283 +       REG_READ(dpll_reg);
15284 +       /* Wait for the clocks to stabilize. */
15285 +       udelay(150);
15286 +
15287 +       if (IS_I965G(dev)) {
15288 +               int sdvo_pixel_multiply =
15289 +                   adjusted_mode->clock / mode->clock;
15290 +               REG_WRITE(dpll_md_reg,
15291 +                         (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
15292 +                         ((sdvo_pixel_multiply -
15293 +                           1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
15294 +       } else {
15295 +               /* write it again -- the BIOS does, after all */
15296 +               REG_WRITE(dpll_reg, dpll);
15297 +       }
15298 +       REG_READ(dpll_reg);
15299 +       /* Wait for the clocks to stabilize. */
15300 +       udelay(150);
15301 +
15302 +       REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
15303 +                 ((adjusted_mode->crtc_htotal - 1) << 16));
15304 +       REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
15305 +                 ((adjusted_mode->crtc_hblank_end - 1) << 16));
15306 +       REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
15307 +                 ((adjusted_mode->crtc_hsync_end - 1) << 16));
15308 +       REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
15309 +                 ((adjusted_mode->crtc_vtotal - 1) << 16));
15310 +       REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
15311 +                 ((adjusted_mode->crtc_vblank_end - 1) << 16));
15312 +       REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
15313 +                 ((adjusted_mode->crtc_vsync_end - 1) << 16));
15314 +       /* pipesrc and dspsize control the size that is scaled from,
15315 +        * which should always be the user's requested size.
15316 +        */
15317 +       REG_WRITE(dspsize_reg,
15318 +                 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
15319 +       REG_WRITE(dsppos_reg, 0);
15320 +       REG_WRITE(pipesrc_reg,
15321 +                 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
15322 +       REG_WRITE(pipeconf_reg, pipeconf);
15323 +       REG_READ(pipeconf_reg);
15324 +
15325 +       psb_intel_wait_for_vblank(dev);
15326 +
15327 +       REG_WRITE(dspcntr_reg, dspcntr);
15328 +
15329 +       /* Flush the plane changes */
15330 +       {
15331 +               struct drm_crtc_helper_funcs *crtc_funcs =
15332 +                   crtc->helper_private;
15333 +               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
15334 +       }
15335 +
15336 +       psb_intel_wait_for_vblank(dev);
15337 +
15338 +       return 0;
15339 +}
15340 +
15341 +/** Loads the palette/gamma unit for the CRTC with the prepared values */
15342 +void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
15343 +{
15344 +       struct drm_device *dev = crtc->dev;
15345 +       struct drm_psb_private *dev_priv =
15346 +                               (struct drm_psb_private *)dev->dev_private;
15347 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15348 +       int palreg = (psb_intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
15349 +       int i;
15350 +
15351 +       /* The clocks have to be on to load the palette. */
15352 +       if (!crtc->enabled)
15353 +               return;
15354 +
15355 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15356 +                                     OSPM_UHB_ONLY_IF_ON)) {
15357 +               for (i = 0; i < 256; i++) {
15358 +                       REG_WRITE(palreg + 4 * i,
15359 +                                 ((psb_intel_crtc->lut_r[i] +
15360 +                                 psb_intel_crtc->lut_adj[i]) << 16) |
15361 +                                 ((psb_intel_crtc->lut_g[i] +
15362 +                                 psb_intel_crtc->lut_adj[i]) << 8) |
15363 +                                 (psb_intel_crtc->lut_b[i] +
15364 +                                 psb_intel_crtc->lut_adj[i]));
15365 +               }
15366 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15367 +       } else {
15368 +               for (i = 0; i < 256; i++) {
15369 +                       dev_priv->save_palette_a[i] =
15370 +                                 ((psb_intel_crtc->lut_r[i] +
15371 +                                 psb_intel_crtc->lut_adj[i]) << 16) |
15372 +                                 ((psb_intel_crtc->lut_g[i] +
15373 +                                 psb_intel_crtc->lut_adj[i]) << 8) |
15374 +                                 (psb_intel_crtc->lut_b[i] +
15375 +                                 psb_intel_crtc->lut_adj[i]);
15376 +               }
15377 +
15378 +       }
15379 +}
15380 +
15381 +#ifndef CONFIG_X86_MRST
15382 +/**
15383 + * Save HW states of giving crtc
15384 + */
15385 +static void psb_intel_crtc_save(struct drm_crtc *crtc)
15386 +{
15387 +       struct drm_device *dev = crtc->dev;
15388 +       /* struct drm_psb_private *dev_priv =
15389 +                       (struct drm_psb_private *)dev->dev_private; */
15390 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15391 +       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
15392 +       int pipeA = (psb_intel_crtc->pipe == 0);
15393 +       uint32_t paletteReg;
15394 +       int i;
15395 +
15396 +       DRM_DEBUG("\n");
15397 +
15398 +       if (!crtc_state) {
15399 +               DRM_DEBUG("No CRTC state found\n");
15400 +               return;
15401 +       }
15402 +
15403 +       crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
15404 +       crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
15405 +       crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
15406 +       crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
15407 +       crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
15408 +       crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
15409 +       crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
15410 +       crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
15411 +       crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
15412 +       crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
15413 +       crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
15414 +       crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
15415 +       crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
15416 +
15417 +       /*NOTE: DSPSIZE DSPPOS only for psb*/
15418 +       crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
15419 +       crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
15420 +
15421 +       crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
15422 +
15423 +       DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
15424 +                       crtc_state->saveDSPCNTR,
15425 +                       crtc_state->savePIPECONF,
15426 +                       crtc_state->savePIPESRC,
15427 +                       crtc_state->saveFP0,
15428 +                       crtc_state->saveFP1,
15429 +                       crtc_state->saveDPLL,
15430 +                       crtc_state->saveHTOTAL,
15431 +                       crtc_state->saveHBLANK,
15432 +                       crtc_state->saveHSYNC,
15433 +                       crtc_state->saveVTOTAL,
15434 +                       crtc_state->saveVBLANK,
15435 +                       crtc_state->saveVSYNC,
15436 +                       crtc_state->saveDSPSTRIDE,
15437 +                       crtc_state->saveDSPSIZE,
15438 +                       crtc_state->saveDSPPOS,
15439 +                       crtc_state->saveDSPBASE
15440 +               );
15441 +
15442 +       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
15443 +       for (i = 0; i < 256; ++i)
15444 +               crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
15445 +}
15446 +
15447 +/**
15448 + * Restore HW states of giving crtc
15449 + */
15450 +static void psb_intel_crtc_restore(struct drm_crtc *crtc)
15451 +{
15452 +       struct drm_device *dev = crtc->dev;
15453 +       /* struct drm_psb_private * dev_priv =
15454 +                               (struct drm_psb_private *)dev->dev_private; */
15455 +       struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
15456 +       struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
15457 +       /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
15458 +       int pipeA = (psb_intel_crtc->pipe == 0);
15459 +       uint32_t paletteReg;
15460 +       int i;
15461 +
15462 +       DRM_DEBUG("\n");
15463 +
15464 +       if (!crtc_state) {
15465 +               DRM_DEBUG("No crtc state\n");
15466 +               return;
15467 +       }
15468 +
15469 +       DRM_DEBUG(
15470 +               "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
15471 +               REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
15472 +               REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
15473 +               REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
15474 +               REG_READ(pipeA ? FPA0 : FPB0),
15475 +               REG_READ(pipeA ? FPA1 : FPB1),
15476 +               REG_READ(pipeA ? DPLL_A : DPLL_B),
15477 +               REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
15478 +               REG_READ(pipeA ? HBLANK_A : HBLANK_B),
15479 +               REG_READ(pipeA ? HSYNC_A : HSYNC_B),
15480 +               REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
15481 +               REG_READ(pipeA ? VBLANK_A : VBLANK_B),
15482 +               REG_READ(pipeA ? VSYNC_A : VSYNC_B),
15483 +               REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
15484 +               REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
15485 +               REG_READ(pipeA ? DSPAPOS : DSPBPOS),
15486 +               REG_READ(pipeA ? DSPABASE : DSPBBASE)
15487 +               );
15488 +
15489 +       DRM_DEBUG(
15490 +               "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
15491 +               crtc_state->saveDSPCNTR,
15492 +               crtc_state->savePIPECONF,
15493 +               crtc_state->savePIPESRC,
15494 +               crtc_state->saveFP0,
15495 +               crtc_state->saveFP1,
15496 +               crtc_state->saveDPLL,
15497 +               crtc_state->saveHTOTAL,
15498 +               crtc_state->saveHBLANK,
15499 +               crtc_state->saveHSYNC,
15500 +               crtc_state->saveVTOTAL,
15501 +               crtc_state->saveVBLANK,
15502 +               crtc_state->saveVSYNC,
15503 +               crtc_state->saveDSPSTRIDE,
15504 +               crtc_state->saveDSPSIZE,
15505 +               crtc_state->saveDSPPOS,
15506 +               crtc_state->saveDSPBASE
15507 +               );
15508 +
15509 +
15510 +#if 0
15511 +       if (drm_helper_crtc_in_use(crtc))
15512 +               crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
15513 +
15514 +
15515 +       if (psb_intel_panel_fitter_pipe(dev) == psb_intel_crtc->pipe) {
15516 +               REG_WRITE(PFIT_CONTROL, crtc_state->savePFITCTRL);
15517 +               DRM_DEBUG("write pfit_controle: %x\n", REG_READ(PFIT_CONTROL));
15518 +       }
15519 +#endif
15520 +
15521 +       if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
15522 +               REG_WRITE(pipeA ? DPLL_A : DPLL_B,
15523 +                       crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
15524 +               REG_READ(pipeA ? DPLL_A : DPLL_B);
15525 +               DRM_DEBUG("write dpll: %x\n",
15526 +                               REG_READ(pipeA ? DPLL_A : DPLL_B));
15527 +               udelay(150);
15528 +       }
15529 +
15530 +       REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
15531 +       REG_READ(pipeA ? FPA0 : FPB0);
15532 +
15533 +       REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
15534 +       REG_READ(pipeA ? FPA1 : FPB1);
15535 +
15536 +       REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
15537 +       REG_READ(pipeA ? DPLL_A : DPLL_B);
15538 +       udelay(150);
15539 +
15540 +       REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
15541 +       REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
15542 +       REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
15543 +       REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
15544 +       REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
15545 +       REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
15546 +       REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
15547 +
15548 +       REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
15549 +       REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
15550 +
15551 +       REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
15552 +       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
15553 +       REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
15554 +
15555 +       psb_intel_wait_for_vblank(dev);
15556 +
15557 +       REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
15558 +       REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
15559 +
15560 +       psb_intel_wait_for_vblank(dev);
15561 +
15562 +       paletteReg = pipeA ? PALETTE_A : PALETTE_B;
15563 +       for (i = 0; i < 256; ++i)
15564 +               REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
15565 +}
15566 +#endif
15567 +
15568 +static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
15569 +                                struct drm_file *file_priv,
15570 +                                uint32_t handle,
15571 +                                uint32_t width, uint32_t height)
15572 +{
15573 +       struct drm_device *dev = crtc->dev;
15574 +       struct drm_psb_private *dev_priv =
15575 +                               (struct drm_psb_private *)dev->dev_private;
15576 +       struct psb_gtt *pg = dev_priv->pg;
15577 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15578 +       struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
15579 +       int pipe = psb_intel_crtc->pipe;
15580 +       uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
15581 +       uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
15582 +       uint32_t temp;
15583 +       size_t addr = 0;
15584 +       uint32_t page_offset;
15585 +       size_t size;
15586 +       void *bo;
15587 +       int ret;
15588 +
15589 +       DRM_DEBUG("\n");
15590 +
15591 +       /* if we want to turn of the cursor ignore width and height */
15592 +       if (!handle) {
15593 +               DRM_DEBUG("cursor off\n");
15594 +               /* turn of the cursor */
15595 +               temp = 0;
15596 +               temp |= CURSOR_MODE_DISABLE;
15597 +
15598 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15599 +                                             OSPM_UHB_ONLY_IF_ON)) {
15600 +                       REG_WRITE(control, temp);
15601 +                       REG_WRITE(base, 0);
15602 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15603 +               }
15604 +
15605 +               /* unpin the old bo */
15606 +               if (psb_intel_crtc->cursor_bo) {
15607 +                       mode_dev->bo_unpin_for_scanout(dev,
15608 +                                                      psb_intel_crtc->
15609 +                                                      cursor_bo);
15610 +                       psb_intel_crtc->cursor_bo = NULL;
15611 +               }
15612 +
15613 +               return 0;
15614 +       }
15615 +
15616 +       /* Currently we only support 64x64 cursors */
15617 +       if (width != 64 || height != 64) {
15618 +               DRM_ERROR("we currently only support 64x64 cursors\n");
15619 +               return -EINVAL;
15620 +       }
15621 +
15622 +       bo = mode_dev->bo_from_handle(dev, file_priv, handle);
15623 +       if (!bo)
15624 +               return -ENOENT;
15625 +
15626 +       ret = mode_dev->bo_pin_for_scanout(dev, bo);
15627 +       if (ret)
15628 +               return ret;
15629 +       size = mode_dev->bo_size(dev, bo);
15630 +       if (size < width * height * 4) {
15631 +               DRM_ERROR("buffer is to small\n");
15632 +               return -ENOMEM;
15633 +       }
15634 +
15635 +       /*insert this bo into gtt*/
15636 +       DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
15637 +                                               __func__, handle);
15638 +
15639 +       ret = psb_gtt_map_meminfo(dev, (IMG_HANDLE)handle, &page_offset);
15640 +       if (ret) {
15641 +               DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
15642 +               return ret;
15643 +       }
15644 +
15645 +       addr = page_offset << PAGE_SHIFT;
15646 +
15647 +       if (IS_POULSBO(dev))
15648 +               addr += pg->stolen_base;
15649 +
15650 +       psb_intel_crtc->cursor_addr = addr;
15651 +
15652 +       temp = 0;
15653 +       /* set the pipe for the cursor */
15654 +       temp |= (pipe << 28);
15655 +       temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
15656 +
15657 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15658 +                                     OSPM_UHB_ONLY_IF_ON)) {
15659 +               REG_WRITE(control, temp);
15660 +               REG_WRITE(base, addr);
15661 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15662 +       }
15663 +
15664 +       /* unpin the old bo */
15665 +       if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
15666 +               mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
15667 +               psb_intel_crtc->cursor_bo = bo;
15668 +       }
15669 +
15670 +       return 0;
15671 +}
15672 +
15673 +static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
15674 +{
15675 +       struct drm_device *dev = crtc->dev;
15676 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15677 +       int pipe = psb_intel_crtc->pipe;
15678 +       uint32_t temp = 0;
15679 +       uint32_t adder;
15680 +
15681 +       if (x < 0) {
15682 +               temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
15683 +               x = -x;
15684 +       }
15685 +       if (y < 0) {
15686 +               temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
15687 +               y = -y;
15688 +       }
15689 +
15690 +       temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
15691 +       temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
15692 +
15693 +       adder = psb_intel_crtc->cursor_addr;
15694 +
15695 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15696 +                                     OSPM_UHB_ONLY_IF_ON)) {
15697 +               REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
15698 +               REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
15699 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15700 +       }
15701 +       return 0;
15702 +}
15703 +
15704 +static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
15705 +                                u16 *green, u16 *blue, uint32_t size)
15706 +{
15707 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15708 +       int i;
15709 +
15710 +       if (size != 256)
15711 +               return;
15712 +
15713 +       for (i = 0; i < 256; i++) {
15714 +               psb_intel_crtc->lut_r[i] = red[i] >> 8;
15715 +               psb_intel_crtc->lut_g[i] = green[i] >> 8;
15716 +               psb_intel_crtc->lut_b[i] = blue[i] >> 8;
15717 +       }
15718 +
15719 +       psb_intel_crtc_load_lut(crtc);
15720 +}
15721 +
15722 +/* Returns the clock of the currently programmed mode of the given pipe. */
15723 +static int psb_intel_crtc_clock_get(struct drm_device *dev,
15724 +                               struct drm_crtc *crtc)
15725 +{
15726 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15727 +       int pipe = psb_intel_crtc->pipe;
15728 +       u32 dpll;
15729 +       u32 fp;
15730 +       struct psb_intel_clock_t clock;
15731 +       bool is_lvds;
15732 +       struct drm_psb_private *dev_priv = dev->dev_private;
15733 +
15734 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15735 +                                     OSPM_UHB_ONLY_IF_ON)) {
15736 +               dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
15737 +               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
15738 +                       fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
15739 +               else
15740 +                       fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
15741 +               is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
15742 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15743 +       } else {
15744 +               dpll = (pipe == 0) ?
15745 +                       dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
15746 +
15747 +               if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
15748 +                       fp = (pipe == 0) ?
15749 +                               dev_priv->saveFPA0 :
15750 +                               dev_priv->saveFPB0;
15751 +               else
15752 +                       fp = (pipe == 0) ?
15753 +                               dev_priv->saveFPA1 :
15754 +                               dev_priv->saveFPB1;
15755 +
15756 +               is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
15757 +       }
15758 +
15759 +       clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
15760 +       clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
15761 +       clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
15762 +
15763 +       if (is_lvds) {
15764 +               clock.p1 =
15765 +                   ffs((dpll &
15766 +                        DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
15767 +                       DPLL_FPA01_P1_POST_DIV_SHIFT);
15768 +               clock.p2 = 14;
15769 +
15770 +               if ((dpll & PLL_REF_INPUT_MASK) ==
15771 +                   PLLB_REF_INPUT_SPREADSPECTRUMIN) {
15772 +                       /* XXX: might not be 66MHz */
15773 +                       i8xx_clock(66000, &clock);
15774 +               } else
15775 +                       i8xx_clock(48000, &clock);
15776 +       } else {
15777 +               if (dpll & PLL_P1_DIVIDE_BY_TWO)
15778 +                       clock.p1 = 2;
15779 +               else {
15780 +                       clock.p1 =
15781 +                           ((dpll &
15782 +                             DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
15783 +                            DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
15784 +               }
15785 +               if (dpll & PLL_P2_DIVIDE_BY_4)
15786 +                       clock.p2 = 4;
15787 +               else
15788 +                       clock.p2 = 2;
15789 +
15790 +               i8xx_clock(48000, &clock);
15791 +       }
15792 +
15793 +       /* XXX: It would be nice to validate the clocks, but we can't reuse
15794 +        * i830PllIsValid() because it relies on the xf86_config connector
15795 +        * configuration being accurate, which it isn't necessarily.
15796 +        */
15797 +
15798 +       return clock.dot;
15799 +}
15800 +
15801 +/** Returns the currently programmed mode of the given pipe. */
15802 +struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
15803 +                                            struct drm_crtc *crtc)
15804 +{
15805 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15806 +       int pipe = psb_intel_crtc->pipe;
15807 +       struct drm_display_mode *mode;
15808 +       int htot;
15809 +       int hsync;
15810 +       int vtot;
15811 +       int vsync;
15812 +       struct drm_psb_private *dev_priv = dev->dev_private;
15813 +
15814 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
15815 +                                     OSPM_UHB_ONLY_IF_ON)) {
15816 +               htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
15817 +               hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
15818 +               vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
15819 +               vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
15820 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
15821 +       } else {
15822 +               htot = (pipe == 0) ?
15823 +                       dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
15824 +               hsync = (pipe == 0) ?
15825 +                       dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
15826 +               vtot = (pipe == 0) ?
15827 +                       dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
15828 +               vsync = (pipe == 0) ?
15829 +                       dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
15830 +       }
15831 +
15832 +       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
15833 +       if (!mode)
15834 +               return NULL;
15835 +
15836 +       mode->clock = psb_intel_crtc_clock_get(dev, crtc);
15837 +       mode->hdisplay = (htot & 0xffff) + 1;
15838 +       mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
15839 +       mode->hsync_start = (hsync & 0xffff) + 1;
15840 +       mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
15841 +       mode->vdisplay = (vtot & 0xffff) + 1;
15842 +       mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
15843 +       mode->vsync_start = (vsync & 0xffff) + 1;
15844 +       mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
15845 +
15846 +       drm_mode_set_name(mode);
15847 +       drm_mode_set_crtcinfo(mode, 0);
15848 +
15849 +       return mode;
15850 +}
15851 +
15852 +static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
15853 +{
15854 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15855 +
15856 +#ifndef CONFIG_X86_MRST
15857 +       kfree(psb_intel_crtc->crtc_state);
15858 +#endif
15859 +       drm_crtc_cleanup(crtc);
15860 +       kfree(psb_intel_crtc);
15861 +}
15862 +
15863 +static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
15864 +       .dpms = psb_intel_crtc_dpms,
15865 +       .mode_fixup = psb_intel_crtc_mode_fixup,
15866 +       .mode_set = psb_intel_crtc_mode_set,
15867 +       .mode_set_base = psb_intel_pipe_set_base,
15868 +       .prepare = psb_intel_crtc_prepare,
15869 +       .commit = psb_intel_crtc_commit,
15870 +};
15871 +
15872 +static const struct drm_crtc_helper_funcs mrst_helper_funcs;
15873 +
15874 +const struct drm_crtc_funcs psb_intel_crtc_funcs = {
15875 +#ifndef CONFIG_X86_MRST
15876 +       .save = psb_intel_crtc_save,
15877 +       .restore = psb_intel_crtc_restore,
15878 +#endif
15879 +       .cursor_set = psb_intel_crtc_cursor_set,
15880 +       .cursor_move = psb_intel_crtc_cursor_move,
15881 +       .gamma_set = psb_intel_crtc_gamma_set,
15882 +       .set_config = drm_crtc_helper_set_config,
15883 +       .destroy = psb_intel_crtc_destroy,
15884 +};
15885 +
15886 +
15887 +void psb_intel_crtc_init(struct drm_device *dev, int pipe,
15888 +                    struct psb_intel_mode_device *mode_dev)
15889 +{
15890 +       struct drm_psb_private *dev_priv = dev->dev_private;
15891 +       struct psb_intel_crtc *psb_intel_crtc;
15892 +       int i;
15893 +       uint16_t *r_base, *g_base, *b_base;
15894 +
15895 +#if PRINT_JLIU7
15896 +       DRM_INFO("JLIU7 enter psb_intel_crtc_init \n");
15897 +#endif                         /* PRINT_JLIU7 */
15898 +
15899 +       /* We allocate a extra array of drm_connector pointers
15900 +        * for fbdev after the crtc */
15901 +       psb_intel_crtc =
15902 +           kzalloc(sizeof(struct psb_intel_crtc) +
15903 +                   (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
15904 +                   GFP_KERNEL);
15905 +       if (psb_intel_crtc == NULL)
15906 +               return;
15907 +
15908 +#ifndef CONFIG_X86_MRST
15909 +       psb_intel_crtc->crtc_state =
15910 +               kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
15911 +       if (!psb_intel_crtc->crtc_state) {
15912 +               DRM_INFO("Crtc state error: No memory\n");
15913 +               kfree(psb_intel_crtc);
15914 +               return;
15915 +       }
15916 +#endif
15917 +
15918 +       drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs);
15919 +
15920 +       drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
15921 +       psb_intel_crtc->pipe = pipe;
15922 +       psb_intel_crtc->plane = pipe;
15923 +
15924 +       r_base = psb_intel_crtc->base.gamma_store;
15925 +       g_base = r_base + 256;
15926 +       b_base = g_base + 256;
15927 +       for (i = 0; i < 256; i++) {
15928 +               psb_intel_crtc->lut_r[i] = i;
15929 +               psb_intel_crtc->lut_g[i] = i;
15930 +               psb_intel_crtc->lut_b[i] = i;
15931 +               r_base[i] = i << 8;
15932 +               g_base[i] = i << 8;
15933 +               b_base[i] = i << 8;
15934 +
15935 +               psb_intel_crtc->lut_adj[i] = 0;
15936 +       }
15937 +
15938 +       psb_intel_crtc->mode_dev = mode_dev;
15939 +       psb_intel_crtc->cursor_addr = 0;
15940 +
15941 +       if (IS_MRST(dev)) {
15942 +               drm_crtc_helper_add(&psb_intel_crtc->base, &mrst_helper_funcs);
15943 +       } else {
15944 +               drm_crtc_helper_add(&psb_intel_crtc->base,
15945 +                                   &psb_intel_helper_funcs);
15946 +       }
15947 +
15948 +       /* Setup the array of drm_connector pointer array */
15949 +       psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
15950 +       BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
15951 +              dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
15952 +       dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] = &psb_intel_crtc->base;
15953 +       dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] = &psb_intel_crtc->base;
15954 +       psb_intel_crtc->mode_set.connectors =
15955 +           (struct drm_connector **) (psb_intel_crtc + 1);
15956 +       psb_intel_crtc->mode_set.num_connectors = 0;
15957 +}
15958 +
15959 +int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
15960 +                               struct drm_file *file_priv)
15961 +{
15962 +       struct drm_psb_private *dev_priv = dev->dev_private;
15963 +       struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
15964 +       struct drm_mode_object *drmmode_obj;
15965 +       struct psb_intel_crtc *crtc;
15966 +
15967 +       if (!dev_priv) {
15968 +               DRM_ERROR("called with no initialization\n");
15969 +               return -EINVAL;
15970 +       }
15971 +
15972 +       drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
15973 +                       DRM_MODE_OBJECT_CRTC);
15974 +
15975 +       if (!drmmode_obj) {
15976 +               DRM_ERROR("no such CRTC id\n");
15977 +               return -EINVAL;
15978 +       }
15979 +
15980 +       crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
15981 +       pipe_from_crtc_id->pipe = crtc->pipe;
15982 +
15983 +       return 0;
15984 +}
15985 +
15986 +struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
15987 +{
15988 +       struct drm_crtc *crtc = NULL;
15989 +
15990 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
15991 +               struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
15992 +               if (psb_intel_crtc->pipe == pipe)
15993 +                       break;
15994 +       }
15995 +       return crtc;
15996 +}
15997 +
15998 +int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
15999 +{
16000 +       int index_mask = 0;
16001 +       struct drm_connector *connector;
16002 +       int entry = 0;
16003 +
16004 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
16005 +                           head) {
16006 +               struct psb_intel_output *psb_intel_output =
16007 +                   to_psb_intel_output(connector);
16008 +               if (type_mask & (1 << psb_intel_output->type))
16009 +                       index_mask |= (1 << entry);
16010 +               entry++;
16011 +       }
16012 +       return index_mask;
16013 +}
16014 +
16015 +#if 0                          /* JB: Should be per device */
16016 +static void psb_intel_setup_outputs(struct drm_device *dev)
16017 +{
16018 +       struct drm_connector *connector;
16019 +
16020 +       psb_intel_crt_init(dev);
16021 +
16022 +       /* Set up integrated LVDS */
16023 +       if (IS_MOBILE(dev) && !IS_I830(dev))
16024 +               psb_intel_lvds_init(dev);
16025 +
16026 +       if (IS_I9XX(dev)) {
16027 +               psb_intel_sdvo_init(dev, SDVOB);
16028 +               psb_intel_sdvo_init(dev, SDVOC);
16029 +       } else
16030 +               psb_intel_dvo_init(dev);
16031 +
16032 +       if (IS_I9XX(dev) && !IS_I915G(dev))
16033 +               psb_intel_tv_init(dev);
16034 +
16035 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
16036 +                           head) {
16037 +               struct psb_intel_output *psb_intel_output =
16038 +                   to_psb_intel_output(connector);
16039 +               struct drm_encoder *encoder = &psb_intel_output->enc;
16040 +               int crtc_mask = 0, clone_mask = 0;
16041 +
16042 +               /* valid crtcs */
16043 +               switch (psb_intel_output->type) {
16044 +               case INTEL_OUTPUT_DVO:
16045 +               case INTEL_OUTPUT_SDVO:
16046 +                       crtc_mask = ((1 << 0) | (1 << 1));
16047 +                       clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
16048 +                                     (1 << INTEL_OUTPUT_DVO) |
16049 +                                     (1 << INTEL_OUTPUT_SDVO));
16050 +                       break;
16051 +               case INTEL_OUTPUT_ANALOG:
16052 +                       crtc_mask = ((1 << 0) | (1 << 1));
16053 +                       clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
16054 +                                     (1 << INTEL_OUTPUT_DVO) |
16055 +                                     (1 << INTEL_OUTPUT_SDVO));
16056 +                       break;
16057 +               case INTEL_OUTPUT_LVDS:
16058 +                       crtc_mask = (1 << 1);
16059 +                       clone_mask = (1 << INTEL_OUTPUT_LVDS);
16060 +                       break;
16061 +               case INTEL_OUTPUT_TVOUT:
16062 +                       crtc_mask = ((1 << 0) | (1 << 1));
16063 +                       clone_mask = (1 << INTEL_OUTPUT_TVOUT);
16064 +                       break;
16065 +               }
16066 +               encoder->possible_crtcs = crtc_mask;
16067 +               encoder->possible_clones =
16068 +                   psb_intel_connector_clones(dev, clone_mask);
16069 +       }
16070 +}
16071 +#endif
16072 +
16073 +#if 0  /* JB: Rework framebuffer code into something none device specific */
16074 +static void psb_intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
16075 +{
16076 +       struct psb_intel_framebuffer *psb_intel_fb =
16077 +                                       to_psb_intel_framebuffer(fb);
16078 +       struct drm_device *dev = fb->dev;
16079 +
16080 +       if (fb->fbdev)
16081 +               intelfb_remove(dev, fb);
16082 +
16083 +       drm_framebuffer_cleanup(fb);
16084 +       drm_gem_object_unreference(fb->mm_private);
16085 +
16086 +       kfree(psb_intel_fb);
16087 +}
16088 +
16089 +static int psb_intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
16090 +                                               struct drm_file *file_priv,
16091 +                                               unsigned int *handle)
16092 +{
16093 +       struct drm_gem_object *object = fb->mm_private;
16094 +
16095 +       return drm_gem_handle_create(file_priv, object, handle);
16096 +}
16097 +
16098 +static const struct drm_framebuffer_funcs psb_intel_fb_funcs = {
16099 +       .destroy = psb_intel_user_framebuffer_destroy,
16100 +       .create_handle = psb_intel_user_framebuffer_create_handle,
16101 +};
16102 +
16103 +struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device *dev,
16104 +                                                struct drm_mode_fb_cmd
16105 +                                                *mode_cmd,
16106 +                                                void *mm_private)
16107 +{
16108 +       struct psb_intel_framebuffer *psb_intel_fb;
16109 +
16110 +       psb_intel_fb = kzalloc(sizeof(*psb_intel_fb), GFP_KERNEL);
16111 +       if (!psb_intel_fb)
16112 +               return NULL;
16113 +
16114 +       if (!drm_framebuffer_init(dev,
16115 +                                 &psb_intel_fb->base,
16116 +                                 &psb_intel_fb_funcs))
16117 +               return NULL;
16118 +
16119 +       drm_helper_mode_fill_fb_struct(&psb_intel_fb->base, mode_cmd);
16120 +
16121 +       return &psb_intel_fb->base;
16122 +}
16123 +
16124 +
16125 +static struct drm_framebuffer *psb_intel_user_framebuffer_create(struct
16126 +                                                            drm_device
16127 +                                                            *dev,
16128 +                                                            struct
16129 +                                                            drm_file
16130 +                                                            *filp,
16131 +                                                            struct
16132 +                                                            drm_mode_fb_cmd
16133 +                                                            *mode_cmd)
16134 +{
16135 +       struct drm_gem_object *obj;
16136 +
16137 +       obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
16138 +       if (!obj)
16139 +               return NULL;
16140 +
16141 +       return psb_intel_framebuffer_create(dev, mode_cmd, obj);
16142 +}
16143 +
16144 +static int psb_intel_insert_new_fb(struct drm_device *dev,
16145 +                              struct drm_file *file_priv,
16146 +                              struct drm_framebuffer *fb,
16147 +                              struct drm_mode_fb_cmd *mode_cmd)
16148 +{
16149 +       struct psb_intel_framebuffer *psb_intel_fb;
16150 +       struct drm_gem_object *obj;
16151 +       struct drm_crtc *crtc;
16152 +
16153 +       psb_intel_fb = to_psb_intel_framebuffer(fb);
16154 +
16155 +       mutex_lock(&dev->struct_mutex);
16156 +       obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
16157 +
16158 +       if (!obj) {
16159 +               mutex_unlock(&dev->struct_mutex);
16160 +               return -EINVAL;
16161 +       }
16162 +       drm_gem_object_unreference(psb_intel_fb->base.mm_private);
16163 +       drm_helper_mode_fill_fb_struct(fb, mode_cmd, obj);
16164 +       mutex_unlock(&dev->struct_mutex);
16165 +
16166 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
16167 +               if (crtc->fb == fb) {
16168 +                       struct drm_crtc_helper_funcs *crtc_funcs =
16169 +                           crtc->helper_private;
16170 +                       crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
16171 +               }
16172 +       }
16173 +       return 0;
16174 +}
16175 +
16176 +static const struct drm_mode_config_funcs psb_intel_mode_funcs = {
16177 +       .resize_fb = psb_intel_insert_new_fb,
16178 +       .fb_create = psb_intel_user_framebuffer_create,
16179 +       .fb_changed = intelfb_probe,
16180 +};
16181 +#endif
16182 +
16183 +#if 0                          /* Should be per device */
16184 +void psb_intel_modeset_init(struct drm_device *dev)
16185 +{
16186 +       int num_pipe;
16187 +       int i;
16188 +
16189 +       drm_mode_config_init(dev);
16190 +
16191 +       dev->mode_config.min_width = 0;
16192 +       dev->mode_config.min_height = 0;
16193 +
16194 +       dev->mode_config.funcs = (void *) &psb_intel_mode_funcs;
16195 +
16196 +       if (IS_I965G(dev)) {
16197 +               dev->mode_config.max_width = 8192;
16198 +               dev->mode_config.max_height = 8192;
16199 +       } else {
16200 +               dev->mode_config.max_width = 2048;
16201 +               dev->mode_config.max_height = 2048;
16202 +       }
16203 +
16204 +       /* set memory base */
16205 +       /* MRST and PSB should use BAR 2*/
16206 +       dev->mode_config.fb_base =
16207 +           pci_resource_start(dev->pdev, 2);
16208 +
16209 +       if (IS_MOBILE(dev) || IS_I9XX(dev))
16210 +               num_pipe = 2;
16211 +       else
16212 +               num_pipe = 1;
16213 +       DRM_DEBUG("%d display pipe%s available.\n",
16214 +                 num_pipe, num_pipe > 1 ? "s" : "");
16215 +
16216 +       for (i = 0; i < num_pipe; i++)
16217 +               psb_intel_crtc_init(dev, i);
16218 +
16219 +       psb_intel_setup_outputs(dev);
16220 +
16221 +       /* setup fbs */
16222 +       /* drm_initial_config(dev); */
16223 +}
16224 +#endif
16225 +
16226 +void psb_intel_modeset_cleanup(struct drm_device *dev)
16227 +{
16228 +       drm_mode_config_cleanup(dev);
16229 +}
16230 +
16231 +
16232 +/* current intel driver doesn't take advantage of encoders
16233 +   always give back the encoder for the connector
16234 +*/
16235 +struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
16236 +{
16237 +       struct psb_intel_output *psb_intel_output =
16238 +                                       to_psb_intel_output(connector);
16239 +
16240 +       return &psb_intel_output->enc;
16241 +}
16242 +
16243 +/* MRST_PLATFORM start */
16244 +
16245 +#if DUMP_REGISTER
16246 +void dump_dc_registers(struct drm_device *dev)
16247 +{
16248 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
16249 +       unsigned int i = 0;
16250 +
16251 +       DRM_INFO("jliu7 dump_dc_registers\n");
16252 +
16253 +
16254 +       if (0x80000000 & REG_READ(0x70008)) {
16255 +               for (i = 0x20a0; i < 0x20af; i += 4) {
16256 +                       DRM_INFO("jliu7 interrupt register=0x%x, value=%x\n",
16257 +                                i, (unsigned int) REG_READ(i));
16258 +               }
16259 +
16260 +               for (i = 0xf014; i < 0xf047; i += 4) {
16261 +                       DRM_INFO("jliu7 pipe A dpll register=0x%x, value=%x\n",
16262 +                            i, (unsigned int) REG_READ(i));
16263 +               }
16264 +
16265 +               for (i = 0x60000; i < 0x6005f; i += 4) {
16266 +                       DRM_INFO
16267 +                           ("jliu7 pipe A timing register=0x%x, value=%x\n",
16268 +                            i, (unsigned int) REG_READ(i));
16269 +               }
16270 +
16271 +               for (i = 0x61140; i < 0x61143; i += 4) {
16272 +                       DRM_INFO("jliu7 SDBOB register=0x%x, value=%x\n",
16273 +                                i, (unsigned int) REG_READ(i));
16274 +               }
16275 +
16276 +               for (i = 0x61180; i < 0x6123F; i += 4) {
16277 +                       DRM_INFO
16278 +                           ("jliu7 LVDS PORT register=0x%x, value=%x\n",
16279 +                            i, (unsigned int) REG_READ(i));
16280 +               }
16281 +
16282 +               for (i = 0x61254; i < 0x612AB; i += 4) {
16283 +                       DRM_INFO("jliu7 BLC register=0x%x, value=%x\n",
16284 +                                i, (unsigned int) REG_READ(i));
16285 +               }
16286 +
16287 +               for (i = 0x70000; i < 0x70047; i += 4) {
16288 +                       DRM_INFO
16289 +                           ("jliu7 PIPE A control register=0x%x, value=%x\n",
16290 +                            i, (unsigned int) REG_READ(i));
16291 +               }
16292 +
16293 +               for (i = 0x70180; i < 0x7020b; i += 4) {
16294 +                       DRM_INFO("jliu7 display A control register=0x%x,"
16295 +                                "value=%x\n", i,
16296 +                                (unsigned int) REG_READ(i));
16297 +               }
16298 +
16299 +               for (i = 0x71400; i < 0x71403; i += 4) {
16300 +                       DRM_INFO
16301 +                           ("jliu7 VGA Display Plane Control register=0x%x,"
16302 +                            "value=%x\n", i, (unsigned int) REG_READ(i));
16303 +               }
16304 +       }
16305 +
16306 +       if (0x80000000 & REG_READ(0x71008)) {
16307 +               for (i = 0x61000; i < 0x6105f; i += 4) {
16308 +                       DRM_INFO
16309 +                           ("jliu7 pipe B timing register=0x%x, value=%x\n",
16310 +                            i, (unsigned int) REG_READ(i));
16311 +               }
16312 +
16313 +               for (i = 0x71000; i < 0x71047; i += 4) {
16314 +                       DRM_INFO
16315 +                           ("jliu7 PIPE B control register=0x%x, value=%x\n",
16316 +                            i, (unsigned int) REG_READ(i));
16317 +               }
16318 +
16319 +               for (i = 0x71180; i < 0x7120b; i += 4) {
16320 +                       DRM_INFO("jliu7 display B control register=0x%x,"
16321 +                                "value=%x\n", i,
16322 +                                (unsigned int) REG_READ(i));
16323 +               }
16324 +       }
16325 +#if 0
16326 +       for (i = 0x70080; i < 0x700df; i += 4) {
16327 +               DRM_INFO("jliu7 cursor A & B register=0x%x, value=%x\n",
16328 +                        i, (unsigned int) REG_READ(i));
16329 +       }
16330 +#endif
16331 +
16332 +}
16333 +
16334 +void dump_dsi_registers(struct drm_device *dev)
16335 +{
16336 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
16337 +       unsigned int i = 0;
16338 +
16339 +       DRM_INFO("jliu7 dump_dsi_registers\n");
16340 +
16341 +       for (i = 0xb000; i < 0xb064; i += 4) {
16342 +               DRM_INFO("jliu7 MIPI IP register=0x%x, value=%x\n", i,
16343 +                        (unsigned int) REG_READ(i));
16344 +       }
16345 +
16346 +       i = 0xb104;
16347 +       DRM_INFO("jliu7 MIPI control register=0x%x, value=%x\n",
16348 +                i, (unsigned int) REG_READ(i));
16349 +}
16350 +#endif                         /* DUMP_REGISTER */
16351 +
16352 +
16353 +struct mrst_limit_t {
16354 +       struct psb_intel_range_t dot, m, p1;
16355 +};
16356 +
16357 +struct mrst_clock_t {
16358 +       /* derived values */
16359 +       int dot;
16360 +       int m;
16361 +       int p1;
16362 +};
16363 +
16364 +#define MRST_LIMIT_LVDS_100L       0
16365 +#define MRST_LIMIT_LVDS_83         1
16366 +#define MRST_LIMIT_LVDS_100        2
16367 +
16368 +#define MRST_DOT_MIN             19750
16369 +#define MRST_DOT_MAX             120000
16370 +#define MRST_M_MIN_100L                    20
16371 +#define MRST_M_MIN_100             10
16372 +#define MRST_M_MIN_83              12
16373 +#define MRST_M_MAX_100L                    34
16374 +#define MRST_M_MAX_100             17
16375 +#define MRST_M_MAX_83              20
16376 +#define MRST_P1_MIN                2
16377 +#define MRST_P1_MAX_0              7
16378 +#define MRST_P1_MAX_1              8
16379 +
16380 +static const struct mrst_limit_t mrst_limits[] = {
16381 +       {                       /* MRST_LIMIT_LVDS_100L */
16382 +        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
16383 +        .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
16384 +        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
16385 +        },
16386 +       {                       /* MRST_LIMIT_LVDS_83L */
16387 +        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
16388 +        .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
16389 +        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
16390 +        },
16391 +       {                       /* MRST_LIMIT_LVDS_100 */
16392 +        .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
16393 +        .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
16394 +        .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
16395 +        },
16396 +};
16397 +
16398 +#define MRST_M_MIN         10
16399 +static const u32 mrst_m_converts[] = {
16400 +       0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
16401 +       0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
16402 +       0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
16403 +};
16404 +
16405 +#define COUNT_MAX 0x10000000
16406 +void mrstWaitForPipeDisable(struct drm_device *dev)
16407 +{
16408 +       int count, temp;
16409 +
16410 +       /* FIXME JLIU7_PO */
16411 +       psb_intel_wait_for_vblank(dev);
16412 +       return;
16413 +
16414 +       /* Wait for for the pipe disable to take effect. */
16415 +       for (count = 0; count < COUNT_MAX; count++) {
16416 +               temp = REG_READ(PIPEACONF);
16417 +               if ((temp & PIPEACONF_PIPE_STATE) == 0)
16418 +                       break;
16419 +       }
16420 +
16421 +       if (count == COUNT_MAX) {
16422 +#if PRINT_JLIU7
16423 +               DRM_INFO("JLIU7 mrstWaitForPipeDisable time out. \n");
16424 +#endif                         /* PRINT_JLIU7 */
16425 +       } else {
16426 +#if PRINT_JLIU7
16427 +               DRM_INFO("JLIU7 mrstWaitForPipeDisable cout = %d. \n",
16428 +                        count);
16429 +#endif                         /* PRINT_JLIU7 */
16430 +       }
16431 +}
16432 +
16433 +void mrstWaitForPipeEnable(struct drm_device *dev)
16434 +{
16435 +       int count, temp;
16436 +
16437 +       /* FIXME JLIU7_PO */
16438 +       psb_intel_wait_for_vblank(dev);
16439 +       return;
16440 +
16441 +       /* Wait for for the pipe disable to take effect. */
16442 +       for (count = 0; count < COUNT_MAX; count++) {
16443 +               temp = REG_READ(PIPEACONF);
16444 +               if ((temp & PIPEACONF_PIPE_STATE) == 1)
16445 +                       break;
16446 +       }
16447 +
16448 +       if (count == COUNT_MAX) {
16449 +#if PRINT_JLIU7
16450 +               DRM_INFO("JLIU7 mrstWaitForPipeEnable time out. \n");
16451 +#endif                         /* PRINT_JLIU7 */
16452 +       } else {
16453 +#if PRINT_JLIU7
16454 +               DRM_INFO("JLIU7 mrstWaitForPipeEnable cout = %d. \n",
16455 +                        count);
16456 +#endif                         /* PRINT_JLIU7 */
16457 +       }
16458 +}
16459 +
16460 +static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
16461 +{
16462 +       const struct mrst_limit_t *limit;
16463 +       struct drm_device *dev = crtc->dev;
16464 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
16465 +
16466 +       if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
16467 +           || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
16468 +               if (dev_priv->sku_100L)
16469 +                       limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
16470 +               if (dev_priv->sku_83)
16471 +                       limit = &mrst_limits[MRST_LIMIT_LVDS_83];
16472 +               if (dev_priv->sku_100)
16473 +                       limit = &mrst_limits[MRST_LIMIT_LVDS_100];
16474 +       } else {
16475 +               limit = NULL;
16476 +#if PRINT_JLIU7
16477 +               DRM_INFO("JLIU7 jliu7 mrst_limit Wrong display type. \n");
16478 +#endif                         /* PRINT_JLIU7 */
16479 +       }
16480 +
16481 +       return limit;
16482 +}
16483 +
16484 +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
16485 +static void mrst_clock(int refclk, struct mrst_clock_t *clock)
16486 +{
16487 +       clock->dot = (refclk * clock->m) / (14 * clock->p1);
16488 +}
16489 +
16490 +void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
16491 +{
16492 +#if PRINT_JLIU7
16493 +       DRM_INFO
16494 +           ("JLIU7 mrstPrintPll %s: dotclock = %d,  m = %d, p1 = %d. \n",
16495 +            prefix, clock->dot, clock->m, clock->p1);
16496 +#endif                         /* PRINT_JLIU7 */
16497 +}
16498 +
16499 +/**
16500 + * Returns a set of divisors for the desired target clock with the given refclk,
16501 + * or FALSE.  Divisor values are the actual divisors for
16502 + */
16503 +static bool
16504 +mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
16505 +               struct mrst_clock_t *best_clock)
16506 +{
16507 +       struct mrst_clock_t clock;
16508 +       const struct mrst_limit_t *limit = mrst_limit(crtc);
16509 +       int err = target;
16510 +
16511 +       memset(best_clock, 0, sizeof(*best_clock));
16512 +
16513 +       for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
16514 +               for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
16515 +                    clock.p1++) {
16516 +                       int this_err;
16517 +
16518 +                       mrst_clock(refclk, &clock);
16519 +
16520 +                       this_err = abs(clock.dot - target);
16521 +                       if (this_err < err) {
16522 +                               *best_clock = clock;
16523 +                               err = this_err;
16524 +                       }
16525 +               }
16526 +       }
16527 +       DRM_DEBUG("mrstFindBestPLL err = %d.\n", err);
16528 +
16529 +       return err != target;
16530 +}
16531 +
16532 +/**
16533 + * Sets the power management mode of the pipe and plane.
16534 + *
16535 + * This code should probably grow support for turning the cursor off and back
16536 + * on appropriately at the same time as we're turning the pipe off/on.
16537 + */
16538 +static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
16539 +{
16540 +       struct drm_device *dev = crtc->dev;
16541 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
16542 +       int pipe = psb_intel_crtc->pipe;
16543 +       int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
16544 +       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
16545 +       int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE;
16546 +       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
16547 +       u32 temp;
16548 +       bool enabled;
16549 +
16550 +#if PRINT_JLIU7
16551 +       DRM_INFO("JLIU7 enter mrst_crtc_dpms, mode = %d, pipe = %d \n",
16552 +                mode, pipe);
16553 +#endif                         /* PRINT_JLIU7 */
16554 +
16555 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
16556 +                                      OSPM_UHB_FORCE_POWER_ON))
16557 +               return;
16558 +
16559 +       /* XXX: When our outputs are all unaware of DPMS modes other than off
16560 +        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
16561 +        */
16562 +       switch (mode) {
16563 +       case DRM_MODE_DPMS_ON:
16564 +       case DRM_MODE_DPMS_STANDBY:
16565 +       case DRM_MODE_DPMS_SUSPEND:
16566 +               /* Enable the DPLL */
16567 +               temp = REG_READ(dpll_reg);
16568 +               if ((temp & DPLL_VCO_ENABLE) == 0) {
16569 +                       REG_WRITE(dpll_reg, temp);
16570 +                       REG_READ(dpll_reg);
16571 +                       /* Wait for the clocks to stabilize. */
16572 +                       udelay(150);
16573 +                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
16574 +                       REG_READ(dpll_reg);
16575 +                       /* Wait for the clocks to stabilize. */
16576 +                       udelay(150);
16577 +                       REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
16578 +                       REG_READ(dpll_reg);
16579 +                       /* Wait for the clocks to stabilize. */
16580 +                       udelay(150);
16581 +               }
16582 +
16583 +               /* Enable the pipe */
16584 +               temp = REG_READ(pipeconf_reg);
16585 +               if ((temp & PIPEACONF_ENABLE) == 0)
16586 +                       REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
16587 +
16588 +               /* Enable the plane */
16589 +               temp = REG_READ(dspcntr_reg);
16590 +               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
16591 +                       REG_WRITE(dspcntr_reg,
16592 +                                 temp | DISPLAY_PLANE_ENABLE);
16593 +                       /* Flush the plane changes */
16594 +                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
16595 +               }
16596 +
16597 +               psb_intel_crtc_load_lut(crtc);
16598 +
16599 +               /* Give the overlay scaler a chance to enable
16600 +                  if it's on this pipe */
16601 +               /* psb_intel_crtc_dpms_video(crtc, true); TODO */
16602 +               break;
16603 +       case DRM_MODE_DPMS_OFF:
16604 +               /* Give the overlay scaler a chance to disable
16605 +                * if it's on this pipe */
16606 +               /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
16607 +
16608 +               /* Disable the VGA plane that we never use */
16609 +               REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
16610 +
16611 +               /* Disable display plane */
16612 +               temp = REG_READ(dspcntr_reg);
16613 +               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
16614 +                       REG_WRITE(dspcntr_reg,
16615 +                                 temp & ~DISPLAY_PLANE_ENABLE);
16616 +                       /* Flush the plane changes */
16617 +                       REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
16618 +                       REG_READ(dspbase_reg);
16619 +               }
16620 +
16621 +               if (!IS_I9XX(dev)) {
16622 +                       /* Wait for vblank for the disable to take effect */
16623 +                       psb_intel_wait_for_vblank(dev);
16624 +               }
16625 +
16626 +               /* Next, disable display pipes */
16627 +               temp = REG_READ(pipeconf_reg);
16628 +               if ((temp & PIPEACONF_ENABLE) != 0) {
16629 +                       REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
16630 +                       REG_READ(pipeconf_reg);
16631 +               }
16632 +
16633 +               /* Wait for for the pipe disable to take effect. */
16634 +               mrstWaitForPipeDisable(dev);
16635 +
16636 +               temp = REG_READ(dpll_reg);
16637 +               if ((temp & DPLL_VCO_ENABLE) != 0) {
16638 +                       REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
16639 +                       REG_READ(dpll_reg);
16640 +               }
16641 +
16642 +               /* Wait for the clocks to turn off. */
16643 +               udelay(150);
16644 +               break;
16645 +       }
16646 +
16647 +#if DUMP_REGISTER
16648 +       dump_dc_registers(dev);
16649 +#endif                         /* DUMP_REGISTER */
16650 +
16651 +       enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
16652 +
16653 +#if 0                          /* JB: Add vblank support later */
16654 +       if (enabled)
16655 +               dev_priv->vblank_pipe |= (1 << pipe);
16656 +       else
16657 +               dev_priv->vblank_pipe &= ~(1 << pipe);
16658 +#endif
16659 +
16660 +#if 0                          /* JB: Add sarea support later */
16661 +       if (!dev->primary->master)
16662 +               return;
16663 +
16664 +       master_priv = dev->primary->master->driver_priv;
16665 +       if (!master_priv->sarea_priv)
16666 +               return;
16667 +
16668 +       switch (pipe) {
16669 +       case 0:
16670 +               master_priv->sarea_priv->planeA_w =
16671 +                   enabled ? crtc->mode.hdisplay : 0;
16672 +               master_priv->sarea_priv->planeA_h =
16673 +                   enabled ? crtc->mode.vdisplay : 0;
16674 +               break;
16675 +       case 1:
16676 +               master_priv->sarea_priv->planeB_w =
16677 +                   enabled ? crtc->mode.hdisplay : 0;
16678 +               master_priv->sarea_priv->planeB_h =
16679 +                   enabled ? crtc->mode.vdisplay : 0;
16680 +               break;
16681 +       default:
16682 +               DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
16683 +               break;
16684 +       }
16685 +#endif
16686 +
16687 +       /*Set FIFO Watermarks*/
16688 +       REG_WRITE(DSPARB, 0x3FFF);
16689 +       REG_WRITE(DSPFW1, 0x3F88080A);
16690 +       REG_WRITE(DSPFW2, 0x0b060808);
16691 +       REG_WRITE(DSPFW3, 0x0);
16692 +       REG_WRITE(DSPFW4, 0x08030404);
16693 +       REG_WRITE(DSPFW5, 0x04040404);
16694 +       REG_WRITE(DSPFW6, 0x78);
16695 +       REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
16696 +       /* Must write Bit 14 of the Chicken Bit Register */
16697 +
16698 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
16699 +}
16700 +
16701 +static int mrst_crtc_mode_set(struct drm_crtc *crtc,
16702 +                             struct drm_display_mode *mode,
16703 +                             struct drm_display_mode *adjusted_mode,
16704 +                             int x, int y,
16705 +                             struct drm_framebuffer *old_fb)
16706 +{
16707 +       struct drm_device *dev = crtc->dev;
16708 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
16709 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
16710 +       int pipe = psb_intel_crtc->pipe;
16711 +       int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
16712 +       int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
16713 +       int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
16714 +       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
16715 +       int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
16716 +       int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
16717 +       int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
16718 +       int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
16719 +       int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
16720 +       int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
16721 +       int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
16722 +       int refclk = 0;
16723 +       struct mrst_clock_t clock;
16724 +       u32 dpll = 0, fp = 0, dspcntr, pipeconf, lvdsport;
16725 +       bool ok, is_sdvo = false;
16726 +       bool is_crt = false, is_lvds = false, is_tv = false;
16727 +       bool is_mipi = false;
16728 +       struct drm_mode_config *mode_config = &dev->mode_config;
16729 +       struct psb_intel_output *psb_intel_output = NULL;
16730 +       uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
16731 +       struct drm_encoder *encoder;
16732 +
16733 +#if PRINT_JLIU7
16734 +       DRM_INFO("JLIU7 enter mrst_crtc_mode_set \n");
16735 +#endif                         /* PRINT_JLIU7 */
16736 +
16737 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
16738 +                                       OSPM_UHB_FORCE_POWER_ON))
16739 +               return 0;
16740 +
16741 +       memcpy(&psb_intel_crtc->saved_mode,
16742 +               mode,
16743 +               sizeof(struct drm_display_mode));
16744 +       memcpy(&psb_intel_crtc->saved_adjusted_mode,
16745 +               adjusted_mode,
16746 +               sizeof(struct drm_display_mode));
16747 +
16748 +       list_for_each_entry(encoder, &mode_config->encoder_list, head) {
16749 +
16750 +               if (encoder->crtc != crtc)
16751 +                       continue;
16752 +
16753 +               psb_intel_output = enc_to_psb_intel_output(encoder);
16754 +               switch (psb_intel_output->type) {
16755 +               case INTEL_OUTPUT_LVDS:
16756 +                       is_lvds = true;
16757 +                       break;
16758 +               case INTEL_OUTPUT_SDVO:
16759 +                       is_sdvo = true;
16760 +                       break;
16761 +               case INTEL_OUTPUT_TVOUT:
16762 +                       is_tv = true;
16763 +                       break;
16764 +               case INTEL_OUTPUT_ANALOG:
16765 +                       is_crt = true;
16766 +                       break;
16767 +               case INTEL_OUTPUT_MIPI:
16768 +                       is_mipi = true;
16769 +                       break;
16770 +               }
16771 +       }
16772 +
16773 +       if (is_lvds | is_mipi) {
16774 +               /*FIXME JLIU7 Get panel power delay parameters from
16775 +                 config data */
16776 +               REG_WRITE(0x61208, 0x25807d0);
16777 +               REG_WRITE(0x6120c, 0x1f407d0);
16778 +               REG_WRITE(0x61210, 0x270f04);
16779 +       }
16780 +
16781 +       /* Disable the VGA plane that we never use */
16782 +       REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
16783 +
16784 +       /* Disable the panel fitter if it was on our pipe */
16785 +       if (psb_intel_panel_fitter_pipe(dev) == pipe)
16786 +               REG_WRITE(PFIT_CONTROL, 0);
16787 +
16788 +       REG_WRITE(pipesrc_reg,
16789 +                 ((mode->crtc_hdisplay - 1) << 16) |
16790 +                 (mode->crtc_vdisplay - 1));
16791 +
16792 +       if (psb_intel_output)
16793 +               drm_connector_property_get_value(&psb_intel_output->base,
16794 +                       dev->mode_config.scaling_mode_property, &scalingType);
16795 +
16796 +       if (scalingType == DRM_MODE_SCALE_CENTER) {
16797 +               /* Moorestown doesn't have register support for centering so
16798 +                * we need to mess with the h/vblank and h/vsync start and
16799 +                * ends to get centering */
16800 +               int offsetX = 0, offsetY = 0;
16801 +
16802 +               offsetX = (adjusted_mode->crtc_hdisplay -
16803 +                          mode->crtc_hdisplay) / 2;
16804 +               offsetY = (adjusted_mode->crtc_vdisplay -
16805 +                          mode->crtc_vdisplay) / 2;
16806 +
16807 +               REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
16808 +                       ((adjusted_mode->crtc_htotal - 1) << 16));
16809 +               REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
16810 +                       ((adjusted_mode->crtc_vtotal - 1) << 16));
16811 +               REG_WRITE(hblank_reg,
16812 +                       (adjusted_mode->crtc_hblank_start - offsetX - 1) |
16813 +                       ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
16814 +               REG_WRITE(hsync_reg,
16815 +                       (adjusted_mode->crtc_hsync_start - offsetX - 1) |
16816 +                       ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
16817 +               REG_WRITE(vblank_reg,
16818 +                       (adjusted_mode->crtc_vblank_start - offsetY - 1) |
16819 +                       ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
16820 +               REG_WRITE(vsync_reg,
16821 +                       (adjusted_mode->crtc_vsync_start - offsetY - 1) |
16822 +                       ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
16823 +       } else {
16824 +               REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
16825 +                       ((adjusted_mode->crtc_htotal - 1) << 16));
16826 +               REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
16827 +                       ((adjusted_mode->crtc_vtotal - 1) << 16));
16828 +               REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
16829 +                       ((adjusted_mode->crtc_hblank_end - 1) << 16));
16830 +               REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
16831 +                       ((adjusted_mode->crtc_hsync_end - 1) << 16));
16832 +               REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
16833 +                       ((adjusted_mode->crtc_vblank_end - 1) << 16));
16834 +               REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
16835 +                       ((adjusted_mode->crtc_vsync_end - 1) << 16));
16836 +       }
16837 +
16838 +       /* Flush the plane changes */
16839 +       {
16840 +               struct drm_crtc_helper_funcs *crtc_funcs =
16841 +                   crtc->helper_private;
16842 +               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
16843 +       }
16844 +
16845 +       /* setup pipeconf */
16846 +       pipeconf = REG_READ(pipeconf_reg);
16847 +
16848 +       /* Set up the display plane register */
16849 +       dspcntr = REG_READ(dspcntr_reg);
16850 +       dspcntr |= DISPPLANE_GAMMA_ENABLE;
16851 +
16852 +       if (pipe == 0)
16853 +               dspcntr |= DISPPLANE_SEL_PIPE_A;
16854 +       else
16855 +               dspcntr |= DISPPLANE_SEL_PIPE_B;
16856 +
16857 +       dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE;
16858 +       dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE;
16859 +
16860 +       if (is_mipi)
16861 +               goto mrst_crtc_mode_set_exit;
16862 +
16863 +       if (dev_priv->sku_100L)
16864 +               refclk = 100000;
16865 +       else if (dev_priv->sku_83)
16866 +               refclk = 166000;
16867 +       else if (dev_priv->sku_100)
16868 +               refclk = 200000;
16869 +
16870 +       dpll = 0;               /*BIT16 = 0 for 100MHz reference */
16871 +
16872 +       ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
16873 +
16874 +       if (!ok) {
16875 +#if PRINT_JLIU7
16876 +               DRM_INFO
16877 +                   ("JLIU7 mrstFindBestPLL fail in mrst_crtc_mode_set. \n");
16878 +#endif                         /* PRINT_JLIU7 */
16879 +       } else {
16880 +#if PRINT_JLIU7
16881 +               DRM_INFO("JLIU7 mrst_crtc_mode_set pixel clock = %d,"
16882 +                        "m = %x, p1 = %x. \n", clock.dot, clock.m,
16883 +                        clock.p1);
16884 +#endif                         /* PRINT_JLIU7 */
16885 +       }
16886 +
16887 +       fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8;
16888 +
16889 +       dpll |= DPLL_VGA_MODE_DIS;
16890 +
16891 +
16892 +       dpll |= DPLL_VCO_ENABLE;
16893 +
16894 +       if (is_lvds)
16895 +               dpll |= DPLLA_MODE_LVDS;
16896 +       else
16897 +               dpll |= DPLLB_MODE_DAC_SERIAL;
16898 +
16899 +       if (is_sdvo) {
16900 +               int sdvo_pixel_multiply =
16901 +                   adjusted_mode->clock / mode->clock;
16902 +
16903 +               dpll |= DPLL_DVO_HIGH_SPEED;
16904 +               dpll |=
16905 +                   (sdvo_pixel_multiply -
16906 +                    1) << SDVO_MULTIPLIER_SHIFT_HIRES;
16907 +       }
16908 +
16909 +
16910 +       /* compute bitmask from p1 value */
16911 +       dpll |= (1 << (clock.p1 - 2)) << 17;
16912 +
16913 +       dpll |= DPLL_VCO_ENABLE;
16914 +
16915 +#if PRINT_JLIU7
16916 +       mrstPrintPll("chosen", &clock);
16917 +#endif                         /* PRINT_JLIU7 */
16918 +
16919 +#if 0
16920 +       if (!xf86ModesEqual(mode, adjusted_mode)) {
16921 +               xf86DrvMsg(pScrn->scrnIndex, X_INFO,
16922 +                          "Adjusted mode for pipe %c:\n",
16923 +                          pipe == 0 ? 'A' : 'B');
16924 +               xf86PrintModeline(pScrn->scrnIndex, mode);
16925 +       }
16926 +       i830PrintPll("chosen", &clock);
16927 +#endif
16928 +
16929 +       if (dpll & DPLL_VCO_ENABLE) {
16930 +               REG_WRITE(fp_reg, fp);
16931 +               REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
16932 +               REG_READ(dpll_reg);
16933 +/* FIXME jliu7 check the DPLLA lock bit PIPEACONF[29] */
16934 +               udelay(150);
16935 +       }
16936 +
16937 +       /* The LVDS pin pair needs to be on before the DPLLs are enabled.
16938 +        * This is an exception to the general rule that mode_set doesn't turn
16939 +        * things on.
16940 +        */
16941 +       if (is_lvds) {
16942 +
16943 +               /*lvdsport = 0x803003c0;*/
16944 +               /*lvdsport = 0x813003c0;*/
16945 +               lvdsport = dev_priv->gct_data.Panel_Port_Control;
16946 +
16947 +               REG_WRITE(LVDS, lvdsport);
16948 +       }
16949 +
16950 +       REG_WRITE(fp_reg, fp);
16951 +       REG_WRITE(dpll_reg, dpll);
16952 +       REG_READ(dpll_reg);
16953 +       /* Wait for the clocks to stabilize. */
16954 +       udelay(150);
16955 +
16956 +       /* write it again -- the BIOS does, after all */
16957 +       REG_WRITE(dpll_reg, dpll);
16958 +       REG_READ(dpll_reg);
16959 +       /* Wait for the clocks to stabilize. */
16960 +       udelay(150);
16961 +
16962 +       REG_WRITE(pipeconf_reg, pipeconf);
16963 +       REG_READ(pipeconf_reg);
16964 +
16965 +       /* Wait for for the pipe enable to take effect. */
16966 +       mrstWaitForPipeEnable(dev);
16967 +
16968 +       REG_WRITE(dspcntr_reg, dspcntr);
16969 +       psb_intel_wait_for_vblank(dev);
16970 +
16971 +mrst_crtc_mode_set_exit:
16972 +
16973 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
16974 +
16975 +       return 0;
16976 +}
16977 +
16978 +
16979 +static const struct drm_crtc_helper_funcs mrst_helper_funcs = {
16980 +       .dpms = mrst_crtc_dpms,
16981 +       .mode_fixup = psb_intel_crtc_mode_fixup,
16982 +       .mode_set = mrst_crtc_mode_set,
16983 +       .mode_set_base = psb_intel_pipe_set_base,
16984 +       .prepare = psb_intel_crtc_prepare,
16985 +       .commit = psb_intel_crtc_commit,
16986 +};
16987 +
16988 +/* MRST_PLATFORM end */
16989 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_display.h b/drivers/gpu/drm/mrst/drv/psb_intel_display.h
16990 new file mode 100644
16991 index 0000000..74e3b5e
16992 --- /dev/null
16993 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_display.h
16994 @@ -0,0 +1,25 @@
16995 +/* copyright (c) 2008, Intel Corporation
16996 + * 
16997 + * This program is free software; you can redistribute it and/or modify it
16998 + * under the terms and conditions of the GNU General Public License,
16999 + * version 2, as published by the Free Software Foundation.
17000 + *
17001 + * This program is distributed in the hope it will be useful, but WITHOUT
17002 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17003 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17004 + * more details.
17005 + *
17006 + * You should have received a copy of the GNU General Public License along with
17007 + * this program; if not, write to the Free Software Foundation, Inc., 
17008 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17009 + *
17010 + * Authors:
17011 + * Eric Anholt <eric@anholt.net>
17012 + */
17013 +
17014 +#ifndef _INTEL_DISPLAY_H_
17015 +#define _INTEL_DISPLAY_H_
17016 +
17017 +bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
17018 +
17019 +#endif
17020 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_drv.h b/drivers/gpu/drm/mrst/drv/psb_intel_drv.h
17021 new file mode 100644
17022 index 0000000..9e77cce
17023 --- /dev/null
17024 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_drv.h
17025 @@ -0,0 +1,283 @@
17026 +/*
17027 + * Copyright (c) 2009, Intel Corporation.
17028 + *
17029 + * This program is free software; you can redistribute it and/or modify it
17030 + * under the terms and conditions of the GNU General Public License,
17031 + * version 2, as published by the Free Software Foundation.
17032 + *
17033 + * This program is distributed in the hope it will be useful, but WITHOUT
17034 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17035 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17036 + * more details.
17037 + *
17038 + * You should have received a copy of the GNU General Public License along with
17039 + * this program; if not, write to the Free Software Foundation, Inc., 
17040 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17041 + *
17042 + */
17043 +
17044 +#ifndef __INTEL_DRV_H__
17045 +#define __INTEL_DRV_H__
17046 +
17047 +#include <linux/i2c.h>
17048 +#include <linux/i2c-id.h>
17049 +#include <linux/i2c-algo-bit.h>
17050 +#include <drm/drm_crtc.h>
17051 +
17052 +#include <drm/drm_crtc_helper.h>
17053 +
17054 +/*
17055 + * MOORESTOWN defines
17056 + */
17057 +#define MRST_I2C 0
17058 +
17059 +#define DUMP_REGISTER 0
17060 +#define MRST_24BIT_LVDS 1
17061 +#define MRST_24BIT_DOT_1 0
17062 +#define MRST_24BIT_WA 0
17063 +
17064 +#define PRINT_JLIU7 0
17065 +#define DELAY_TIME1 2000 /* 1000 = 1ms */
17066 +
17067 +/*
17068 + * Display related stuff
17069 + */
17070 +
17071 +/* store information about an Ixxx DVO */
17072 +/* The i830->i865 use multiple DVOs with multiple i2cs */
17073 +/* the i915, i945 have a single sDVO i2c bus - which is different */
17074 +#define MAX_OUTPUTS 6
17075 +/* maximum connectors per crtcs in the mode set */
17076 +#define INTELFB_CONN_LIMIT 4
17077 +
17078 +#define INTEL_I2C_BUS_DVO 1
17079 +#define INTEL_I2C_BUS_SDVO 2
17080 +
17081 +/* these are outputs from the chip - integrated only
17082 + * external chips are via DVO or SDVO output */
17083 +#define INTEL_OUTPUT_UNUSED 0
17084 +#define INTEL_OUTPUT_ANALOG 1
17085 +#define INTEL_OUTPUT_DVO 2
17086 +#define INTEL_OUTPUT_SDVO 3
17087 +#define INTEL_OUTPUT_LVDS 4
17088 +#define INTEL_OUTPUT_TVOUT 5
17089 +#define INTEL_OUTPUT_MIPI 6
17090 +
17091 +#define INTEL_DVO_CHIP_NONE 0
17092 +#define INTEL_DVO_CHIP_LVDS 1
17093 +#define INTEL_DVO_CHIP_TMDS 2
17094 +#define INTEL_DVO_CHIP_TVOUT 4
17095 +
17096 +enum mipi_panel_type {
17097 +       NSC_800X480 = 1,
17098 +       LGE_480X1024 = 2,
17099 +       TPO_864X480 = 3
17100 +};
17101 +
17102 +struct opregion_header {
17103 +       u8 signature[16];
17104 +       u32 size;
17105 +       u32 opregion_ver;
17106 +       u8 bios_ver[32];
17107 +       u8 vbios_ver[16];
17108 +       u8 driver_ver[16];
17109 +       u32 mboxes;
17110 +       u8 reserved[164];
17111 +} __attribute__((packed));
17112 +
17113 +struct opregion_apci {
17114 +       /*FIXME: add it later*/
17115 +} __attribute__((packed));
17116 +
17117 +struct opregion_swsci {
17118 +       /*FIXME: add it later*/
17119 +} __attribute__((packed));
17120 +
17121 +struct opregion_acpi {
17122 +       /*FIXME: add it later*/
17123 +} __attribute__((packed));
17124 +
17125 +struct psb_intel_opregion {
17126 +       struct opregion_header *header;
17127 +       struct opregion_acpi *acpi;
17128 +       struct opregion_swsci *swsci;
17129 +       struct opregion_asle *asle;
17130 +       int enabled;
17131 +};
17132 +
17133 +/**
17134 + * Hold information useally put on the device driver privates here,
17135 + * since it needs to be shared across multiple of devices drivers privates.
17136 +*/
17137 +struct psb_intel_mode_device {
17138 +
17139 +       /*
17140 +        * Abstracted memory manager operations
17141 +        */
17142 +       void *(*bo_from_handle) (struct drm_device *dev,
17143 +                                struct drm_file *file_priv,
17144 +                                unsigned int handle);
17145 +        size_t(*bo_size) (struct drm_device *dev, void *bo);
17146 +        size_t(*bo_offset) (struct drm_device *dev, void *bo);
17147 +       int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo);
17148 +       int (*bo_unpin_for_scanout) (struct drm_device *dev, void *bo);
17149 +
17150 +       /*
17151 +        * Cursor
17152 +        */
17153 +       int cursor_needs_physical;
17154 +
17155 +       /*
17156 +        * LVDS info
17157 +        */
17158 +       int backlight_duty_cycle;       /* restore backlight to this value */
17159 +       bool panel_wants_dither;
17160 +       struct drm_display_mode *panel_fixed_mode;
17161 +       struct drm_display_mode *vbt_mode;      /* if any */
17162 +
17163 +       uint32_t saveBLC_PWM_CTL;
17164 +};
17165 +
17166 +struct psb_intel_i2c_chan {
17167 +       /* for getting at dev. private (mmio etc.) */
17168 +       struct drm_device *drm_dev;
17169 +       u32 reg;                /* GPIO reg */
17170 +       struct i2c_adapter adapter;
17171 +       struct i2c_algo_bit_data algo;
17172 +       u8 slave_addr;
17173 +};
17174 +
17175 +struct psb_intel_output {
17176 +       struct drm_connector base;
17177 +
17178 +       struct drm_encoder enc;
17179 +       int type;
17180 +       struct psb_intel_i2c_chan *i2c_bus;     /* for control functions */
17181 +       struct psb_intel_i2c_chan *ddc_bus;     /* for DDC only stuff */
17182 +       bool load_detect_temp;
17183 +       void *dev_priv;
17184 +
17185 +       struct psb_intel_mode_device *mode_dev;
17186 +
17187 +};
17188 +
17189 +struct psb_intel_crtc_state {
17190 +       uint32_t saveDSPCNTR;
17191 +       uint32_t savePIPECONF;
17192 +       uint32_t savePIPESRC;
17193 +       uint32_t saveDPLL;
17194 +       uint32_t saveFP0;
17195 +       uint32_t saveFP1;
17196 +       uint32_t saveHTOTAL;
17197 +       uint32_t saveHBLANK;
17198 +       uint32_t saveHSYNC;
17199 +       uint32_t saveVTOTAL;
17200 +       uint32_t saveVBLANK;
17201 +       uint32_t saveVSYNC;
17202 +       uint32_t saveDSPSTRIDE;
17203 +       uint32_t saveDSPSIZE;
17204 +       uint32_t saveDSPPOS;
17205 +       uint32_t saveDSPBASE;
17206 +       uint32_t savePalette[256];
17207 +};
17208 +
17209 +struct psb_intel_crtc {
17210 +       struct drm_crtc base;
17211 +       int pipe;
17212 +       int plane;
17213 +       uint32_t cursor_addr;
17214 +       u8 lut_r[256], lut_g[256], lut_b[256];
17215 +       u8 lut_adj[256];
17216 +       struct psb_intel_framebuffer *fbdev_fb;
17217 +       /* a mode_set for fbdev users on this crtc */
17218 +       struct drm_mode_set mode_set;
17219 +
17220 +       /* current bo we scanout from */
17221 +       void *scanout_bo;
17222 +
17223 +       /* current bo we cursor from */
17224 +       void *cursor_bo;
17225 +
17226 +       struct drm_display_mode saved_mode;
17227 +       struct drm_display_mode saved_adjusted_mode;
17228 +
17229 +       struct psb_intel_mode_device *mode_dev;
17230 +
17231 +/*FIXME: Workaround to avoid MRST block.*/
17232 +#ifndef CONFIG_X86_MRST
17233 +       /* Saved Crtc HW states */
17234 +       struct psb_intel_crtc_state *crtc_state;
17235 +#endif
17236 +};
17237 +
17238 +#define to_psb_intel_crtc(x)   \
17239 +               container_of(x, struct psb_intel_crtc, base)
17240 +#define to_psb_intel_output(x) \
17241 +               container_of(x, struct psb_intel_output, base)
17242 +#define enc_to_psb_intel_output(x)     \
17243 +               container_of(x, struct psb_intel_output, enc)
17244 +#define to_psb_intel_framebuffer(x)    \
17245 +               container_of(x, struct psb_framebuffer, base)
17246 +
17247 +struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
17248 +                                       const u32 reg, const char *name);
17249 +void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan);
17250 +int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output);
17251 +extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output);
17252 +
17253 +extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,
17254 +                           struct psb_intel_mode_device *mode_dev);
17255 +extern void psb_intel_crt_init(struct drm_device *dev);
17256 +extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device);
17257 +extern void psb_intel_dvo_init(struct drm_device *dev);
17258 +extern void psb_intel_tv_init(struct drm_device *dev);
17259 +extern void psb_intel_lvds_init(struct drm_device *dev,
17260 +                           struct psb_intel_mode_device *mode_dev);
17261 +extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level);
17262 +extern void mrst_lvds_init(struct drm_device *dev,
17263 +                          struct psb_intel_mode_device *mode_dev);
17264 +extern void mrst_dsi_init(struct drm_device *dev,
17265 +                          struct psb_intel_mode_device *mode_dev);
17266 +
17267 +extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc);
17268 +extern void psb_intel_encoder_prepare(struct drm_encoder *encoder);
17269 +extern void psb_intel_encoder_commit(struct drm_encoder *encoder);
17270 +
17271 +extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector
17272 +                                             *connector);
17273 +
17274 +extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
17275 +                                                   struct drm_crtc *crtc);
17276 +extern void psb_intel_wait_for_vblank(struct drm_device *dev);
17277 +extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
17278 +                               struct drm_file *file_priv);
17279 +extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
17280 +                                                int pipe);
17281 +extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev,
17282 +                                            int sdvoB);
17283 +extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector);
17284 +extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector,
17285 +                                  int enable);
17286 +extern int intelfb_probe(struct drm_device *dev);
17287 +extern int intelfb_remove(struct drm_device *dev,
17288 +                         struct drm_framebuffer *fb);
17289 +extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device
17290 +                                                       *dev, struct
17291 +                                                       drm_mode_fb_cmd
17292 +                                                       *mode_cmd,
17293 +                                                       void *mm_private);
17294 +extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
17295 +                                     struct drm_display_mode *mode,
17296 +                                     struct drm_display_mode *adjusted_mode);
17297 +extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
17298 +                                    struct drm_display_mode *mode);
17299 +extern int psb_intel_lvds_set_property(struct drm_connector *connector,
17300 +                                       struct drm_property *property,
17301 +                                       uint64_t value);
17302 +extern void psb_intel_lvds_destroy(struct drm_connector *connector);
17303 +extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
17304 +
17305 +extern uint8_t blc_pol;
17306 +extern uint8_t blc_freq;
17307 +
17308 +#endif                         /* __INTEL_DRV_H__ */
17309 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_dsi.c b/drivers/gpu/drm/mrst/drv/psb_intel_dsi.c
17310 new file mode 100644
17311 index 0000000..3d45df8
17312 --- /dev/null
17313 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_dsi.c
17314 @@ -0,0 +1,2450 @@
17315 +/*
17316 + * Copyright Â© 2006-2007 Intel Corporation
17317 + *
17318 + * This program is free software; you can redistribute it and/or modify it
17319 + * under the terms and conditions of the GNU General Public License,
17320 + * version 2, as published by the Free Software Foundation.
17321 + *
17322 + * This program is distributed in the hope it will be useful, but WITHOUT
17323 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17324 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17325 + * more details.
17326 + *
17327 + * You should have received a copy of the GNU General Public License along with
17328 + * this program; if not, write to the Free Software Foundation, Inc.,
17329 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17330 + *
17331 + * Authors:
17332 + *     jim liu <jim.liu@intel.com>
17333 + */
17334 +
17335 +#include <linux/backlight.h>
17336 +#include <drm/drmP.h>
17337 +#include <drm/drm.h>
17338 +#include <drm/drm_crtc.h>
17339 +#include <drm/drm_edid.h>
17340 +#include <asm/ipc_defs.h>
17341 +
17342 +#include "psb_drv.h"
17343 +#include "psb_intel_drv.h"
17344 +#include "psb_intel_reg.h"
17345 +#include "ospm_power.h"
17346 +
17347 +#define DRM_MODE_ENCODER_MIPI  5
17348 +
17349 +#define BRIGHTNESS_MAX_LEVEL 100
17350 +#define BLC_POLARITY_NORMAL 0
17351 +
17352 +#if DUMP_REGISTER
17353 +extern void dump_dsi_registers(struct drm_device *dev);
17354 +#endif /* DUMP_REGISTER */
17355 +void mrst_init_TPO_MIPI(struct drm_device *dev);
17356 +
17357 +int dsi_backlight;     /* restore backlight to this value */
17358 +
17359 +/**
17360 + * Returns the maximum level of the backlight duty cycle field.
17361 + */
17362 +static u32 mrst_dsi_get_max_backlight(struct drm_device *dev)
17363 +{
17364 +#if PRINT_JLIU7
17365 +     DRM_INFO("JLIU7 enter mrst_dsi_get_max_backlight \n");
17366 +#endif /* PRINT_JLIU7 */
17367 +
17368 +       return BRIGHTNESS_MAX_LEVEL;
17369 +
17370 +/* FIXME jliu7 need to revisit */
17371 +}
17372 +
17373 +/**
17374 + * Sets the power state for the panel.
17375 + */
17376 +static void mrst_dsi_set_power(struct drm_device *dev,
17377 +                       struct psb_intel_output *output, bool on)
17378 +{
17379 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
17380 +
17381 +       DRM_INFO("Enter mrst_dsi_set_power \n");
17382 +
17383 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17384 +                                      OSPM_UHB_FORCE_POWER_ON))
17385 +               return;
17386 +
17387 +       if (on) {
17388 +               /* program MIPI DSI controller and Display Controller
17389 +                * set the device ready bit + set 'turn on' bit b048
17390 +                * wait for 100 ms ??
17391 +                * set pipe enable bit */
17392 +               REG_WRITE(DPI_CONTROL_REG, 2);
17393 +               msleep(100);
17394 +               if (dev_priv->panel_make == TPO_864X480)
17395 +                       dev_priv->init_drvIC(dev); /* initialize the panel */
17396 +               /* Turn on backlight */
17397 +               REG_WRITE(BLC_PWM_CTL, 0x2faf1fc9);
17398 +       } else  {
17399 +               /* set the shutdown bit b048h
17400 +                * de-assert pipe enable
17401 +                * clear device ready bit unless DBI is to be left on */
17402 +               REG_WRITE(BLC_PWM_CTL, 0x2faf0000); /* turn off backlight */
17403 +               REG_WRITE(DPI_CONTROL_REG, 1); /* send shut down message */
17404 +       }
17405 +
17406 +    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17407 +}
17408 +
17409 +static void mrst_dsi_dpms(struct drm_encoder *encoder, int mode)
17410 +{
17411 +       struct drm_device *dev = encoder->dev;
17412 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
17413 +
17414 +#if PRINT_JLIU7
17415 +     DRM_INFO("JLIU7 enter mrst_dsi_dpms \n");
17416 +#endif /* PRINT_JLIU7 */
17417 +
17418 +       if (mode == DRM_MODE_DPMS_ON)
17419 +               mrst_dsi_set_power(dev, output, true);
17420 +       else
17421 +               mrst_dsi_set_power(dev, output, false);
17422 +
17423 +       /* XXX: We never power down the DSI pairs. */
17424 +}
17425 +
17426 +static void mrst_dsi_save(struct drm_connector *connector)
17427 +{
17428 +#if 0 /* JB: Disable for drop */
17429 +       struct drm_device *dev = connector->dev;
17430 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
17431 +
17432 +#if PRINT_JLIU7
17433 +     DRM_INFO("JLIU7 enter  mrst_dsi_save \n");
17434 +#endif /* PRINT_JLIU7 */
17435 +
17436 +       dev_priv->savePP_ON = REG_READ(LVDSPP_ON);
17437 +       dev_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
17438 +       dev_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
17439 +       dev_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
17440 +       dev_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
17441 +       dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
17442 +                                      BACKLIGHT_DUTY_CYCLE_MASK);
17443 +
17444 +       /*
17445 +        * make backlight to full brightness
17446 +        */
17447 +       dsi_backlight = mrst_dsi_get_max_backlight(dev);
17448 +#endif
17449 +}
17450 +
17451 +static void mrst_dsi_restore(struct drm_connector *connector)
17452 +{
17453 +#if 0 /* JB: Disable for drop */
17454 +       struct drm_device *dev = connector->dev;
17455 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
17456 +
17457 +#if PRINT_JLIU7
17458 +     DRM_INFO("JLIU7 enter  mrst_dsi_restore \n");
17459 +#endif /* PRINT_JLIU7 */
17460 +
17461 +       REG_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
17462 +       REG_WRITE(LVDSPP_ON, dev_priv->savePP_ON);
17463 +       REG_WRITE(LVDSPP_OFF, dev_priv->savePP_OFF);
17464 +       REG_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
17465 +       *REG_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
17466 +       if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
17467 +               mrst_dsi_set_power(dev, true);
17468 +       else
17469 +               mrst_dsi_set_power(dev, false);
17470 +#endif
17471 +}
17472 +
17473 +static void mrst_dsi_prepare(struct drm_encoder *encoder)
17474 +{
17475 +       struct drm_device *dev = encoder->dev;
17476 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
17477 +       struct psb_intel_mode_device *mode_dev = output->mode_dev;
17478 +
17479 +#if PRINT_JLIU7
17480 +     DRM_INFO("JLIU7 enter  mrst_dsi_prepare \n");
17481 +#endif /* PRINT_JLIU7 */
17482 +
17483 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17484 +                                       OSPM_UHB_FORCE_POWER_ON))
17485 +               return;
17486 +
17487 +       mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
17488 +       mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
17489 +                                         BACKLIGHT_DUTY_CYCLE_MASK);
17490 +
17491 +       mrst_dsi_set_power(dev, output, false);
17492 +
17493 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17494 +}
17495 +
17496 +static void mrst_dsi_commit(struct drm_encoder *encoder)
17497 +{
17498 +       struct drm_device *dev = encoder->dev;
17499 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
17500 +       struct psb_intel_mode_device *mode_dev = output->mode_dev;
17501 +
17502 +#if PRINT_JLIU7
17503 +     DRM_INFO("JLIU7 enter  mrst_dsi_commit \n");
17504 +#endif /* PRINT_JLIU7 */
17505 +
17506 +       if (mode_dev->backlight_duty_cycle == 0)
17507 +               mode_dev->backlight_duty_cycle =
17508 +                       mrst_dsi_get_max_backlight(dev);
17509 +
17510 +       mrst_dsi_set_power(dev, output, true);
17511 +
17512 +#if DUMP_REGISTER
17513 +       dump_dsi_registers(dev);
17514 +#endif /* DUMP_REGISTER */
17515 +}
17516 +
17517 +#if 0
17518 +/* ************************************************************************* *\
17519 +FUNCTION: GetHS_TX_timeoutCount
17520 +DESCRIPTION: In burst mode, value  greater than one DPI line Time in byte clock
17521 +       (txbyteclkhs). To timeout this timer 1+ of the
17522 +       above said value is recommended.
17523 +
17524 +       In non-burst mode, Value greater than one DPI frame time
17525 +       in byte clock(txbyteclkhs).
17526 +
17527 +       To timeout this timer 1+ of the above said value is recommended.
17528 +
17529 +\* ************************************************************************* */
17530 +static u32 GetHS_TX_timeoutCount(DRM_DRIVER_PRIVATE_T *dev_priv)
17531 +{
17532 +
17533 +       u32 timeoutCount = 0, HTOT_count = 0, VTOT_count = 0, HTotalPixel = 0;
17534 +
17535 +       /* Total pixels need to be transfer per line*/
17536 +       HTotalPixel = (dev_priv->HsyncWidth +
17537 +                       dev_priv->HbackPorch +
17538 +                       dev_priv->HfrontPorch) *
17539 +                       dev_priv->laneCount +
17540 +                       dev_priv->HactiveArea;
17541 +
17542 +       /* byte count = (pixel count *  bits per pixel) / 8 */
17543 +       HTOT_count = (HTotalPixel * dev_priv->bpp) / 8;
17544 +
17545 +       if (dev_priv->videoModeFormat == BURST_MODE) {
17546 +               timeoutCount = HTOT_count + 1;
17547 +#if 1 /*FIXME remove it after power-on */
17548 +               VTOT_count = dev_priv->VactiveArea +
17549 +                               dev_priv->VbackPorch +
17550 +                               dev_priv->VfrontPorch + dev_priv->VsyncWidth;
17551 +
17552 +               /* timeoutCount = (HTOT_count * VTOT_count) + 1; */
17553 +               timeoutCount = (HTOT_count * VTOT_count) + 1;
17554 +#endif
17555 +       } else {
17556 +               VTOT_count = dev_priv->VactiveArea +
17557 +                               dev_priv->VbackPorch +
17558 +                               dev_priv->VfrontPorch +
17559 +                               dev_priv->VsyncWidth;
17560 +               /* timeoutCount = (HTOT_count * VTOT_count) + 1; */
17561 +               timeoutCount = (HTOT_count * VTOT_count) + 1;
17562 +       }
17563 +
17564 +       return timeoutCount & 0xFFFF;
17565 +}
17566 +
17567 +/* ************************************************************************* *\
17568 +FUNCTION: GetLP_RX_timeoutCount
17569 +
17570 +DESCRIPTION: The timeout value is protocol specific. Time out value is
17571 +               calculated from txclkesc(50ns).
17572 +
17573 +       Minimum value =
17574 +               Time to send one Trigger message = 4 X txclkesc
17575 +                                       [Escape mode entry sequence)
17576 +               + 8-bit trigger message (2x8xtxclkesc)
17577 +               +1 txclksesc [stop_state]
17578 +       = 21 X txclkesc [ 15h]
17579 +
17580 +       Maximum Value =
17581 +               Time to send a long packet with maximum payload data
17582 +                       = 4 X txclkesc [Escape mode entry sequence)
17583 +               + 8-bit Low power data transmission Command (2x8xtxclkesc)
17584 +               + packet header [ 4X8X2X txclkesc]
17585 +               +payload [ nX8X2Xtxclkesc]
17586 +               +CRC[2X8X2txclkesc]
17587 +               +1 txclksesc [stop_state]
17588 +       = 117 txclkesc +n[payload in terms of bytes]X16txclkesc.
17589 +
17590 +\* ************************************************************************* */
17591 +static u32 GetLP_RX_timeoutCount(DRM_DRIVER_PRIVATE_T *dev_priv)
17592 +{
17593 +
17594 +       u32 timeoutCount = 0;
17595 +
17596 +       if (dev_priv->config_phase) {
17597 +               /* Assuming 256 byte DDB data.*/
17598 +               timeoutCount = 117 + 256 * 16;
17599 +       } else {
17600 +               /* For DPI video only mode use the minimum value.*/
17601 +               timeoutCount = 0x15;
17602 +#if 1 /*FIXME remove it after power-on */
17603 +               /* Assuming 256 byte DDB data.*/
17604 +               timeoutCount = 117 + 256 * 16;
17605 +#endif
17606 +       }
17607 +
17608 +       return timeoutCount;
17609 +}
17610 +#endif /* #if 0 - to avoid warnings */
17611 +
17612 +/* ************************************************************************* *\
17613 +FUNCTION: GetHSA_Count
17614 +
17615 +DESCRIPTION: Shows the horizontal sync value in terms of byte clock
17616 +                       (txbyteclkhs)
17617 +       Minimum HSA period should be sufficient to transmit a hsync start short
17618 +               packet(4 bytes)
17619 +               i) For Non-burst Mode with sync pulse, Min value 4 in decimal
17620 +                       [plus an optional 6 bytes for a zero payload blanking
17621 +                        packet]. But if the value is less than 10 but more
17622 +                       than 4, then this count will be added to the HBP s
17623 +                       count for one lane.
17624 +               ii) For Non-Burst Sync Event & Burst Mode, there is no HSA,
17625 +                       so you can program this to zero. If you program this
17626 +                       register, these byte values will be added to HBP.
17627 +               iii) For Burst mode of operation, normally the values
17628 +                       programmed in terms of byte clock are based on the
17629 +                       principle - time for transfering
17630 +                       HSA in Burst mode is the same as in non-bust mode.
17631 +\* ************************************************************************* */
17632 +static u32 GetHSA_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17633 +{
17634 +       u32 HSA_count;
17635 +       u32 HSA_countX8;
17636 +
17637 +       /* byte clock count = (pixel clock count *  bits per pixel) /8 */
17638 +       /*HSA_countX8 = dev_priv->HsyncWidth * dev_priv->bpp;
17639 +
17640 +       if (dev_priv->videoModeFormat == BURST_MODE) {
17641 +               HSA_countX8 *= dev_priv->DDR_Clock /
17642 +                               dev_priv->DDR_Clock_Calculated;
17643 +       }
17644 +
17645 +       HSA_count = HSA_countX8 / 8;*/
17646 +
17647 +       /* since mode_set already computed Display Controller timings,
17648 +        *  read the register and compute mipi timings.
17649 +       */
17650 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17651 +                                       OSPM_UHB_ONLY_IF_ON)) {
17652 +               HSA_countX8 = REG_READ(HSYNC_A);
17653 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17654 +       } else
17655 +               HSA_countX8 = dev_priv->saveHSYNC_A;
17656 +
17657 +       /* Get the hsync pulse width */
17658 +       HSA_count = ((HSA_countX8 & 0xffff0000)>>16) - (HSA_countX8 & 0xffff);
17659 +       /* compute HSA according to equation:
17660 +        (hsync_end - hsync_start) * 24 bpp / (2 * 8 bits per lane * 2 lanes)*/
17661 +       HSA_count = (HSA_count * dev_priv->bpp)/(2 * 8 * 2);
17662 +       if (HSA_count < 4) /* minimum value of 4 */
17663 +               HSA_count = 4;
17664 +
17665 +       return HSA_count;
17666 +}
17667 +
17668 +/* ************************************************************************* *\
17669 +FUNCTION: GetHBP_Count
17670 +
17671 +DESCRIPTION: Shows the horizontal back porch value in terms of txbyteclkhs.
17672 +       Minimum HBP period should be sufficient to transmit a ï¿½hsync end short
17673 +               packet(4 bytes) + Blanking packet overhead(6 bytes) +
17674 +               RGB packet header(4 bytes)�
17675 +       For Burst mode of operation, normally the values programmed in terms of
17676 +               byte clock are based on the principle - time for transfering HBP
17677 +               in Burst mode is the same as in non-bust mode.
17678 +
17679 +       Min value ï¿½ 14 in decimal
17680 +               [accounted with zero payload for blanking packet] for one lane.
17681 +       Max value ï¿½ any value greater than 14 based on DPI resolution
17682 +\* ************************************************************************* */
17683 +static u32 GetHBP_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17684 +{
17685 +       u32 HBP_count;
17686 +       u32 HBE, HSE;
17687 +
17688 +       /* byte clock count = (pixel clock count *  bits per pixel) /8 */
17689 +       /*HBP_countX8 = dev_priv->HbackPorch * dev_priv->bpp;
17690 +
17691 +       if (dev_priv->videoModeFormat == BURST_MODE) {
17692 +               HBP_countX8 *= dev_priv->DDR_Clock /
17693 +                               dev_priv->DDR_Clock_Calculated;
17694 +       }
17695 +
17696 +       HBP_count = HBP_countX8 / 8;*/
17697 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17698 +                                       OSPM_UHB_ONLY_IF_ON)) {
17699 +               HBE = (REG_READ(HBLANK_A) & 0xffff0000) >> 16;
17700 +               HSE = (REG_READ(HSYNC_A) & 0xffff0000) >> 16;
17701 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17702 +       } else {
17703 +               HBE = (dev_priv->saveHBLANK_A & 0xffff0000) >> 16;
17704 +               HSE = (dev_priv->saveHSYNC_A & 0xffff0000) >> 16;
17705 +       }
17706 +
17707 +       /* Get the hsync pulse width */
17708 +       HBP_count = HBE - HSE;
17709 +       /*compute HSA according to equation:
17710 +        *(hblank_end - hsync_end) * 24 bpp / (2 * 8 bits per lane * 2 lanes)*/
17711 +       HBP_count = (HBP_count * dev_priv->bpp)/(2 * 8 * 2);
17712 +       if (HBP_count < 8) /* minimum value of 8 */
17713 +               HBP_count = 8;
17714 +
17715 +       return HBP_count;
17716 +}
17717 +
17718 +/* ************************************************************************* *\
17719 +FUNCTION: GetHFP_Count
17720 +
17721 +DESCRIPTION: Shows the horizontal front porch value in terms of txbyteclkhs.
17722 +Minimum HFP period should be sufficient to transmit ï¿½RGB Data packet
17723 +footer(2 bytes) + Blanking packet overhead(6 bytes)� for non burst mode.
17724 +
17725 +For burst mode, Minimum HFP period should be sufficient to transmit
17726 +Blanking packet overhead(6 bytes)�
17727 +
17728 +For Burst mode of operation, normally the values programmed in terms of
17729 +       byte clock are based on the principle - time for transfering HFP
17730 +       in Burst mode is the same as in non-bust mode.
17731 +
17732 +Min value ï¿½ 8 in decimal  for non-burst mode [accounted with zero payload
17733 +       for blanking packet] for one lane.
17734 +Min value ï¿½ 6 in decimal for burst mode for one lane.
17735 +
17736 +Max value ï¿½ any value greater than the minimum vaue based on DPI resolution
17737 +\* ************************************************************************* */
17738 +static u32 GetHFP_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17739 +{
17740 +       u32 HFP_count;
17741 +       u32 HBS, HSS;
17742 +
17743 +       /* byte clock count = (pixel clock count *  bits per pixel) /8 */
17744 +       /*HFP_countX8 = dev_priv->HfrontPorch * dev_priv->bpp;
17745 +
17746 +       if (dev_priv->videoModeFormat == BURST_MODE) {
17747 +               HFP_countX8 *= dev_priv->DDR_Clock /
17748 +                               dev_priv->DDR_Clock_Calculated;
17749 +       }
17750 +
17751 +       HFP_count = HFP_countX8 / 8;*/
17752 +
17753 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17754 +                                       OSPM_UHB_ONLY_IF_ON)) {
17755 +               HBS = REG_READ(HBLANK_A) & 0xffff;
17756 +               HSS = REG_READ(HSYNC_A) & 0xffff;
17757 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17758 +       } else {
17759 +               HBS = dev_priv->saveHBLANK_A & 0xffff;
17760 +               HSS = dev_priv->saveHSYNC_A & 0xffff;
17761 +       }
17762 +
17763 +       /* Get the hsync pulse width */
17764 +       HFP_count = HSS - HBS;
17765 +       /*compute HSA according to equation:
17766 +        *(hblank_end - hsync_end) * 24 bpp / (2 * 8 bits per lane * 2 lanes)*/
17767 +       HFP_count = (HFP_count * dev_priv->bpp)/(2 * 8 * 2);
17768 +       if (HFP_count < 8) /* minimum value of 8 */
17769 +               HFP_count = 8;
17770 +
17771 +       return HFP_count;
17772 +}
17773 +
17774 +/* ************************************************************************* *\
17775 +FUNCTION: GetHAdr_Count
17776 +
17777 +DESCRIPTION: Shows the horizontal active area value in terms of txbyteclkhs.
17778 +       In Non Burst Mode, Count equal to RGB word count value
17779 +
17780 +In Burst Mode, RGB pixel packets are time-compressed, leaving more time
17781 +       during a scan line for LP mode (saving power) or for multiplexing
17782 +       other transmissions onto the DSI link. Hence, the count equals the
17783 +       time in txbyteclkhs for sending  time compressed RGB pixels plus
17784 +       the time needed for moving to power save mode or the time needed
17785 +       for secondary channel to use the DSI link.
17786 +
17787 +But if the left out time for moving to low power mode is less than
17788 +       8 txbyteclkhs [2txbyteclkhs for RGB data packet footer and
17789 +       6txbyteclkhs for a blanking packet with zero payload],  then
17790 +       this count will be added to the HFP's count for one lane.
17791 +
17792 +Min value ï¿½ 8 in decimal  for non-burst mode [accounted with zero payload
17793 +       for blanking packet] for one lane.
17794 +Min value ï¿½ 6 in decimal for burst mode for one lane.
17795 +
17796 +Max value ï¿½ any value greater than the minimum vaue based on DPI resolution
17797 +\* ************************************************************************* */
17798 +static u32 GetHAdr_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17799 +{
17800 +       u32 HAdr_count;
17801 +       u32 Hactive;
17802 +
17803 +       /* byte clock count = (pixel clock count *  bits per pixel) /8 */
17804 +       /*HAdr_countX8 = dev_priv->HactiveArea * dev_priv->bpp;
17805 +
17806 +       if (dev_priv->videoModeFormat == BURST_MODE) {
17807 +               HAdr_countX8 *= dev_priv->DDR_Clock /
17808 +                               dev_priv->DDR_Clock_Calculated;
17809 +       }
17810 +
17811 +       HAdr_count = HAdr_countX8 / 8;*/
17812 +
17813 +       /* use HactiveArea instead of H_TOTAL register or else panel 
17814 +          centering won't work.*/
17815 +       Hactive = dev_priv->HactiveArea;
17816 +
17817 +       /* compute HAdr according to equation:
17818 +        * (hactive * 24 bpp/8) / 2 lanes)*/
17819 +
17820 +       HAdr_count = (Hactive * dev_priv->bpp/8) / 2;
17821 +
17822 +       return HAdr_count;
17823 +}
17824 +
17825 +/* ************************************************************************* *\
17826 +FUNCTION: GetVSA_Count
17827 +
17828 +DESCRIPTION: Shows the vertical sync value in terms of lines
17829 +
17830 +\* ************************************************************************* */
17831 +static u32 GetVSA_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17832 +{
17833 +       u32 VSA_count;
17834 +       u32 VSA_countX8;
17835 +
17836 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17837 +                                       OSPM_UHB_ONLY_IF_ON)) {
17838 +               VSA_countX8 = REG_READ(VSYNC_A);
17839 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17840 +       } else
17841 +               VSA_countX8 = dev_priv->saveVSYNC_A;
17842 +
17843 +       /* Get the vsync pulse width */
17844 +       VSA_count = ((VSA_countX8 & 0xffff0000)>>16) - (VSA_countX8 & 0xffff);
17845 +
17846 +       if (VSA_count < 2) /* minimum value of 2 */
17847 +               VSA_count = 2;
17848 +
17849 +       return VSA_count;
17850 +}
17851 +
17852 +/* ************************************************************************* *\
17853 + * FUNCTION: GetVBP_Count
17854 + *
17855 + * DESCRIPTION: Shows the vertical back porch value in lines.
17856 + *
17857 +\* ************************************************************************* */
17858 +static u32 GetVBP_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17859 +{
17860 +       u32 VBP_count;
17861 +       u32 VBE, VSE;
17862 +
17863 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17864 +                                       OSPM_UHB_ONLY_IF_ON)) {
17865 +               VBE = (REG_READ(VBLANK_A) & 0xffff0000) >> 16;
17866 +               VSE = (REG_READ(VSYNC_A) & 0xffff0000) >> 16;
17867 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17868 +       } else {
17869 +               VBE = (dev_priv->saveVBLANK_A & 0xffff0000) >> 16;
17870 +               VSE = (dev_priv->saveVSYNC_A & 0xffff0000) >> 16;
17871 +       }
17872 +
17873 +       /* Get the hsync pulse width */
17874 +       VBP_count = VBE - VSE;
17875 +
17876 +       if (VBP_count < 2) /* minimum value of 2 */
17877 +               VBP_count = 2;
17878 +
17879 +       return VBP_count;
17880 +}
17881 +/* ************************************************************************* *\
17882 + * FUNCTION: GetVFP_Count
17883 + *
17884 + * DESCRIPTION: Shows the vertical front porch value in terms of lines.
17885 + *
17886 +\* ************************************************************************* */
17887 +static u32 GetVFP_Count(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv)
17888 +{
17889 +       u32 VFP_count;
17890 +       u32 VBS, VSS;
17891 +
17892 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
17893 +                                       OSPM_UHB_ONLY_IF_ON)) {
17894 +               VBS = REG_READ(VBLANK_A) & 0xffff;
17895 +               VSS = REG_READ(VSYNC_A) & 0xffff;
17896 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
17897 +       } else {
17898 +               VBS = dev_priv->saveVBLANK_A & 0xffff;
17899 +               VSS = dev_priv->saveVSYNC_A & 0xffff;
17900 +       }
17901 +
17902 +       /* Get the hsync pulse width */
17903 +       VFP_count = VSS - VBS;
17904 +
17905 +       if (VFP_count < 2) /* minimum value of 2 */
17906 +               VFP_count = 2;
17907 +
17908 +       return VFP_count;
17909 +}
17910 +
17911 +#if 0
17912 +/* ************************************************************************* *\
17913 +FUNCTION: GetHighLowSwitchCount
17914 +
17915 +DESCRIPTION: High speed to low power or Low power to high speed switching time
17916 +       in terms byte clock (txbyteclkhs). This value is based on the
17917 +       byte clock (txbyteclkhs) and low power clock frequency (txclkesc)
17918 +
17919 +Typical value - Number of byte clocks required to switch from low power mode
17920 +       to high speed mode after "txrequesths" is asserted.
17921 +
17922 +The worst count value among the low to high or high to low switching time
17923 +       in terms of txbyteclkhs  has to be programmed in this register.
17924 +
17925 +Usefull Formulae:
17926 +       DDR clock period = 2 times UI
17927 +       txbyteclkhs clock = 8 times UI
17928 +       Tlpx = 1 / txclkesc
17929 +       CALCULATION OF LOW POWER TO HIGH SPEED SWITCH COUNT VALUE
17930 +       (from Standard D-PHY spec)
17931 +
17932 +       LP01 + LP00 + HS0 = 1Tlpx + 1Tlpx + 3Tlpx [Approx] +
17933 +       1DDR clock [2UI] + 1txbyteclkhs clock [8UI]
17934 +
17935 +       CALCULATION OF  HIGH SPEED TO LOW POWER SWITCH COUNT VALUE
17936 +       (from Standard D-PHY spec)
17937 +
17938 +       Ths-trail = 1txbyteclkhs clock [8UI] +
17939 +                   5DDR clock [10UI] + 4 Tlpx [Approx]
17940 +\* ************************************************************************* */
17941 +static u32 GetHighLowSwitchCount(DRM_DRIVER_PRIVATE_T *dev_priv)
17942 +{
17943 +       u32 HighLowSwitchCount, HighToLowSwitchCount, LowToHighSwitchCount;
17944 +
17945 +/* ************************************************************************* *\
17946 +CALCULATION OF HIGH SPEED  TO LOW POWER SWITCH COUNT VALUE
17947 +(from Standard D-PHY spec)
17948 +
17949 +Ths-trail = 1txbyteclkhs clock [8UI] + 5DDR clock [10UI] + 4 Tlpx [Approx]
17950 +
17951 +Tlpx = 50 ns, Using max txclkesc (20MHz)
17952 +
17953 +txbyteclkhs_period = 4000 / dev_priv->DDR_Clock; in ns
17954 +UI_period = 500 / dev_priv->DDR_Clock; in ns
17955 +
17956 +HS_to_LP = Ths-trail = 18 * UI_period  + 4 * Tlpx
17957 +               = 9000 / dev_priv->DDR_Clock + 200;
17958 +
17959 +HighToLowSwitchCount = HS_to_LP / txbyteclkhs_period
17960 +       = (9000 / dev_priv->DDR_Clock + 200) / (4000 / dev_priv->DDR_Clock)
17961 +               = (9000 + (200 *  dev_priv->DDR_Clock)) / 4000
17962 +
17963 +\* ************************************************************************* */
17964 +       HighToLowSwitchCount = (9000 + (200 * dev_priv->DDR_Clock)) / 4000 + 1;
17965 +
17966 +/* ************************************************************************* *\
17967 +CALCULATION OF LOW POWER TO HIGH SPEED SWITCH COUNT VALUE
17968 +(from Standard D-PHY spec)
17969 +
17970 +LP01 + LP00 + HS0 = 1Tlpx + 1Tlpx + 3Tlpx [Approx] +
17971 +1DDR clock [2UI] + 1txbyteclkhs clock [8UI]
17972 +
17973 +       LP_to_HS = 10 * UI_period + 5 * Tlpx =
17974 +                       = 5000 / dev_priv->DDR_Clock + 250;
17975 +
17976 +       LowToHighSwitchCount = LP_to_HS / txbyteclkhs_period
17977 +                       = (5000 / dev_priv->DDR_Clock + 250) /
17978 +                         (4000 / dev_priv->DDR_Clock)
17979 +
17980 +                       = (5000 + (250 *  dev_priv->DDR_Clock)) / 4000
17981 +
17982 +\* ************************************************************************* */
17983 +       LowToHighSwitchCount = (5000 + (250 * dev_priv->DDR_Clock)) / 4000 + 1;
17984 +
17985 +       if (HighToLowSwitchCount > LowToHighSwitchCount)
17986 +               HighLowSwitchCount = HighToLowSwitchCount;
17987 +       else
17988 +               HighLowSwitchCount = LowToHighSwitchCount;
17989 +
17990 +       /* FIXME jliu need to fine tune the above formulae and remove the
17991 +        * following after power on */
17992 +       if (HighLowSwitchCount < 0x1f)
17993 +               HighLowSwitchCount = 0x1f;
17994 +
17995 +       return HighLowSwitchCount;
17996 +}
17997 +
17998 +/* ************************************************************************* *\
17999 +FUNCTION: mrst_gen_long_write
18000 +DESCRIPTION:
18001 +\* ************************************************************************* */
18002 +static void mrst_gen_long_write(struct drm_device *dev,
18003 +                               u32 *data,
18004 +                               u16 wc,
18005 +                               u8 vc)
18006 +{
18007 +       u32 gen_data_reg = HS_GEN_DATA_REG;
18008 +       u32 gen_ctrl_reg = HS_GEN_CTRL_REG;
18009 +       u32 date_full_bit = HS_DATA_FIFO_FULL;
18010 +       u32 control_full_bit = HS_CTRL_FIFO_FULL;
18011 +       u16 wc_saved = wc;
18012 +
18013 +#if PRINT_JLIU7
18014 +     DRM_INFO("JLIU7 enter mrst_gen_long_write \n");
18015 +#endif /* PRINT_JLIU7 */
18016 +
18017 +       /* sanity check */
18018 +       if (vc > 4) {
18019 +               DRM_ERROR
18020 +               (KERN_ERR "MIPI Virtual channel Can't greater than 4.\n");
18021 +               return;
18022 +       }
18023 +
18024 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
18025 +                                       OSPM_UHB_FORCE_POWER_ON))
18026 +               return;
18027 +
18028 +       if (0) { /* FIXME JLIU7 check if it is in LP*/
18029 +               gen_data_reg = LP_GEN_DATA_REG;
18030 +               gen_ctrl_reg = LP_GEN_CTRL_REG;
18031 +               date_full_bit = LP_DATA_FIFO_FULL;
18032 +               control_full_bit = LP_CTRL_FIFO_FULL;
18033 +       }
18034 +
18035 +       while (wc >= 4) {
18036 +               /* Check if MIPI IP generic data fifo is not full */
18037 +               while ((REG_READ(GEN_FIFO_STAT_REG) & date_full_bit)
18038 +                                               == date_full_bit) {
18039 +                       /* Do Nothing Here */
18040 +                       /* This will make checkpatch work */
18041 +               }
18042 +
18043 +               /* write to data buffer */
18044 +               REG_WRITE(gen_data_reg, *data);
18045 +
18046 +               wc -= 4;
18047 +               data++;
18048 +       }
18049 +
18050 +       switch (wc) {
18051 +       case 1:
18052 +               REG_WRITE8(gen_data_reg, *((u8 *)data));
18053 +               break;
18054 +       case 2:
18055 +               REG_WRITE16(gen_data_reg, *((u16 *)data));
18056 +               break;
18057 +       case 3:
18058 +               REG_WRITE16(gen_data_reg, *((u16 *)data));
18059 +               data = (u32 *)((u8 *) data + 2);
18060 +               REG_WRITE8(gen_data_reg, *((u8 *)data));
18061 +               break;
18062 +       }
18063 +
18064 +       /* Check if MIPI IP generic control fifo is not full */
18065 +       while ((REG_READ(GEN_FIFO_STAT_REG) & control_full_bit)
18066 +                                               == control_full_bit) {
18067 +               /* Do Nothing Here */
18068 +               /* This will make Checkpatch work */
18069 +       }
18070 +       /* write to control buffer */
18071 +       REG_WRITE(gen_ctrl_reg, 0x29 | (wc_saved << 8) | (vc << 6));
18072 +
18073 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
18074 +}
18075 +
18076 +/* ************************************************************************* *\
18077 +FUNCTION: mrst_init_HIMAX_MIPI_bridge
18078 +DESCRIPTION:
18079 +\* ************************************************************************* */
18080 +static void    mrst_init_HIMAX_MIPI_bridge(struct drm_device *dev)
18081 +{
18082 +       u32 gen_data[2];
18083 +       u16 wc = 0;
18084 +       u8 vc = 0;
18085 +       u32 gen_data_intel = 0x200105;
18086 +
18087 +#if PRINT_JLIU7
18088 +     DRM_INFO("JLIU7 enter mrst_init_HIMAX_MIPI_bridge \n");
18089 +#endif /* PRINT_JLIU7 */
18090 +
18091 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
18092 +                                       OSPM_UHB_FORCE_POWER_ON))
18093 +               return;
18094 +
18095 +       /* exit sleep mode */
18096 +       wc = 0x5;
18097 +       gen_data[0] = gen_data_intel | (0x11 << 24);
18098 +       gen_data[1] = 0;
18099 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18100 +
18101 +       /* set_pixel_format */
18102 +       gen_data[0] = gen_data_intel | (0x3A << 24);
18103 +       gen_data[1] = 0x77;
18104 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18105 +
18106 +       /* Set resolution for (800X480) */
18107 +       wc = 0x8;
18108 +       gen_data[0] = gen_data_intel | (0x2A << 24);
18109 +       gen_data[1] = 0x1F030000;
18110 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18111 +       gen_data[0] = gen_data_intel | (0x2B << 24);
18112 +       gen_data[1] = 0xDF010000;
18113 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18114 +
18115 +       /* System control */
18116 +       wc = 0x6;
18117 +       gen_data[0] = gen_data_intel | (0xEE << 24);
18118 +       gen_data[1] = 0x10FA;
18119 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18120 +
18121 +       /* INPUT TIMING FOR TEST PATTERN(800X480) */
18122 +       /* H-size */
18123 +       gen_data[1] = 0x2000;
18124 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18125 +       gen_data[1] = 0x0301;
18126 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18127 +
18128 +       /* V-size */
18129 +       gen_data[1] = 0xE002;
18130 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18131 +       gen_data[1] = 0x0103;
18132 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18133 +
18134 +       /* H-total */
18135 +       gen_data[1] = 0x2004;
18136 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18137 +       gen_data[1] = 0x0405;
18138 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18139 +
18140 +       /* V-total */
18141 +       gen_data[1] = 0x0d06;
18142 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18143 +       gen_data[1] = 0x0207;
18144 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18145 +
18146 +       /* H-blank */
18147 +       gen_data[1] = 0x0308;
18148 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18149 +       gen_data[1] = 0x0009;
18150 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18151 +
18152 +       /* H-blank */
18153 +       gen_data[1] = 0x030A;
18154 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18155 +       gen_data[1] = 0x000B;
18156 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18157 +
18158 +       /* H-start */
18159 +       gen_data[1] = 0xD80C;
18160 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18161 +       gen_data[1] = 0x000D;
18162 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18163 +
18164 +       /* V-start */
18165 +       gen_data[1] = 0x230E;
18166 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18167 +       gen_data[1] = 0x000F;
18168 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18169 +
18170 +       /* RGB domain */
18171 +       gen_data[1] = 0x0027;
18172 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18173 +
18174 +       /* INP_FORM Setting */
18175 +       /* set_1 */
18176 +       gen_data[1] = 0x1C10;
18177 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18178 +
18179 +       /* set_2 */
18180 +       gen_data[1] = 0x0711;
18181 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18182 +
18183 +       /* set_3 */
18184 +       gen_data[1] = 0x0012;
18185 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18186 +
18187 +       /* set_4 */
18188 +       gen_data[1] = 0x0013;
18189 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18190 +
18191 +       /* set_5 */
18192 +       gen_data[1] = 0x2314;
18193 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18194 +
18195 +       /* set_6 */
18196 +       gen_data[1] = 0x0015;
18197 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18198 +
18199 +       /* set_7 */
18200 +       gen_data[1] = 0x2316;
18201 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18202 +
18203 +       /* set_8 */
18204 +       gen_data[1] = 0x0017;
18205 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18206 +
18207 +       /* set_1 */
18208 +       gen_data[1] = 0x0330;
18209 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18210 +
18211 +       /* FRC Setting */
18212 +       /* FRC_set_2 */
18213 +       gen_data[1] = 0x237A;
18214 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18215 +
18216 +       /* FRC_set_3 */
18217 +       gen_data[1] = 0x4C7B;
18218 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18219 +
18220 +       /* FRC_set_4 */
18221 +       gen_data[1] = 0x037C;
18222 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18223 +
18224 +       /* FRC_set_5 */
18225 +       gen_data[1] = 0x3482;
18226 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18227 +
18228 +       /* FRC_set_7 */
18229 +       gen_data[1] = 0x1785;
18230 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18231 +
18232 +#if 0
18233 +       /* FRC_set_8 */
18234 +       gen_data[1] = 0xD08F;
18235 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18236 +#endif
18237 +
18238 +       /* OUTPUT TIMING FOR TEST PATTERN (800X480) */
18239 +       /* out_htotal */
18240 +       gen_data[1] = 0x2090;
18241 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18242 +       gen_data[1] = 0x0491;
18243 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18244 +
18245 +       /* out_hsync */
18246 +       gen_data[1] = 0x0392;
18247 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18248 +       gen_data[1] = 0x0093;
18249 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18250 +
18251 +       /* out_hstart */
18252 +       gen_data[1] = 0xD894;
18253 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18254 +       gen_data[1] = 0x0095;
18255 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18256 +
18257 +       /* out_hsize */
18258 +       gen_data[1] = 0x2096;
18259 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18260 +       gen_data[1] = 0x0397;
18261 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18262 +
18263 +       /* out_vtotal */
18264 +       gen_data[1] = 0x0D98;
18265 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18266 +       gen_data[1] = 0x0299;
18267 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18268 +
18269 +       /* out_vsync */
18270 +       gen_data[1] = 0x039A;
18271 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18272 +       gen_data[1] = 0x009B;
18273 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18274 +
18275 +       /* out_vstart */
18276 +       gen_data[1] = 0x239C;
18277 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18278 +       gen_data[1] = 0x009D;
18279 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18280 +
18281 +       /* out_vsize */
18282 +       gen_data[1] = 0xE09E;
18283 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18284 +       gen_data[1] = 0x019F;
18285 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18286 +
18287 +       /* FRC_set_6 */
18288 +       gen_data[1] = 0x9084;
18289 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18290 +
18291 +       /* Other setting */
18292 +       gen_data[1] = 0x0526;
18293 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18294 +
18295 +       /* RBG domain */
18296 +       gen_data[1] = 0x1177;
18297 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18298 +
18299 +       /* rgbw */
18300 +       /* set_1 */
18301 +       gen_data[1] = 0xD28F;
18302 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18303 +
18304 +       /* set_2 */
18305 +       gen_data[1] = 0x02D0;
18306 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18307 +
18308 +       /* set_3 */
18309 +       gen_data[1] = 0x08D1;
18310 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18311 +
18312 +       /* set_4 */
18313 +       gen_data[1] = 0x05D2;
18314 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18315 +
18316 +       /* set_5 */
18317 +       gen_data[1] = 0x24D4;
18318 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18319 +
18320 +       /* set_6 */
18321 +       gen_data[1] = 0x00D5;
18322 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18323 +       gen_data[1] = 0x02D7;
18324 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18325 +       gen_data[1] = 0x00D8;
18326 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18327 +
18328 +       gen_data[1] = 0x48F3;
18329 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18330 +       gen_data[1] = 0xD4F2;
18331 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18332 +       gen_data[1] = 0x3D8E;
18333 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18334 +       gen_data[1] = 0x60FD;
18335 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18336 +       gen_data[1] = 0x00B5;
18337 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18338 +       gen_data[1] = 0x48F4;
18339 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18340 +
18341 +       /* inside patten */
18342 +       gen_data[1] = 0x0060;
18343 +       mrst_gen_long_write(dev, gen_data, wc, vc);
18344 +
18345 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
18346 +}
18347 +#endif
18348 +
18349 +static void mrst_wait_for_LP_CTRL_FIFO(struct drm_device *dev)
18350 +{
18351 +       int timeout = 0;
18352 +       udelay(500);
18353 +
18354 +       /* This will time out after approximately 2+ seconds */
18355 +       while ((timeout < 20000) && (REG_READ(GEN_FIFO_STAT_REG) &
18356 +                                                       LP_CTRL_FIFO_FULL)) {
18357 +               udelay(100);
18358 +               timeout++;
18359 +       }
18360 +
18361 +       if (timeout == 20000)
18362 +               DRM_INFO("MIPI: LP CMD FIFO was never cleared!\n");
18363 +}
18364 +
18365 +static void mrst_wait_for_HS_DATA_FIFO(struct drm_device *dev)
18366 +{
18367 +       int timeout = 0;
18368 +       udelay(500);
18369 +
18370 +       /* This will time out after approximately 2+ seconds */
18371 +       while ((timeout < 20000) && (REG_READ(GEN_FIFO_STAT_REG) &
18372 +                                                       HS_DATA_FIFO_FULL)) {
18373 +               udelay(100);
18374 +               timeout++;
18375 +       }
18376 +
18377 +       if (timeout == 20000)
18378 +               DRM_INFO("MIPI: HS Data FIFO was never cleared!\n");
18379 +}
18380 +
18381 +static void mrst_wait_for_HS_CTRL_FIFO(struct drm_device *dev)
18382 +{
18383 +       int timeout = 0;
18384 +       udelay(500);
18385 +
18386 +       /* This will time out after approximately 2+ seconds */
18387 +       while ((timeout < 20000) && (REG_READ(GEN_FIFO_STAT_REG) &
18388 +                                                       HS_CTRL_FIFO_FULL)) {
18389 +               udelay(100);
18390 +               timeout++;
18391 +       }
18392 +       if (timeout == 20000)
18393 +               DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n");
18394 +}
18395 +
18396 +/* ************************************************************************* *\
18397 +FUNCTION: mrst_init_NSC_MIPI_bridge
18398 +DESCRIPTION:   This function is called only by mrst_dsi_mode_set and
18399 +               restore_display_registers.  since this function does not
18400 +               acquire the mutex, it is important that the calling function
18401 +               does!
18402 +\* ************************************************************************* */
18403 +void mrst_init_NSC_MIPI_bridge(struct drm_device *dev)
18404 +{
18405 +
18406 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
18407 +
18408 +       DRM_INFO("Enter mrst_init_NSC_MIPI_bridge.\n");
18409 +
18410 +       /* Program MIPI IP to 100MHz DSI, Non-Burst mode with sync event,
18411 +               2 Data Lanes */
18412 +
18413 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18414 +       /* enable RGB24*/
18415 +       REG_WRITE(LP_GEN_CTRL_REG, 0x003205e3);
18416 +
18417 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18418 +       /* enable all error reporting*/
18419 +       REG_WRITE(LP_GEN_CTRL_REG, 0x000040e3);
18420 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18421 +       REG_WRITE(LP_GEN_CTRL_REG, 0x000041e3);
18422 +
18423 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18424 +       /* enable 2 data lane; video shaping & error reporting */
18425 +       REG_WRITE(LP_GEN_CTRL_REG, 0x00a842e3); /* 0x006842e3 for 1 data lane */
18426 +
18427 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18428 +       /* HS timeout */
18429 +       REG_WRITE(LP_GEN_CTRL_REG, 0x009243e3);
18430 +
18431 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18432 +       /* setle = 6h; low power timeout = ((2^21)-1)*4TX_esc_clks. */
18433 +       REG_WRITE(LP_GEN_CTRL_REG, 0x00e645e3);
18434 +
18435 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18436 +       /* enable all virtual channels */
18437 +       REG_WRITE(LP_GEN_CTRL_REG, 0x000f46e3);
18438 +
18439 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18440 +       /* set output strength to low-drive */
18441 +       REG_WRITE(LP_GEN_CTRL_REG, 0x00007de3);
18442 +
18443 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18444 +       if (dev_priv->sku_83) {
18445 +               /* set escape clock to divede by 8 */
18446 +               REG_WRITE(LP_GEN_CTRL_REG, 0x000044e3);
18447 +       } else  if (dev_priv->sku_100L) {
18448 +               /* set escape clock to divede by 16 */
18449 +               REG_WRITE(LP_GEN_CTRL_REG, 0x001044e3);
18450 +       } else if (dev_priv->sku_100) {
18451 +               /* set escape clock to divede by 32*/
18452 +               /*REG_WRITE(LP_GEN_CTRL_REG, 0x003044e3);*/
18453 +               REG_WRITE(LP_GEN_CTRL_REG, 0x001044e3);
18454 +
18455 +               /*mrst_wait_for_LP_CTRL_FIFO(dev);*/
18456 +               /* setle = 6h; low power timeout = ((2^21)-1)*4TX_esc_clks. */
18457 +               /*REG_WRITE(LP_GEN_CTRL_REG, 0x00ec45e3);*/
18458 +       }
18459 +
18460 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18461 +       /* CFG_VALID=1; RGB_CLK_EN=1. */
18462 +       REG_WRITE(LP_GEN_CTRL_REG, 0x00057fe3);
18463 +
18464 +       /*ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);*/
18465 +}
18466 +
18467 +static int mrst_check_mipi_error(struct drm_device *dev)
18468 +{
18469 +       u32 int_status_reg = 0;
18470 +       u32 relevant_error_bits = 0x0fff; /* only care about error bits 0-11 */
18471 +       u32 reported_errors = 0;
18472 +
18473 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18474 +       REG_WRITE(LP_GEN_CTRL_REG, 0x010524); /* 2-parameter gen short read */
18475 +
18476 +       /* sleep 100 microseconds */
18477 +       udelay(100);
18478 +
18479 +       int_status_reg = REG_READ(INTR_STAT_REG);
18480 +       printk(KERN_ALERT "MIPI Intr Status Reg: 0x%X\n", int_status_reg);
18481 +
18482 +       reported_errors = int_status_reg & relevant_error_bits;
18483 +       if (reported_errors) {
18484 +               printk(KERN_ALERT "MIPI Init sequence reported errs: 0x%X\n",
18485 +                       reported_errors);
18486 +               /* Clear the error bits */
18487 +               REG_WRITE(INTR_STAT_REG, reported_errors);
18488 +               return reported_errors;
18489 +       }
18490 +
18491 +       return 0;
18492 +}
18493 +
18494 +/* ************************************************************************* *\
18495 + * FUNCTION: mrst_init_TPO_MIPI
18496 + *
18497 + * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
18498 + *               restore_display_registers.  since this function does not
18499 + *               acquire the mutex, it is important that the calling function
18500 + *               does!
18501 +\* ************************************************************************* */
18502 +void mrst_init_TPO_MIPI(struct drm_device *dev)
18503 +{
18504 +       /*DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;*/
18505 +
18506 +       DRM_INFO("Enter mrst init TPO MIPI display.\n");
18507 +
18508 +       /* Flip page order */
18509 +       mrst_wait_for_HS_DATA_FIFO(dev);
18510 +       REG_WRITE(0xb068, 0x00008036);
18511 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18512 +       REG_WRITE(0xb070, 0x00000229);
18513 +
18514 +       /* 0xF0 */
18515 +       mrst_wait_for_HS_DATA_FIFO(dev);
18516 +       REG_WRITE(0xb068, 0x005a5af0);
18517 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18518 +       REG_WRITE(0xb070, 0x00000329);
18519 +
18520 +       /* Write protection key */
18521 +       mrst_wait_for_HS_DATA_FIFO(dev);
18522 +       REG_WRITE(0xb068, 0x005a5af1);
18523 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18524 +       REG_WRITE(0xb070, 0x00000329);
18525 +
18526 +       /* 0xFC */
18527 +       mrst_wait_for_HS_DATA_FIFO(dev);
18528 +       REG_WRITE(0xb068, 0x005a5afc);
18529 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18530 +       REG_WRITE(0xb070, 0x00000329);
18531 +
18532 +       /* 0xB7 */
18533 +       mrst_wait_for_HS_DATA_FIFO(dev);
18534 +       REG_WRITE(0xb068, 0x770000b7);
18535 +       mrst_wait_for_HS_DATA_FIFO(dev);
18536 +       REG_WRITE(0xb068, 0x00000044);
18537 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18538 +       REG_WRITE(0xb070, 0x00000529);
18539 +
18540 +       /* 0xB6 */
18541 +       mrst_wait_for_HS_DATA_FIFO(dev);
18542 +       REG_WRITE(0xb068, 0x000a0ab6);
18543 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18544 +       REG_WRITE(0xb070, 0x00000329);
18545 +
18546 +       /* 0xF2 */
18547 +       mrst_wait_for_HS_DATA_FIFO(dev);
18548 +       REG_WRITE(0xb068, 0x081010f2);
18549 +       mrst_wait_for_HS_DATA_FIFO(dev);
18550 +       REG_WRITE(0xb068, 0x4a070708);
18551 +       mrst_wait_for_HS_DATA_FIFO(dev);
18552 +       REG_WRITE(0xb068, 0x000000c5);
18553 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18554 +       REG_WRITE(0xb070, 0x00000929);
18555 +
18556 +       /* 0xF8 */
18557 +       mrst_wait_for_HS_DATA_FIFO(dev);
18558 +       REG_WRITE(0xb068, 0x024003f8);
18559 +       mrst_wait_for_HS_DATA_FIFO(dev);
18560 +       REG_WRITE(0xb068, 0x01030a04);
18561 +       mrst_wait_for_HS_DATA_FIFO(dev);
18562 +       REG_WRITE(0xb068, 0x0e020220);
18563 +       mrst_wait_for_HS_DATA_FIFO(dev);
18564 +       REG_WRITE(0xb068, 0x00000004);
18565 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18566 +       REG_WRITE(0xb070, 0x00000d29);
18567 +
18568 +       /* 0xE2 */
18569 +       mrst_wait_for_HS_DATA_FIFO(dev);
18570 +       REG_WRITE(0xb068, 0x398fc3e2);
18571 +       mrst_wait_for_HS_DATA_FIFO(dev);
18572 +       REG_WRITE(0xb068, 0x0000916f);
18573 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18574 +       REG_WRITE(0xb070, 0x00000629);
18575 +
18576 +       /* 0xB0 */
18577 +       mrst_wait_for_HS_DATA_FIFO(dev);
18578 +       REG_WRITE(0xb068, 0x000000b0);
18579 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18580 +       REG_WRITE(0xb070, 0x00000229);
18581 +
18582 +       /* 0xF4 */
18583 +       mrst_wait_for_HS_DATA_FIFO(dev);
18584 +       REG_WRITE(0xb068, 0x240242f4);
18585 +       mrst_wait_for_HS_DATA_FIFO(dev);
18586 +       REG_WRITE(0xb068, 0x78ee2002);
18587 +       mrst_wait_for_HS_DATA_FIFO(dev);
18588 +       REG_WRITE(0xb068, 0x2a071050);
18589 +       mrst_wait_for_HS_DATA_FIFO(dev);
18590 +       REG_WRITE(0xb068, 0x507fee10);
18591 +       mrst_wait_for_HS_DATA_FIFO(dev);
18592 +       REG_WRITE(0xb068, 0x10300710);
18593 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18594 +       REG_WRITE(0xb070, 0x00001429);
18595 +
18596 +       /* 0xBA */
18597 +       mrst_wait_for_HS_DATA_FIFO(dev);
18598 +       REG_WRITE(0xb068, 0x19fe07ba);
18599 +       mrst_wait_for_HS_DATA_FIFO(dev);
18600 +       REG_WRITE(0xb068, 0x101c0a31);
18601 +       mrst_wait_for_HS_DATA_FIFO(dev);
18602 +       REG_WRITE(0xb068, 0x00000010);
18603 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18604 +       REG_WRITE(0xb070, 0x00000929);
18605 +
18606 +       /* 0xBB */
18607 +       mrst_wait_for_HS_DATA_FIFO(dev);
18608 +       REG_WRITE(0xb068, 0x28ff07bb);
18609 +       mrst_wait_for_HS_DATA_FIFO(dev);
18610 +       REG_WRITE(0xb068, 0x24280a31);
18611 +       mrst_wait_for_HS_DATA_FIFO(dev);
18612 +       REG_WRITE(0xb068, 0x00000034);
18613 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18614 +       REG_WRITE(0xb070, 0x00000929);
18615 +
18616 +       /* 0xFB */
18617 +       mrst_wait_for_HS_DATA_FIFO(dev);
18618 +       REG_WRITE(0xb068, 0x535d05fb);
18619 +       mrst_wait_for_HS_DATA_FIFO(dev);
18620 +       REG_WRITE(0xb068, 0x1b1a2130);
18621 +       mrst_wait_for_HS_DATA_FIFO(dev);
18622 +       REG_WRITE(0xb068, 0x221e180e);
18623 +       mrst_wait_for_HS_DATA_FIFO(dev);
18624 +       REG_WRITE(0xb068, 0x131d2120);
18625 +       mrst_wait_for_HS_DATA_FIFO(dev);
18626 +       REG_WRITE(0xb068, 0x535d0508);
18627 +       mrst_wait_for_HS_DATA_FIFO(dev);
18628 +       REG_WRITE(0xb068, 0x1c1a2131);
18629 +       mrst_wait_for_HS_DATA_FIFO(dev);
18630 +       REG_WRITE(0xb068, 0x231f160d);
18631 +       mrst_wait_for_HS_DATA_FIFO(dev);
18632 +       REG_WRITE(0xb068, 0x111b2220);
18633 +       mrst_wait_for_HS_DATA_FIFO(dev);
18634 +       REG_WRITE(0xb068, 0x535c2008);
18635 +       mrst_wait_for_HS_DATA_FIFO(dev);
18636 +       REG_WRITE(0xb068, 0x1f1d2433);
18637 +       mrst_wait_for_HS_DATA_FIFO(dev);
18638 +       REG_WRITE(0xb068, 0x2c251a10);
18639 +       mrst_wait_for_HS_DATA_FIFO(dev);
18640 +       REG_WRITE(0xb068, 0x2c34372d);
18641 +       mrst_wait_for_HS_DATA_FIFO(dev);
18642 +       REG_WRITE(0xb068, 0x00000023);
18643 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18644 +       REG_WRITE(0xb070, 0x00003129);
18645 +
18646 +       /* 0xFA */
18647 +       mrst_wait_for_HS_DATA_FIFO(dev);
18648 +       REG_WRITE(0xb068, 0x525c0bfa);
18649 +       mrst_wait_for_HS_DATA_FIFO(dev);
18650 +       REG_WRITE(0xb068, 0x1c1c232f);
18651 +       mrst_wait_for_HS_DATA_FIFO(dev);
18652 +       REG_WRITE(0xb068, 0x2623190e);
18653 +       mrst_wait_for_HS_DATA_FIFO(dev);
18654 +       REG_WRITE(0xb068, 0x18212625);
18655 +       mrst_wait_for_HS_DATA_FIFO(dev);
18656 +       REG_WRITE(0xb068, 0x545d0d0e);
18657 +       mrst_wait_for_HS_DATA_FIFO(dev);
18658 +       REG_WRITE(0xb068, 0x1e1d2333);
18659 +       mrst_wait_for_HS_DATA_FIFO(dev);
18660 +       REG_WRITE(0xb068, 0x26231a10);
18661 +       mrst_wait_for_HS_DATA_FIFO(dev);
18662 +       REG_WRITE(0xb068, 0x1a222725);
18663 +       mrst_wait_for_HS_DATA_FIFO(dev);
18664 +       REG_WRITE(0xb068, 0x545d280f);
18665 +       mrst_wait_for_HS_DATA_FIFO(dev);
18666 +       REG_WRITE(0xb068, 0x21202635);
18667 +       mrst_wait_for_HS_DATA_FIFO(dev);
18668 +       REG_WRITE(0xb068, 0x31292013);
18669 +       mrst_wait_for_HS_DATA_FIFO(dev);
18670 +       REG_WRITE(0xb068, 0x31393d33);
18671 +       mrst_wait_for_HS_DATA_FIFO(dev);
18672 +       REG_WRITE(0xb068, 0x00000029);
18673 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18674 +       REG_WRITE(0xb070, 0x00003129);
18675 +
18676 +       /* Set DM */
18677 +       mrst_wait_for_HS_DATA_FIFO(dev);
18678 +       REG_WRITE(0xb068, 0x000100f7);
18679 +       mrst_wait_for_HS_CTRL_FIFO(dev);
18680 +       REG_WRITE(0xb070, 0x00000329);
18681 +}
18682 +
18683 +static void panel_reset_on(void)
18684 +{
18685 +       struct ipc_pmic_reg_data tmp_reg = {0};
18686 +
18687 +       tmp_reg.ioc = 1;
18688 +       tmp_reg.num_entries = 1;
18689 +
18690 +       tmp_reg.pmic_reg_data[0].register_address = 0xf4;
18691 +       if (ipc_pmic_register_read(&tmp_reg)) {
18692 +               printk(KERN_WARNING "pnl_rst_on: fail to read pmic 0xf4!\n");
18693 +               return;
18694 +       }
18695 +       tmp_reg.pmic_reg_data[0].value &= 0xbf;
18696 +
18697 +       if (ipc_pmic_register_write(&tmp_reg, TRUE))
18698 +               printk(KERN_WARNING "pnl_rst_on: fail to write pmic 0xe6!\n");
18699 +}
18700 +
18701 +static void panel_reset_off(void)
18702 +{
18703 +       struct ipc_pmic_reg_data tmp_reg = {0};
18704 +
18705 +       printk(KERN_INFO "panel_reset_off\n");
18706 +
18707 +       tmp_reg.ioc = 1;
18708 +       tmp_reg.num_entries = 1;
18709 +
18710 +       tmp_reg.pmic_reg_data[0].register_address = 0xf4;
18711 +       if (ipc_pmic_register_read(&tmp_reg)) {
18712 +               printk(KERN_WARNING "pnl_rst_off: fail to read pmic 0xf4!\n");
18713 +               return;
18714 +       }
18715 +       tmp_reg.pmic_reg_data[0].value |= 0x40;
18716 +
18717 +       if (ipc_pmic_register_write(&tmp_reg, TRUE))
18718 +               printk(KERN_WARNING "pnl_rst_off: fail to write pmic 0xe6!\n");
18719 +}
18720 +
18721 +static void panel_reset(void)
18722 +{
18723 +       printk(KERN_INFO "panel_reset\n");
18724 +
18725 +       panel_reset_on();
18726 +       msleep(20);
18727 +       panel_reset_off();
18728 +       msleep(20);
18729 +}
18730 +
18731 +/* ************************************************************************* *\
18732 + * FUNCTION: mrst_init_LGE_MIPI
18733 + *
18734 + * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
18735 + *              restore_display_registers.  since this function does not
18736 + *              acquire the mutex, it is important that the calling function
18737 + *              does!
18738 +\* ************************************************************************* */
18739 +void mrst_init_LGE_MIPI(struct drm_device *dev)
18740 +{
18741 +       /*DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;*/
18742 +       int i = 0;
18743 +
18744 +       DRM_INFO("Enter mrst init LGE MIPI display.\n");
18745 +
18746 +       mrst_wait_for_LP_CTRL_FIFO(dev);
18747 +       REG_WRITE(0xb06c, 0x00870123);
18748 +
18749 +       /* LGE 480x1024 Panel Initialization sequence */
18750 +       for (i = 0; i < 10; i++) {
18751 +               /* Panel Characteristics Settings */
18752 +               mrst_wait_for_HS_DATA_FIFO(dev);
18753 +               REG_WRITE(HS_GEN_DATA_REG, 0xb2200105);
18754 +               mrst_wait_for_HS_DATA_FIFO(dev);
18755 +               REG_WRITE(HS_GEN_DATA_REG, 0x0ec820);
18756 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18757 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x7 << 8 | 0x0 << 6);
18758 +
18759 +               /* Panel Driver Setting */
18760 +               mrst_wait_for_HS_DATA_FIFO(dev);
18761 +               REG_WRITE(HS_GEN_DATA_REG, 0xb3200105);
18762 +               mrst_wait_for_HS_DATA_FIFO(dev);
18763 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18764 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18765 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x5 << 8 | 0x0 << 6);
18766 +
18767 +               /* Display Mode Control */
18768 +               mrst_wait_for_HS_DATA_FIFO(dev);
18769 +               REG_WRITE(HS_GEN_DATA_REG, 0xb4200105);
18770 +               mrst_wait_for_HS_DATA_FIFO(dev);
18771 +               REG_WRITE(HS_GEN_DATA_REG, 0x00);
18772 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18773 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x5 << 8 | 0x0 << 6);
18774 +
18775 +               /* Display Mode and Frame Memory write Mode Setting */
18776 +               mrst_wait_for_HS_DATA_FIFO(dev);
18777 +               REG_WRITE(HS_GEN_DATA_REG, 0xb5200105);
18778 +               mrst_wait_for_HS_DATA_FIFO(dev);
18779 +               REG_WRITE(HS_GEN_DATA_REG, 0x000f0f12);
18780 +               mrst_wait_for_HS_DATA_FIFO(dev);
18781 +               REG_WRITE(HS_GEN_DATA_REG, 0x00);
18782 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18783 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x9 << 8 | 0x0 << 6);
18784 +
18785 +               /* Display Control (GIP Specific) */
18786 +               mrst_wait_for_HS_DATA_FIFO(dev);
18787 +               REG_WRITE(HS_GEN_DATA_REG, 0xb6200105);
18788 +               mrst_wait_for_HS_DATA_FIFO(dev);
18789 +               REG_WRITE(HS_GEN_DATA_REG, 0x40021803);
18790 +               mrst_wait_for_HS_DATA_FIFO(dev);
18791 +               REG_WRITE(HS_GEN_DATA_REG, 0x3010);
18792 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18793 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xa << 8 | 0x0 << 6);
18794 +
18795 +               /* Power Setting */
18796 +               mrst_wait_for_HS_DATA_FIFO(dev);
18797 +               REG_WRITE(HS_GEN_DATA_REG, 0xc0200105);
18798 +               mrst_wait_for_HS_DATA_FIFO(dev);
18799 +               REG_WRITE(HS_GEN_DATA_REG, 0x1f01);
18800 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18801 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x6 << 8 | 0x0 << 6);
18802 +
18803 +               /* Power Setting */
18804 +               mrst_wait_for_HS_DATA_FIFO(dev);
18805 +               REG_WRITE(HS_GEN_DATA_REG, 0xc3200105);
18806 +               mrst_wait_for_HS_DATA_FIFO(dev);
18807 +               REG_WRITE(HS_GEN_DATA_REG, 0x03040407);
18808 +               mrst_wait_for_HS_DATA_FIFO(dev);
18809 +               REG_WRITE(HS_GEN_DATA_REG, 0x07);
18810 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18811 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x9 << 8 | 0x0 << 6);
18812 +
18813 +               /*   */
18814 +               mrst_wait_for_HS_DATA_FIFO(dev);
18815 +               REG_WRITE(HS_GEN_DATA_REG, 0xc4200105);
18816 +               mrst_wait_for_HS_DATA_FIFO(dev);
18817 +               REG_WRITE(HS_GEN_DATA_REG, 0x15154412);
18818 +               mrst_wait_for_HS_DATA_FIFO(dev);
18819 +               REG_WRITE(HS_GEN_DATA_REG, 0x6d04);
18820 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18821 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xa << 8 | 0x0 << 6);
18822 +
18823 +               /*   */
18824 +               mrst_wait_for_HS_DATA_FIFO(dev);
18825 +               REG_WRITE(HS_GEN_DATA_REG, 0xc5200105);
18826 +               mrst_wait_for_HS_DATA_FIFO(dev);
18827 +               REG_WRITE(HS_GEN_DATA_REG, 0x64);
18828 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18829 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x5 << 8 | 0x0 << 6);
18830 +
18831 +               /*   */
18832 +               mrst_wait_for_HS_DATA_FIFO(dev);
18833 +               REG_WRITE(HS_GEN_DATA_REG, 0xc6200105);
18834 +               mrst_wait_for_HS_DATA_FIFO(dev);
18835 +               REG_WRITE(HS_GEN_DATA_REG, 0x004024);
18836 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18837 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x7 << 8 | 0x0 << 6);
18838 +
18839 +               /* red */
18840 +               mrst_wait_for_HS_DATA_FIFO(dev);
18841 +               REG_WRITE(HS_GEN_DATA_REG, 0xd0200105);
18842 +               mrst_wait_for_HS_DATA_FIFO(dev);
18843 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18844 +               mrst_wait_for_HS_DATA_FIFO(dev);
18845 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18846 +               mrst_wait_for_HS_DATA_FIFO(dev);
18847 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18848 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18849 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18850 +
18851 +               mrst_wait_for_HS_DATA_FIFO(dev);
18852 +               REG_WRITE(HS_GEN_DATA_REG, 0xd1200105);
18853 +               mrst_wait_for_HS_DATA_FIFO(dev);
18854 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18855 +               mrst_wait_for_HS_DATA_FIFO(dev);
18856 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18857 +               mrst_wait_for_HS_DATA_FIFO(dev);
18858 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18859 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18860 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18861 +
18862 +               /* green */
18863 +               mrst_wait_for_HS_DATA_FIFO(dev);
18864 +               REG_WRITE(HS_GEN_DATA_REG, 0xd2200105);
18865 +               mrst_wait_for_HS_DATA_FIFO(dev);
18866 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18867 +               mrst_wait_for_HS_DATA_FIFO(dev);
18868 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18869 +               mrst_wait_for_HS_DATA_FIFO(dev);
18870 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18871 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18872 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18873 +
18874 +               mrst_wait_for_HS_DATA_FIFO(dev);
18875 +               REG_WRITE(HS_GEN_DATA_REG, 0xd3200105);
18876 +               mrst_wait_for_HS_DATA_FIFO(dev);
18877 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18878 +               mrst_wait_for_HS_DATA_FIFO(dev);
18879 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18880 +               mrst_wait_for_HS_DATA_FIFO(dev);
18881 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18882 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18883 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18884 +
18885 +               /* blue */
18886 +               mrst_wait_for_HS_DATA_FIFO(dev);
18887 +               REG_WRITE(HS_GEN_DATA_REG, 0xd4200105);
18888 +               mrst_wait_for_HS_DATA_FIFO(dev);
18889 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18890 +               mrst_wait_for_HS_DATA_FIFO(dev);
18891 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18892 +               mrst_wait_for_HS_DATA_FIFO(dev);
18893 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18894 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18895 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18896 +
18897 +               mrst_wait_for_HS_DATA_FIFO(dev);
18898 +               REG_WRITE(HS_GEN_DATA_REG, 0xd5200105);
18899 +               mrst_wait_for_HS_DATA_FIFO(dev);
18900 +               REG_WRITE(HS_GEN_DATA_REG, 0x06774701);
18901 +               mrst_wait_for_HS_DATA_FIFO(dev);
18902 +               REG_WRITE(HS_GEN_DATA_REG, 0x00200000);
18903 +               mrst_wait_for_HS_DATA_FIFO(dev);
18904 +               REG_WRITE(HS_GEN_DATA_REG, 0x02);
18905 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18906 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0xd << 8 | 0x0 << 6);
18907 +
18908 +               if (!mrst_check_mipi_error(dev)) {
18909 +                       i = 0;
18910 +                       break;
18911 +               }
18912 +       }
18913 +
18914 +       for (i = 0; i < 10; i++) {
18915 +               /* Sleep Out  */
18916 +               mrst_wait_for_HS_DATA_FIFO(dev);
18917 +               REG_WRITE(HS_GEN_DATA_REG, 0x11200105);
18918 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18919 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x4 << 8 | 0x0 << 6);
18920 +
18921 +               if (!mrst_check_mipi_error(dev)) {
18922 +                       i = 0;
18923 +                       break;
18924 +               }
18925 +       }
18926 +
18927 +       udelay(10000);
18928 +
18929 +       for (i = 0; i < 10; i++) {
18930 +               /* Display On */
18931 +               mrst_wait_for_HS_DATA_FIFO(dev);
18932 +               REG_WRITE(HS_GEN_DATA_REG, 0x29200105);
18933 +               mrst_wait_for_HS_CTRL_FIFO(dev);
18934 +               REG_WRITE(HS_GEN_CTRL_REG, 0x29 | 0x4 << 8 | 0x0 << 6);
18935 +
18936 +               if (!mrst_check_mipi_error(dev)) {
18937 +                       i = 0;
18938 +                       break;
18939 +               }
18940 +       }
18941 +
18942 +       /*ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);*/
18943 +}
18944 +
18945 +/*enum mipi_panel_type {
18946 +       NSC_800X480 = 0,
18947 +       LGE_480X1024 = 1,
18948 +       TPO_864X480 = 2
18949 +};*/
18950 +
18951 +static void mrst_dsi_mode_set(struct drm_encoder *encoder,
18952 +                               struct drm_display_mode *mode,
18953 +                               struct drm_display_mode *adjusted_mode)
18954 +{
18955 +       struct psb_intel_mode_device *mode_dev =
18956 +                               enc_to_psb_intel_output(encoder)->mode_dev;
18957 +       struct drm_device *dev = encoder->dev;
18958 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
18959 +       u32 dsiFuncPrgValue = 0;
18960 +       u32 SupportedFormat = 0;
18961 +       u32 channelNumber = 0;
18962 +       u32 DBI_dataWidth = 0;
18963 +       u32 resolution = 0;
18964 +       u32 mipi_control_val = 0;
18965 +       u32 intr_en_val = 0;
18966 +       u32 turnaround_timeout_val = 0;
18967 +       u32 device_reset_val = 0;
18968 +       u32 init_count_val = 0;
18969 +       u32 hs_tx_timeout_val = 0;
18970 +       u32 lp_rx_timeout_val = 0;
18971 +       u32 high_low_switch_count_val = 0;
18972 +       u32 eot_disable_val = 0;
18973 +       u32 lp_byteclk_val = 0;
18974 +       u32 device_ready_val = 0;
18975 +       /*u32 dpi_control_val = 0;*/
18976 +       u32 vsa_count = 0;
18977 +       u32 vbp_count = 0;
18978 +       u32 vfp_count = 0;
18979 +       u32 hsa_count = 0;
18980 +       u32 hbp_count = 0;
18981 +       u32 hfp_count = 0;
18982 +       u32 haa_count = 0;
18983 +       u32 video_mode_format = 0;
18984 +       u32 max_ret_packet_size = 0;
18985 +       uint64_t curValue = DRM_MODE_SCALE_FULLSCREEN;
18986 +       /*enum mipi_panel_type panel_make;*/
18987 +       u32 mipi_port, tmp_VAL;
18988 +
18989 +       DRM_INFO("enter mrst_dsi_mode_set \n");
18990 +#if 0
18991 +       switch (dev_priv->gct_data.bpi) {
18992 +       case 1:
18993 +               panel_make = NSC_800X480;
18994 +               break;
18995 +       case 2:
18996 +               panel_make = TPO_864X480;
18997 +               break;
18998 +       case 3:
18999 +               panel_make = LGE_480X1024;
19000 +               break;
19001 +       default:
19002 +               DRM_INFO("MIPI: unknown panel type!  Setting NSC.\n");
19003 +               panel_make = NSC_800X480; /* assume NSC */
19004 +       }
19005 +
19006 +       /* Force TPO for Aava testing */
19007 +       panel_make = TPO_864X480;
19008 +#endif
19009 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
19010 +                                       OSPM_UHB_FORCE_POWER_ON))
19011 +               return;
19012 +
19013 +       switch (dev_priv->bpp) {
19014 +       case 16:
19015 +               SupportedFormat = RGB_565_FMT;
19016 +               break;
19017 +       case 18:
19018 +               SupportedFormat = RGB_666_FMT;
19019 +               break;
19020 +       case 24:
19021 +               SupportedFormat = RGB_888_FMT;
19022 +               break;
19023 +       default:
19024 +               DRM_INFO("mrst_dsi_mode_set,  invalid bpp \n");
19025 +               break;
19026 +       }
19027 +
19028 +
19029 +       if (dev_priv->dpi) {
19030 +               drm_connector_property_get_value(
19031 +                       &enc_to_psb_intel_output(encoder)->base,
19032 +                       dev->mode_config.scaling_mode_property,
19033 +                       &curValue);
19034 +
19035 +               if (curValue == DRM_MODE_SCALE_CENTER)
19036 +                       REG_WRITE(PFIT_CONTROL, 0);
19037 +               else if (curValue == DRM_MODE_SCALE_ASPECT) {
19038 +                       if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
19039 +                           (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
19040 +                               if ((adjusted_mode->crtc_hdisplay *
19041 +                                    mode->vdisplay) == (mode->hdisplay *
19042 +                                    adjusted_mode->crtc_vdisplay))
19043 +                                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
19044 +                               else if ((adjusted_mode->crtc_hdisplay *
19045 +                                         mode->vdisplay) > (mode->hdisplay *
19046 +                                         adjusted_mode->crtc_vdisplay))
19047 +                                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
19048 +                                                 PFIT_SCALING_MODE_PILLARBOX);
19049 +                               else
19050 +                                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
19051 +                                                 PFIT_SCALING_MODE_LETTERBOX);
19052 +                       } else
19053 +                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
19054 +               } else /*(curValue == DRM_MODE_SCALE_FULLSCREEN)*/
19055 +                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
19056 +
19057 +               switch (dev_priv->panel_make) {
19058 +               case NSC_800X480:
19059 +                       intr_en_val             = 0xffffffff;
19060 +                       turnaround_timeout_val  = 0x00000001;
19061 +                       device_reset_val        = 0x000000ff;
19062 +                       init_count_val          = 0x00000fff;
19063 +                       resolution = dev_priv->HactiveArea |
19064 +                                    (dev_priv->VactiveArea << RES_V_POS);
19065 +                       SupportedFormat <<= FMT_DPI_POS;
19066 +                       dsiFuncPrgValue = dev_priv->laneCount | SupportedFormat;
19067 +                       vsa_count = GetVSA_Count(dev, dev_priv);
19068 +                       vbp_count = GetVBP_Count(dev, dev_priv);
19069 +                       vfp_count = GetVFP_Count(dev, dev_priv);
19070 +                       hsa_count = GetHSA_Count(dev, dev_priv);
19071 +                       hbp_count = GetHBP_Count(dev, dev_priv);
19072 +                       hfp_count = GetHFP_Count(dev, dev_priv);
19073 +                       haa_count = GetHAdr_Count(dev, dev_priv);
19074 +                       video_mode_format = dev_priv->videoModeFormat;
19075 +                       hs_tx_timeout_val               = 0x00001000;
19076 +                       lp_rx_timeout_val               = 0x0000ffff;
19077 +                       high_low_switch_count_val       = 0x46;
19078 +                       eot_disable_val                 = 0x00000000;
19079 +                       lp_byteclk_val                  = 0x00000004;
19080 +                       device_ready_val                = 0x00000001;
19081 +                       max_ret_packet_size             = 0x40;
19082 +                       break;
19083 +               case TPO_864X480:
19084 +                       intr_en_val             = 0xffffffff;
19085 +                       turnaround_timeout_val  = 0x0000000a;
19086 +                       device_reset_val        = 0x000000ff;
19087 +                       init_count_val          = 0x00000fff;
19088 +                       resolution              = 0x01e00360;
19089 +                       dsiFuncPrgValue         = 0x00000202;
19090 +                       vsa_count               = 0x00000004;
19091 +                       vbp_count               = 0x00000008;
19092 +                       vfp_count               = 0x00000008;
19093 +                       hsa_count               = 0x00000006;
19094 +                       hbp_count               = 0x0000000f;
19095 +                       hfp_count               = 0x0000000f;
19096 +                       haa_count               = 0x00000510;
19097 +                       video_mode_format       = 0x00000003;
19098 +                       hs_tx_timeout_val       = 0x00090000;
19099 +                       lp_rx_timeout_val               = 0x0000ffff;
19100 +                       high_low_switch_count_val       = 0x00000046;
19101 +                       eot_disable_val                 = 0x00000000;
19102 +                       lp_byteclk_val                  = 0x00000004;
19103 +                       device_ready_val                = 0x00000001;
19104 +                       max_ret_packet_size             = 0x40;
19105 +                       break;
19106 +               case LGE_480X1024:
19107 +                       intr_en_val             = 0xffffffff;
19108 +                       turnaround_timeout_val  = 0x00000012;
19109 +                       device_reset_val        = 0x000000ff;
19110 +                       init_count_val          = 0x00000fff;
19111 +                       resolution              = 0x040001e0;
19112 +                       dsiFuncPrgValue         = 0x00000202;
19113 +                       vsa_count               = 0x00000005;
19114 +                       vbp_count               = 0x0000000f;
19115 +                       vfp_count               = 0x0000000f;
19116 +                       hsa_count               = 0x00000008;
19117 +                       hbp_count               = 0x00000018;
19118 +                       hfp_count               = 0x0000000f;
19119 +                       haa_count               = 0x00000320;
19120 +                       video_mode_format       = 0x00000003;
19121 +                       hs_tx_timeout_val       = 0x00ffffff;
19122 +                       lp_rx_timeout_val               = 0x0000ffff;
19123 +                       high_low_switch_count_val       = 0x00000016;
19124 +                       eot_disable_val                 = 0x00000000;
19125 +                       lp_byteclk_val                  = 0x00000004;
19126 +                       device_ready_val                = 0x00000001;
19127 +                       max_ret_packet_size             = 0x40;
19128 +                       break;
19129 +               }
19130 +
19131 +               /* set 100 mhz dsi clk based on sku */
19132 +               if (dev_priv->sku_83)
19133 +                       mipi_control_val = 0x0018; /* 100 mhz * 1 = 100 mhz */
19134 +               else if (dev_priv->sku_100L)
19135 +                       mipi_control_val = 0x0019; /* 50 mhz * 2 = 100 mhz */
19136 +               else if (dev_priv->sku_100)
19137 +                       mipi_control_val = 0x0018; /* 100 mhz * 1 = 100 mhz */
19138 +
19139 +               /* wait for PIPE A to disable */
19140 +               while (REG_READ(0x70008) & 0x40000000) {
19141 +                       /* Do Nothing Here */
19142 +                       /* This should make checkpatch work */
19143 +               }
19144 +
19145 +               /* wait for DPI FIFO to clear */
19146 +               while ((REG_READ(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
19147 +                                                       != DPI_FIFO_EMPTY) {
19148 +                       /* Do Nothing Here */
19149 +                       /* This should make checkpatch work */
19150 +               }
19151 +
19152 +               /* Clear Device Ready Bit */
19153 +               REG_WRITE(DEVICE_READY_REG, 0x00000000);
19154 +
19155 +               /* clear intr status register */
19156 +               tmp_VAL = REG_READ(INTR_STAT_REG);
19157 +               REG_WRITE(INTR_STAT_REG, tmp_VAL);
19158 +
19159 +               /* Reset Aava panel */
19160 +               if (dev_priv->panel_make == TPO_864X480) {
19161 +                       panel_reset();
19162 +                       msleep(1000);
19163 +               }
19164 +
19165 +               /* Enable MIPI Port */
19166 +               mipi_port = MIPI_PORT_EN | MIPI_BORDER_EN;
19167 +
19168 +               /* Enable dithering if required */
19169 +               if (mode_dev->panel_wants_dither)
19170 +                       mipi_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
19171 +
19172 +               REG_WRITE(MIPI, mipi_port);
19173 +
19174 +               /* set the lane speed */
19175 +               REG_WRITE(MIPI_CONTROL_REG, mipi_control_val);
19176 +
19177 +               /* Enable all the error interrupt */
19178 +               REG_WRITE(INTR_EN_REG, intr_en_val);
19179 +               REG_WRITE(TURN_AROUND_TIMEOUT_REG, turnaround_timeout_val);
19180 +               REG_WRITE(DEVICE_RESET_REG, device_reset_val);
19181 +               REG_WRITE(INIT_COUNT_REG, init_count_val);
19182 +
19183 +               REG_WRITE(DSI_FUNC_PRG_REG, dsiFuncPrgValue);
19184 +
19185 +               REG_WRITE(DPI_RESOLUTION_REG, resolution);
19186 +               /*REG_WRITE(DBI_RESOLUTION_REG, 0x00000000);*/
19187 +
19188 +               REG_WRITE(VERT_SYNC_PAD_COUNT_REG, vsa_count);
19189 +               REG_WRITE(VERT_BACK_PORCH_COUNT_REG, vbp_count);
19190 +               REG_WRITE(VERT_FRONT_PORCH_COUNT_REG, vfp_count);
19191 +
19192 +               REG_WRITE(HORIZ_SYNC_PAD_COUNT_REG, hsa_count);
19193 +               REG_WRITE(HORIZ_BACK_PORCH_COUNT_REG, hbp_count);
19194 +               REG_WRITE(HORIZ_FRONT_PORCH_COUNT_REG, hfp_count);
19195 +               REG_WRITE(HORIZ_ACTIVE_AREA_COUNT_REG, haa_count);
19196 +
19197 +               REG_WRITE(VIDEO_FMT_REG, video_mode_format);
19198 +
19199 +               REG_WRITE(HS_TX_TIMEOUT_REG, hs_tx_timeout_val);
19200 +               REG_WRITE(LP_RX_TIMEOUT_REG, lp_rx_timeout_val);
19201 +
19202 +               REG_WRITE(HIGH_LOW_SWITCH_COUNT_REG,
19203 +                         high_low_switch_count_val);
19204 +
19205 +               REG_WRITE(EOT_DISABLE_REG, eot_disable_val);
19206 +
19207 +               REG_WRITE(LP_BYTECLK_REG, lp_byteclk_val);
19208 +               REG_WRITE(MAX_RET_PAK_REG, max_ret_packet_size);
19209 +
19210 +               REG_WRITE(DEVICE_READY_REG, device_ready_val);
19211 +               REG_WRITE(DPI_CONTROL_REG, DPI_TURN_ON);
19212 +       } else {
19213 +               /* JLIU7 FIXME VIRTUAL_CHANNEL_NUMBER_1 or
19214 +                * VIRTUAL_CHANNEL_NUMBER_0*/
19215 +               channelNumber =
19216 +                       VIRTUAL_CHANNEL_NUMBER_1 << DBI_CHANNEL_NUMBER_POS;
19217 +               DBI_dataWidth = DBI_DATA_WIDTH_16BIT << DBI_DATA_WIDTH_POS;
19218 +               dsiFuncPrgValue =
19219 +                       dev_priv->laneCount | channelNumber | DBI_dataWidth;
19220 +               /* JLIU7 FIXME */
19221 +               SupportedFormat <<= FMT_DBI_POS;
19222 +               dsiFuncPrgValue |= SupportedFormat;
19223 +               REG_WRITE(DSI_FUNC_PRG_REG, dsiFuncPrgValue);
19224 +
19225 +               REG_WRITE(DPI_RESOLUTION_REG, 0x00000000);
19226 +               REG_WRITE(DBI_RESOLUTION_REG, resolution);
19227 +       }
19228 +
19229 +       dev_priv->dsi_device_ready = true;
19230 +
19231 +       if ((dev_priv->panel_make == NSC_800X480) || (dev_priv->panel_make == LGE_480X1024))
19232 +               dev_priv->init_drvIC(dev); /* initialize the mipi panel */
19233 +
19234 +       /* set the dphy settings for 100 mhz */
19235 +       REG_WRITE(0xb080, 0x0b061c04);
19236 +
19237 +       REG_WRITE(PIPEACONF, dev_priv->pipeconf);
19238 +       /* REG_READ(PIPEACONF); */
19239 +
19240 +       /* Wait for 20ms for the pipe enable to take effect. */
19241 +       /*udelay(20000);*/
19242 +
19243 +       REG_WRITE(DSPACNTR, dev_priv->dspcntr);
19244 +
19245 +       /* Wait for 20ms for the plane enable to take effect. */
19246 +       /*udelay(20000);*/
19247 +
19248 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
19249 +}
19250 +
19251 +/**
19252 + * Detect the MIPI connection.
19253 + *
19254 + * This always returns CONNECTOR_STATUS_CONNECTED.
19255 + * This connector should only have
19256 + * been set up if the MIPI was actually connected anyway.
19257 + */
19258 +static enum drm_connector_status mrst_dsi_detect(struct drm_connector
19259 +                                                  *connector)
19260 +{
19261 +#if PRINT_JLIU7
19262 +     DRM_INFO("JLIU7 enter  mrst_dsi_detect \n");
19263 +#endif /* PRINT_JLIU7 */
19264 +
19265 +       return connector_status_connected;
19266 +}
19267 +
19268 +/**
19269 + * Return the list of MIPI DDB modes if available.
19270 + */
19271 +static int mrst_dsi_get_modes(struct drm_connector *connector)
19272 +{
19273 +       struct drm_device *dev = connector->dev;
19274 +       struct psb_intel_output *psb_intel_output =
19275 +                                       to_psb_intel_output(connector);
19276 +       struct psb_intel_mode_device *mode_dev = psb_intel_output->mode_dev;
19277 +
19278 +/* FIXME get the MIPI DDB modes */
19279 +
19280 +       /* Didn't get an DDB, so
19281 +        * Set wide sync ranges so we get all modes
19282 +        * handed to valid_mode for checking
19283 +        */
19284 +       connector->display_info.min_vfreq = 0;
19285 +       connector->display_info.max_vfreq = 200;
19286 +       connector->display_info.min_hfreq = 0;
19287 +       connector->display_info.max_hfreq = 200;
19288 +
19289 +       if (mode_dev->panel_fixed_mode != NULL) {
19290 +               struct drm_display_mode *mode =
19291 +                   drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
19292 +               drm_mode_probed_add(connector, mode);
19293 +               return 1;
19294 +       }
19295 +
19296 +       return 0;
19297 +}
19298 +
19299 +static const struct drm_encoder_helper_funcs mrst_dsi_helper_funcs = {
19300 +       .dpms = mrst_dsi_dpms,
19301 +       .mode_fixup = psb_intel_lvds_mode_fixup,
19302 +       .prepare = mrst_dsi_prepare,
19303 +       .mode_set = mrst_dsi_mode_set,
19304 +       .commit = mrst_dsi_commit,
19305 +};
19306 +
19307 +static const struct drm_connector_helper_funcs
19308 +    mrst_dsi_connector_helper_funcs = {
19309 +       .get_modes = mrst_dsi_get_modes,
19310 +       .mode_valid = psb_intel_lvds_mode_valid,
19311 +       .best_encoder = psb_intel_best_encoder,
19312 +};
19313 +
19314 +static const struct drm_connector_funcs mrst_dsi_connector_funcs = {
19315 +       .dpms = drm_helper_connector_dpms,
19316 +       .save = mrst_dsi_save,
19317 +       .restore = mrst_dsi_restore,
19318 +       .detect = mrst_dsi_detect,
19319 +       .fill_modes = drm_helper_probe_single_connector_modes,
19320 +       .set_property = psb_intel_lvds_set_property,
19321 +       .destroy = psb_intel_lvds_destroy,
19322 +};
19323 +
19324 +/** Returns the panel fixed mode from configuration. */
19325 +/** FIXME JLIU7 need to revist it. */
19326 +struct drm_display_mode *mrst_dsi_get_configuration_mode(struct drm_device *dev)
19327 +{
19328 +       struct drm_display_mode *mode;
19329 +       struct drm_psb_private *dev_priv =
19330 +               (struct drm_psb_private *) dev->dev_private;
19331 +       u8 panel_index = dev_priv->gct_data.bpi;
19332 +       u8 panel_type = dev_priv->gct_data.pt;
19333 +       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
19334 +       bool use_gct = false;
19335 +
19336 +       DRM_INFO("Enter mrst_dsi_get_configuration_mode\n");
19337 +
19338 +       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
19339 +       if (!mode)
19340 +               return NULL;
19341 +
19342 +       if (dev_priv->vbt_data.Size != 0x00) /*if non-zero, vbt is present*/
19343 +               if ((1<<panel_index) & panel_type) /* if non-zero,*/
19344 +                       use_gct = true;                 /*then mipi panel.*/
19345 +
19346 +       if (use_gct) {
19347 +               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
19348 +               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
19349 +               mode->hsync_start = mode->hdisplay + \
19350 +                               ((ti->hsync_offset_hi << 8) | \
19351 +                               ti->hsync_offset_lo);
19352 +               mode->hsync_end = mode->hsync_start + \
19353 +                               ((ti->hsync_pulse_width_hi << 8) | \
19354 +                               ti->hsync_pulse_width_lo);
19355 +               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
19356 +                                                               ti->hblank_lo);
19357 +               mode->vsync_start = \
19358 +                       mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
19359 +                                               ti->vsync_offset_lo);
19360 +               mode->vsync_end = \
19361 +                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
19362 +                                               ti->vsync_pulse_width_lo);
19363 +               mode->vtotal = mode->vdisplay + \
19364 +                               ((ti->vblank_hi << 8) | ti->vblank_lo);
19365 +               mode->clock = ti->pixel_clock * 10;
19366 +#if 1
19367 +               printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
19368 +               printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
19369 +               printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
19370 +               printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
19371 +               printk(KERN_INFO "htotal is %d\n", mode->htotal);
19372 +               printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
19373 +               printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
19374 +               printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
19375 +               printk(KERN_INFO "clock is %d\n", mode->clock);
19376 +#endif
19377 +
19378 +       } else {
19379 +
19380 +#if 0 /* LGE 480x1024 tentative timings */
19381 +       mode->hdisplay = 480;
19382 +       mode->vdisplay = 1024;
19383 +       mode->hsync_start = 499;
19384 +       mode->hsync_end = 506;
19385 +       mode->htotal = 517;
19386 +       mode->vsync_start = 1039;
19387 +       mode->vsync_end = 1041;
19388 +       mode->vtotal = 1047;
19389 +       mode->clock = 33264;
19390 +#endif
19391 +#if 1 /*FIXME jliu7 remove it later */
19392 +       /* copy from SV - hard coded fixed mode for
19393 +        * DSI TPO TD043MTEA2 LCD panel */
19394 +       mode->hdisplay = 864;
19395 +       mode->vdisplay = 480;
19396 +       mode->hsync_start = 873;
19397 +       mode->hsync_end = 876;
19398 +       mode->htotal = 887;
19399 +       mode->vsync_start = 487;
19400 +       mode->vsync_end = 490;
19401 +       mode->vtotal = 499;
19402 +       mode->clock = 33264;
19403 +#endif /*FIXME jliu7 remove it later */
19404 +
19405 +#if 0 /*FIXME jliu7 remove it later */
19406 +           /* hard coded fixed mode for DSI TPO TD043MTEA2 LCD panel */
19407 +       mode->hdisplay = 800;
19408 +       mode->vdisplay = 480;
19409 +       mode->hsync_start = 836;
19410 +       mode->hsync_end = 846;
19411 +       mode->htotal = 1056;
19412 +       mode->vsync_start = 489;
19413 +       mode->vsync_end = 491;
19414 +       mode->vtotal = 525;
19415 +       mode->clock = 33264;
19416 +#endif /*FIXME jliu7 remove it later */
19417 +
19418 +#if 0 /*FIXME jliu7 remove it later */
19419 +           /* hard coded fixed mode for LVDS 800x480 */
19420 +       mode->hdisplay = 800;
19421 +       mode->vdisplay = 480;
19422 +       mode->hsync_start = 801;
19423 +       mode->hsync_end = 802;
19424 +       mode->htotal = 1024;
19425 +       mode->vsync_start = 481;
19426 +       mode->vsync_end = 482;
19427 +       mode->vtotal = 525;
19428 +       mode->clock = 30994;
19429 +#endif /*FIXME jliu7 remove it later */
19430 +
19431 +#if 0  /*FIXME jliu7 remove it later, jliu7 modify it according to the spec*/
19432 +       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
19433 +       mode->hdisplay = 1024;
19434 +       mode->vdisplay = 600;
19435 +       mode->hsync_start = 1072;
19436 +       mode->hsync_end = 1104;
19437 +       mode->htotal = 1184;
19438 +       mode->vsync_start = 603;
19439 +       mode->vsync_end = 604;
19440 +       mode->vtotal = 608;
19441 +       mode->clock = 53990;
19442 +#endif                         /*FIXME jliu7 remove it later */
19443 +
19444 +#if 0          /*FIXME jliu7 remove it, it is copied from SBIOS */
19445 +       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
19446 +       mode->hdisplay = 1024;
19447 +       mode->vdisplay = 600;
19448 +       mode->hsync_start = 1104;
19449 +       mode->hsync_end = 1136;
19450 +       mode->htotal = 1184;
19451 +       mode->vsync_start = 603;
19452 +       mode->vsync_end = 604;
19453 +       mode->vtotal = 608;
19454 +       mode->clock = 53990;
19455 +#endif                         /*FIXME jliu7 remove it later */
19456 +
19457 +#if 0                          /*FIXME jliu7 remove it later */
19458 +       /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
19459 +       mode->hdisplay = 1024;
19460 +       mode->vdisplay = 600;
19461 +       mode->hsync_start = 1124;
19462 +       mode->hsync_end = 1204;
19463 +       mode->htotal = 1312;
19464 +       mode->vsync_start = 607;
19465 +       mode->vsync_end = 610;
19466 +       mode->vtotal = 621;
19467 +       mode->clock = 48885;
19468 +#endif                         /*FIXME jliu7 remove it later */
19469 +
19470 +#if 0                          /*FIXME jliu7 remove it later */
19471 +       /* hard coded fixed mode for LVDS 1024x768 */
19472 +       mode->hdisplay = 1024;
19473 +       mode->vdisplay = 768;
19474 +       mode->hsync_start = 1048;
19475 +       mode->hsync_end = 1184;
19476 +       mode->htotal = 1344;
19477 +       mode->vsync_start = 771;
19478 +       mode->vsync_end = 777;
19479 +       mode->vtotal = 806;
19480 +       mode->clock = 65000;
19481 +#endif                         /*FIXME jliu7 remove it later */
19482 +
19483 +#if 0                          /*FIXME jliu7 remove it later */
19484 +       /* hard coded fixed mode for LVDS 1366x768 */
19485 +       mode->hdisplay = 1366;
19486 +       mode->vdisplay = 768;
19487 +       mode->hsync_start = 1430;
19488 +       mode->hsync_end = 1558;
19489 +       mode->htotal = 1664;
19490 +       mode->vsync_start = 769;
19491 +       mode->vsync_end = 770;
19492 +       mode->vtotal = 776;
19493 +       mode->clock = 77500;
19494 +#endif                         /*FIXME jliu7 remove it later */
19495 +       }
19496 +       drm_mode_set_name(mode);
19497 +       drm_mode_set_crtcinfo(mode, 0);
19498 +
19499 +       return mode;
19500 +}
19501 +
19502 +/* ************************************************************************* *\
19503 +FUNCTION: mrstDSI_clockInit
19504 +DESCRIPTION:
19505 +
19506 +\* ************************************************************************* */
19507 +static u32 sku_83_mipi_2xclk[4] = {166667, 333333, 444444, 666667};
19508 +static u32 sku_100_mipi_2xclk[4] = {200000, 400000, 533333, 800000};
19509 +static u32 sku_100L_mipi_2xclk[4] = {100000, 200000, 266667, 400000};
19510 +#define MIPI_2XCLK_COUNT                       0x04
19511 +
19512 +static bool mrstDSI_clockInit(DRM_DRIVER_PRIVATE_T *dev_priv)
19513 +{
19514 +       u32 Htotal = 0, Vtotal = 0, RRate = 0, mipi_2xclk = 0;
19515 +       u32 i = 0;
19516 +       u32 *p_mipi_2xclk = NULL;
19517 +
19518 +#if 0 /* JLIU7_PO old values */
19519 +       /* FIXME jliu7 DPI hard coded for TPO TD043MTEA2 LCD panel */
19520 +       dev_priv->pixelClock = 33264; /*KHz*/
19521 +       dev_priv->HsyncWidth = 10;
19522 +       dev_priv->HbackPorch = 210;
19523 +       dev_priv->HfrontPorch = 36;
19524 +       dev_priv->HactiveArea = 800;
19525 +       dev_priv->VsyncWidth = 2;
19526 +       dev_priv->VbackPorch = 34;
19527 +       dev_priv->VfrontPorch = 9;
19528 +       dev_priv->VactiveArea = 480;
19529 +       dev_priv->bpp = 24;
19530 +
19531 +       /* FIXME jliu7 DBI hard coded for TPO TD043MTEA2 LCD panel */
19532 +       dev_priv->dbi_pixelClock = 33264; /*KHz*/
19533 +       dev_priv->dbi_HsyncWidth = 10;
19534 +       dev_priv->dbi_HbackPorch = 210;
19535 +       dev_priv->dbi_HfrontPorch = 36;
19536 +       dev_priv->dbi_HactiveArea = 800;
19537 +       dev_priv->dbi_VsyncWidth = 2;
19538 +       dev_priv->dbi_VbackPorch = 34;
19539 +       dev_priv->dbi_VfrontPorch = 9;
19540 +       dev_priv->dbi_VactiveArea = 480;
19541 +       dev_priv->dbi_bpp = 24;
19542 +#else /* JLIU7_PO old values */
19543 +       /* FIXME jliu7 DPI hard coded for TPO TD043MTEA2 LCD panel */
19544 +       /* FIXME Pre-Si value, 1 or 2 lanes; 50MHz; Non-Burst w/ sync event */
19545 +       dev_priv->pixelClock = 33264; /*KHz*/
19546 +       dev_priv->HsyncWidth = 10;
19547 +       dev_priv->HbackPorch = 8;
19548 +       dev_priv->HfrontPorch = 3;
19549 +       dev_priv->HactiveArea = 800;
19550 +       dev_priv->VsyncWidth = 2;
19551 +       dev_priv->VbackPorch = 3;
19552 +       dev_priv->VfrontPorch = 2;
19553 +       dev_priv->VactiveArea = 480;
19554 +       dev_priv->bpp = 24;
19555 +
19556 +       /* FIXME jliu7 DBI hard coded for TPO TD043MTEA2 LCD panel */
19557 +       dev_priv->dbi_pixelClock = 33264; /*KHz*/
19558 +       dev_priv->dbi_HsyncWidth = 10;
19559 +       dev_priv->dbi_HbackPorch = 8;
19560 +       dev_priv->dbi_HfrontPorch = 3;
19561 +       dev_priv->dbi_HactiveArea = 800;
19562 +       dev_priv->dbi_VsyncWidth = 2;
19563 +       dev_priv->dbi_VbackPorch = 3;
19564 +       dev_priv->dbi_VfrontPorch = 2;
19565 +       dev_priv->dbi_VactiveArea = 480;
19566 +       dev_priv->dbi_bpp = 24;
19567 +#endif /* JLIU7_PO old values */
19568 +
19569 +       Htotal = dev_priv->HsyncWidth
19570 +                + dev_priv->HbackPorch
19571 +                + dev_priv->HfrontPorch
19572 +                + dev_priv->HactiveArea;
19573 +       Vtotal = dev_priv->VsyncWidth
19574 +                + dev_priv->VbackPorch
19575 +                + dev_priv->VfrontPorch
19576 +                + dev_priv->VactiveArea;
19577 +
19578 +       RRate = ((dev_priv->pixelClock * 1000) / (Htotal * Vtotal)) + 1;
19579 +
19580 +       dev_priv->RRate = RRate;
19581 +
19582 +       /* ddr clock frequence = (pixel clock frequence *  bits per pixel)/2*/
19583 +       mipi_2xclk = (dev_priv->pixelClock * dev_priv->bpp) /
19584 +                    dev_priv->laneCount; /* KHz */
19585 +       dev_priv->DDR_Clock_Calculated = mipi_2xclk / 2; /* KHz */
19586 +
19587 +       DRM_DEBUG("mrstDSI_clockInit RRate = %d, mipi_2xclk = %d. \n",
19588 +                 RRate, mipi_2xclk);
19589 +
19590 +       if (dev_priv->sku_100)
19591 +               p_mipi_2xclk = sku_100_mipi_2xclk;
19592 +       else if (dev_priv->sku_100L)
19593 +               p_mipi_2xclk = sku_100L_mipi_2xclk;
19594 +       else
19595 +               p_mipi_2xclk = sku_83_mipi_2xclk;
19596 +
19597 +       for (; i < MIPI_2XCLK_COUNT; i++) {
19598 +               if ((dev_priv->DDR_Clock_Calculated * 2) < p_mipi_2xclk[i])
19599 +                       break;
19600 +       }
19601 +
19602 +       if (i == MIPI_2XCLK_COUNT) {
19603 +               DRM_DEBUG("mrstDSI_clkInit DDR clk too big-DDR_Clk_Calcd=%d\n",
19604 +                       dev_priv->DDR_Clock_Calculated);
19605 +               return false;
19606 +       }
19607 +
19608 +       dev_priv->DDR_Clock = p_mipi_2xclk[i] / 2;
19609 +       dev_priv->ClockBits = i;
19610 +
19611 +#if 1 /* FIXME remove it after power on*/
19612 +       DRM_DEBUG("mrstDSI_clkInit mipi_2x_clk_divr=0x%x, DDR_Clk_Calcd=%d\n",
19613 +                 i,
19614 +                 dev_priv->DDR_Clock_Calculated);
19615 +#endif /* FIXME remove it after power on*/
19616 +
19617 +       return true;
19618 +}
19619 +
19620 +/**
19621 + * mrst_dsi_init - setup MIPI connectors on this device
19622 + * @dev: drm device
19623 + *
19624 + * Create the connector, try to figure out what
19625 + * modes we can display on the MIPI panel (if present).
19626 + */
19627 +void mrst_dsi_init(struct drm_device *dev,
19628 +                   struct psb_intel_mode_device *mode_dev)
19629 +{
19630 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
19631 +       struct psb_intel_output *psb_intel_output;
19632 +       struct drm_connector *connector;
19633 +       struct drm_encoder *encoder;
19634 +
19635 +       DRM_INFO("JLIU7 enter mrst_dsi_init \n");
19636 +
19637 +       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
19638 +       if (!psb_intel_output)
19639 +               return;
19640 +
19641 +       psb_intel_output->mode_dev = mode_dev;
19642 +       connector = &psb_intel_output->base;
19643 +       encoder = &psb_intel_output->enc;
19644 +       drm_connector_init(dev, &psb_intel_output->base,
19645 +                          &mrst_dsi_connector_funcs,
19646 +                          DRM_MODE_CONNECTOR_MIPI);
19647 +
19648 +       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
19649 +                        DRM_MODE_ENCODER_MIPI);
19650 +
19651 +       drm_mode_connector_attach_encoder(&psb_intel_output->base,
19652 +                                         &psb_intel_output->enc);
19653 +       psb_intel_output->type = INTEL_OUTPUT_MIPI;
19654 +
19655 +       drm_encoder_helper_add(encoder, &mrst_dsi_helper_funcs);
19656 +       drm_connector_helper_add(connector,
19657 +                                &mrst_dsi_connector_helper_funcs);
19658 +       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
19659 +       connector->interlace_allowed = false;
19660 +       connector->doublescan_allowed = false;
19661 +
19662 +       drm_connector_attach_property(connector,
19663 +                                     dev->mode_config.scaling_mode_property,
19664 +                                     DRM_MODE_SCALE_FULLSCREEN);
19665 +       drm_connector_attach_property(connector,
19666 +                                     dev_priv->backlight_property,
19667 +                                     BRIGHTNESS_MAX_LEVEL);
19668 +
19669 +       dsi_backlight = BRIGHTNESS_MAX_LEVEL;
19670 +       blc_pol = BLC_POLARITY_NORMAL;
19671 +       blc_freq = 0xc8;
19672 +
19673 +       mode_dev->panel_wants_dither = false;
19674 +       if (dev_priv->vbt_data.Size != 0x00) {
19675 +               mode_dev->panel_wants_dither = (dev_priv->gct_data.Panel_MIPI_Display_Descriptor & (BIT3 | BIT4));
19676 +               switch (dev_priv->gct_data.bpi) { /* set panel make */
19677 +               case 1:
19678 +                       dev_priv->panel_make = NSC_800X480;
19679 +                       break;
19680 +               case 2:
19681 +                       dev_priv->panel_make = TPO_864X480;
19682 +                       break;
19683 +               case 3:
19684 +                       dev_priv->panel_make = LGE_480X1024;
19685 +                       break;
19686 +               default:
19687 +                       DRM_INFO("MIPI: unknown panel type!  Setting NSC.\n");
19688 +                       dev_priv->panel_make = NSC_800X480; /* assume NSC */
19689 +               }
19690 +       } else {
19691 +               DRM_INFO("MIPI: No GCT! Setting NSC.\n");
19692 +               dev_priv->panel_make = NSC_800X480;
19693 +       }
19694 +
19695 +       /* set panel initialize function */
19696 +       switch (dev_priv->panel_make) {
19697 +       case NSC_800X480:
19698 +               dev_priv->init_drvIC = mrst_init_NSC_MIPI_bridge;
19699 +               break;
19700 +       case TPO_864X480:
19701 +               dev_priv->init_drvIC = mrst_init_TPO_MIPI;
19702 +               break;
19703 +       case LGE_480X1024:
19704 +               dev_priv->init_drvIC = mrst_init_LGE_MIPI;
19705 +               break;
19706 +       }
19707 +
19708 +       /*
19709 +        * MIPI discovery:
19710 +        * 1) check for DDB data
19711 +        * 2) check for VBT data
19712 +        * 4) make sure lid is open
19713 +        *    if closed, act like it's not there for now
19714 +        */
19715 +
19716 +       /* FIXME jliu7 we only support DPI */
19717 +       dev_priv->dpi = true;
19718 +
19719 +       /* FIXME hard coded 4 lanes for Himax HX8858-A,
19720 +        * 2 lanes for NSC LM2550 */
19721 +       dev_priv->laneCount = 2;
19722 +
19723 +       /* FIXME hard coded for NSC PO. */
19724 +       /* We only support BUST_MODE */
19725 +       dev_priv->videoModeFormat =  NON_BURST_MODE_SYNC_EVENTS;
19726 +       /* FIXME change it to true if GET_DDB works */
19727 +       dev_priv->config_phase = false;
19728 +
19729 +       if (!mrstDSI_clockInit(dev_priv)) {
19730 +               DRM_DEBUG("Can't iniitialize MRST DSI clock.\n");
19731 +#if 0 /* FIXME JLIU7 */
19732 +               goto failed_find;
19733 +#endif /* FIXME JLIU7 */
19734 +       }
19735 +
19736 +       /*
19737 +        * If we didn't get DDB data, try geting panel timing
19738 +        * from configuration data
19739 +        */
19740 +       mode_dev->panel_fixed_mode = mrst_dsi_get_configuration_mode(dev);
19741 +
19742 +       if (mode_dev->panel_fixed_mode) {
19743 +               mode_dev->panel_fixed_mode->type |=
19744 +                   DRM_MODE_TYPE_PREFERRED;
19745 +               goto out;       /* FIXME: check for quirks */
19746 +       }
19747 +
19748 +       /* If we still don't have a mode after all that, give up. */
19749 +       if (!mode_dev->panel_fixed_mode) {
19750 +               DRM_DEBUG
19751 +                   ("Found no modes on the lvds, ignoring the LVDS\n");
19752 +               goto failed_find;
19753 +       }
19754 +
19755 +out:
19756 +       drm_sysfs_connector_add(connector);
19757 +       return;
19758 +
19759 +failed_find:
19760 +       DRM_DEBUG("No MIIP modes found, disabling.\n");
19761 +       drm_encoder_cleanup(encoder);
19762 +       drm_connector_cleanup(connector);
19763 +       kfree(connector);
19764 +}
19765 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_dsi_aava.c b/drivers/gpu/drm/mrst/drv/psb_intel_dsi_aava.c
19766 new file mode 100644
19767 index 0000000..6c21480
19768 --- /dev/null
19769 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_dsi_aava.c
19770 @@ -0,0 +1,996 @@
19771 +/*
19772 + * Copyright Â© 2006-2007 Intel Corporation
19773 + *
19774 + * Permission is hereby granted, free of charge, to any person obtaining a
19775 + * copy of this software and associated documentation files (the "Software"),
19776 + * to deal in the Software without restriction, including without limitation
19777 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19778 + * and/or sell copies of the Software, and to permit persons to whom the
19779 + * Software is furnished to do so, subject to the following conditions:
19780 + *
19781 + * The above copyright notice and this permission notice (including the next
19782 + * paragraph) shall be included in all copies or substantial portions of the
19783 + * Software.
19784 + *
19785 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19786 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19787 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19788 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19789 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19790 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19791 + * DEALINGS IN THE SOFTWARE.
19792 + *
19793 + * Authors:
19794 + *     jim liu <jim.liu@intel.com>
19795 + */
19796 +
19797 +/* This enables setting backlights on with a delay at startup,
19798 +   should be removed after resolving issue with backlights going off
19799 +   after setting them on in initial mrst_dsi_set_power call */
19800 +#define AAVA_BACKLIGHT_HACK
19801 +
19802 +#include <linux/backlight.h>
19803 +#include <drm/drmP.h>
19804 +#include <drm/drm.h>
19805 +#include <drm/drm_crtc.h>
19806 +#include <drm/drm_edid.h>
19807 +
19808 +#include <asm/ipc_defs.h>
19809 +
19810 +#ifdef AAVA_BACKLIGHT_HACK
19811 +#include <linux/workqueue.h>
19812 +#endif /* AAVA_BACKLIGHT_HACK */
19813 +
19814 +#include "psb_drv.h"
19815 +#include "psb_intel_drv.h"
19816 +#include "psb_intel_reg.h"
19817 +#include "ospm_power.h"
19818 +
19819 +#define DRM_MODE_ENCODER_MIPI   5
19820 +
19821 +//#define DBG_PRINTS 1
19822 +#define DBG_PRINTS 0
19823 +
19824 +#define NEW_CRAP_SAMPLE_SETTINGS
19825 +
19826 +#define AAVA_EV_0_5
19827 +
19828 +#define VSIZE          480
19829 +#define HSIZE          864
19830 +#define HFP_DOTS       10
19831 +#define HBP_DOTS       10
19832 +#define HSYNC_DOTS     4
19833 +#define VFP_LINES      8
19834 +#define VBP_LINES      8
19835 +#define VSYNC_LINES    4
19836 +
19837 +#define MIPI_LANES     2
19838 +#define MIPI_HACT      ((HSIZE * 3) / MIPI_LANES)
19839 +#define MIPI_HFP       ((HFP_DOTS * 3) / MIPI_LANES)
19840 +#define MIPI_HBP       ((HBP_DOTS * 3) / MIPI_LANES)
19841 +#define MIPI_HSPAD     ((HSYNC_DOTS * 3) / MIPI_LANES)
19842 +#define MIPI_VFP       VFP_LINES
19843 +#define MIPI_VSPAD     VSYNC_LINES
19844 +#define MIPI_VBP       VBP_LINES
19845 +
19846 +#define DISP_HPIX              (HSIZE - 1)
19847 +#define DISP_VPIX              (VSIZE - 1)
19848 +#define DISP_HBLANK_START      DISP_HPIX
19849 +#define DISP_HBLANK_END                (DISP_HBLANK_START + HFP_DOTS + HSYNC_DOTS + HBP_DOTS - 1)
19850 +#define DISP_HSYNC_START       (DISP_HBLANK_START + HFP_DOTS - 1)
19851 +#define DISP_HSYNC_END         (DISP_HSYNC_START + HSYNC_DOTS - 1)
19852 +#define DISP_VBLANK_START      DISP_VPIX
19853 +#define DISP_VBLANK_END                (DISP_VBLANK_START + VFP_LINES + VSYNC_LINES + VBP_LINES - 1)
19854 +#define DISP_VSYNC_START       (DISP_VBLANK_START + VFP_LINES - 1)
19855 +#define DISP_VSYNC_END         (DISP_VSYNC_START + VSYNC_LINES - 1)
19856 +
19857 +#define BRIGHTNESS_MAX_LEVEL 100
19858 +
19859 +static unsigned int dphy_reg = 0x0d0a7f06;
19860 +static unsigned int mipi_clock = 0x2;
19861 +
19862 +#ifdef AAVA_BACKLIGHT_HACK
19863 +static void bl_work_handler(struct work_struct *work);
19864 +DECLARE_DELAYED_WORK(bl_work, bl_work_handler);
19865 +#endif /* AAVA_BACKLIGHT_HACK */
19866 +
19867 +// Temporary access from sysfs begin
19868 +static struct drm_encoder *orig_encoder;
19869 +static void mrst_dsi_prepare(struct drm_encoder *encoder);
19870 +static void mrst_dsi_commit(struct drm_encoder *encoder);
19871 +static void mrst_dsi_mode_set(struct drm_encoder *encoder,
19872 +                             struct drm_display_mode *mode,
19873 +                             struct drm_display_mode *adjusted_mode);
19874 +static void panel_reset(void);
19875 +
19876 +static ssize_t dphy_store(struct class *class, const char *buf, size_t len)
19877 +{
19878 +       ssize_t status;
19879 +       unsigned long value;
19880 +
19881 +       status = strict_strtoul(buf, 16, &value);
19882 +       dphy_reg = value;
19883 +       printk("!!! dphy_reg = %x, clock = %x\n", dphy_reg, mipi_clock);
19884 +
19885 +       return len;
19886 +}
19887 +
19888 +static ssize_t clock_store(struct class *class, const char *buf, size_t len)
19889 +{
19890 +       ssize_t status;
19891 +       unsigned long value;
19892 +
19893 +       status = strict_strtoul(buf, 0, &value);
19894 +       mipi_clock = value;
19895 +       printk("!!! dphy_reg = %x, clock = %x\n", dphy_reg, mipi_clock);
19896 +
19897 +       return len;
19898 +}
19899 +
19900 +static ssize_t apply_settings(struct class *class, const char *buf, size_t len)
19901 +{
19902 +       ssize_t status;
19903 +       long value;
19904 +
19905 +       printk("!!! dphy_reg = %x, clock = %x\n", dphy_reg, mipi_clock);
19906 +
19907 +       status = strict_strtoul(buf, 0, &value);
19908 +       if (value > 0) {
19909 +               mrst_dsi_prepare(orig_encoder);
19910 +               msleep(500);
19911 +               if (value > 1) {
19912 +                       panel_reset();
19913 +                       msleep(500);
19914 +               }
19915 +               mrst_dsi_mode_set(orig_encoder, NULL, NULL);
19916 +               msleep(500);
19917 +               mrst_dsi_commit(orig_encoder);
19918 +       }
19919 +
19920 +       return len;
19921 +}
19922 +// Temporary access from sysfs end
19923 +
19924 +static void panel_init(struct drm_device *dev)
19925 +{
19926 +#if DBG_PRINTS
19927 +       printk("panel_init\n");
19928 +#endif /* DBG_PRINTS */
19929 +
19930 +       /* Flip page order */
19931 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19932 +                                                       HS_DATA_FIFO_FULL);
19933 +       REG_WRITE(0xb068, 0x00008036);
19934 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19935 +                                                       HS_CTRL_FIFO_FULL);
19936 +       REG_WRITE(0xb070, 0x00000229);
19937 +
19938 +#ifdef NEW_CRAP_SAMPLE_SETTINGS
19939 +       // 0xF0, for new crap displays
19940 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19941 +                                                       HS_DATA_FIFO_FULL);
19942 +       REG_WRITE(0xb068, 0x005a5af0);
19943 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19944 +                                                       HS_CTRL_FIFO_FULL);
19945 +       REG_WRITE(0xb070, 0x00000329);
19946 +#endif
19947 +
19948 +       /* Write protection key */
19949 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19950 +                                                       HS_DATA_FIFO_FULL);
19951 +       REG_WRITE(0xb068, 0x005a5af1);
19952 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19953 +                                                       HS_CTRL_FIFO_FULL);
19954 +       REG_WRITE(0xb070, 0x00000329);
19955 +
19956 +#ifdef NEW_CRAP_SAMPLE_SETTINGS
19957 +       // 0xFC, for new crap displays
19958 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19959 +                                                       HS_DATA_FIFO_FULL);
19960 +       REG_WRITE(0xb068, 0x005a5afc);
19961 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19962 +                                                       HS_CTRL_FIFO_FULL);
19963 +       REG_WRITE(0xb070, 0x00000329);
19964 +
19965 +       // 0xB7, for new crap displays
19966 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19967 +                                                       HS_DATA_FIFO_FULL);
19968 +#ifdef DOES_NOT_WORK
19969 +       /* Suggested by TPO, doesn't work as usual */
19970 +       REG_WRITE(0xb068, 0x110000b7);
19971 +       REG_WRITE(0xb068, 0x00000044);
19972 +#else
19973 +       REG_WRITE(0xb068, 0x770000b7);
19974 +       REG_WRITE(0xb068, 0x00000044);
19975 +#endif
19976 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19977 +                                                       HS_CTRL_FIFO_FULL);
19978 +       REG_WRITE(0xb070, 0x00000529);
19979 +
19980 +       // 0xB6, for new crap displays
19981 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19982 +                                                       HS_DATA_FIFO_FULL);
19983 +       REG_WRITE(0xb068, 0x000a0ab6);
19984 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19985 +                                                       HS_CTRL_FIFO_FULL);
19986 +       REG_WRITE(0xb070, 0x00000329);
19987 +
19988 +       // 0xF2, for new crap displays
19989 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
19990 +                                                       HS_DATA_FIFO_FULL);
19991 +       REG_WRITE(0xb068, 0x081010f2);
19992 +       REG_WRITE(0xb068, 0x4a070708);
19993 +       REG_WRITE(0xb068, 0x000000c5);
19994 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
19995 +                                                       HS_CTRL_FIFO_FULL);
19996 +       REG_WRITE(0xb070, 0x00000929);
19997 +
19998 +       // 0xF8, for new crap displays
19999 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20000 +                                                       HS_DATA_FIFO_FULL);
20001 +       REG_WRITE(0xb068, 0x024003f8);
20002 +       REG_WRITE(0xb068, 0x01030a04);
20003 +       REG_WRITE(0xb068, 0x0e020220);
20004 +       REG_WRITE(0xb068, 0x00000004);
20005 +
20006 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20007 +                                                       HS_CTRL_FIFO_FULL);
20008 +       REG_WRITE(0xb070, 0x00000d29);
20009 +
20010 +       // 0xE2, for new crap displays
20011 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20012 +                                                       HS_DATA_FIFO_FULL);
20013 +       REG_WRITE(0xb068, 0x398fc3e2);
20014 +       REG_WRITE(0xb068, 0x0000916f);
20015 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20016 +                                                       HS_CTRL_FIFO_FULL);
20017 +       REG_WRITE(0xb070, 0x00000629);
20018 +
20019 +#ifdef DOES_NOT_WORK
20020 +       /* Suggested by TPO, doesn't work as usual */
20021 +       // 0xE3, for new crap displays
20022 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20023 +                                                       HS_DATA_FIFO_FULL);
20024 +       REG_WRITE(0xb068, 0x20f684e3);
20025 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20026 +                                                       HS_CTRL_FIFO_FULL);
20027 +       REG_WRITE(0xb070, 0x00000429);
20028 +
20029 +       msleep(50);
20030 +#endif
20031 +
20032 +       // 0xB0, for new crap displays
20033 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20034 +                                                       HS_DATA_FIFO_FULL);
20035 +       REG_WRITE(0xb068, 0x000000b0);
20036 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20037 +                                                       HS_CTRL_FIFO_FULL);
20038 +       REG_WRITE(0xb070, 0x00000229);
20039 +
20040 +       // 0xF4, for new crap displays
20041 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20042 +                                                       HS_DATA_FIFO_FULL);
20043 +       REG_WRITE(0xb068, 0x240242f4);
20044 +       REG_WRITE(0xb068, 0x78ee2002);
20045 +       REG_WRITE(0xb068, 0x2a071050);
20046 +       REG_WRITE(0xb068, 0x507fee10);
20047 +       REG_WRITE(0xb068, 0x10300710);
20048 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20049 +                                                       HS_CTRL_FIFO_FULL);
20050 +       REG_WRITE(0xb070, 0x00001429);
20051 +
20052 +       // 0xBA, for new crap displays
20053 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20054 +                                                       HS_DATA_FIFO_FULL);
20055 +       REG_WRITE(0xb068, 0x19fe07ba);
20056 +       REG_WRITE(0xb068, 0x101c0a31);
20057 +       REG_WRITE(0xb068, 0x00000010);
20058 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20059 +                                                       HS_CTRL_FIFO_FULL);
20060 +       REG_WRITE(0xb070, 0x00000929);
20061 +
20062 +       // 0xBB, for new crap displays
20063 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20064 +                                                       HS_DATA_FIFO_FULL);
20065 +       REG_WRITE(0xb068, 0x28ff07bb);
20066 +       REG_WRITE(0xb068, 0x24280a31);
20067 +       REG_WRITE(0xb068, 0x00000034);
20068 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20069 +                                                       HS_CTRL_FIFO_FULL);
20070 +       REG_WRITE(0xb070, 0x00000929);
20071 +
20072 +       // 0xFB, for new crap displays
20073 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20074 +                                                       HS_DATA_FIFO_FULL);
20075 +       REG_WRITE(0xb068, 0x535d05fb);
20076 +       REG_WRITE(0xb068, 0x1b1a2130);
20077 +       REG_WRITE(0xb068, 0x221e180e);
20078 +       REG_WRITE(0xb068, 0x131d2120);
20079 +       REG_WRITE(0xb068, 0x535d0508);
20080 +       REG_WRITE(0xb068, 0x1c1a2131);
20081 +       REG_WRITE(0xb068, 0x231f160d);
20082 +       REG_WRITE(0xb068, 0x111b2220);
20083 +       REG_WRITE(0xb068, 0x535c2008);
20084 +       REG_WRITE(0xb068, 0x1f1d2433);
20085 +       REG_WRITE(0xb068, 0x2c251a10);
20086 +       REG_WRITE(0xb068, 0x2c34372d);
20087 +       REG_WRITE(0xb068, 0x00000023);
20088 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20089 +                                                       HS_CTRL_FIFO_FULL);
20090 +       REG_WRITE(0xb070, 0x00003129);
20091 +
20092 +       // 0xFA, for new crap displays
20093 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20094 +                                                       HS_DATA_FIFO_FULL);
20095 +       REG_WRITE(0xb068, 0x525c0bfa);
20096 +       REG_WRITE(0xb068, 0x1c1c232f);
20097 +       REG_WRITE(0xb068, 0x2623190e);
20098 +       REG_WRITE(0xb068, 0x18212625);
20099 +       REG_WRITE(0xb068, 0x545d0d0e);
20100 +       REG_WRITE(0xb068, 0x1e1d2333);
20101 +       REG_WRITE(0xb068, 0x26231a10);
20102 +       REG_WRITE(0xb068, 0x1a222725);
20103 +       REG_WRITE(0xb068, 0x545d280f);
20104 +       REG_WRITE(0xb068, 0x21202635);
20105 +       REG_WRITE(0xb068, 0x31292013);
20106 +       REG_WRITE(0xb068, 0x31393d33);
20107 +       REG_WRITE(0xb068, 0x00000029);
20108 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20109 +                                                       HS_CTRL_FIFO_FULL);
20110 +       REG_WRITE(0xb070, 0x00003129);
20111 +#endif
20112 +
20113 +       /* Set DM */
20114 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_DATA_FIFO_FULL) ==
20115 +                                                       HS_DATA_FIFO_FULL);
20116 +       REG_WRITE(0xb068, 0x000100f7);
20117 +       while ((REG_READ(GEN_FIFO_STAT_REG) & HS_CTRL_FIFO_FULL) ==
20118 +                                                       HS_CTRL_FIFO_FULL);
20119 +       REG_WRITE(0xb070, 0x00000329);
20120 +}
20121 +
20122 +
20123 +static void panel_reset_on(void)
20124 +{
20125 +       struct ipc_pmic_reg_data tmp_reg = {0};
20126 +#if DBG_PRINTS
20127 +       printk("panel_reset_on\n");
20128 +#endif /* DBG_PRINTS */
20129 +       tmp_reg.ioc = 1;
20130 +       tmp_reg.num_entries = 1;
20131 +#ifdef AAVA_EV_0_5
20132 +       tmp_reg.pmic_reg_data[0].register_address = 0xe6;
20133 +       tmp_reg.pmic_reg_data[0].value = 0x01;
20134 +#else /* CDK */
20135 +       tmp_reg.pmic_reg_data[0].register_address = 0xf4;
20136 +       if (ipc_pmic_register_read(&tmp_reg)) {
20137 +               printk("panel_reset_on: failed to read pmic reg 0xf4!\n");
20138 +               return;
20139 +       }
20140 +       tmp_reg.pmic_reg_data[0].value &= 0xbf;
20141 +#endif /* AAVA_EV_0_5 */
20142 +       if (ipc_pmic_register_write(&tmp_reg, TRUE)) {
20143 +               printk("panel_reset_on: failed to write pmic reg 0xe6!\n");
20144 +       }
20145 +}
20146 +
20147 +
20148 +static void panel_reset_off(void)
20149 +{
20150 +       struct ipc_pmic_reg_data tmp_reg = {0};
20151 +#if DBG_PRINTS
20152 +       printk("panel_reset_off\n");
20153 +#endif /* DBG_PRINTS */
20154 +       tmp_reg.ioc = 1;
20155 +       tmp_reg.num_entries = 1;
20156 +#ifdef AAVA_EV_0_5
20157 +       tmp_reg.pmic_reg_data[0].register_address = 0xe6;
20158 +       tmp_reg.pmic_reg_data[0].value = 0x09;
20159 +#else /* CDK */
20160 +       tmp_reg.pmic_reg_data[0].register_address = 0xf4;
20161 +       if (ipc_pmic_register_read(&tmp_reg)) {
20162 +               printk("panel_reset_off: failed to read pmic reg 0xf4!\n");
20163 +               return;
20164 +       }
20165 +       tmp_reg.pmic_reg_data[0].value |= 0x40;
20166 +#endif /* AAVA_EV_0_5 */
20167 +       if (ipc_pmic_register_write(&tmp_reg, TRUE)) {
20168 +               printk("panel_reset_off: failed to write pmic reg 0xe6!\n");
20169 +       }
20170 +}
20171 +
20172 +
20173 +static void panel_reset(void)
20174 +{
20175 +#if DBG_PRINTS
20176 +       printk("panel_reset\n");
20177 +#endif /* DBG_PRINTS */
20178 +
20179 +       panel_reset_on();
20180 +       msleep(20);
20181 +       panel_reset_off();
20182 +       msleep(20);
20183 +}
20184 +
20185 +
20186 +static void backlight_state(bool on)
20187 +{
20188 +       struct ipc_pmic_reg_data tmp_reg;
20189 +
20190 +#if DBG_PRINTS
20191 +       printk("backlight_state\n");
20192 +#endif /* DBG_PRINTS */
20193 +
20194 +       tmp_reg.ioc = 1;
20195 +       tmp_reg.num_entries = 2;
20196 +       tmp_reg.pmic_reg_data[0].register_address = 0x2a;
20197 +       tmp_reg.pmic_reg_data[1].register_address = 0x28;
20198 +
20199 +       if( on ) {
20200 +#if DBG_PRINTS
20201 +               printk("backlight_state: ON\n");
20202 +#endif /* DBG_PRINTS */
20203 +               tmp_reg.pmic_reg_data[0].value = 0xaa;
20204 +#ifdef AAVA_EV_0_5
20205 +               tmp_reg.pmic_reg_data[1].value = 0x30;
20206 +#else /* CDK */
20207 +               tmp_reg.pmic_reg_data[1].value = 0x60;
20208 +#endif /* AAVA_EV_0_5 */
20209 +       } else {
20210 +#if DBG_PRINTS
20211 +               printk("backlight_state: OFF\n");
20212 +#endif /* DBG_PRINTS */
20213 +               tmp_reg.pmic_reg_data[0].value = 0x00;
20214 +               tmp_reg.pmic_reg_data[1].value = 0x00;
20215 +       }
20216 +
20217 +       if (ipc_pmic_register_write(&tmp_reg, TRUE)) {
20218 +               printk("backlight_state: failed to write pmic regs 0x2a and 0x28!\n");
20219 +       }
20220 +}
20221 +
20222 +#ifdef AAVA_BACKLIGHT_HACK
20223 +static void bl_work_handler(struct work_struct *work)
20224 +{
20225 +       backlight_state(true);
20226 +}
20227 +#endif /* AAVA_BACKLIGHT_HACK */
20228 +
20229 +
20230 +/**
20231 + * Sets the power state for the panel.
20232 + */
20233 +static void mrst_dsi_set_power(struct drm_device *dev,
20234 +                              struct psb_intel_output *output, bool on)
20235 +{
20236 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
20237 +       u32 pp_status;
20238 +
20239 +#if DBG_PRINTS
20240 +       printk("mrst_dsi_set_power\n");
20241 +#endif /* DBG_PRINTS */
20242 +
20243 +       /*
20244 +        * The DIS device must be ready before we can change power state.
20245 +        */
20246 +       if (!dev_priv->dsi_device_ready)
20247 +       {
20248 +#if DBG_PRINTS
20249 +               printk("mrst_dsi_set_power: !dev_priv->dsi_device_ready!\n");
20250 +#endif /* DBG_PRINTS */
20251 +               return;
20252 +       }
20253 +
20254 +       /*
20255 +        * We don't support dual DSI yet. May be in POR in the future.
20256 +        */
20257 +       if (dev_priv->dual_display)
20258 +       {
20259 +#if DBG_PRINTS
20260 +               printk("mrst_dsi_set_power: dev_priv->dual_display!\n");
20261 +#endif /* DBG_PRINTS */
20262 +       return;
20263 +       }
20264 +
20265 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
20266 +                                      OSPM_UHB_FORCE_POWER_ON))
20267 +               return;
20268 +
20269 +       if (on) {
20270 +#if DBG_PRINTS
20271 +               printk("mrst_dsi_set_power: on\n");
20272 +#endif /* DBG_PRINTS */
20273 +               if (dev_priv->dpi && !dev_priv->dpi_panel_on) {
20274 +#if DBG_PRINTS
20275 +                       printk("mrst_dsi_set_power: dpi\n");
20276 +#endif /* DBG_PRINTS */
20277 +                       REG_WRITE(DPI_CONTROL_REG, DPI_TURN_ON);
20278 +                       REG_WRITE(PP_CONTROL,
20279 +                                 (REG_READ(PP_CONTROL) | POWER_TARGET_ON));
20280 +                       do {
20281 +                               pp_status = REG_READ(PP_STATUS);
20282 +                       } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
20283 +
20284 +                       /* Run TPO display specific initialisations */
20285 +// MiKo TBD, this delay may need to be tuned
20286 +                       msleep(50);
20287 +                       panel_init(dev);
20288 +
20289 +                       /* Set backlights on */
20290 +                       backlight_state( true );
20291 +                       dev_priv->dpi_panel_on = true;
20292 +               }
20293 +       } else {
20294 +#if DBG_PRINTS
20295 +               printk("mrst_dsi_set_power: off\n");
20296 +#endif /* DBG_PRINTS */
20297 +               if (dev_priv->dpi && dev_priv->dpi_panel_on) {
20298 +#if DBG_PRINTS
20299 +                       printk("mrst_dsi_set_power: dpi\n");
20300 +#endif /* DBG_PRINTS */
20301 +                       /* Set backlights off */
20302 +                       backlight_state( false );
20303 +
20304 +// MiKo TBD, something clever could be done here to save power, for example:
20305 +// -Set display to sleep mode, or
20306 +// -Set display to HW reset, or
20307 +// -Shutdown the voltages to display
20308 +
20309 +                       REG_WRITE(PP_CONTROL,
20310 +                                 (REG_READ(PP_CONTROL) & ~POWER_TARGET_ON));
20311 +                       do {
20312 +                               pp_status = REG_READ(PP_STATUS);
20313 +                       } while (pp_status & PP_ON);
20314 +
20315 +                       REG_WRITE(DPI_CONTROL_REG, DPI_SHUT_DOWN);
20316 +
20317 +                       dev_priv->dpi_panel_on = false;
20318 +               }
20319 +       }
20320 +
20321 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
20322 +}
20323 +
20324 +
20325 +static void mrst_dsi_dpms(struct drm_encoder *encoder, int mode)
20326 +{
20327 +       struct drm_device *dev = encoder->dev;
20328 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
20329 +
20330 +#if DBG_PRINTS
20331 +       printk("mrst_dsi_dpms\n");
20332 +#endif /* DBG_PRINTS */
20333 +
20334 +       if (mode == DRM_MODE_DPMS_ON)
20335 +               mrst_dsi_set_power(dev, output, true);
20336 +       else
20337 +               mrst_dsi_set_power(dev, output, false);
20338 +}
20339 +
20340 +
20341 +static void mrst_dsi_save(struct drm_connector *connector)
20342 +{
20343 +#if DBG_PRINTS
20344 +       printk("mrst_dsi_save\n");
20345 +#endif /* DBG_PRINTS */
20346 +       // MiKo TBD
20347 +}
20348 +
20349 +
20350 +static void mrst_dsi_restore(struct drm_connector *connector)
20351 +{
20352 +#if DBG_PRINTS
20353 +       printk("mrst_dsi_restore\n");
20354 +#endif /* DBG_PRINTS */
20355 +       // MiKo TBD
20356 +}
20357 +
20358 +
20359 +static void mrst_dsi_prepare(struct drm_encoder *encoder)
20360 +{
20361 +       struct drm_device *dev = encoder->dev;
20362 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
20363 +
20364 +#if DBG_PRINTS
20365 +       printk("mrst_dsi_prepare\n");
20366 +#endif /* DBG_PRINTS */
20367 +
20368 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
20369 +                                      OSPM_UHB_FORCE_POWER_ON))
20370 +               return;
20371 +
20372 +       mrst_dsi_set_power(dev, output, false);
20373 +
20374 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
20375 +}
20376 +
20377 +
20378 +static void mrst_dsi_commit(struct drm_encoder *encoder)
20379 +{
20380 +       struct drm_device *dev = encoder->dev;
20381 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
20382 +
20383 +#if DBG_PRINTS
20384 +       printk("mrst_dsi_commit\n");
20385 +#endif /* DBG_PRINTS */
20386 +
20387 +       mrst_dsi_set_power(dev, output, true);
20388 +}
20389 +
20390 +
20391 +static void mrst_dsi_mode_set(struct drm_encoder *encoder,
20392 +                             struct drm_display_mode *mode,
20393 +                             struct drm_display_mode *adjusted_mode)
20394 +{
20395 +       struct drm_device *dev = encoder->dev;
20396 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
20397 +       u32 SupportedFormat = 0;
20398 +       u32 resolution = 0;
20399 +       uint64_t curValue = DRM_MODE_SCALE_FULLSCREEN;
20400 +
20401 +#if DBG_PRINTS
20402 +       printk("mrst_dsi_mode_set\n");
20403 +#endif /* DBG_PRINTS */
20404 +
20405 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
20406 +                                      OSPM_UHB_FORCE_POWER_ON))
20407 +               return;
20408 +
20409 +       /* Sleep to ensure that the graphics engine is ready
20410 +        * since its mode_set is called before ours
20411 +        */
20412 +       msleep(100);
20413 +
20414 +       switch (dev_priv->bpp)
20415 +       {
20416 +       case 24:
20417 +               SupportedFormat = RGB_888_FMT;
20418 +               break;
20419 +       default:
20420 +               printk("mrst_dsi_mode_set, invalid bpp!\n");
20421 +               break;
20422 +       }
20423 +
20424 +       if (dev_priv->dpi) {
20425 +               drm_connector_property_get_value(
20426 +                                       &enc_to_psb_intel_output(encoder)->base,
20427 +                                       dev->mode_config.scaling_mode_property,
20428 +                                       &curValue);
20429 +               if (curValue == DRM_MODE_SCALE_CENTER) {
20430 +                       REG_WRITE(PFIT_CONTROL, 0);
20431 +               } else if (curValue == DRM_MODE_SCALE_FULLSCREEN) {
20432 +                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
20433 +               } else {
20434 +                       printk("mrst_dsi_mode_set, scaling not supported!\n");
20435 +                       REG_WRITE(PFIT_CONTROL, 0);
20436 +               }
20437 +
20438 +
20439 +               /* MIPI clock ratio 1:1 */
20440 +               //REG_WRITE(MIPI_CONTROL_REG, 0x00000018);
20441 +               //REG_WRITE(0xb080, 0x0b061a02);
20442 +
20443 +               /* MIPI clock ratio 2:1 */
20444 +               //REG_WRITE(MIPI_CONTROL_REG, 0x00000019);
20445 +               //REG_WRITE(0xb080, 0x3f1f1c04);
20446 +
20447 +               /* MIPI clock ratio 3:1 */
20448 +               //REG_WRITE(MIPI_CONTROL_REG, 0x0000001a);
20449 +               //REG_WRITE(0xb080, 0x091f7f08);
20450 +
20451 +               /* MIPI clock ratio 4:1 */
20452 +               REG_WRITE(MIPI_CONTROL_REG, (0x00000018 | mipi_clock));
20453 +               REG_WRITE(0xb080, dphy_reg);
20454 +
20455 +               /* Enable all interrupts */
20456 +               REG_WRITE(INTR_EN_REG, 0xffffffff);
20457 +
20458 +               REG_WRITE(TURN_AROUND_TIMEOUT_REG, 0x0000000A);
20459 +               REG_WRITE(DEVICE_RESET_REG, 0x000000ff);
20460 +               REG_WRITE(INIT_COUNT_REG, 0x00000fff);
20461 +               REG_WRITE(HS_TX_TIMEOUT_REG, 0x90000);
20462 +               REG_WRITE(LP_RX_TIMEOUT_REG, 0xffff);
20463 +               REG_WRITE(HIGH_LOW_SWITCH_COUNT_REG, 0x46);
20464 +               REG_WRITE(EOT_DISABLE_REG, 0x00000000);
20465 +               REG_WRITE(LP_BYTECLK_REG, 0x00000004);
20466 +
20467 +               REG_WRITE(VIDEO_FMT_REG, dev_priv->videoModeFormat);
20468 +
20469 +               SupportedFormat <<= FMT_DPI_POS;
20470 +               REG_WRITE(DSI_FUNC_PRG_REG,
20471 +                               (dev_priv->laneCount | SupportedFormat));
20472 +
20473 +               resolution = dev_priv->HactiveArea |
20474 +                               (dev_priv->VactiveArea << RES_V_POS);
20475 +               REG_WRITE(DPI_RESOLUTION_REG, resolution);
20476 +
20477 +               REG_WRITE(VERT_SYNC_PAD_COUNT_REG, dev_priv->VsyncWidth);
20478 +               REG_WRITE(VERT_BACK_PORCH_COUNT_REG, dev_priv->VbackPorch);
20479 +               REG_WRITE(VERT_FRONT_PORCH_COUNT_REG, dev_priv->VfrontPorch);
20480 +
20481 +               REG_WRITE(HORIZ_SYNC_PAD_COUNT_REG, dev_priv->HsyncWidth);
20482 +               REG_WRITE(HORIZ_BACK_PORCH_COUNT_REG, dev_priv->HbackPorch);
20483 +               REG_WRITE(HORIZ_FRONT_PORCH_COUNT_REG, dev_priv->HfrontPorch);
20484 +               REG_WRITE(HORIZ_ACTIVE_AREA_COUNT_REG, MIPI_HACT);
20485 +       }
20486 +
20487 +       /* Enable MIPI Port */
20488 +       REG_WRITE(MIPI, MIPI_PORT_EN);
20489 +
20490 +       REG_WRITE(DEVICE_READY_REG, 0x00000001);
20491 +       REG_WRITE(DPI_CONTROL_REG, 0x00000002); /* Turn On */
20492 +
20493 +       dev_priv->dsi_device_ready = true;
20494 +
20495 +       /* Enable pipe */
20496 +       REG_WRITE(PIPEACONF, dev_priv->pipeconf);
20497 +       REG_READ(PIPEACONF);
20498 +
20499 +       /* Wait for 20ms for the pipe enable to take effect. */
20500 +       udelay(20000);
20501 +
20502 +       /* Enable plane */
20503 +       REG_WRITE(DSPACNTR, dev_priv->dspcntr);
20504 +
20505 +       /* Wait for 20ms for the plane enable to take effect. */
20506 +       udelay(20000);
20507 +
20508 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
20509 +}
20510 +
20511 +
20512 +/**
20513 + * Detect the MIPI connection.
20514 + *
20515 + * This always returns CONNECTOR_STATUS_CONNECTED.
20516 + * This connector should only have
20517 + * been set up if the MIPI was actually connected anyway.
20518 + */
20519 +static enum drm_connector_status mrst_dsi_detect(struct drm_connector
20520 +                                                *connector)
20521 +{
20522 +#if DBG_PRINTS
20523 +       printk("mrst_dsi_detect\n");
20524 +#endif /* DBG_PRINTS */
20525 +       return connector_status_connected;
20526 +}
20527 +
20528 +
20529 +/**
20530 + * Return the list of MIPI DDB modes if available.
20531 + */
20532 +static int mrst_dsi_get_modes(struct drm_connector *connector)
20533 +{
20534 +       struct drm_device *dev = connector->dev;
20535 +       struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector);
20536 +       struct psb_intel_mode_device *mode_dev = psb_intel_output->mode_dev;
20537 +
20538 +       /* Didn't get an DDB, so
20539 +        * Set wide sync ranges so we get all modes
20540 +        * handed to valid_mode for checking
20541 +        */
20542 +       connector->display_info.min_vfreq = 0;
20543 +       connector->display_info.max_vfreq = 200;
20544 +       connector->display_info.min_hfreq = 0;
20545 +       connector->display_info.max_hfreq = 200;
20546 +
20547 +       if (mode_dev->panel_fixed_mode != NULL) {
20548 +               struct drm_display_mode *mode =
20549 +                       drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
20550 +               drm_mode_probed_add(connector, mode);
20551 +               return 1;
20552 +       }
20553 +       return 0;
20554 +}
20555 +
20556 +
20557 +static const struct drm_encoder_helper_funcs mrst_dsi_helper_funcs = {
20558 +       .dpms           = mrst_dsi_dpms,
20559 +       .mode_fixup     = psb_intel_lvds_mode_fixup,
20560 +       .prepare        = mrst_dsi_prepare,
20561 +       .mode_set       = mrst_dsi_mode_set,
20562 +       .commit = mrst_dsi_commit,
20563 +};
20564 +
20565 +
20566 +static const struct drm_connector_helper_funcs
20567 +       mrst_dsi_connector_helper_funcs = {
20568 +               .get_modes      = mrst_dsi_get_modes,
20569 +               .mode_valid     = psb_intel_lvds_mode_valid,
20570 +               .best_encoder   = psb_intel_best_encoder,
20571 +};
20572 +
20573 +
20574 +static const struct drm_connector_funcs mrst_dsi_connector_funcs = {
20575 +       .dpms           = drm_helper_connector_dpms,
20576 +       .save           = mrst_dsi_save,
20577 +       .restore        = mrst_dsi_restore,
20578 +       .detect         = mrst_dsi_detect,
20579 +       .fill_modes     = drm_helper_probe_single_connector_modes,
20580 +       .set_property   = psb_intel_lvds_set_property,
20581 +       .destroy        = psb_intel_lvds_destroy,
20582 +};
20583 +
20584 +
20585 +/** Returns the panel fixed mode from configuration. */
20586 +struct drm_display_mode *mrst_dsi_get_configuration_mode(struct drm_device *dev)
20587 +{
20588 +       struct drm_display_mode *mode;
20589 +
20590 +       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
20591 +       if (!mode)
20592 +               return NULL;
20593 +
20594 +       /* MiKo, fixed mode for TPO display
20595 +           Note: Using defined values for easier match with ITP scripts
20596 +                 and adding 1 since psb_intel_display.c decreases by 1
20597 +       */
20598 +       mode->hdisplay = (DISP_HPIX + 1);
20599 +       mode->vdisplay = (DISP_VPIX + 1);
20600 +       mode->hsync_start = (DISP_HSYNC_START + 1);
20601 +       mode->hsync_end = (DISP_HSYNC_END + 1);
20602 +       mode->htotal = (DISP_HBLANK_END + 1);
20603 +       mode->vsync_start = (DISP_VSYNC_START + 1);
20604 +       mode->vsync_end = (DISP_VSYNC_END + 1);
20605 +       mode->vtotal = (DISP_VBLANK_END + 1);
20606 +       mode->clock = 33264;
20607 +
20608 +       drm_mode_set_name(mode);
20609 +       drm_mode_set_crtcinfo(mode, 0);
20610 +
20611 +       return mode;
20612 +}
20613 +
20614 +
20615 +/* ************************************************************************* *\
20616 +FUNCTION: mrst_mipi_settings_init
20617 +                                                                                                                               `
20618 +DESCRIPTION:
20619 +
20620 +\* ************************************************************************* */
20621 +static bool mrst_mipi_settings_init(DRM_DRIVER_PRIVATE_T *dev_priv)
20622 +{
20623 +       /* MiKo, fixed values for TPO display */
20624 +       dev_priv->pixelClock = 33264;
20625 +       dev_priv->HsyncWidth = MIPI_HSPAD;
20626 +       dev_priv->HbackPorch = MIPI_HBP;
20627 +       dev_priv->HfrontPorch = MIPI_HFP;
20628 +       dev_priv->HactiveArea = HSIZE;
20629 +       dev_priv->VsyncWidth = MIPI_VSPAD;
20630 +       dev_priv->VbackPorch = MIPI_VBP;
20631 +       dev_priv->VfrontPorch = MIPI_VFP;
20632 +       dev_priv->VactiveArea = VSIZE;
20633 +       dev_priv->bpp = 24;
20634 +
20635 +       /* video mode */
20636 +       dev_priv->dpi = true;
20637 +
20638 +       /* MiKo, set these true by default to ensure that first mode set is done
20639 +                cleanly
20640 +       */
20641 +       dev_priv->dpi_panel_on = true;
20642 +       dev_priv->dsi_device_ready = true;
20643 +
20644 +       /* 2 lanes */
20645 +       dev_priv->laneCount = MIPI_LANES;
20646 +
20647 +       /* Burst mode */
20648 +       dev_priv->videoModeFormat = BURST_MODE;
20649 +
20650 +       return true;
20651 +}
20652 +
20653 +
20654 +/**
20655 + * mrst_dsi_init - setup MIPI connectors on this device
20656 + * @dev: drm device
20657 + *
20658 + * Create the connector, try to figure out what
20659 + * modes we can display on the MIPI panel (if present).
20660 + */
20661 +void mrst_dsi_init(struct drm_device *dev,
20662 +                   struct psb_intel_mode_device *mode_dev)
20663 +{
20664 +       DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
20665 +       struct psb_intel_output *psb_intel_output;
20666 +       struct drm_connector *connector;
20667 +       struct drm_encoder *encoder;
20668 +
20669 +#if DBG_PRINTS
20670 +       printk("mrst_dsi_init\n");
20671 +#endif /* DBG_PRINTS */
20672 +
20673 +       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
20674 +       if (!psb_intel_output)
20675 +               return;
20676 +
20677 +       panel_reset();
20678 +
20679 +#ifdef AAVA_BACKLIGHT_HACK
20680 +       schedule_delayed_work(&bl_work, 2*HZ);
20681 +#endif /* AAVA_BACKLIGHT_HACK */
20682 +
20683 +       psb_intel_output->mode_dev = mode_dev;
20684 +       connector = &psb_intel_output->base;
20685 +       encoder = &psb_intel_output->enc;
20686 +       drm_connector_init(dev,
20687 +                          &psb_intel_output->base,
20688 +                          &mrst_dsi_connector_funcs,
20689 +                          DRM_MODE_CONNECTOR_MIPI);
20690 +
20691 +       drm_encoder_init(dev,
20692 +                        &psb_intel_output->enc,
20693 +                        &psb_intel_lvds_enc_funcs,
20694 +                        DRM_MODE_ENCODER_MIPI);
20695 +
20696 +       drm_mode_connector_attach_encoder(&psb_intel_output->base,
20697 +                                         &psb_intel_output->enc);
20698 +       psb_intel_output->type = INTEL_OUTPUT_MIPI;
20699 +
20700 +       drm_encoder_helper_add(encoder, &mrst_dsi_helper_funcs);
20701 +       drm_connector_helper_add(connector, &mrst_dsi_connector_helper_funcs);
20702 +       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
20703 +       connector->interlace_allowed = false;
20704 +       connector->doublescan_allowed = false;
20705 +
20706 +       drm_connector_attach_property(connector,
20707 +                                     dev->mode_config.scaling_mode_property,
20708 +                                     DRM_MODE_SCALE_FULLSCREEN);
20709 +       drm_connector_attach_property(connector,
20710 +                                     dev_priv->backlight_property,
20711 +                                     BRIGHTNESS_MAX_LEVEL);
20712 +
20713 +       if (!mrst_mipi_settings_init(dev_priv))
20714 +               printk("Can't initialize MIPI settings\n");
20715 +
20716 +       /* No config phase */
20717 +       dev_priv->config_phase = false;
20718 +
20719 +       /* Get the fixed mode */
20720 +       mode_dev->panel_fixed_mode = mrst_dsi_get_configuration_mode(dev);
20721 +       if (mode_dev->panel_fixed_mode) {
20722 +               mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
20723 +       } else {
20724 +               printk("Found no modes for MIPI!\n");
20725 +               goto failed_find;
20726 +       }
20727 +// Temporary access from sysfs begin
20728 +       orig_encoder = encoder;
20729 +// Temporary access from sysfs end
20730 +       drm_sysfs_connector_add(connector);
20731 +       return;
20732 +
20733 +failed_find:
20734 +       drm_encoder_cleanup(encoder);
20735 +       drm_connector_cleanup(connector);
20736 +       kfree(connector);
20737 +}
20738 +
20739 +// Temporary access from sysfs begin
20740 +static struct class_attribute miko_class_attrs[] = {
20741 +       __ATTR(dphy, 0644, NULL, dphy_store),
20742 +       __ATTR(clock, 0644, NULL, clock_store),
20743 +       __ATTR(apply, 0200, NULL, apply_settings),
20744 +       __ATTR_NULL,
20745 +};
20746 +
20747 +static struct class miko_class = {
20748 +       .name =         "miko",
20749 +       .owner =        THIS_MODULE,
20750 +
20751 +       .class_attrs =  miko_class_attrs,
20752 +};
20753 +
20754 +static int __init miko_sysfs_init(void)
20755 +{
20756 +       int             status;
20757 +
20758 +       status = class_register(&miko_class);
20759 +       if (status < 0)
20760 +               return status;
20761 +
20762 +       return status;
20763 +}
20764 +postcore_initcall(miko_sysfs_init);
20765 +// Temporary access from sysfs end
20766 +
20767 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_i2c.c b/drivers/gpu/drm/mrst/drv/psb_intel_i2c.c
20768 new file mode 100644
20769 index 0000000..415847d
20770 --- /dev/null
20771 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_i2c.c
20772 @@ -0,0 +1,172 @@
20773 +/*
20774 + * Copyright Â© 2006-2007 Intel Corporation
20775 + *
20776 + * This program is free software; you can redistribute it and/or modify it
20777 + * under the terms and conditions of the GNU General Public License,
20778 + * version 2, as published by the Free Software Foundation.
20779 + *
20780 + * This program is distributed in the hope it will be useful, but WITHOUT
20781 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20782 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
20783 + * more details.
20784 + *
20785 + * You should have received a copy of the GNU General Public License along with
20786 + * this program; if not, write to the Free Software Foundation, Inc., 
20787 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20788 + *
20789 + * Authors:
20790 + *     Eric Anholt <eric@anholt.net>
20791 + */
20792 +
20793 +#include <linux/i2c.h>
20794 +#include <linux/i2c-id.h>
20795 +#include <linux/i2c-algo-bit.h>
20796 +
20797 +#include "psb_drv.h"
20798 +#include "psb_intel_reg.h"
20799 +
20800 +/*
20801 + * Intel GPIO access functions
20802 + */
20803 +
20804 +#define I2C_RISEFALL_TIME 20
20805 +
20806 +static int get_clock(void *data)
20807 +{
20808 +       struct psb_intel_i2c_chan *chan = data;
20809 +       struct drm_device *dev = chan->drm_dev;
20810 +       u32 val;
20811 +
20812 +       val = REG_READ(chan->reg);
20813 +       return (val & GPIO_CLOCK_VAL_IN) != 0;
20814 +}
20815 +
20816 +static int get_data(void *data)
20817 +{
20818 +       struct psb_intel_i2c_chan *chan = data;
20819 +       struct drm_device *dev = chan->drm_dev;
20820 +       u32 val;
20821 +
20822 +       val = REG_READ(chan->reg);
20823 +       return (val & GPIO_DATA_VAL_IN) != 0;
20824 +}
20825 +
20826 +static void set_clock(void *data, int state_high)
20827 +{
20828 +       struct psb_intel_i2c_chan *chan = data;
20829 +       struct drm_device *dev = chan->drm_dev;
20830 +       u32 reserved = 0, clock_bits;
20831 +
20832 +       /* On most chips, these bits must be preserved in software. */
20833 +       if (!IS_I830(dev) && !IS_845G(dev))
20834 +               reserved =
20835 +                   REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
20836 +                                          GPIO_CLOCK_PULLUP_DISABLE);
20837 +
20838 +       if (state_high)
20839 +               clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
20840 +       else
20841 +               clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
20842 +                   GPIO_CLOCK_VAL_MASK;
20843 +       REG_WRITE(chan->reg, reserved | clock_bits);
20844 +       udelay(I2C_RISEFALL_TIME);      /* wait for the line to change state */
20845 +}
20846 +
20847 +static void set_data(void *data, int state_high)
20848 +{
20849 +       struct psb_intel_i2c_chan *chan = data;
20850 +       struct drm_device *dev = chan->drm_dev;
20851 +       u32 reserved = 0, data_bits;
20852 +
20853 +       /* On most chips, these bits must be preserved in software. */
20854 +       if (!IS_I830(dev) && !IS_845G(dev))
20855 +               reserved =
20856 +                   REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
20857 +                                          GPIO_CLOCK_PULLUP_DISABLE);
20858 +
20859 +       if (state_high)
20860 +               data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
20861 +       else
20862 +               data_bits =
20863 +                   GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
20864 +                   GPIO_DATA_VAL_MASK;
20865 +
20866 +       REG_WRITE(chan->reg, reserved | data_bits);
20867 +       udelay(I2C_RISEFALL_TIME);      /* wait for the line to change state */
20868 +}
20869 +
20870 +/**
20871 + * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
20872 + * @dev: DRM device
20873 + * @output: driver specific output device
20874 + * @reg: GPIO reg to use
20875 + * @name: name for this bus
20876 + *
20877 + * Creates and registers a new i2c bus with the Linux i2c layer, for use
20878 + * in output probing and control (e.g. DDC or SDVO control functions).
20879 + *
20880 + * Possible values for @reg include:
20881 + *   %GPIOA
20882 + *   %GPIOB
20883 + *   %GPIOC
20884 + *   %GPIOD
20885 + *   %GPIOE
20886 + *   %GPIOF
20887 + *   %GPIOG
20888 + *   %GPIOH
20889 + * see PRM for details on how these different busses are used.
20890 + */
20891 +struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
20892 +                                       const u32 reg, const char *name)
20893 +{
20894 +       struct psb_intel_i2c_chan *chan;
20895 +
20896 +       chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
20897 +       if (!chan)
20898 +               goto out_free;
20899 +
20900 +       chan->drm_dev = dev;
20901 +       chan->reg = reg;
20902 +       snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
20903 +       chan->adapter.owner = THIS_MODULE;
20904 +       chan->adapter.algo_data = &chan->algo;
20905 +       chan->adapter.dev.parent = &dev->pdev->dev;
20906 +       chan->algo.setsda = set_data;
20907 +       chan->algo.setscl = set_clock;
20908 +       chan->algo.getsda = get_data;
20909 +       chan->algo.getscl = get_clock;
20910 +       chan->algo.udelay = 20;
20911 +       chan->algo.timeout = usecs_to_jiffies(2200);
20912 +       chan->algo.data = chan;
20913 +
20914 +       i2c_set_adapdata(&chan->adapter, chan);
20915 +
20916 +       if (i2c_bit_add_bus(&chan->adapter))
20917 +               goto out_free;
20918 +
20919 +       /* JJJ:  raise SCL and SDA? */
20920 +       set_data(chan, 1);
20921 +       set_clock(chan, 1);
20922 +       udelay(20);
20923 +
20924 +       return chan;
20925 +
20926 +out_free:
20927 +       kfree(chan);
20928 +       return NULL;
20929 +}
20930 +
20931 +/**
20932 + * psb_intel_i2c_destroy - unregister and free i2c bus resources
20933 + * @output: channel to free
20934 + *
20935 + * Unregister the adapter from the i2c layer, then free the structure.
20936 + */
20937 +void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
20938 +{
20939 +       if (!chan)
20940 +               return;
20941 +
20942 +       i2c_del_adapter(&chan->adapter);
20943 +       kfree(chan);
20944 +}
20945 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_lvds.c b/drivers/gpu/drm/mrst/drv/psb_intel_lvds.c
20946 new file mode 100644
20947 index 0000000..b426b53
20948 --- /dev/null
20949 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_lvds.c
20950 @@ -0,0 +1,1385 @@
20951 +/*
20952 + * Copyright Â© 2006-2007 Intel Corporation
20953 + *
20954 + * This program is free software; you can redistribute it and/or modify it
20955 + * under the terms and conditions of the GNU General Public License,
20956 + * version 2, as published by the Free Software Foundation.
20957 + *
20958 + * This program is distributed in the hope it will be useful, but WITHOUT
20959 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20960 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
20961 + * more details.
20962 + *
20963 + * You should have received a copy of the GNU General Public License along with
20964 + * this program; if not, write to the Free Software Foundation, Inc., 
20965 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20966 + *
20967 + * Authors:
20968 + *     Eric Anholt <eric@anholt.net>
20969 + *     Dave Airlie <airlied@linux.ie>
20970 + *     Jesse Barnes <jesse.barnes@intel.com>
20971 + */
20972 +
20973 +#include <linux/i2c.h>
20974 +/* #include <drm/drm_crtc.h> */
20975 +/* #include <drm/drm_edid.h> */
20976 +#include <drm/drmP.h>
20977 +
20978 +#include "psb_intel_bios.h"
20979 +#include "psb_drv.h"
20980 +#include "psb_intel_drv.h"
20981 +#include "psb_intel_reg.h"
20982 +#include "ospm_power.h"
20983 +
20984 +/* MRST defines start */
20985 +uint8_t blc_freq;
20986 +uint8_t blc_minbrightness;
20987 +uint8_t blc_i2caddr;
20988 +uint8_t blc_brightnesscmd;
20989 +int lvds_backlight;            /* restore backlight to this value */
20990 +
20991 +u32 CoreClock;
20992 +u32 PWMControlRegFreq;
20993 +
20994 +/**
20995 + * LVDS I2C backlight control macros
20996 + */
20997 +#define BRIGHTNESS_MAX_LEVEL 100
20998 +#define BRIGHTNESS_MASK 0xFF
20999 +#define BLC_I2C_TYPE   0x01
21000 +#define BLC_PWM_TYPT   0x02
21001 +
21002 +#define BLC_POLARITY_NORMAL 0
21003 +#define BLC_POLARITY_INVERSE 1
21004 +
21005 +#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
21006 +#define PSB_BLC_MIN_PWM_REG_FREQ       (0x2)
21007 +#define PSB_BLC_PWM_PRECISION_FACTOR   (10)
21008 +#define PSB_BACKLIGHT_PWM_CTL_SHIFT    (16)
21009 +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
21010 +
21011 +struct psb_intel_lvds_priv {
21012 +       /**
21013 +        * Saved LVDO output states
21014 +        */
21015 +       uint32_t savePP_ON;
21016 +       uint32_t savePP_OFF;
21017 +       uint32_t saveLVDS;
21018 +       uint32_t savePP_CONTROL;
21019 +       uint32_t savePP_CYCLE;
21020 +       uint32_t savePFIT_CONTROL;
21021 +       uint32_t savePFIT_PGM_RATIOS;
21022 +       uint32_t saveBLC_PWM_CTL;
21023 +};
21024 +
21025 +/* MRST defines end */
21026 +
21027 +/**
21028 + * Returns the maximum level of the backlight duty cycle field.
21029 + */
21030 +static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
21031 +{
21032 +       struct drm_psb_private *dev_priv = dev->dev_private;
21033 +       u32 retVal;
21034 +
21035 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21036 +                                       OSPM_UHB_ONLY_IF_ON)) {
21037 +               retVal = ((REG_READ(BLC_PWM_CTL) &
21038 +                         BACKLIGHT_MODULATION_FREQ_MASK) >>
21039 +                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
21040 +
21041 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
21042 +       } else
21043 +               retVal = ((dev_priv->saveBLC_PWM_CTL &
21044 +                         BACKLIGHT_MODULATION_FREQ_MASK) >>
21045 +                         BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
21046 +
21047 +       return retVal;
21048 +}
21049 +
21050 +/**
21051 + * Set LVDS backlight level by I2C command
21052 + */
21053 +static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
21054 +                                       unsigned int level)
21055 + {
21056 +       struct drm_psb_private *dev_priv =
21057 +               (struct drm_psb_private *)dev->dev_private;
21058 +
21059 +       struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
21060 +       u8 out_buf[2];
21061 +       unsigned int blc_i2c_brightness;
21062 +
21063 +       struct i2c_msg msgs[] = {
21064 +               {
21065 +                       .addr = lvds_i2c_bus->slave_addr,
21066 +                       .flags = 0,
21067 +                       .len = 2,
21068 +                       .buf = out_buf,
21069 +               }
21070 +       };
21071 +
21072 +       blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
21073 +                            BRIGHTNESS_MASK /
21074 +                            BRIGHTNESS_MAX_LEVEL);
21075 +
21076 +       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
21077 +               blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
21078 +
21079 +       out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
21080 +       out_buf[1] = (u8)blc_i2c_brightness;
21081 +
21082 +       if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
21083 +               DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n",
21084 +                       blc_brightnesscmd,
21085 +                       blc_i2c_brightness);
21086 +               return 0;
21087 +       }
21088 +
21089 +       DRM_ERROR("I2C transfer error\n");
21090 +       return -1;
21091 +}
21092 +
21093 +
21094 +static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
21095 +{
21096 +       struct drm_psb_private *dev_priv =
21097 +                       (struct drm_psb_private *)dev->dev_private;
21098 +
21099 +       u32 max_pwm_blc;
21100 +       u32 blc_pwm_duty_cycle;
21101 +
21102 +       max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
21103 +
21104 +       /*BLC_PWM_CTL Should be initiated while backlight device init*/
21105 +       BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
21106 +
21107 +       blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
21108 +
21109 +       if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
21110 +               blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
21111 +
21112 +       blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
21113 +       REG_WRITE(BLC_PWM_CTL,
21114 +                 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
21115 +                 (blc_pwm_duty_cycle));
21116 +
21117 +       return 0;
21118 +}
21119 +
21120 +/**
21121 + * Set LVDS backlight level either by I2C or PWM
21122 + */
21123 +void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
21124 +{
21125 +       /*u32 blc_pwm_ctl;*/
21126 +       struct drm_psb_private *dev_priv =
21127 +                       (struct drm_psb_private *)dev->dev_private;
21128 +
21129 +       DRM_DEBUG("backlight level is %d\n", level);
21130 +
21131 +       if (!dev_priv->lvds_bl) {
21132 +               DRM_ERROR("NO LVDS Backlight Info\n");
21133 +               return;
21134 +       }
21135 +
21136 +       if (IS_MRST(dev)) {
21137 +               DRM_ERROR(
21138 +               "psb_intel_lvds_set_brightness called...not expected\n");
21139 +               return;
21140 +       }
21141 +
21142 +       if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
21143 +               psb_lvds_i2c_set_brightness(dev, level);
21144 +       else
21145 +               psb_lvds_pwm_set_brightness(dev, level);
21146 +}
21147 +
21148 +/**
21149 + * Sets the backlight level.
21150 + *
21151 + * \param level backlight level, from 0 to psb_intel_lvds_get_max_backlight().
21152 + */
21153 +static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
21154 +{
21155 +       struct drm_psb_private *dev_priv = dev->dev_private;
21156 +       u32 blc_pwm_ctl;
21157 +
21158 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21159 +                                       OSPM_UHB_ONLY_IF_ON)) {
21160 +               blc_pwm_ctl =
21161 +                       REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
21162 +               REG_WRITE(BLC_PWM_CTL,
21163 +                               (blc_pwm_ctl |
21164 +                               (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
21165 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
21166 +       } else {
21167 +               blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
21168 +                               ~BACKLIGHT_DUTY_CYCLE_MASK;
21169 +               dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
21170 +                                       (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
21171 +       }
21172 +}
21173 +
21174 +/**
21175 + * Sets the power state for the panel.
21176 + */
21177 +static void psb_intel_lvds_set_power(struct drm_device *dev,
21178 +                                struct psb_intel_output *output, bool on)
21179 +{
21180 +       u32 pp_status;
21181 +
21182 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21183 +                                       OSPM_UHB_FORCE_POWER_ON))
21184 +               return;
21185 +
21186 +       if (on) {
21187 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
21188 +                         POWER_TARGET_ON);
21189 +               do {
21190 +                       pp_status = REG_READ(PP_STATUS);
21191 +               } while ((pp_status & PP_ON) == 0);
21192 +
21193 +               psb_intel_lvds_set_backlight(dev,
21194 +                                        output->
21195 +                                        mode_dev->backlight_duty_cycle);
21196 +       } else {
21197 +               psb_intel_lvds_set_backlight(dev, 0);
21198 +
21199 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
21200 +                         ~POWER_TARGET_ON);
21201 +               do {
21202 +                       pp_status = REG_READ(PP_STATUS);
21203 +               } while (pp_status & PP_ON);
21204 +       }
21205 +
21206 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
21207 +}
21208 +
21209 +static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
21210 +{
21211 +       struct drm_device *dev = encoder->dev;
21212 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
21213 +
21214 +       if (mode == DRM_MODE_DPMS_ON)
21215 +               psb_intel_lvds_set_power(dev, output, true);
21216 +       else
21217 +               psb_intel_lvds_set_power(dev, output, false);
21218 +
21219 +       /* XXX: We never power down the LVDS pairs. */
21220 +}
21221 +
21222 +static void psb_intel_lvds_save(struct drm_connector *connector)
21223 +{
21224 +       struct drm_device *dev = connector->dev;
21225 +       struct drm_psb_private *dev_priv =
21226 +               (struct drm_psb_private *)dev->dev_private;
21227 +       struct psb_intel_output *psb_intel_output =
21228 +               to_psb_intel_output(connector);
21229 +       struct psb_intel_lvds_priv *lvds_priv =
21230 +               (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
21231 +
21232 +       if (IS_POULSBO(dev)) {
21233 +               lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
21234 +               lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
21235 +               lvds_priv->saveLVDS = REG_READ(LVDS);
21236 +               lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
21237 +               lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
21238 +               /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/
21239 +               lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
21240 +               lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
21241 +               lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
21242 +
21243 +               /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/
21244 +               dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
21245 +                                               BACKLIGHT_DUTY_CYCLE_MASK);
21246 +
21247 +               /*
21248 +                * If the light is off at server startup,
21249 +                * just make it full brightness
21250 +                */
21251 +               if (dev_priv->backlight_duty_cycle == 0)
21252 +                       dev_priv->backlight_duty_cycle =
21253 +                       psb_intel_lvds_get_max_backlight(dev);
21254 +
21255 +               DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
21256 +                               lvds_priv->savePP_ON,
21257 +                               lvds_priv->savePP_OFF,
21258 +                               lvds_priv->saveLVDS,
21259 +                               lvds_priv->savePP_CONTROL,
21260 +                               lvds_priv->savePP_CYCLE,
21261 +                               lvds_priv->saveBLC_PWM_CTL);
21262 +       }
21263 +}
21264 +
21265 +static void psb_intel_lvds_restore(struct drm_connector *connector)
21266 +{
21267 +       struct drm_device *dev = connector->dev;
21268 +       u32 pp_status;
21269 +
21270 +       /*struct drm_psb_private *dev_priv =
21271 +                               (struct drm_psb_private *)dev->dev_private;*/
21272 +       struct psb_intel_output *psb_intel_output =
21273 +                                       to_psb_intel_output(connector);
21274 +       struct psb_intel_lvds_priv *lvds_priv =
21275 +               (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
21276 +
21277 +       if (IS_POULSBO(dev)) {
21278 +               DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
21279 +                               lvds_priv->savePP_ON,
21280 +                               lvds_priv->savePP_OFF,
21281 +                               lvds_priv->saveLVDS,
21282 +                               lvds_priv->savePP_CONTROL,
21283 +                               lvds_priv->savePP_CYCLE,
21284 +                               lvds_priv->saveBLC_PWM_CTL);
21285 +
21286 +               REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL);
21287 +               REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL);
21288 +               REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS);
21289 +               REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON);
21290 +               REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF);
21291 +               /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/
21292 +               REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE);
21293 +               REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL);
21294 +               REG_WRITE(LVDS, lvds_priv->saveLVDS);
21295 +
21296 +               if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) {
21297 +                       REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
21298 +                               POWER_TARGET_ON);
21299 +                       do {
21300 +                               pp_status = REG_READ(PP_STATUS);
21301 +                       } while ((pp_status & PP_ON) == 0);
21302 +               } else {
21303 +                       REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
21304 +                               ~POWER_TARGET_ON);
21305 +                       do {
21306 +                               pp_status = REG_READ(PP_STATUS);
21307 +                       } while (pp_status & PP_ON);
21308 +               }
21309 +       }
21310 +}
21311 +
21312 +int psb_intel_lvds_mode_valid(struct drm_connector *connector,
21313 +                                struct drm_display_mode *mode)
21314 +{
21315 +       struct psb_intel_output *psb_intel_output =
21316 +                               to_psb_intel_output(connector);
21317 +       struct drm_display_mode *fixed_mode =
21318 +           psb_intel_output->mode_dev->panel_fixed_mode;
21319 +
21320 +#if PRINT_JLIU7
21321 +       DRM_INFO("JLIU7 enter  psb_intel_lvds_mode_valid \n");
21322 +#endif                         /* PRINT_JLIU7 */
21323 +
21324 +       /* just in case */
21325 +       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
21326 +               return MODE_NO_DBLESCAN;
21327 +
21328 +       /* just in case */
21329 +       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
21330 +               return MODE_NO_INTERLACE;
21331 +
21332 +       if (fixed_mode) {
21333 +               if (mode->hdisplay > fixed_mode->hdisplay)
21334 +                       return MODE_PANEL;
21335 +               if (mode->vdisplay > fixed_mode->vdisplay)
21336 +                       return MODE_PANEL;
21337 +       }
21338 +       return MODE_OK;
21339 +}
21340 +
21341 +bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
21342 +                                 struct drm_display_mode *mode,
21343 +                                 struct drm_display_mode *adjusted_mode)
21344 +{
21345 +       struct psb_intel_mode_device *mode_dev =
21346 +           enc_to_psb_intel_output(encoder)->mode_dev;
21347 +       struct drm_device *dev = encoder->dev;
21348 +       struct psb_intel_crtc *psb_intel_crtc =
21349 +                               to_psb_intel_crtc(encoder->crtc);
21350 +       struct drm_encoder *tmp_encoder;
21351 +
21352 +#if PRINT_JLIU7
21353 +       DRM_INFO("JLIU7 enter  psb_intel_lvds_mode_fixup \n");
21354 +#endif                         /* PRINT_JLIU7 */
21355 +
21356 +       /* Should never happen!! */
21357 +       if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
21358 +               printk(KERN_ERR
21359 +                      "Can't support LVDS/MIPI on pipe B on MRST\n");
21360 +               return false;
21361 +       } else if (!IS_MRST(dev) && !IS_I965G(dev)
21362 +                  && psb_intel_crtc->pipe == 0) {
21363 +               printk(KERN_ERR "Can't support LVDS on pipe A\n");
21364 +               return false;
21365 +       }
21366 +       /* Should never happen!! */
21367 +       list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
21368 +                           head) {
21369 +               if (tmp_encoder != encoder
21370 +                   && tmp_encoder->crtc == encoder->crtc) {
21371 +                       printk(KERN_ERR "Can't enable LVDS and another "
21372 +                              "encoder on the same pipe\n");
21373 +                       return false;
21374 +               }
21375 +       }
21376 +
21377 +       /*
21378 +        * If we have timings from the BIOS for the panel, put them in
21379 +        * to the adjusted mode.  The CRTC will be set up for this mode,
21380 +        * with the panel scaling set up to source from the H/VDisplay
21381 +        * of the original mode.
21382 +        */
21383 +       if (mode_dev->panel_fixed_mode != NULL) {
21384 +               adjusted_mode->hdisplay =
21385 +                   mode_dev->panel_fixed_mode->hdisplay;
21386 +               adjusted_mode->hsync_start =
21387 +                   mode_dev->panel_fixed_mode->hsync_start;
21388 +               adjusted_mode->hsync_end =
21389 +                   mode_dev->panel_fixed_mode->hsync_end;
21390 +               adjusted_mode->htotal = mode_dev->panel_fixed_mode->htotal;
21391 +               adjusted_mode->vdisplay =
21392 +                   mode_dev->panel_fixed_mode->vdisplay;
21393 +               adjusted_mode->vsync_start =
21394 +                   mode_dev->panel_fixed_mode->vsync_start;
21395 +               adjusted_mode->vsync_end =
21396 +                   mode_dev->panel_fixed_mode->vsync_end;
21397 +               adjusted_mode->vtotal = mode_dev->panel_fixed_mode->vtotal;
21398 +               adjusted_mode->clock = mode_dev->panel_fixed_mode->clock;
21399 +               drm_mode_set_crtcinfo(adjusted_mode,
21400 +                                     CRTC_INTERLACE_HALVE_V);
21401 +       }
21402 +
21403 +       /*
21404 +        * XXX: It would be nice to support lower refresh rates on the
21405 +        * panels to reduce power consumption, and perhaps match the
21406 +        * user's requested refresh rate.
21407 +        */
21408 +
21409 +       return true;
21410 +}
21411 +
21412 +static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
21413 +{
21414 +       struct drm_device *dev = encoder->dev;
21415 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
21416 +       struct psb_intel_mode_device *mode_dev = output->mode_dev;
21417 +
21418 +#if PRINT_JLIU7
21419 +       DRM_INFO("JLIU7 enter  psb_intel_lvds_prepare \n");
21420 +#endif                         /* PRINT_JLIU7 */
21421 +
21422 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21423 +                                       OSPM_UHB_FORCE_POWER_ON))
21424 +               return;
21425 +
21426 +       mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
21427 +       mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
21428 +                                         BACKLIGHT_DUTY_CYCLE_MASK);
21429 +
21430 +       psb_intel_lvds_set_power(dev, output, false);
21431 +
21432 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
21433 +}
21434 +
21435 +static void psb_intel_lvds_commit(struct drm_encoder *encoder)
21436 +{
21437 +       struct drm_device *dev = encoder->dev;
21438 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
21439 +       struct psb_intel_mode_device *mode_dev = output->mode_dev;
21440 +
21441 +#if PRINT_JLIU7
21442 +       DRM_INFO("JLIU7 enter  psb_intel_lvds_commit \n");
21443 +#endif                         /* PRINT_JLIU7 */
21444 +
21445 +       if (mode_dev->backlight_duty_cycle == 0)
21446 +               mode_dev->backlight_duty_cycle =
21447 +                   psb_intel_lvds_get_max_backlight(dev);
21448 +
21449 +       psb_intel_lvds_set_power(dev, output, true);
21450 +}
21451 +
21452 +static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
21453 +                               struct drm_display_mode *mode,
21454 +                               struct drm_display_mode *adjusted_mode)
21455 +{
21456 +       struct psb_intel_mode_device *mode_dev =
21457 +           enc_to_psb_intel_output(encoder)->mode_dev;
21458 +       struct drm_device *dev = encoder->dev;
21459 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(
21460 +                                                       encoder->crtc);
21461 +       u32 pfit_control;
21462 +
21463 +       /*
21464 +        * The LVDS pin pair will already have been turned on in the
21465 +        * psb_intel_crtc_mode_set since it has a large impact on the DPLL
21466 +        * settings.
21467 +        */
21468 +
21469 +       /*
21470 +        * Enable automatic panel scaling so that non-native modes fill the
21471 +        * screen.  Should be enabled before the pipe is enabled, according to
21472 +        * register description and PRM.
21473 +        */
21474 +       if (mode->hdisplay != adjusted_mode->hdisplay ||
21475 +           mode->vdisplay != adjusted_mode->vdisplay)
21476 +               pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
21477 +                               HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
21478 +                               HORIZ_INTERP_BILINEAR);
21479 +       else
21480 +               pfit_control = 0;
21481 +
21482 +       if (!IS_I965G(dev)) {
21483 +               if (mode_dev->panel_wants_dither)
21484 +                       pfit_control |= PANEL_8TO6_DITHER_ENABLE;
21485 +       } else
21486 +               pfit_control |= psb_intel_crtc->pipe << PFIT_PIPE_SHIFT;
21487 +
21488 +       REG_WRITE(PFIT_CONTROL, pfit_control);
21489 +}
21490 +
21491 +/**
21492 + * Detect the LVDS connection.
21493 + *
21494 + * This always returns CONNECTOR_STATUS_CONNECTED.
21495 + * This connector should only have
21496 + * been set up if the LVDS was actually connected anyway.
21497 + */
21498 +static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
21499 +                                                  *connector)
21500 +{
21501 +       return connector_status_connected;
21502 +}
21503 +
21504 +/**
21505 + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
21506 + */
21507 +static int psb_intel_lvds_get_modes(struct drm_connector *connector)
21508 +{
21509 +       struct drm_device *dev = connector->dev;
21510 +       struct psb_intel_output *psb_intel_output =
21511 +                                       to_psb_intel_output(connector);
21512 +       struct psb_intel_mode_device *mode_dev =
21513 +                                       psb_intel_output->mode_dev;
21514 +       int ret = 0;
21515 +
21516 +       if (!IS_MRST(dev))
21517 +               ret = psb_intel_ddc_get_modes(psb_intel_output);
21518 +
21519 +       if (ret)
21520 +               return ret;
21521 +
21522 +       /* Didn't get an EDID, so
21523 +        * Set wide sync ranges so we get all modes
21524 +        * handed to valid_mode for checking
21525 +        */
21526 +       connector->display_info.min_vfreq = 0;
21527 +       connector->display_info.max_vfreq = 200;
21528 +       connector->display_info.min_hfreq = 0;
21529 +       connector->display_info.max_hfreq = 200;
21530 +
21531 +       if (mode_dev->panel_fixed_mode != NULL) {
21532 +               struct drm_display_mode *mode =
21533 +                   drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
21534 +               drm_mode_probed_add(connector, mode);
21535 +               return 1;
21536 +       }
21537 +
21538 +       return 0;
21539 +}
21540 +
21541 +/**
21542 + * psb_intel_lvds_destroy - unregister and free LVDS structures
21543 + * @connector: connector to free
21544 + *
21545 + * Unregister the DDC bus for this connector then free the driver private
21546 + * structure.
21547 + */
21548 +void psb_intel_lvds_destroy(struct drm_connector *connector)
21549 +{
21550 +       struct psb_intel_output *psb_intel_output =
21551 +                                       to_psb_intel_output(connector);
21552 +
21553 +       if (psb_intel_output->ddc_bus)
21554 +               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
21555 +       drm_sysfs_connector_remove(connector);
21556 +       drm_connector_cleanup(connector);
21557 +       kfree(connector);
21558 +}
21559 +
21560 +int psb_intel_lvds_set_property(struct drm_connector *connector,
21561 +                                      struct drm_property *property,
21562 +                                      uint64_t value)
21563 +{
21564 +       struct drm_encoder *pEncoder = connector->encoder;
21565 +
21566 +       if (!strcmp(property->name, "scaling mode") && pEncoder) {
21567 +               struct psb_intel_crtc *pPsbCrtc =
21568 +                                       to_psb_intel_crtc(pEncoder->crtc);
21569 +               uint64_t curValue;
21570 +
21571 +               if (!pPsbCrtc)
21572 +                       goto set_prop_error;
21573 +
21574 +               switch (value) {
21575 +               case DRM_MODE_SCALE_FULLSCREEN:
21576 +                       break;
21577 +               case DRM_MODE_SCALE_CENTER:
21578 +                       break;
21579 +               case DRM_MODE_SCALE_ASPECT:
21580 +                       break;
21581 +               default:
21582 +                       goto set_prop_error;
21583 +               }
21584 +
21585 +               if (drm_connector_property_get_value(connector,
21586 +                                                    property,
21587 +                                                    &curValue))
21588 +                       goto set_prop_error;
21589 +
21590 +               if (curValue == value)
21591 +                       goto set_prop_done;
21592 +
21593 +               if (drm_connector_property_set_value(connector,
21594 +                                                       property,
21595 +                                                       value))
21596 +                       goto set_prop_error;
21597 +
21598 +               if (pPsbCrtc->saved_mode.hdisplay != 0 &&
21599 +                   pPsbCrtc->saved_mode.vdisplay != 0) {
21600 +                       if (!drm_crtc_helper_set_mode(pEncoder->crtc,
21601 +                                                     &pPsbCrtc->saved_mode,
21602 +                                                     pEncoder->crtc->x,
21603 +                                                     pEncoder->crtc->y,
21604 +                                                     pEncoder->crtc->fb))
21605 +                               goto set_prop_error;
21606 +               }
21607 +       } else if (!strcmp(property->name, "backlight") && pEncoder) {
21608 +               if (drm_connector_property_set_value(connector,
21609 +                                                       property,
21610 +                                                       value))
21611 +                       goto set_prop_error;
21612 +               else {
21613 +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
21614 +                       struct backlight_device bd;
21615 +                       bd.props.brightness = value;
21616 +                       psb_set_brightness(&bd);
21617 +#endif
21618 +               }
21619 +       }
21620 +
21621 +set_prop_done:
21622 +    return 0;
21623 +set_prop_error:
21624 +    return -1;
21625 +}
21626 +
21627 +static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
21628 +       .dpms = psb_intel_lvds_encoder_dpms,
21629 +       .mode_fixup = psb_intel_lvds_mode_fixup,
21630 +       .prepare = psb_intel_lvds_prepare,
21631 +       .mode_set = psb_intel_lvds_mode_set,
21632 +       .commit = psb_intel_lvds_commit,
21633 +};
21634 +
21635 +static const struct drm_connector_helper_funcs
21636 +    psb_intel_lvds_connector_helper_funcs = {
21637 +       .get_modes = psb_intel_lvds_get_modes,
21638 +       .mode_valid = psb_intel_lvds_mode_valid,
21639 +       .best_encoder = psb_intel_best_encoder,
21640 +};
21641 +
21642 +static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
21643 +       .dpms = drm_helper_connector_dpms,
21644 +       .save = psb_intel_lvds_save,
21645 +       .restore = psb_intel_lvds_restore,
21646 +       .detect = psb_intel_lvds_detect,
21647 +       .fill_modes = drm_helper_probe_single_connector_modes,
21648 +       .set_property = psb_intel_lvds_set_property,
21649 +       .destroy = psb_intel_lvds_destroy,
21650 +};
21651 +
21652 +
21653 +static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
21654 +{
21655 +       drm_encoder_cleanup(encoder);
21656 +}
21657 +
21658 +const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
21659 +       .destroy = psb_intel_lvds_enc_destroy,
21660 +};
21661 +
21662 +
21663 +
21664 +/**
21665 + * psb_intel_lvds_init - setup LVDS connectors on this device
21666 + * @dev: drm device
21667 + *
21668 + * Create the connector, register the LVDS DDC bus, and try to figure out what
21669 + * modes we can display on the LVDS panel (if present).
21670 + */
21671 +void psb_intel_lvds_init(struct drm_device *dev,
21672 +                    struct psb_intel_mode_device *mode_dev)
21673 +{
21674 +       struct psb_intel_output *psb_intel_output;
21675 +       struct psb_intel_lvds_priv *lvds_priv;
21676 +       struct drm_connector *connector;
21677 +       struct drm_encoder *encoder;
21678 +       struct drm_display_mode *scan;  /* *modes, *bios_mode; */
21679 +       struct drm_crtc *crtc;
21680 +       struct drm_psb_private *dev_priv =
21681 +                               (struct drm_psb_private *)dev->dev_private;
21682 +       u32 lvds;
21683 +       int pipe;
21684 +
21685 +       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
21686 +       if (!psb_intel_output)
21687 +               return;
21688 +
21689 +       lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
21690 +       if (!lvds_priv) {
21691 +               kfree(psb_intel_output);
21692 +               DRM_DEBUG("LVDS private allocation error\n");
21693 +               return;
21694 +       }
21695 +
21696 +       psb_intel_output->dev_priv = lvds_priv;
21697 +
21698 +       psb_intel_output->mode_dev = mode_dev;
21699 +       connector = &psb_intel_output->base;
21700 +       encoder = &psb_intel_output->enc;
21701 +       drm_connector_init(dev, &psb_intel_output->base,
21702 +                          &psb_intel_lvds_connector_funcs,
21703 +                          DRM_MODE_CONNECTOR_LVDS);
21704 +
21705 +       drm_encoder_init(dev, &psb_intel_output->enc,
21706 +                        &psb_intel_lvds_enc_funcs,
21707 +                        DRM_MODE_ENCODER_LVDS);
21708 +
21709 +       drm_mode_connector_attach_encoder(&psb_intel_output->base,
21710 +                                         &psb_intel_output->enc);
21711 +       psb_intel_output->type = INTEL_OUTPUT_LVDS;
21712 +
21713 +       drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
21714 +       drm_connector_helper_add(connector,
21715 +                                &psb_intel_lvds_connector_helper_funcs);
21716 +       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
21717 +       connector->interlace_allowed = false;
21718 +       connector->doublescan_allowed = false;
21719 +
21720 +       /*Attach connector properties*/
21721 +       drm_connector_attach_property(connector,
21722 +                                     dev->mode_config.scaling_mode_property,
21723 +                                     DRM_MODE_SCALE_FULLSCREEN);
21724 +       drm_connector_attach_property(connector,
21725 +                                     dev_priv->backlight_property,
21726 +                                     BRIGHTNESS_MAX_LEVEL);
21727 +
21728 +       /**
21729 +        * Set up I2C bus
21730 +        * FIXME: distroy i2c_bus when exit
21731 +        */
21732 +       psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
21733 +                                                        GPIOB,
21734 +                                                        "LVDSBLC_B");
21735 +       if (!psb_intel_output->i2c_bus) {
21736 +               dev_printk(KERN_ERR,
21737 +                       &dev->pdev->dev, "I2C bus registration failed.\n");
21738 +               goto failed_blc_i2c;
21739 +       }
21740 +       psb_intel_output->i2c_bus->slave_addr = 0x2C;
21741 +       dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
21742 +
21743 +       /*
21744 +        * LVDS discovery:
21745 +        * 1) check for EDID on DDC
21746 +        * 2) check for VBT data
21747 +        * 3) check to see if LVDS is already on
21748 +        *    if none of the above, no panel
21749 +        * 4) make sure lid is open
21750 +        *    if closed, act like it's not there for now
21751 +        */
21752 +
21753 +       /* Set up the DDC bus. */
21754 +       psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
21755 +                                                        GPIOC,
21756 +                                                        "LVDSDDC_C");
21757 +       if (!psb_intel_output->ddc_bus) {
21758 +               dev_printk(KERN_ERR, &dev->pdev->dev,
21759 +                          "DDC bus registration " "failed.\n");
21760 +               goto failed_ddc;
21761 +       }
21762 +
21763 +       /*
21764 +        * Attempt to get the fixed panel mode from DDC.  Assume that the
21765 +        * preferred mode is the right one.
21766 +        */
21767 +       psb_intel_ddc_get_modes(psb_intel_output);
21768 +       list_for_each_entry(scan, &connector->probed_modes, head) {
21769 +               if (scan->type & DRM_MODE_TYPE_PREFERRED) {
21770 +                       mode_dev->panel_fixed_mode =
21771 +                           drm_mode_duplicate(dev, scan);
21772 +                       goto out;       /* FIXME: check for quirks */
21773 +               }
21774 +       }
21775 +
21776 +       /* Failed to get EDID, what about VBT? do we need this?*/
21777 +       if (mode_dev->vbt_mode)
21778 +               mode_dev->panel_fixed_mode =
21779 +                   drm_mode_duplicate(dev, mode_dev->vbt_mode);
21780 +
21781 +       if (!mode_dev->panel_fixed_mode)
21782 +               if (dev_priv->lfp_lvds_vbt_mode)
21783 +                       mode_dev->panel_fixed_mode =
21784 +                               drm_mode_duplicate(dev,
21785 +                                       dev_priv->lfp_lvds_vbt_mode);
21786 +
21787 +       /*
21788 +        * If we didn't get EDID, try checking if the panel is already turned
21789 +        * on.  If so, assume that whatever is currently programmed is the
21790 +        * correct mode.
21791 +        */
21792 +       lvds = REG_READ(LVDS);
21793 +       pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
21794 +       crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
21795 +
21796 +       if (crtc && (lvds & LVDS_PORT_EN)) {
21797 +               mode_dev->panel_fixed_mode =
21798 +                   psb_intel_crtc_mode_get(dev, crtc);
21799 +               if (mode_dev->panel_fixed_mode) {
21800 +                       mode_dev->panel_fixed_mode->type |=
21801 +                           DRM_MODE_TYPE_PREFERRED;
21802 +                       goto out;       /* FIXME: check for quirks */
21803 +               }
21804 +       }
21805 +
21806 +       /* If we still don't have a mode after all that, give up. */
21807 +       if (!mode_dev->panel_fixed_mode) {
21808 +               DRM_DEBUG
21809 +                       ("Found no modes on the lvds, ignoring the LVDS\n");
21810 +               goto failed_find;
21811 +       }
21812 +
21813 +       /* FIXME: detect aopen & mac mini type stuff automatically? */
21814 +       /*
21815 +        * Blacklist machines with BIOSes that list an LVDS panel without
21816 +        * actually having one.
21817 +        */
21818 +       if (IS_I945GM(dev)) {
21819 +               /* aopen mini pc */
21820 +               if (dev->pdev->subsystem_vendor == 0xa0a0) {
21821 +                       DRM_DEBUG
21822 +                           ("Suspected AOpen Mini PC, ignoring the LVDS\n");
21823 +                       goto failed_find;
21824 +               }
21825 +
21826 +               if ((dev->pdev->subsystem_vendor == 0x8086) &&
21827 +                   (dev->pdev->subsystem_device == 0x7270)) {
21828 +                       /* It's a Mac Mini or Macbook Pro. */
21829 +
21830 +                       if (mode_dev->panel_fixed_mode != NULL &&
21831 +                           mode_dev->panel_fixed_mode->hdisplay == 800 &&
21832 +                           mode_dev->panel_fixed_mode->vdisplay == 600) {
21833 +                               DRM_DEBUG
21834 +                                   ("Suspected Mac Mini, ignoring the LVDS\n");
21835 +                               goto failed_find;
21836 +                       }
21837 +               }
21838 +       }
21839 +
21840 +out:
21841 +       drm_sysfs_connector_add(connector);
21842 +
21843 +#if PRINT_JLIU7
21844 +       DRM_INFO("PRINT_JLIU7 hdisplay = %d\n",
21845 +                mode_dev->panel_fixed_mode->hdisplay);
21846 +       DRM_INFO("PRINT_JLIU7 vdisplay = %d\n",
21847 +                mode_dev->panel_fixed_mode->vdisplay);
21848 +       DRM_INFO("PRINT_JLIU7 hsync_start = %d\n",
21849 +                mode_dev->panel_fixed_mode->hsync_start);
21850 +       DRM_INFO("PRINT_JLIU7 hsync_end = %d\n",
21851 +                mode_dev->panel_fixed_mode->hsync_end);
21852 +       DRM_INFO("PRINT_JLIU7 htotal = %d\n",
21853 +                mode_dev->panel_fixed_mode->htotal);
21854 +       DRM_INFO("PRINT_JLIU7 vsync_start = %d\n",
21855 +                mode_dev->panel_fixed_mode->vsync_start);
21856 +       DRM_INFO("PRINT_JLIU7 vsync_end = %d\n",
21857 +                mode_dev->panel_fixed_mode->vsync_end);
21858 +       DRM_INFO("PRINT_JLIU7 vtotal = %d\n",
21859 +                mode_dev->panel_fixed_mode->vtotal);
21860 +       DRM_INFO("PRINT_JLIU7 clock = %d\n",
21861 +                mode_dev->panel_fixed_mode->clock);
21862 +#endif                         /* PRINT_JLIU7 */
21863 +       return;
21864 +
21865 +failed_find:
21866 +       if (psb_intel_output->ddc_bus)
21867 +               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
21868 +failed_ddc:
21869 +       if (psb_intel_output->i2c_bus)
21870 +               psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
21871 +failed_blc_i2c:
21872 +       drm_encoder_cleanup(encoder);
21873 +       drm_connector_cleanup(connector);
21874 +       kfree(connector);
21875 +}
21876 +
21877 +/* MRST platform start */
21878 +
21879 +/*
21880 + * FIXME need to move to register define head file
21881 + */
21882 +#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT           (16)
21883 +#define MRST_BACKLIGHT_MODULATION_FREQ_MASK            (0xffff << 16)
21884 +
21885 +/* The max/min PWM frequency in BPCR[31:17] - */
21886 +/* The smallest number is 1 (not 0) that can fit in the
21887 + * 15-bit field of the and then*/
21888 +/* shifts to the left by one bit to get the actual 16-bit
21889 + * value that the 15-bits correspond to.*/
21890 +#define MRST_BLC_MAX_PWM_REG_FREQ          0xFFFF
21891 +
21892 +#define BRIGHTNESS_MAX_LEVEL 100
21893 +#define BLC_PWM_PRECISION_FACTOR 10    /* 10000000 */
21894 +#define BLC_PWM_FREQ_CALC_CONSTANT 32
21895 +#define MHz 1000000
21896 +#define BLC_POLARITY_NORMAL 0
21897 +#define BLC_POLARITY_INVERSE 1
21898 +
21899 +/**
21900 + * Calculate PWM control register value.
21901 + */
21902 +#if 0
21903 +static bool mrstLVDSCalculatePWMCtrlRegFreq(struct drm_device *dev)
21904 +{
21905 +       unsigned long value = 0;
21906 +       if (blc_freq == 0) {
21907 +               /* DRM_ERROR(KERN_ERR "mrstLVDSCalculatePWMCtrlRegFreq:
21908 +                * Frequency Requested is 0.\n"); */
21909 +               return false;
21910 +       }
21911 +
21912 +       value = (CoreClock * MHz);
21913 +       value = (value / BLC_PWM_FREQ_CALC_CONSTANT);
21914 +       value = (value * BLC_PWM_PRECISION_FACTOR);
21915 +       value = (value / blc_freq);
21916 +       value = (value / BLC_PWM_PRECISION_FACTOR);
21917 +
21918 +       if (value > (unsigned long) MRST_BLC_MAX_PWM_REG_FREQ) {
21919 +               return 0;
21920 +       } else {
21921 +               PWMControlRegFreq = (u32) value;
21922 +               return 1;
21923 +       }
21924 +}
21925 +#endif
21926 +/**
21927 + * Sets the power state for the panel.
21928 + */
21929 +static void mrst_lvds_set_power(struct drm_device *dev,
21930 +                               struct psb_intel_output *output, bool on)
21931 +{
21932 +       u32 pp_status;
21933 +
21934 +#if PRINT_JLIU7
21935 +       DRM_INFO("JLIU7 enter mrst_lvds_set_power \n");
21936 +#endif                         /* PRINT_JLIU7 */
21937 +
21938 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21939 +                                       OSPM_UHB_FORCE_POWER_ON))
21940 +               return;
21941 +
21942 +       if (on) {
21943 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
21944 +                         POWER_TARGET_ON);
21945 +               do {
21946 +                       pp_status = REG_READ(PP_STATUS);
21947 +               } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
21948 +       } else {
21949 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
21950 +                         ~POWER_TARGET_ON);
21951 +               do {
21952 +                       pp_status = REG_READ(PP_STATUS);
21953 +               } while (pp_status & PP_ON);
21954 +       }
21955 +
21956 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
21957 +}
21958 +
21959 +static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
21960 +{
21961 +       struct drm_device *dev = encoder->dev;
21962 +       struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
21963 +
21964 +#if PRINT_JLIU7
21965 +       DRM_INFO("JLIU7 enter mrst_lvds_dpms \n");
21966 +#endif                         /* PRINT_JLIU7 */
21967 +
21968 +       if (mode == DRM_MODE_DPMS_ON)
21969 +               mrst_lvds_set_power(dev, output, true);
21970 +       else
21971 +               mrst_lvds_set_power(dev, output, false);
21972 +
21973 +       /* XXX: We never power down the LVDS pairs. */
21974 +}
21975 +
21976 +static void mrst_lvds_mode_set(struct drm_encoder *encoder,
21977 +                              struct drm_display_mode *mode,
21978 +                              struct drm_display_mode *adjusted_mode)
21979 +{
21980 +       struct psb_intel_mode_device *mode_dev =
21981 +                               enc_to_psb_intel_output(encoder)->mode_dev;
21982 +       struct drm_device *dev = encoder->dev;
21983 +       u32 lvds_port;
21984 +       uint64_t curValue = DRM_MODE_SCALE_FULLSCREEN;
21985 +
21986 +#if PRINT_JLIU7
21987 +       DRM_INFO("JLIU7 enter  mrst_lvds_mode_set \n");
21988 +#endif                         /* PRINT_JLIU7 */
21989 +
21990 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
21991 +                                       OSPM_UHB_FORCE_POWER_ON))
21992 +               return;
21993 +
21994 +       /*
21995 +        * The LVDS pin pair will already have been turned on in the
21996 +        * psb_intel_crtc_mode_set since it has a large impact on the DPLL
21997 +        * settings.
21998 +        */
21999 +       /*FIXME JLIU7 Get panel power delay parameters from config data */
22000 +       REG_WRITE(0x61208, 0x25807d0);
22001 +       REG_WRITE(0x6120c, 0x1f407d0);
22002 +       REG_WRITE(0x61210, 0x270f04);
22003 +
22004 +       lvds_port = (REG_READ(LVDS) &
22005 +                   (~LVDS_PIPEB_SELECT)) |
22006 +                   LVDS_PORT_EN |
22007 +                   LVDS_BORDER_EN;
22008 +
22009 +       if (mode_dev->panel_wants_dither)
22010 +               lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
22011 +
22012 +       REG_WRITE(LVDS, lvds_port);
22013 +
22014 +       drm_connector_property_get_value(
22015 +                               &enc_to_psb_intel_output(encoder)->base,
22016 +                               dev->mode_config.scaling_mode_property,
22017 +                               &curValue);
22018 +
22019 +       if (curValue == DRM_MODE_SCALE_CENTER)
22020 +               REG_WRITE(PFIT_CONTROL, 0);
22021 +       else if (curValue == DRM_MODE_SCALE_ASPECT) {
22022 +               if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
22023 +                   (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
22024 +                       if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
22025 +                           (mode->hdisplay * adjusted_mode->crtc_vdisplay))
22026 +                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
22027 +                       else if ((adjusted_mode->crtc_hdisplay *
22028 +                               mode->vdisplay) > (mode->hdisplay *
22029 +                               adjusted_mode->crtc_vdisplay))
22030 +                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
22031 +                                         PFIT_SCALING_MODE_PILLARBOX);
22032 +                       else
22033 +                               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
22034 +                                         PFIT_SCALING_MODE_LETTERBOX);
22035 +               } else
22036 +                       REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
22037 +       } else /*(curValue == DRM_MODE_SCALE_FULLSCREEN)*/
22038 +               REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
22039 +
22040 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
22041 +}
22042 +
22043 +
22044 +static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
22045 +       .dpms = mrst_lvds_dpms,
22046 +       .mode_fixup = psb_intel_lvds_mode_fixup,
22047 +       .prepare = psb_intel_lvds_prepare,
22048 +       .mode_set = mrst_lvds_mode_set,
22049 +       .commit = psb_intel_lvds_commit,
22050 +};
22051 +
22052 +/** Returns the panel fixed mode from configuration. */
22053 +/** FIXME JLIU7 need to revist it. */
22054 +struct drm_display_mode *mrst_lvds_get_configuration_mode(struct drm_device
22055 +                                                         *dev)
22056 +{
22057 +       struct drm_display_mode *mode;
22058 +       struct drm_psb_private *dev_priv =
22059 +               (struct drm_psb_private *) dev->dev_private;
22060 +       struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
22061 +
22062 +       mode = kzalloc(sizeof(*mode), GFP_KERNEL);
22063 +       if (!mode)
22064 +               return NULL;
22065 +
22066 +       if (dev_priv->vbt_data.Size != 0x00) { /*if non-zero, then use vbt*/
22067 +
22068 +               mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
22069 +               mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
22070 +               mode->hsync_start = mode->hdisplay + \
22071 +                               ((ti->hsync_offset_hi << 8) | \
22072 +                               ti->hsync_offset_lo);
22073 +               mode->hsync_end = mode->hsync_start + \
22074 +                               ((ti->hsync_pulse_width_hi << 8) | \
22075 +                               ti->hsync_pulse_width_lo);
22076 +               mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
22077 +                                                       ti->hblank_lo);
22078 +               mode->vsync_start = \
22079 +                       mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
22080 +                                               ti->vsync_offset_lo);
22081 +               mode->vsync_end = \
22082 +                       mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
22083 +                                               ti->vsync_pulse_width_lo);
22084 +               mode->vtotal = mode->vdisplay + \
22085 +                               ((ti->vblank_hi << 8) | ti->vblank_lo);
22086 +               mode->clock = ti->pixel_clock * 10;
22087 +#if 0
22088 +               printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
22089 +               printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
22090 +               printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
22091 +               printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
22092 +               printk(KERN_INFO "htotal is %d\n", mode->htotal);
22093 +               printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
22094 +               printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
22095 +               printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
22096 +               printk(KERN_INFO "clock is %d\n", mode->clock);
22097 +#endif
22098 +       } else {
22099 +
22100 +#if 0                          /*FIXME jliu7 remove it later */
22101 +       /* hard coded fixed mode for TPO LTPS LPJ040K001A */
22102 +       mode->hdisplay = 800;
22103 +       mode->vdisplay = 480;
22104 +       mode->hsync_start = 836;
22105 +       mode->hsync_end = 846;
22106 +       mode->htotal = 1056;
22107 +       mode->vsync_start = 489;
22108 +       mode->vsync_end = 491;
22109 +       mode->vtotal = 525;
22110 +       mode->clock = 33264;
22111 +#endif                         /*FIXME jliu7 remove it later */
22112 +
22113 +#if 0                          /*FIXME jliu7 remove it later */
22114 +       /* hard coded fixed mode for LVDS 800x480 */
22115 +       mode->hdisplay = 800;
22116 +       mode->vdisplay = 480;
22117 +       mode->hsync_start = 801;
22118 +       mode->hsync_end = 802;
22119 +       mode->htotal = 1024;
22120 +       mode->vsync_start = 481;
22121 +       mode->vsync_end = 482;
22122 +       mode->vtotal = 525;
22123 +       mode->clock = 30994;
22124 +#endif                         /*FIXME jliu7 remove it later */
22125 +
22126 +#if 1  /*FIXME jliu7 remove it later, jliu7 modify it according to the spec*/
22127 +       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
22128 +       mode->hdisplay = 1024;
22129 +       mode->vdisplay = 600;
22130 +       mode->hsync_start = 1072;
22131 +       mode->hsync_end = 1104;
22132 +       mode->htotal = 1184;
22133 +       mode->vsync_start = 603;
22134 +       mode->vsync_end = 604;
22135 +       mode->vtotal = 608;
22136 +       mode->clock = 53990;
22137 +#endif                         /*FIXME jliu7 remove it later */
22138 +
22139 +#if 0  /*FIXME jliu7 remove it, it is copied from SBIOS */
22140 +       /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
22141 +       mode->hdisplay = 1024;
22142 +       mode->vdisplay = 600;
22143 +       mode->hsync_start = 1104;
22144 +       mode->hsync_end = 1136;
22145 +       mode->htotal = 1184;
22146 +       mode->vsync_start = 603;
22147 +       mode->vsync_end = 604;
22148 +       mode->vtotal = 608;
22149 +       mode->clock = 53990;
22150 +#endif                         /*FIXME jliu7 remove it later */
22151 +
22152 +#if 0                          /*FIXME jliu7 remove it later */
22153 +       /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
22154 +       mode->hdisplay = 1024;
22155 +       mode->vdisplay = 600;
22156 +       mode->hsync_start = 1124;
22157 +       mode->hsync_end = 1204;
22158 +       mode->htotal = 1312;
22159 +       mode->vsync_start = 607;
22160 +       mode->vsync_end = 610;
22161 +       mode->vtotal = 621;
22162 +       mode->clock = 48885;
22163 +#endif                         /*FIXME jliu7 remove it later */
22164 +
22165 +#if 0                          /*FIXME jliu7 remove it later */
22166 +       /* hard coded fixed mode for LVDS 1024x768 */
22167 +       mode->hdisplay = 1024;
22168 +       mode->vdisplay = 768;
22169 +       mode->hsync_start = 1048;
22170 +       mode->hsync_end = 1184;
22171 +       mode->htotal = 1344;
22172 +       mode->vsync_start = 771;
22173 +       mode->vsync_end = 777;
22174 +       mode->vtotal = 806;
22175 +       mode->clock = 65000;
22176 +#endif                         /*FIXME jliu7 remove it later */
22177 +
22178 +#if 0                          /*FIXME jliu7 remove it later */
22179 +       /* hard coded fixed mode for LVDS 1366x768 */
22180 +       mode->hdisplay = 1366;
22181 +       mode->vdisplay = 768;
22182 +       mode->hsync_start = 1430;
22183 +       mode->hsync_end = 1558;
22184 +       mode->htotal = 1664;
22185 +       mode->vsync_start = 769;
22186 +       mode->vsync_end = 770;
22187 +       mode->vtotal = 776;
22188 +       mode->clock = 77500;
22189 +#endif                         /*FIXME jliu7 remove it later */
22190 +       }
22191 +       drm_mode_set_name(mode);
22192 +       drm_mode_set_crtcinfo(mode, 0);
22193 +
22194 +       return mode;
22195 +}
22196 +
22197 +/**
22198 + * mrst_lvds_init - setup LVDS connectors on this device
22199 + * @dev: drm device
22200 + *
22201 + * Create the connector, register the LVDS DDC bus, and try to figure out what
22202 + * modes we can display on the LVDS panel (if present).
22203 + */
22204 +void mrst_lvds_init(struct drm_device *dev,
22205 +                   struct psb_intel_mode_device *mode_dev)
22206 +{
22207 +       struct psb_intel_output *psb_intel_output;
22208 +       struct drm_connector *connector;
22209 +       struct drm_encoder *encoder;
22210 +       struct drm_psb_private *dev_priv =
22211 +                               (struct drm_psb_private *) dev->dev_private;
22212 +       struct edid *edid;
22213 +       int ret = 0;
22214 +       struct i2c_adapter *i2c_adap;
22215 +       struct drm_display_mode *scan;  /* *modes, *bios_mode; */
22216 +
22217 +#if PRINT_JLIU7
22218 +       DRM_INFO("JLIU7 enter mrst_lvds_init \n");
22219 +#endif                         /* PRINT_JLIU7 */
22220 +
22221 +       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
22222 +       if (!psb_intel_output)
22223 +               return;
22224 +
22225 +       psb_intel_output->mode_dev = mode_dev;
22226 +       connector = &psb_intel_output->base;
22227 +       encoder = &psb_intel_output->enc;
22228 +       drm_connector_init(dev, &psb_intel_output->base,
22229 +                          &psb_intel_lvds_connector_funcs,
22230 +                          DRM_MODE_CONNECTOR_LVDS);
22231 +
22232 +       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
22233 +                        DRM_MODE_ENCODER_LVDS);
22234 +
22235 +       drm_mode_connector_attach_encoder(&psb_intel_output->base,
22236 +                                         &psb_intel_output->enc);
22237 +       psb_intel_output->type = INTEL_OUTPUT_LVDS;
22238 +
22239 +       drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
22240 +       drm_connector_helper_add(connector,
22241 +                                &psb_intel_lvds_connector_helper_funcs);
22242 +       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
22243 +       connector->interlace_allowed = false;
22244 +       connector->doublescan_allowed = false;
22245 +
22246 +       drm_connector_attach_property(connector,
22247 +                                       dev->mode_config.scaling_mode_property,
22248 +                                       DRM_MODE_SCALE_FULLSCREEN);
22249 +       drm_connector_attach_property(connector,
22250 +                                       dev_priv->backlight_property,
22251 +                                       BRIGHTNESS_MAX_LEVEL);
22252 +
22253 +       lvds_backlight = BRIGHTNESS_MAX_LEVEL;
22254 +
22255 +       mode_dev->panel_wants_dither = false;
22256 +       if (dev_priv->vbt_data.Size != 0x00)
22257 +               mode_dev->panel_wants_dither = (dev_priv->gct_data.Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
22258 +
22259 +       /*
22260 +        * LVDS discovery:
22261 +        * 1) check for EDID on DDC
22262 +        * 2) check for VBT data
22263 +        * 3) check to see if LVDS is already on
22264 +        *    if none of the above, no panel
22265 +        * 4) make sure lid is open
22266 +        *    if closed, act like it's not there for now
22267 +        */
22268 +       i2c_adap = i2c_get_adapter(2);
22269 +       if (i2c_adap == NULL)
22270 +               printk(KERN_ALERT "No ddc adapter available!\n");
22271 +       /* Set up the DDC bus. */
22272 +/*     psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
22273 +                                                        GPIOC,
22274 +                                                        "LVDSDDC_C");
22275 +       if (!psb_intel_output->ddc_bus) {
22276 +               dev_printk(KERN_ERR, &dev->pdev->dev,
22277 +                          "DDC bus registration " "failed.\n");
22278 +               goto failed_ddc;
22279 +       }*/
22280 +
22281 +       /*
22282 +        * Attempt to get the fixed panel mode from DDC.  Assume that the
22283 +        * preferred mode is the right one.
22284 +        */
22285 +       edid = drm_get_edid(connector, i2c_adap);
22286 +       if (edid) {
22287 +               drm_mode_connector_update_edid_property(connector, edid);
22288 +               ret = drm_add_edid_modes(connector, edid);
22289 +               kfree(edid);
22290 +       }
22291 +
22292 +       list_for_each_entry(scan, &connector->probed_modes, head) {
22293 +               if (scan->type & DRM_MODE_TYPE_PREFERRED) {
22294 +                       mode_dev->panel_fixed_mode =
22295 +                           drm_mode_duplicate(dev, scan);
22296 +                       goto out;       /* FIXME: check for quirks */
22297 +               }
22298 +       }
22299 +
22300 +       /*
22301 +        * If we didn't get EDID, try geting panel timing
22302 +        * from configuration data
22303 +        */
22304 +       mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
22305 +
22306 +       if (mode_dev->panel_fixed_mode) {
22307 +               mode_dev->panel_fixed_mode->type |=
22308 +                   DRM_MODE_TYPE_PREFERRED;
22309 +               goto out;       /* FIXME: check for quirks */
22310 +       }
22311 +
22312 +       /* If we still don't have a mode after all that, give up. */
22313 +       if (!mode_dev->panel_fixed_mode) {
22314 +               DRM_DEBUG
22315 +                   ("Found no modes on the lvds, ignoring the LVDS\n");
22316 +               goto failed_find;
22317 +       }
22318 +
22319 +out:
22320 +       drm_sysfs_connector_add(connector);
22321 +       return;
22322 +
22323 +failed_find:
22324 +       DRM_DEBUG("No LVDS modes found, disabling.\n");
22325 +       if (psb_intel_output->ddc_bus)
22326 +               psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
22327 +
22328 +/* failed_ddc: */
22329 +
22330 +       drm_encoder_cleanup(encoder);
22331 +       drm_connector_cleanup(connector);
22332 +       kfree(connector);
22333 +}
22334 +
22335 +/* MRST platform end */
22336 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_modes.c b/drivers/gpu/drm/mrst/drv/psb_intel_modes.c
22337 new file mode 100644
22338 index 0000000..e248aed
22339 --- /dev/null
22340 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_modes.c
22341 @@ -0,0 +1,77 @@
22342 +/*
22343 + * Copyright (c) 2007 Intel Corporation
22344 + *
22345 + * This program is free software; you can redistribute it and/or modify it
22346 + * under the terms and conditions of the GNU General Public License,
22347 + * version 2, as published by the Free Software Foundation.
22348 + *
22349 + * This program is distributed in the hope it will be useful, but WITHOUT
22350 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22351 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
22352 + * more details.
22353 + *
22354 + * You should have received a copy of the GNU General Public License along with
22355 + * this program; if not, write to the Free Software Foundation, Inc., 
22356 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22357 + *
22358 + * Authers: Jesse Barnes <jesse.barnes@intel.com>
22359 + */
22360 +
22361 +#include <linux/i2c.h>
22362 +#include <linux/fb.h>
22363 +#include <drm/drmP.h>
22364 +#include "psb_intel_drv.h"
22365 +
22366 +/**
22367 + * psb_intel_ddc_probe
22368 + *
22369 + */
22370 +bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output)
22371 +{
22372 +       u8 out_buf[] = { 0x0, 0x0 };
22373 +       u8 buf[2];
22374 +       int ret;
22375 +       struct i2c_msg msgs[] = {
22376 +               {
22377 +                .addr = 0x50,
22378 +                .flags = 0,
22379 +                .len = 1,
22380 +                .buf = out_buf,
22381 +                },
22382 +               {
22383 +                .addr = 0x50,
22384 +                .flags = I2C_M_RD,
22385 +                .len = 1,
22386 +                .buf = buf,
22387 +                }
22388 +       };
22389 +
22390 +       ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2);
22391 +       if (ret == 2)
22392 +               return true;
22393 +
22394 +       return false;
22395 +}
22396 +
22397 +/**
22398 + * psb_intel_ddc_get_modes - get modelist from monitor
22399 + * @connector: DRM connector device to use
22400 + *
22401 + * Fetch the EDID information from @connector using the DDC bus.
22402 + */
22403 +int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output)
22404 +{
22405 +       struct edid *edid;
22406 +       int ret = 0;
22407 +
22408 +       edid =
22409 +           drm_get_edid(&psb_intel_output->base,
22410 +                        &psb_intel_output->ddc_bus->adapter);
22411 +       if (edid) {
22412 +               drm_mode_connector_update_edid_property(&psb_intel_output->
22413 +                                                       base, edid);
22414 +               ret = drm_add_edid_modes(&psb_intel_output->base, edid);
22415 +               kfree(edid);
22416 +       }
22417 +       return ret;
22418 +}
22419 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_reg.h b/drivers/gpu/drm/mrst/drv/psb_intel_reg.h
22420 new file mode 100644
22421 index 0000000..d6b8921
22422 --- /dev/null
22423 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_reg.h
22424 @@ -0,0 +1,1099 @@
22425 +/*
22426 + * Copyright (c) 2009, Intel Corporation.
22427 + * 
22428 + * This program is free software; you can redistribute it and/or modify it
22429 + * under the terms and conditions of the GNU General Public License,
22430 + * version 2, as published by the Free Software Foundation.
22431 + *
22432 + * This program is distributed in the hope it will be useful, but WITHOUT
22433 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22434 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
22435 + * more details.
22436 + *
22437 + * You should have received a copy of the GNU General Public License along with
22438 + * this program; if not, write to the Free Software Foundation, Inc., 
22439 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22440 + */
22441 +
22442 +#define BLC_PWM_CTL            0x61254
22443 +#define BLC_PWM_CTL2           0x61250
22444 +#define BACKLIGHT_MODULATION_FREQ_SHIFT                (17)
22445 +/**
22446 + * This is the most significant 15 bits of the number of backlight cycles in a
22447 + * complete cycle of the modulated backlight control.
22448 + *
22449 + * The actual value is this field multiplied by two.
22450 + */
22451 +#define BACKLIGHT_MODULATION_FREQ_MASK         (0x7fff << 17)
22452 +#define BLM_LEGACY_MODE                                (1 << 16)
22453 +/**
22454 + * This is the number of cycles out of the backlight modulation cycle for which
22455 + * the backlight is on.
22456 + *
22457 + * This field must be no greater than the number of cycles in the complete
22458 + * backlight modulation cycle.
22459 + */
22460 +#define BACKLIGHT_DUTY_CYCLE_SHIFT             (0)
22461 +#define BACKLIGHT_DUTY_CYCLE_MASK              (0xffff)
22462 +
22463 +#define I915_GCFGC                     0xf0
22464 +#define I915_LOW_FREQUENCY_ENABLE              (1 << 7)
22465 +#define I915_DISPLAY_CLOCK_190_200_MHZ         (0 << 4)
22466 +#define I915_DISPLAY_CLOCK_333_MHZ             (4 << 4)
22467 +#define I915_DISPLAY_CLOCK_MASK                        (7 << 4)
22468 +
22469 +#define I855_HPLLCC                    0xc0
22470 +#define I855_CLOCK_CONTROL_MASK                        (3 << 0)
22471 +#define I855_CLOCK_133_200                     (0 << 0)
22472 +#define I855_CLOCK_100_200                     (1 << 0)
22473 +#define I855_CLOCK_100_133                     (2 << 0)
22474 +#define I855_CLOCK_166_250                     (3 << 0)
22475 +
22476 +/* I830 CRTC registers */
22477 +#define HTOTAL_A       0x60000
22478 +#define HBLANK_A       0x60004
22479 +#define HSYNC_A        0x60008
22480 +#define VTOTAL_A       0x6000c
22481 +#define VBLANK_A       0x60010
22482 +#define VSYNC_A        0x60014
22483 +#define PIPEASRC       0x6001c
22484 +#define BCLRPAT_A      0x60020
22485 +#define VSYNCSHIFT_A   0x60028
22486 +
22487 +#define HTOTAL_B       0x61000
22488 +#define HBLANK_B       0x61004
22489 +#define HSYNC_B        0x61008
22490 +#define VTOTAL_B       0x6100c
22491 +#define VBLANK_B       0x61010
22492 +#define VSYNC_B        0x61014
22493 +#define PIPEBSRC       0x6101c
22494 +#define BCLRPAT_B      0x61020
22495 +#define VSYNCSHIFT_B   0x61028
22496 +
22497 +#define PP_STATUS      0x61200
22498 +# define PP_ON                                 (1 << 31)
22499 +/**
22500 + * Indicates that all dependencies of the panel are on:
22501 + *
22502 + * - PLL enabled
22503 + * - pipe enabled
22504 + * - LVDS/DVOB/DVOC on
22505 + */
22506 +# define PP_READY                              (1 << 30)
22507 +# define PP_SEQUENCE_NONE                      (0 << 28)
22508 +# define PP_SEQUENCE_ON                                (1 << 28)
22509 +# define PP_SEQUENCE_OFF                       (2 << 28)
22510 +# define PP_SEQUENCE_MASK                      0x30000000
22511 +#define PP_CONTROL     0x61204
22512 +# define POWER_TARGET_ON                       (1 << 0)
22513 +
22514 +#define LVDSPP_ON       0x61208
22515 +#define LVDSPP_OFF      0x6120c
22516 +#define PP_CYCLE        0x61210
22517 +
22518 +#define PFIT_CONTROL   0x61230
22519 +# define PFIT_ENABLE                           (1 << 31)
22520 +# define PFIT_PIPE_MASK                                (3 << 29)
22521 +# define PFIT_PIPE_SHIFT                       29
22522 +# define PFIT_SCALING_MODE_PILLARBOX            (1 << 27)
22523 +# define PFIT_SCALING_MODE_LETTERBOX            (3 << 26)
22524 +# define VERT_INTERP_DISABLE                   (0 << 10)
22525 +# define VERT_INTERP_BILINEAR                  (1 << 10)
22526 +# define VERT_INTERP_MASK                      (3 << 10)
22527 +# define VERT_AUTO_SCALE                       (1 << 9)
22528 +# define HORIZ_INTERP_DISABLE                  (0 << 6)
22529 +# define HORIZ_INTERP_BILINEAR                 (1 << 6)
22530 +# define HORIZ_INTERP_MASK                     (3 << 6)
22531 +# define HORIZ_AUTO_SCALE                      (1 << 5)
22532 +# define PANEL_8TO6_DITHER_ENABLE              (1 << 3)
22533 +
22534 +#define PFIT_PGM_RATIOS        0x61234
22535 +# define PFIT_VERT_SCALE_MASK                  0xfff00000
22536 +# define PFIT_HORIZ_SCALE_MASK                 0x0000fff0
22537 +
22538 +#define PFIT_AUTO_RATIOS       0x61238
22539 +
22540 +
22541 +#define DPLL_A         0x06014
22542 +#define DPLL_B         0x06018
22543 +# define DPLL_VCO_ENABLE                       (1 << 31)
22544 +# define DPLL_DVO_HIGH_SPEED                   (1 << 30)
22545 +# define DPLL_SYNCLOCK_ENABLE                  (1 << 29)
22546 +# define DPLL_VGA_MODE_DIS                     (1 << 28)
22547 +# define DPLLB_MODE_DAC_SERIAL                 (1 << 26)       /* i915 */
22548 +# define DPLLB_MODE_LVDS                       (2 << 26)       /* i915 */
22549 +# define DPLL_MODE_MASK                                (3 << 26)
22550 +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10       (0 << 24)       /* i915 */
22551 +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5                (1 << 24)       /* i915 */
22552 +# define DPLLB_LVDS_P2_CLOCK_DIV_14            (0 << 24)       /* i915 */
22553 +# define DPLLB_LVDS_P2_CLOCK_DIV_7             (1 << 24)       /* i915 */
22554 +# define DPLL_P2_CLOCK_DIV_MASK                        0x03000000      /* i915 */
22555 +# define DPLL_FPA01_P1_POST_DIV_MASK           0x00ff0000      /* i915 */
22556 +/**
22557 + *  The i830 generation, in DAC/serial mode, defines p1 as two plus this
22558 + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
22559 + */
22560 +# define DPLL_FPA01_P1_POST_DIV_MASK_I830      0x001f0000
22561 +/**
22562 + * The i830 generation, in LVDS mode, defines P1 as the bit number set within
22563 + * this field (only one bit may be set).
22564 + */
22565 +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
22566 +# define DPLL_FPA01_P1_POST_DIV_SHIFT          16
22567 +# define PLL_P2_DIVIDE_BY_4            (1 << 23)       /* i830, required
22568 +                                                        * in DVO non-gang */
22569 +# define PLL_P1_DIVIDE_BY_TWO                  (1 << 21)       /* i830 */
22570 +# define PLL_REF_INPUT_DREFCLK                 (0 << 13)
22571 +# define PLL_REF_INPUT_TVCLKINA                        (1 << 13)       /* i830 */
22572 +# define PLL_REF_INPUT_TVCLKINBC               (2 << 13)       /* SDVO
22573 +                                                                * TVCLKIN */
22574 +# define PLLB_REF_INPUT_SPREADSPECTRUMIN       (3 << 13)
22575 +# define PLL_REF_INPUT_MASK                    (3 << 13)
22576 +# define PLL_LOAD_PULSE_PHASE_SHIFT            9
22577 +/*
22578 + * Parallel to Serial Load Pulse phase selection.
22579 + * Selects the phase for the 10X DPLL clock for the PCIe
22580 + * digital display port. The range is 4 to 13; 10 or more
22581 + * is just a flip delay. The default is 6
22582 + */
22583 +# define PLL_LOAD_PULSE_PHASE_MASK     (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
22584 +# define DISPLAY_RATE_SELECT_FPA1      (1 << 8)
22585 +
22586 +/**
22587 + * SDVO multiplier for 945G/GM. Not used on 965.
22588 + *
22589 + * \sa DPLL_MD_UDI_MULTIPLIER_MASK
22590 + */
22591 +# define SDVO_MULTIPLIER_MASK                  0x000000ff
22592 +# define SDVO_MULTIPLIER_SHIFT_HIRES           4
22593 +# define SDVO_MULTIPLIER_SHIFT_VGA             0
22594 +
22595 +/** @defgroup DPLL_MD
22596 + * @{
22597 + */
22598 +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
22599 +#define DPLL_A_MD              0x0601c
22600 +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
22601 +#define DPLL_B_MD              0x06020
22602 +/**
22603 + * UDI pixel divider, controlling how many pixels are stuffed into a packet.
22604 + *
22605 + * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
22606 + */
22607 +# define DPLL_MD_UDI_DIVIDER_MASK              0x3f000000
22608 +# define DPLL_MD_UDI_DIVIDER_SHIFT             24
22609 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
22610 +# define DPLL_MD_VGA_UDI_DIVIDER_MASK          0x003f0000
22611 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT         16
22612 +/**
22613 + * SDVO/UDI pixel multiplier.
22614 + *
22615 + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
22616 + * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
22617 + * modes, the bus rate would be below the limits, so SDVO allows for stuffing
22618 + * dummy bytes in the datastream at an increased clock rate, with both sides of
22619 + * the link knowing how many bytes are fill.
22620 + *
22621 + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
22622 + * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
22623 + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
22624 + * through an SDVO command.
22625 + *
22626 + * This register field has values of multiplication factor minus 1, with
22627 + * a maximum multiplier of 5 for SDVO.
22628 + */
22629 +# define DPLL_MD_UDI_MULTIPLIER_MASK           0x00003f00
22630 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT          8
22631 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
22632 + * This best be set to the default value (3) or the CRT won't work. No,
22633 + * I don't entirely understand what this does...
22634 + */
22635 +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK       0x0000003f
22636 +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT      0
22637 +/** @} */
22638 +
22639 +#define DPLL_TEST              0x606c
22640 +# define DPLLB_TEST_SDVO_DIV_1                 (0 << 22)
22641 +# define DPLLB_TEST_SDVO_DIV_2                 (1 << 22)
22642 +# define DPLLB_TEST_SDVO_DIV_4                 (2 << 22)
22643 +# define DPLLB_TEST_SDVO_DIV_MASK              (3 << 22)
22644 +# define DPLLB_TEST_N_BYPASS                   (1 << 19)
22645 +# define DPLLB_TEST_M_BYPASS                   (1 << 18)
22646 +# define DPLLB_INPUT_BUFFER_ENABLE             (1 << 16)
22647 +# define DPLLA_TEST_N_BYPASS                   (1 << 3)
22648 +# define DPLLA_TEST_M_BYPASS                   (1 << 2)
22649 +# define DPLLA_INPUT_BUFFER_ENABLE             (1 << 0)
22650 +
22651 +#define ADPA                   0x61100
22652 +#define ADPA_DAC_ENABLE        (1<<31)
22653 +#define ADPA_DAC_DISABLE       0
22654 +#define ADPA_PIPE_SELECT_MASK  (1<<30)
22655 +#define ADPA_PIPE_A_SELECT     0
22656 +#define ADPA_PIPE_B_SELECT     (1<<30)
22657 +#define ADPA_USE_VGA_HVPOLARITY (1<<15)
22658 +#define ADPA_SETS_HVPOLARITY   0
22659 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
22660 +#define ADPA_VSYNC_CNTL_ENABLE 0
22661 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
22662 +#define ADPA_HSYNC_CNTL_ENABLE 0
22663 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
22664 +#define ADPA_VSYNC_ACTIVE_LOW  0
22665 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
22666 +#define ADPA_HSYNC_ACTIVE_LOW  0
22667 +
22668 +#define FPA0           0x06040
22669 +#define FPA1           0x06044
22670 +#define FPB0           0x06048
22671 +#define FPB1           0x0604c
22672 +# define FP_N_DIV_MASK                         0x003f0000
22673 +# define FP_N_DIV_SHIFT                                16
22674 +# define FP_M1_DIV_MASK                                0x00003f00
22675 +# define FP_M1_DIV_SHIFT                       8
22676 +# define FP_M2_DIV_MASK                                0x0000003f
22677 +# define FP_M2_DIV_SHIFT                       0
22678 +
22679 +
22680 +#define PORT_HOTPLUG_EN                0x61110
22681 +# define SDVOB_HOTPLUG_INT_EN                  (1 << 26)
22682 +# define SDVOC_HOTPLUG_INT_EN                  (1 << 25)
22683 +# define TV_HOTPLUG_INT_EN                     (1 << 18)
22684 +# define CRT_HOTPLUG_INT_EN                    (1 << 9)
22685 +# define CRT_HOTPLUG_FORCE_DETECT              (1 << 3)
22686 +
22687 +#define PORT_HOTPLUG_STAT      0x61114
22688 +# define CRT_HOTPLUG_INT_STATUS                        (1 << 11)
22689 +# define TV_HOTPLUG_INT_STATUS                 (1 << 10)
22690 +# define CRT_HOTPLUG_MONITOR_MASK              (3 << 8)
22691 +# define CRT_HOTPLUG_MONITOR_COLOR             (3 << 8)
22692 +# define CRT_HOTPLUG_MONITOR_MONO              (2 << 8)
22693 +# define CRT_HOTPLUG_MONITOR_NONE              (0 << 8)
22694 +# define SDVOC_HOTPLUG_INT_STATUS              (1 << 7)
22695 +# define SDVOB_HOTPLUG_INT_STATUS              (1 << 6)
22696 +
22697 +#define SDVOB                  0x61140
22698 +#define SDVOC                  0x61160
22699 +#define SDVO_ENABLE                            (1 << 31)
22700 +#define SDVO_PIPE_B_SELECT                     (1 << 30)
22701 +#define SDVO_STALL_SELECT                      (1 << 29)
22702 +#define SDVO_INTERRUPT_ENABLE                  (1 << 26)
22703 +/**
22704 + * 915G/GM SDVO pixel multiplier.
22705 + *
22706 + * Programmed value is multiplier - 1, up to 5x.
22707 + *
22708 + * \sa DPLL_MD_UDI_MULTIPLIER_MASK
22709 + */
22710 +#define SDVO_PORT_MULTIPLY_MASK                        (7 << 23)
22711 +#define SDVO_PORT_MULTIPLY_SHIFT               23
22712 +#define SDVO_PHASE_SELECT_MASK                 (15 << 19)
22713 +#define SDVO_PHASE_SELECT_DEFAULT              (6 << 19)
22714 +#define SDVO_CLOCK_OUTPUT_INVERT               (1 << 18)
22715 +#define SDVOC_GANG_MODE                                (1 << 16)
22716 +#define SDVO_BORDER_ENABLE                     (1 << 7)
22717 +#define SDVOB_PCIE_CONCURRENCY                 (1 << 3)
22718 +#define SDVO_DETECTED                          (1 << 2)
22719 +/* Bits to be preserved when writing */
22720 +#define SDVOB_PRESERVE_MASK            ((1 << 17) | (1 << 16) | (1 << 14))
22721 +#define SDVOC_PRESERVE_MASK                    (1 << 17)
22722 +
22723 +/** @defgroup LVDS
22724 + * @{
22725 + */
22726 +/**
22727 + * This register controls the LVDS output enable, pipe selection, and data
22728 + * format selection.
22729 + *
22730 + * All of the clock/data pairs are force powered down by power sequencing.
22731 + */
22732 +#define LVDS                   0x61180
22733 +/**
22734 + * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
22735 + * the DPLL semantics change when the LVDS is assigned to that pipe.
22736 + */
22737 +# define LVDS_PORT_EN                  (1 << 31)
22738 +/** Selects pipe B for LVDS data.  Must be set on pre-965. */
22739 +# define LVDS_PIPEB_SELECT             (1 << 30)
22740 +
22741 +/** Turns on border drawing to allow centered display. */
22742 +# define LVDS_BORDER_EN                 (1 << 15)
22743 +
22744 +/**
22745 + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
22746 + * pixel.
22747 + */
22748 +# define LVDS_A0A2_CLKA_POWER_MASK     (3 << 8)
22749 +# define LVDS_A0A2_CLKA_POWER_DOWN     (0 << 8)
22750 +# define LVDS_A0A2_CLKA_POWER_UP       (3 << 8)
22751 +/**
22752 + * Controls the A3 data pair, which contains the additional LSBs for 24 bit
22753 + * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
22754 + * on.
22755 + */
22756 +# define LVDS_A3_POWER_MASK            (3 << 6)
22757 +# define LVDS_A3_POWER_DOWN            (0 << 6)
22758 +# define LVDS_A3_POWER_UP              (3 << 6)
22759 +/**
22760 + * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
22761 + * is set.
22762 + */
22763 +# define LVDS_CLKB_POWER_MASK          (3 << 4)
22764 +# define LVDS_CLKB_POWER_DOWN          (0 << 4)
22765 +# define LVDS_CLKB_POWER_UP            (3 << 4)
22766 +
22767 +/**
22768 + * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
22769 + * setting for whether we are in dual-channel mode.  The B3 pair will
22770 + * additionally only be powered up when LVDS_A3_POWER_UP is set.
22771 + */
22772 +# define LVDS_B0B3_POWER_MASK          (3 << 2)
22773 +# define LVDS_B0B3_POWER_DOWN          (0 << 2)
22774 +# define LVDS_B0B3_POWER_UP            (3 << 2)
22775 +
22776 +#define PIPEACONF 0x70008
22777 +#define PIPEACONF_ENABLE       (1<<31)
22778 +#define PIPEACONF_DISABLE      0
22779 +#define PIPEACONF_DOUBLE_WIDE  (1<<30)
22780 +#define I965_PIPECONF_ACTIVE   (1<<30)
22781 +#define PIPEACONF_SINGLE_WIDE  0
22782 +#define PIPEACONF_PIPE_UNLOCKED 0
22783 +#define PIPEACONF_PIPE_LOCKED  (1<<25)
22784 +#define PIPEACONF_PALETTE      0
22785 +#define PIPEACONF_GAMMA        (1<<24)
22786 +#define PIPECONF_FORCE_BORDER  (1<<25)
22787 +#define PIPECONF_PROGRESSIVE   (0 << 21)
22788 +#define PIPECONF_INTERLACE_W_FIELD_INDICATION  (6 << 21)
22789 +#define PIPECONF_INTERLACE_FIELD_0_ONLY                (7 << 21)
22790 +
22791 +#define PIPEBCONF 0x71008
22792 +#define PIPEBCONF_ENABLE       (1<<31)
22793 +#define PIPEBCONF_DISABLE      0
22794 +#define PIPEBCONF_DOUBLE_WIDE  (1<<30)
22795 +#define PIPEBCONF_DISABLE      0
22796 +#define PIPEBCONF_GAMMA        (1<<24)
22797 +#define PIPEBCONF_PALETTE      0
22798 +
22799 +#define PIPEBGCMAXRED          0x71010
22800 +#define PIPEBGCMAXGREEN                0x71014
22801 +#define PIPEBGCMAXBLUE         0x71018
22802 +
22803 +#define PIPEASTAT       0x70024
22804 +#define PIPEBSTAT              0x71024
22805 +#define PIPE_VBLANK_CLEAR         (1 << 1)
22806 +#define PIPE_START_VBLANK_INTERRUPT_ENABLE     (1UL<<18)
22807 +#define PIPE_VBLANK_INTERRUPT_ENABLE           (1UL<<17)
22808 +
22809 +#define PIPE_VSYNC_ENABL               (1UL<<25)
22810 +#define PIPE_VSYNC_CLEAR               (1UL<<9)
22811 +#define HISTOGRAM_INT_CONTROL          0x61268
22812 +#define HISTOGRAM_BIN_DATA             0X61264
22813 +#define HISTOGRAM_LOGIC_CONTROL                0x61260
22814 +#define PWM_CONTROL_LOGIC              0x61250
22815 +#define PIPE_DPST_EVENT_ENABLE         (1UL<<23)
22816 +#define PIPE_HOTPLUG_INTERRUPT_STATUS  (1UL<<10)
22817 +#define PIPE_DPST_EVENT_STATUS         (1UL<<7)
22818 +#define HISTOGRAM_INTERRUPT_ENABLE     (1UL<<31)
22819 +#define HISTOGRAM_LOGIC_ENABLE         (1UL<<31)
22820 +#define PWM_LOGIC_ENABLE               (1UL<<31)
22821 +#define PWM_PHASEIN_ENABLE             (1UL<<25)
22822 +#define PWM_PHASEIN_INT_ENABLE         (1UL<<24)
22823 +#define PWM_PHASEIN_VB_COUNT           0x00001f00
22824 +#define PWM_PHASEIN_INC                        0x0000001f
22825 +#define HISTOGRAM_INT_CTRL_CLEAR       (1UL<<30)
22826 +#define DPST_YUV_LUMA_MODE             0
22827 +
22828 +struct dpst_ie_histogram_control {
22829 +       union {
22830 +               uint32_t data;
22831 +               struct {
22832 +                       uint32_t bin_reg_index:7;
22833 +                       uint32_t reserved:4;
22834 +                       uint32_t bin_reg_func_select:1;
22835 +                       uint32_t sync_to_phase_in:1;
22836 +                       uint32_t alt_enhancement_mode:2;
22837 +                       uint32_t reserved1:1;
22838 +                       uint32_t sync_to_phase_in_count:8;
22839 +                       uint32_t histogram_mode_select:1;
22840 +                       uint32_t reserved2:4;
22841 +                       uint32_t ie_pipe_assignment:1;
22842 +                       uint32_t ie_mode_table_enabled:1;
22843 +                       uint32_t ie_histogram_enable:1;
22844 +               };
22845 +       };
22846 +};
22847 +
22848 +struct dpst_guardband {
22849 +       union {
22850 +               uint32_t data;
22851 +               struct {
22852 +                       uint32_t guardband:22;
22853 +                       uint32_t guardband_interrupt_delay:8;
22854 +                       uint32_t interrupt_status:1;
22855 +                       uint32_t interrupt_enable:1;
22856 +               };
22857 +       };
22858 +};
22859 +
22860 +#define PIPEAFRAMEHIGH         0x70040
22861 +#define PIPEAFRAMEPIXEL                0x70044
22862 +#define PIPEBFRAMEHIGH         0x71040
22863 +#define PIPEBFRAMEPIXEL                0x71044
22864 +#define PIPE_FRAME_HIGH_MASK    0x0000ffff
22865 +#define PIPE_FRAME_HIGH_SHIFT   0
22866 +#define PIPE_FRAME_LOW_MASK     0xff000000
22867 +#define PIPE_FRAME_LOW_SHIFT    24
22868 +#define PIPE_PIXEL_MASK         0x00ffffff
22869 +#define PIPE_PIXEL_SHIFT        0
22870 +
22871 +#define DSPARB                 0x70030
22872 +#define DSPFW1                 0x70034
22873 +#define DSPFW2                 0x70038
22874 +#define DSPFW3                 0x7003c
22875 +#define DSPFW4                 0x70050
22876 +#define DSPFW5                 0x70054
22877 +#define DSPFW6                 0x70058
22878 +#define DSPCHICKENBIT          0x70400
22879 +#define DSPACNTR               0x70180
22880 +#define DSPBCNTR               0x71180
22881 +#define DISPLAY_PLANE_ENABLE                   (1<<31)
22882 +#define DISPLAY_PLANE_DISABLE                  0
22883 +#define DISPPLANE_GAMMA_ENABLE                 (1<<30)
22884 +#define DISPPLANE_GAMMA_DISABLE                        0
22885 +#define DISPPLANE_PIXFORMAT_MASK               (0xf<<26)
22886 +#define DISPPLANE_8BPP                         (0x2<<26)
22887 +#define DISPPLANE_15_16BPP                     (0x4<<26)
22888 +#define DISPPLANE_16BPP                                (0x5<<26)
22889 +#define DISPPLANE_32BPP_NO_ALPHA               (0x6<<26)
22890 +#define DISPPLANE_32BPP                                (0x7<<26)
22891 +#define DISPPLANE_STEREO_ENABLE                        (1<<25)
22892 +#define DISPPLANE_STEREO_DISABLE               0
22893 +#define DISPPLANE_SEL_PIPE_MASK                        (1<<24)
22894 +#define DISPPLANE_SEL_PIPE_A                   0
22895 +#define DISPPLANE_SEL_PIPE_B                   (1<<24)
22896 +#define DISPPLANE_SRC_KEY_ENABLE               (1<<22)
22897 +#define DISPPLANE_SRC_KEY_DISABLE              0
22898 +#define DISPPLANE_LINE_DOUBLE                  (1<<20)
22899 +#define DISPPLANE_NO_LINE_DOUBLE               0
22900 +#define DISPPLANE_STEREO_POLARITY_FIRST                0
22901 +#define DISPPLANE_STEREO_POLARITY_SECOND       (1<<18)
22902 +/* plane B only */
22903 +#define DISPPLANE_ALPHA_TRANS_ENABLE           (1<<15)
22904 +#define DISPPLANE_ALPHA_TRANS_DISABLE          0
22905 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA                0
22906 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY         (1)
22907 +
22908 +#define DSPABASE               0x70184
22909 +#define DSPALINOFF             0x70184
22910 +#define DSPASTRIDE             0x70188
22911 +
22912 +#define DSPBBASE               0x71184
22913 +#define DSPBLINOFF             0X71184
22914 +#define DSPBADDR               DSPBBASE
22915 +#define DSPBSTRIDE             0x71188
22916 +
22917 +#define DSPAKEYVAL             0x70194
22918 +#define DSPAKEYMASK            0x70198
22919 +
22920 +#define DSPAPOS                        0x7018C /* reserved */
22921 +#define DSPASIZE               0x70190
22922 +#define DSPBPOS                        0x7118C
22923 +#define DSPBSIZE               0x71190
22924 +
22925 +#define DSPASURF               0x7019C
22926 +#define DSPATILEOFF            0x701A4
22927 +
22928 +#define DSPBSURF               0x7119C
22929 +#define DSPBTILEOFF            0x711A4
22930 +
22931 +/* plane C only */
22932 +#define DSPCCNTR               0x72180
22933 +#define DSPCLINOFF             0x72184
22934 +#define DSPCSTRIDE             0x72188
22935 +#define DSPCPOS                0x7218C
22936 +#define DSPCSIZE               0x72190
22937 +#define DSPCSURF               0x7219C
22938 +#define DSPCKEYMAXVAL  0x721A0
22939 +#define DSPCKEYMINVAL  0x72194
22940 +#define DSPCKEYMSK             0x72198
22941 +
22942 +#define VGACNTRL               0x71400
22943 +# define VGA_DISP_DISABLE                      (1 << 31)
22944 +# define VGA_2X_MODE                           (1 << 30)
22945 +# define VGA_PIPE_B_SELECT                     (1 << 29)
22946 +
22947 +/*
22948 + * Overlay registers
22949 + */
22950 +#define OV_OVADD               0x30000
22951 +#define OV_OGAMC5              0x30010
22952 +#define OV_OGAMC4              0x30014
22953 +#define OV_OGAMC3              0x30018
22954 +#define OV_OGAMC2              0x3001C
22955 +#define OV_OGAMC1              0x30020
22956 +#define OV_OGAMC0              0x30024
22957 +
22958 +/*
22959 + * Some BIOS scratch area registers.  The 845 (and 830?) store the amount
22960 + * of video memory available to the BIOS in SWF1.
22961 + */
22962 +
22963 +#define SWF0                   0x71410
22964 +#define SWF1                   0x71414
22965 +#define SWF2                   0x71418
22966 +#define SWF3                   0x7141c
22967 +#define SWF4                   0x71420
22968 +#define SWF5                   0x71424
22969 +#define SWF6                   0x71428
22970 +
22971 +/*
22972 + * 855 scratch registers.
22973 + */
22974 +#define SWF00                  0x70410
22975 +#define SWF01                  0x70414
22976 +#define SWF02                  0x70418
22977 +#define SWF03                  0x7041c
22978 +#define SWF04                  0x70420
22979 +#define SWF05                  0x70424
22980 +#define SWF06                  0x70428
22981 +
22982 +#define SWF10                  SWF0
22983 +#define SWF11                  SWF1
22984 +#define SWF12                  SWF2
22985 +#define SWF13                  SWF3
22986 +#define SWF14                  SWF4
22987 +#define SWF15                  SWF5
22988 +#define SWF16                  SWF6
22989 +
22990 +#define SWF30                  0x72414
22991 +#define SWF31                  0x72418
22992 +#define SWF32                  0x7241c
22993 +
22994 +
22995 +/*
22996 + * Palette registers
22997 + */
22998 +#define PALETTE_A              0x0a000
22999 +#define PALETTE_B              0x0a800
23000 +
23001 +#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC)
23002 +#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG)
23003 +#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
23004 +#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
23005 +#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG)
23006 +
23007 +
23008 +/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G) */
23009 +#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)
23010 +#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG)
23011 +#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG)
23012 +#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG)
23013 +
23014 +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
23015 +                      (dev)->pci_device == 0x2982 || \
23016 +                      (dev)->pci_device == 0x2992 || \
23017 +                      (dev)->pci_device == 0x29A2 || \
23018 +                      (dev)->pci_device == 0x2A02 || \
23019 +                      (dev)->pci_device == 0x2A12)
23020 +
23021 +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
23022 +
23023 +#define IS_G33(dev)    ((dev)->pci_device == 0x29C2 || \
23024 +                       (dev)->pci_device == 0x29B2 ||  \
23025 +                       (dev)->pci_device == 0x29D2)
23026 +
23027 +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
23028 +                     IS_I945GM(dev) || IS_I965G(dev) || IS_POULSBO(dev) || \
23029 +                     IS_MRST(dev))
23030 +
23031 +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
23032 +                       IS_I945GM(dev) || IS_I965GM(dev) || \
23033 +                       IS_POULSBO(dev) || IS_MRST(dev))
23034 +
23035 +/* Cursor A & B regs */
23036 +#define CURACNTR               0x70080
23037 +#define   CURSOR_MODE_DISABLE   0x00
23038 +#define   CURSOR_MODE_64_32B_AX 0x07
23039 +#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
23040 +#define   MCURSOR_GAMMA_ENABLE  (1 << 26)
23041 +#define CURABASE               0x70084
23042 +#define CURAPOS                        0x70088
23043 +#define   CURSOR_POS_MASK       0x007FF
23044 +#define   CURSOR_POS_SIGN       0x8000
23045 +#define   CURSOR_X_SHIFT        0
23046 +#define   CURSOR_Y_SHIFT        16
23047 +#define CURBCNTR               0x700c0
23048 +#define CURBBASE               0x700c4
23049 +#define CURBPOS                        0x700c8
23050 +
23051 +/*
23052 + * Interrupt Registers
23053 + */
23054 +#define IER 0x020a0
23055 +#define IIR 0x020a4
23056 +#define IMR 0x020a8
23057 +#define ISR 0x020ac
23058 +
23059 +/*
23060 + * MOORESTOWN delta registers
23061 + */
23062 +#define MRST_DPLL_A            0x0f014
23063 +#define DPLLA_MODE_LVDS                        (2 << 26)       /* mrst */
23064 +#define MRST_FPA0              0x0f040
23065 +#define MRST_FPA1              0x0f044
23066 +#define MRST_PERF_MODE         0x020f4
23067 +
23068 +/* #define LVDS                        0x61180 */
23069 +# define MRST_PANEL_8TO6_DITHER_ENABLE         (1 << 25)
23070 +# define MRST_PANEL_24_DOT_1_FORMAT            (1 << 24)
23071 +# define LVDS_A3_POWER_UP_0_OUTPUT             (1 << 6)
23072 +
23073 +#define MIPI                   0x61190
23074 +# define MIPI_PORT_EN                  (1 << 31)
23075 +/** Turns on border drawing to allow centered display. */
23076 +# define MIPI_BORDER_EN                        (1 << 15)
23077 +
23078 +/* #define PP_CONTROL  0x61204 */
23079 +# define POWER_DOWN_ON_RESET           (1 << 1)
23080 +
23081 +/* #define PFIT_CONTROL        0x61230 */
23082 +# define PFIT_PIPE_SELECT                              (3 << 29)
23083 +# define PFIT_PIPE_SELECT_SHIFT                        (29)
23084 +
23085 +/* #define BLC_PWM_CTL         0x61254 */
23086 +#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT           (16)
23087 +#define MRST_BACKLIGHT_MODULATION_FREQ_MASK            (0xffff << 16)
23088 +
23089 +/* #define PIPEACONF 0x70008 */
23090 +#define PIPEACONF_PIPE_STATE   (1<<30)
23091 +/* #define DSPACNTR            0x70180 */
23092 +#if 0                          /*FIXME JLIU7 need to define the following */
23093 +1000 = 32 - bit RGBX(10 : 10 : 10 : 2)
23094 +pixel format.Ignore alpha.1010 = BGRX 10 : 10 : 10 : 2 1100 = 64 - bit RGBX
23095 +(16 : 16 : 16 : 16) 16 bit floating point pixel format.
23096 +Ignore alpha.1110 = 32 - bit RGBX(8 : 8 : 8 : 8) pixel format.
23097 +    Ignore
23098 +    alpha.
23099 +#endif                         /*FIXME JLIU7 need to define the following */
23100 +
23101 +#define MRST_DSPABASE          0x7019c
23102 +
23103 +/*
23104 + * MOORESTOWN reserved registers
23105 + */
23106 +#if 0
23107 +#define DSPAPOS                        0x7018C /* reserved */
23108 +#define DSPASIZE               0x70190
23109 +#endif
23110 +/*
23111 + * Moorestown registers.
23112 + */
23113 +/*===========================================================================
23114 +; General Constants
23115 +;--------------------------------------------------------------------------*/
23116 +#define BIT0  0x00000001
23117 +#define BIT1  0x00000002
23118 +#define BIT2  0x00000004
23119 +#define BIT3  0x00000008
23120 +#define BIT4  0x00000010
23121 +#define BIT5  0x00000020
23122 +#define BIT6  0x00000040
23123 +#define BIT7  0x00000080
23124 +#define BIT8  0x00000100
23125 +#define BIT9  0x00000200
23126 +#define BIT10 0x00000400
23127 +#define BIT11 0x00000800
23128 +#define BIT12 0x00001000
23129 +#define BIT13 0x00002000
23130 +#define BIT14 0x00004000
23131 +#define BIT15 0x00008000
23132 +#define BIT16 0x00010000
23133 +#define BIT17 0x00020000
23134 +#define BIT18 0x00040000
23135 +#define BIT19 0x00080000
23136 +#define BIT20 0x00100000
23137 +#define BIT21 0x00200000
23138 +#define BIT22 0x00400000
23139 +#define BIT23 0x00800000
23140 +#define BIT24 0x01000000
23141 +#define BIT25 0x02000000
23142 +#define BIT26 0x04000000
23143 +#define BIT27 0x08000000
23144 +#define BIT28 0x10000000
23145 +#define BIT29 0x20000000
23146 +#define BIT30 0x40000000
23147 +#define BIT31 0x80000000
23148 +/*===========================================================================
23149 +; MIPI IP registers
23150 +;--------------------------------------------------------------------------*/
23151 +#define DEVICE_READY_REG             0xb000
23152 +#define INTR_STAT_REG                0xb004
23153 +#define RX_SOT_ERROR BIT0
23154 +#define RX_SOT_SYNC_ERROR BIT1
23155 +#define RX_ESCAPE_MODE_ENTRY_ERROR BIT3
23156 +#define RX_LP_TX_SYNC_ERROR BIT4
23157 +#define RX_HS_RECEIVE_TIMEOUT_ERROR BIT5
23158 +#define RX_FALSE_CONTROL_ERROR BIT6
23159 +#define RX_ECC_SINGLE_BIT_ERROR BIT7
23160 +#define RX_ECC_MULTI_BIT_ERROR BIT8
23161 +#define RX_CHECKSUM_ERROR BIT9
23162 +#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT10
23163 +#define RX_DSI_VC_ID_INVALID BIT11
23164 +#define TX_FALSE_CONTROL_ERROR BIT12
23165 +#define TX_ECC_SINGLE_BIT_ERROR BIT13
23166 +#define TX_ECC_MULTI_BIT_ERROR BIT14
23167 +#define TX_CHECKSUM_ERROR BIT15
23168 +#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT16
23169 +#define TX_DSI_VC_ID_INVALID BIT17
23170 +#define HIGH_CONTENTION BIT18
23171 +#define LOW_CONTENTION BIT19
23172 +#define DPI_FIFO_UNDER_RUN BIT20
23173 +#define HS_TX_TIMEOUT BIT21
23174 +#define LP_RX_TIMEOUT BIT22
23175 +#define TURN_AROUND_ACK_TIMEOUT BIT23
23176 +#define ACK_WITH_NO_ERROR BIT24
23177 +#define INTR_EN_REG                  0xb008
23178 +#define DSI_FUNC_PRG_REG             0xb00c
23179 +#define DPI_CHANNEL_NUMBER_POS   0x03
23180 +#define DBI_CHANNEL_NUMBER_POS   0x05
23181 +#define FMT_DPI_POS              0x07
23182 +#define FMT_DBI_POS              0x0A
23183 +#define DBI_DATA_WIDTH_POS       0x0D
23184 +#define HS_TX_TIMEOUT_REG            0xb010
23185 +#define LP_RX_TIMEOUT_REG            0xb014
23186 +#define TURN_AROUND_TIMEOUT_REG      0xb018
23187 +#define DEVICE_RESET_REG             0xb01C
23188 +#define DPI_RESOLUTION_REG           0xb020
23189 +#define RES_V_POS                0x10
23190 +#define DBI_RESOLUTION_REG           0xb024
23191 +#define HORIZ_SYNC_PAD_COUNT_REG     0xb028
23192 +#define HORIZ_BACK_PORCH_COUNT_REG   0xb02C
23193 +#define HORIZ_FRONT_PORCH_COUNT_REG  0xb030
23194 +#define HORIZ_ACTIVE_AREA_COUNT_REG  0xb034
23195 +#define VERT_SYNC_PAD_COUNT_REG      0xb038
23196 +#define VERT_BACK_PORCH_COUNT_REG    0xb03c
23197 +#define VERT_FRONT_PORCH_COUNT_REG   0xb040
23198 +#define HIGH_LOW_SWITCH_COUNT_REG    0xb044
23199 +#define DPI_CONTROL_REG              0xb048
23200 +#define DPI_SHUT_DOWN            BIT0
23201 +#define DPI_TURN_ON              BIT1
23202 +#define DPI_COLOR_MODE_ON        BIT2
23203 +#define DPI_COLOR_MODE_OFF       BIT3
23204 +#define DPI_BACK_LIGHT_ON        BIT4
23205 +#define DPI_BACK_LIGHT_OFF       BIT5
23206 +#define DPI_LP                   BIT6
23207 +#define DPI_DATA_REG                 0xb04c
23208 +#define DPI_BACK_LIGHT_ON_DATA   0x07
23209 +#define DPI_BACK_LIGHT_OFF_DATA  0x17
23210 +#define INIT_COUNT_REG               0xb050
23211 +#define MAX_RET_PAK_REG              0xb054
23212 +#define VIDEO_FMT_REG                0xb058
23213 +#define EOT_DISABLE_REG              0xb05c
23214 +#define LP_BYTECLK_REG               0xb060
23215 +#define LP_GEN_DATA_REG              0xb064
23216 +#define HS_GEN_DATA_REG              0xb068
23217 +#define LP_GEN_CTRL_REG              0xb06C
23218 +#define HS_GEN_CTRL_REG              0xb070
23219 +#define GEN_FIFO_STAT_REG            0xb074
23220 +#define HS_DATA_FIFO_FULL        BIT0
23221 +#define HS_DATA_FIFO_HALF_EMPTY  BIT1
23222 +#define HS_DATA_FIFO_EMPTY       BIT2
23223 +#define LP_DATA_FIFO_FULL        BIT8
23224 +#define LP_DATA_FIFO_HALF_EMPTY  BIT9
23225 +#define LP_DATA_FIFO_EMPTY       BIT10
23226 +#define HS_CTRL_FIFO_FULL        BIT16
23227 +#define HS_CTRL_FIFO_HALF_EMPTY  BIT17
23228 +#define HS_CTRL_FIFO_EMPTY       BIT18
23229 +#define LP_CTRL_FIFO_FULL        BIT24
23230 +#define LP_CTRL_FIFO_HALF_EMPTY  BIT25
23231 +#define LP_CTRL_FIFO_EMPTY       BIT26
23232 +#define DBI_FIFO_EMPTY         BIT27
23233 +#define DPI_FIFO_EMPTY         BIT28
23234 +#define HS_LS_DBI_ENABLE_REG           0xb078
23235 +#define TXCLKESC_REG                   0xb07c
23236 +#define DPHY_PARAM_REG                 0xb080
23237 +/*===========================================================================
23238 +; MIPI Adapter registers
23239 +;--------------------------------------------------------------------------*/
23240 +#define MIPI_CONTROL_REG             0xb104
23241 +#define MIPI_2X_CLOCK_BITS       (BIT0 | BIT1)
23242 +#define MIPI_DATA_ADDRESS_REG        0xb108
23243 +#define MIPI_DATA_LENGTH_REG         0xb10C
23244 +#define MIPI_COMMAND_ADDRESS_REG     0xb110
23245 +#define MIPI_COMMAND_LENGTH_REG      0xb114
23246 +#define MIPI_READ_DATA_RETURN_REG0   0xb118
23247 +#define MIPI_READ_DATA_RETURN_REG1   0xb11C
23248 +#define MIPI_READ_DATA_RETURN_REG2   0xb120
23249 +#define MIPI_READ_DATA_RETURN_REG3   0xb124
23250 +#define MIPI_READ_DATA_RETURN_REG4   0xb128
23251 +#define MIPI_READ_DATA_RETURN_REG5   0xb12C
23252 +#define MIPI_READ_DATA_RETURN_REG6   0xb130
23253 +#define MIPI_READ_DATA_RETURN_REG7   0xb134
23254 +#define MIPI_READ_DATA_VALID_REG     0xb138
23255 +/* DBI COMMANDS */
23256 +#define soft_reset                   0x01
23257 +/* ************************************************************************* *\
23258 +The display module performs a software reset.
23259 +Registers are written with their SW Reset default values.
23260 +\* ************************************************************************* */
23261 +#define get_power_mode               0x0a
23262 +/* ************************************************************************* *\
23263 +The display module returns the current power mode
23264 +\* ************************************************************************* */
23265 +#define get_address_mode             0x0b
23266 +/* ************************************************************************* *\
23267 +The display module returns the current status.
23268 +\* ************************************************************************* */
23269 +#define get_pixel_format             0x0c
23270 +/* ************************************************************************* *\
23271 +This command gets the pixel format for the RGB image data
23272 +used by the interface.
23273 +\* ************************************************************************* */
23274 +#define get_display_mode             0x0d
23275 +/* ************************************************************************* *\
23276 +The display module returns the Display Image Mode status.
23277 +\* ************************************************************************* */
23278 +#define get_signal_mode              0x0e
23279 +/* ************************************************************************* *\
23280 +The display module returns the Display Signal Mode.
23281 +\* ************************************************************************* */
23282 +#define get_diagnostic_result        0x0f
23283 +/* ************************************************************************* *\
23284 +The display module returns the self-diagnostic results following
23285 +a Sleep Out command.
23286 +\* ************************************************************************* */
23287 +#define enter_sleep_mode             0x10
23288 +/* ************************************************************************* *\
23289 +This command causes the display module to enter the Sleep mode.
23290 +In this mode, all unnecessary blocks inside the display module are disabled
23291 +except interface communication. This is the lowest power mode
23292 +the display module supports.
23293 +\* ************************************************************************* */
23294 +#define exit_sleep_mode              0x11
23295 +/* ************************************************************************* *\
23296 +This command causes the display module to exit Sleep mode.
23297 +All blocks inside the display module are enabled.
23298 +\* ************************************************************************* */
23299 +#define enter_partial_mode           0x12
23300 +/* ************************************************************************* *\
23301 +This command causes the display module to enter the Partial Display Mode.
23302 +The Partial Display Mode window is described by the set_partial_area command.
23303 +\* ************************************************************************* */
23304 +#define enter_normal_mode            0x13
23305 +/* ************************************************************************* *\
23306 +This command causes the display module to enter the Normal mode.
23307 +Normal Mode is defined as Partial Display mode and Scroll mode are off
23308 +\* ************************************************************************* */
23309 +#define exit_invert_mode             0x20
23310 +/* ************************************************************************* *\
23311 +This command causes the display module to stop inverting the image data on
23312 +the display device. The frame memory contents remain unchanged.
23313 +No status bits are changed.
23314 +\* ************************************************************************* */
23315 +#define enter_invert_mode            0x21
23316 +/* ************************************************************************* *\
23317 +This command causes the display module to invert the image data only on
23318 +the display device. The frame memory contents remain unchanged.
23319 +No status bits are changed.
23320 +\* ************************************************************************* */
23321 +#define set_gamma_curve              0x26
23322 +/* ************************************************************************* *\
23323 +This command selects the desired gamma curve for the display device.
23324 +Four fixed gamma curves are defined in section DCS spec.
23325 +\* ************************************************************************* */
23326 +#define set_display_off              0x28
23327 +/* ************************************************************************* *\
23328 +This command causes the display module to stop displaying the image data
23329 +on the display device. The frame memory contents remain unchanged.
23330 +No status bits are changed.
23331 +\* ************************************************************************* */
23332 +#define set_display_on               0x29
23333 +/* ************************************************************************* *\
23334 +This command causes the display module to start displaying the image data
23335 +on the display device. The frame memory contents remain unchanged.
23336 +No status bits are changed.
23337 +\* ************************************************************************* */
23338 +#define set_column_address           0x2a
23339 +/* ************************************************************************* *\
23340 +This command defines the column extent of the frame memory accessed by the
23341 +hostprocessor with the read_memory_continue and write_memory_continue commands.
23342 +No status bits are changed.
23343 +\* ************************************************************************* */
23344 +#define set_page_address             0x2b
23345 +/* ************************************************************************* *\
23346 +This command defines the page extent of the frame memory accessed by the host
23347 +processor with the write_memory_continue and read_memory_continue command.
23348 +No status bits are changed.
23349 +\* ************************************************************************* */
23350 +#define write_mem_start              0x2c
23351 +/* ************************************************************************* *\
23352 +This command transfers image data from the host processor to the display
23353 +module s frame memory starting at the pixel location specified by
23354 +preceding set_column_address and set_page_address commands.
23355 +\* ************************************************************************* */
23356 +#define set_partial_area             0x30
23357 +/* ************************************************************************* *\
23358 +This command defines the Partial Display mode s display area.
23359 +There are two parameters associated with
23360 +this command, the first defines the Start Row (SR) and the second the End Row
23361 +(ER). SR and ER refer to the Frame Memory Line Pointer.
23362 +\* ************************************************************************* */
23363 +#define set_scroll_area              0x33
23364 +/* ************************************************************************* *\
23365 +This command defines the display modules Vertical Scrolling Area.
23366 +\* ************************************************************************* */
23367 +#define set_tear_off                 0x34
23368 +/* ************************************************************************* *\
23369 +This command turns off the display modules Tearing Effect output signal on
23370 +the TE signal line.
23371 +\* ************************************************************************* */
23372 +#define set_tear_on                  0x35
23373 +/* ************************************************************************* *\
23374 +This command turns on the display modules Tearing Effect output signal
23375 +on the TE signal line.
23376 +\* ************************************************************************* */
23377 +#define set_address_mode             0x36
23378 +/* ************************************************************************* *\
23379 +This command sets the data order for transfers from the host processor to
23380 +display modules frame memory,bits B[7:5] and B3, and from the display
23381 +modules frame memory to the display device, bits B[2:0] and B4.
23382 +\* ************************************************************************* */
23383 +#define set_scroll_start             0x37
23384 +/* ************************************************************************* *\
23385 +This command sets the start of the vertical scrolling area in the frame memory.
23386 +The vertical scrolling area is fully defined when this command is used with
23387 +the set_scroll_area command The set_scroll_start command has one parameter,
23388 +the Vertical Scroll Pointer. The VSP defines the line in the frame memory
23389 +that is written to the display device as the first line of the vertical
23390 +scroll area.
23391 +\* ************************************************************************* */
23392 +#define exit_idle_mode               0x38
23393 +/* ************************************************************************* *\
23394 +This command causes the display module to exit Idle mode.
23395 +\* ************************************************************************* */
23396 +#define enter_idle_mode              0x39
23397 +/* ************************************************************************* *\
23398 +This command causes the display module to enter Idle Mode.
23399 +In Idle Mode, color expression is reduced. Colors are shown on the display
23400 +device using the MSB of each of the R, G and B color components in the frame
23401 +memory
23402 +\* ************************************************************************* */
23403 +#define set_pixel_format             0x3a
23404 +/* ************************************************************************* *\
23405 +This command sets the pixel format for the RGB image data used by the interface.
23406 +Bits D[6:4]  DPI Pixel Format Definition
23407 +Bits D[2:0]  DBI Pixel Format Definition
23408 +Bits D7 and D3 are not used.
23409 +\* ************************************************************************* */
23410 +#define write_mem_cont               0x3c
23411 +/* ************************************************************************* *\
23412 +This command transfers image data from the host processor to the display
23413 +module's frame memory continuing from the pixel location following the
23414 +previous write_memory_continue or write_memory_start command.
23415 +\* ************************************************************************* */
23416 +#define set_tear_scanline            0x44
23417 +/* ************************************************************************* *\
23418 +This command turns on the display modules Tearing Effect output signal on the
23419 +TE signal line when the display module reaches line N.
23420 +\* ************************************************************************* */
23421 +#define get_scanline                 0x45
23422 +/* ************************************************************************* *\
23423 +The display module returns the current scanline, N, used to update the
23424 +display device. The total number of scanlines on a display device is
23425 +defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as
23426 +the first line of V Sync and is denoted as Line 0.
23427 +When in Sleep Mode, the value returned by get_scanline is undefined.
23428 +\* ************************************************************************* */
23429 +/* DCS Interface Pixel Formats */
23430 +#define DCS_PIXEL_FORMAT_3BPP         0x1
23431 +#define DCS_PIXEL_FORMAT_8BPP         0x2
23432 +#define DCS_PIXEL_FORMAT_12BPP        0x3
23433 +#define DCS_PIXEL_FORMAT_16BPP        0x5
23434 +#define DCS_PIXEL_FORMAT_18BPP        0x6
23435 +#define DCS_PIXEL_FORMAT_24BPP        0x7
23436 +/* ONE PARAMETER READ DATA */
23437 +#define addr_mode_data           0xfc
23438 +#define diag_res_data            0x00
23439 +#define disp_mode_data           0x23
23440 +#define pxl_fmt_data             0x77
23441 +#define pwr_mode_data            0x74
23442 +#define sig_mode_data            0x00
23443 +/* TWO PARAMETERS READ DATA */
23444 +#define scanline_data1           0xff
23445 +#define scanline_data2           0xff
23446 +/* DPI PIXEL FORMATS */
23447 +#define RGB_565_FMT                 0x01       /* RGB 565 FORMAT */
23448 +#define RGB_666_FMT                 0x02       /* RGB 666 FORMAT */
23449 +#define LRGB_666_FMT                0x03       /* RGB LOOSELY PACKED
23450 +                                                * 666 FORMAT
23451 +                                                */
23452 +#define RGB_888_FMT                 0x04       /* RGB 888 FORMAT */
23453 +#define NON_BURST_MODE_SYNC_PULSE      0x01    /* Non Burst Mode
23454 +                                                * with Sync Pulse
23455 +                                                */
23456 +#define NON_BURST_MODE_SYNC_EVENTS     0x02    /* Non Burst Mode
23457 +                                                * with Sync events
23458 +                                                */
23459 +#define BURST_MODE                     0x03    /* Burst Mode */
23460 +#define VIRTUAL_CHANNEL_NUMBER_0       0x00    /* Virtual channel 0 */
23461 +#define VIRTUAL_CHANNEL_NUMBER_1       0x01    /* Virtual channel 1 */
23462 +#define VIRTUAL_CHANNEL_NUMBER_2       0x02    /* Virtual channel 2 */
23463 +#define VIRTUAL_CHANNEL_NUMBER_3       0x03    /* Virtual channel 3 */
23464 +#define DBI_NOT_SUPPORTED              0x00    /* command mode
23465 +                                                * is not supported
23466 +                                                */
23467 +#define DBI_DATA_WIDTH_16BIT           0x01    /* 16 bit data */
23468 +#define DBI_DATA_WIDTH_9BIT                    0x02    /* 9 bit data */
23469 +#define DBI_DATA_WIDTH_8BIT                    0x03    /* 8 bit data */
23470 +#define DBI_COMMAND_BUFFER_SIZE                0x120   /* Allocate at least
23471 +                                                * 0x100 Byte with 32
23472 +                                                * byte alignment
23473 +                                                */
23474 +#define DBI_DATA_BUFFER_SIZE           0x120   /* Allocate at least
23475 +                                                * 0x100 Byte with 32
23476 +                                                * byte alignment
23477 +                                                */
23478 +#define ALIGNMENT_32BYTE_MASK          (~(BIT0|BIT1|BIT2|BIT3|BIT4))
23479 +#define SKU_83                                                 0x01
23480 +#define SKU_100                                        0x02
23481 +#define SKU_100L                                       0x04
23482 +#define SKU_BYPASS                                     0x08
23483 +#if 0
23484 +/* ************************************************************************* *\
23485 +DSI command data structure
23486 +\* ************************************************************************* */
23487 +union DSI_LONG_PACKET_HEADER {
23488 +       u32 DSI_longPacketHeader;
23489 +       struct {
23490 +               u8 dataID;
23491 +               u16 wordCount;
23492 +               u8 ECC;
23493 +       };
23494 +#if 0                          /*FIXME JLIU7 */
23495 +       struct {
23496 +               u8 DT:6;
23497 +               u8 VC:2;
23498 +       };
23499 +#endif                         /*FIXME JLIU7 */
23500 +};
23501 +
23502 +union MIPI_ADPT_CMD_LNG_REG {
23503 +       u32 commnadLengthReg;
23504 +       struct {
23505 +               u8 command0;
23506 +               u8 command1;
23507 +               u8 command2;
23508 +               u8 command3;
23509 +       };
23510 +};
23511 +
23512 +struct SET_COLUMN_ADDRESS_DATA {
23513 +       u8 command;
23514 +       u16 SC;                 /* Start Column */
23515 +       u16 EC;                 /* End Column */
23516 +};
23517 +
23518 +struct SET_PAGE_ADDRESS_DATA {
23519 +       u8 command;
23520 +       u16 SP;                 /* Start Page */
23521 +       u16 EP;                 /* End Page */
23522 +};
23523 +#endif
23524 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_sdvo.c b/drivers/gpu/drm/mrst/drv/psb_intel_sdvo.c
23525 new file mode 100644
23526 index 0000000..87696ed
23527 --- /dev/null
23528 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_sdvo.c
23529 @@ -0,0 +1,1408 @@
23530 +/*
23531 + * Copyright (c) 2006-2007 Intel Corporation
23532 + *
23533 + * This program is free software; you can redistribute it and/or modify it
23534 + * under the terms and conditions of the GNU General Public License,
23535 + * version 2, as published by the Free Software Foundation.
23536 + *
23537 + * This program is distributed in the hope it will be useful, but WITHOUT
23538 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23539 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
23540 + * more details.
23541 + *
23542 + * You should have received a copy of the GNU General Public License along with
23543 + * this program; if not, write to the Free Software Foundation, Inc., 
23544 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23545 + *
23546 + * Authors:
23547 + *     Eric Anholt <eric@anholt.net>
23548 + */
23549 +
23550 +#include <linux/i2c.h>
23551 +#include <linux/delay.h>
23552 +/* #include <drm/drm_crtc.h> */
23553 +#include <drm/drmP.h>
23554 +#include "psb_drv.h"
23555 +#include "psb_intel_drv.h"
23556 +#include "psb_intel_reg.h"
23557 +#include "psb_intel_sdvo_regs.h"
23558 +
23559 +struct psb_intel_sdvo_priv {
23560 +       struct psb_intel_i2c_chan *i2c_bus;
23561 +       int slaveaddr;
23562 +       int output_device;
23563 +
23564 +       u16 active_outputs;
23565 +
23566 +       struct psb_intel_sdvo_caps caps;
23567 +       int pixel_clock_min, pixel_clock_max;
23568 +
23569 +       int save_sdvo_mult;
23570 +       u16 save_active_outputs;
23571 +       struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
23572 +       struct psb_intel_sdvo_dtd save_output_dtd[16];
23573 +       u32 save_SDVOX;
23574 +       u8 in_out_map[4];
23575 +
23576 +       u8 by_input_wiring;
23577 +       u32 active_device;
23578 +};
23579 +
23580 +/**
23581 + * Writes the SDVOB or SDVOC with the given value, but always writes both
23582 + * SDVOB and SDVOC to work around apparent hardware issues (according to
23583 + * comments in the BIOS).
23584 + */
23585 +void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output,
23586 +                               u32 val)
23587 +{
23588 +       struct drm_device *dev = psb_intel_output->base.dev;
23589 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
23590 +       u32 bval = val, cval = val;
23591 +       int i;
23592 +
23593 +       if (sdvo_priv->output_device == SDVOB)
23594 +               cval = REG_READ(SDVOC);
23595 +       else
23596 +               bval = REG_READ(SDVOB);
23597 +       /*
23598 +        * Write the registers twice for luck. Sometimes,
23599 +        * writing them only once doesn't appear to 'stick'.
23600 +        * The BIOS does this too. Yay, magic
23601 +        */
23602 +       for (i = 0; i < 2; i++) {
23603 +               REG_WRITE(SDVOB, bval);
23604 +               REG_READ(SDVOB);
23605 +               REG_WRITE(SDVOC, cval);
23606 +               REG_READ(SDVOC);
23607 +       }
23608 +}
23609 +
23610 +static bool psb_intel_sdvo_read_byte(
23611 +                               struct psb_intel_output *psb_intel_output,
23612 +                               u8 addr, u8 *ch)
23613 +{
23614 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
23615 +       u8 out_buf[2];
23616 +       u8 buf[2];
23617 +       int ret;
23618 +
23619 +       struct i2c_msg msgs[] = {
23620 +               {
23621 +                .addr = sdvo_priv->i2c_bus->slave_addr,
23622 +                .flags = 0,
23623 +                .len = 1,
23624 +                .buf = out_buf,
23625 +                },
23626 +               {
23627 +                .addr = sdvo_priv->i2c_bus->slave_addr,
23628 +                .flags = I2C_M_RD,
23629 +                .len = 1,
23630 +                .buf = buf,
23631 +                }
23632 +       };
23633 +
23634 +       out_buf[0] = addr;
23635 +       out_buf[1] = 0;
23636 +
23637 +       ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
23638 +       if (ret == 2) {
23639 +               /* DRM_DEBUG("got back from addr %02X = %02x\n",
23640 +                * out_buf[0], buf[0]);
23641 +                */
23642 +               *ch = buf[0];
23643 +               return true;
23644 +       }
23645 +
23646 +       DRM_DEBUG("i2c transfer returned %d\n", ret);
23647 +       return false;
23648 +}
23649 +
23650 +static bool psb_intel_sdvo_write_byte(
23651 +                       struct psb_intel_output *psb_intel_output,
23652 +                       int addr, u8 ch)
23653 +{
23654 +       u8 out_buf[2];
23655 +       struct i2c_msg msgs[] = {
23656 +               {
23657 +                .addr = psb_intel_output->i2c_bus->slave_addr,
23658 +                .flags = 0,
23659 +                .len = 2,
23660 +                .buf = out_buf,
23661 +                }
23662 +       };
23663 +
23664 +       out_buf[0] = addr;
23665 +       out_buf[1] = ch;
23666 +
23667 +       if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1)
23668 +               return true;
23669 +       return false;
23670 +}
23671 +
23672 +#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
23673 +/** Mapping of command numbers to names, for debug output */
23674 +const static struct _sdvo_cmd_name {
23675 +       u8 cmd;
23676 +       char *name;
23677 +} sdvo_cmd_names[] = {
23678 +SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
23679 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
23680 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
23681 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
23682 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
23683 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
23684 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
23685 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
23686 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
23687 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
23688 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
23689 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
23690 +           SDVO_CMD_NAME_ENTRY
23691 +           (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
23692 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
23693 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
23694 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
23695 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
23696 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
23697 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
23698 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
23699 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
23700 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
23701 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
23702 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
23703 +           SDVO_CMD_NAME_ENTRY
23704 +           (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
23705 +           SDVO_CMD_NAME_ENTRY
23706 +           (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
23707 +           SDVO_CMD_NAME_ENTRY
23708 +           (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
23709 +           SDVO_CMD_NAME_ENTRY
23710 +           (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
23711 +           SDVO_CMD_NAME_ENTRY
23712 +           (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
23713 +           SDVO_CMD_NAME_ENTRY
23714 +           (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
23715 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
23716 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
23717 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
23718 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
23719 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
23720 +           SDVO_CMD_NAME_ENTRY
23721 +           (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
23722 +           SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),};
23723 +
23724 +#define SDVO_NAME(dev_priv) \
23725 +                ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
23726 +#define SDVO_PRIV(output)   ((struct psb_intel_sdvo_priv *) (output)->dev_priv)
23727 +
23728 +static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
23729 +                                    u8 cmd,
23730 +                                    void *args,
23731 +                                    int args_len)
23732 +{
23733 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
23734 +       int i;
23735 +
23736 +       if (1) {
23737 +               DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
23738 +               for (i = 0; i < args_len; i++)
23739 +                       printk(KERN_INFO"%02X ", ((u8 *) args)[i]);
23740 +               for (; i < 8; i++)
23741 +                       printk("   ");
23742 +               for (i = 0;
23743 +                    i <
23744 +                    sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
23745 +                    i++) {
23746 +                       if (cmd == sdvo_cmd_names[i].cmd) {
23747 +                               printk("(%s)", sdvo_cmd_names[i].name);
23748 +                               break;
23749 +                       }
23750 +               }
23751 +               if (i ==
23752 +                   sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
23753 +                       printk("(%02X)", cmd);
23754 +               printk("\n");
23755 +       }
23756 +
23757 +       for (i = 0; i < args_len; i++) {
23758 +               psb_intel_sdvo_write_byte(psb_intel_output,
23759 +                                       SDVO_I2C_ARG_0 - i,
23760 +                                       ((u8 *) args)[i]);
23761 +       }
23762 +
23763 +       psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd);
23764 +}
23765 +
23766 +static const char *cmd_status_names[] = {
23767 +       "Power on",
23768 +       "Success",
23769 +       "Not supported",
23770 +       "Invalid arg",
23771 +       "Pending",
23772 +       "Target not specified",
23773 +       "Scaling not supported"
23774 +};
23775 +
23776 +static u8 psb_intel_sdvo_read_response(
23777 +                               struct psb_intel_output *psb_intel_output,
23778 +                               void *response, int response_len)
23779 +{
23780 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
23781 +       int i;
23782 +       u8 status;
23783 +       u8 retry = 50;
23784 +
23785 +       while (retry--) {
23786 +               /* Read the command response */
23787 +               for (i = 0; i < response_len; i++) {
23788 +                       psb_intel_sdvo_read_byte(psb_intel_output,
23789 +                                            SDVO_I2C_RETURN_0 + i,
23790 +                                            &((u8 *) response)[i]);
23791 +               }
23792 +
23793 +               /* read the return status */
23794 +               psb_intel_sdvo_read_byte(psb_intel_output,
23795 +                                        SDVO_I2C_CMD_STATUS,
23796 +                                        &status);
23797 +
23798 +               if (1) {
23799 +                       DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
23800 +                       for (i = 0; i < response_len; i++)
23801 +                               printk(KERN_INFO"%02X ", ((u8 *) response)[i]);
23802 +                       for (; i < 8; i++)
23803 +                               printk("   ");
23804 +                       if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
23805 +                               printk(KERN_INFO"(%s)",
23806 +                                        cmd_status_names[status]);
23807 +                       else
23808 +                               printk(KERN_INFO"(??? %d)", status);
23809 +                       printk("\n");
23810 +               }
23811 +
23812 +               if (status != SDVO_CMD_STATUS_PENDING)
23813 +                       return status;
23814 +
23815 +               mdelay(50);
23816 +       }
23817 +
23818 +       return status;
23819 +}
23820 +
23821 +int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
23822 +{
23823 +       if (mode->clock >= 100000)
23824 +               return 1;
23825 +       else if (mode->clock >= 50000)
23826 +               return 2;
23827 +       else
23828 +               return 4;
23829 +}
23830 +
23831 +/**
23832 + * Don't check status code from this as it switches the bus back to the
23833 + * SDVO chips which defeats the purpose of doing a bus switch in the first
23834 + * place.
23835 + */
23836 +void psb_intel_sdvo_set_control_bus_switch(
23837 +                               struct psb_intel_output *psb_intel_output,
23838 +                               u8 target)
23839 +{
23840 +       psb_intel_sdvo_write_cmd(psb_intel_output,
23841 +                                SDVO_CMD_SET_CONTROL_BUS_SWITCH,
23842 +                                &target,
23843 +                                1);
23844 +}
23845 +
23846 +static bool psb_intel_sdvo_set_target_input(
23847 +                               struct psb_intel_output *psb_intel_output,
23848 +                               bool target_0, bool target_1)
23849 +{
23850 +       struct psb_intel_sdvo_set_target_input_args targets = { 0 };
23851 +       u8 status;
23852 +
23853 +       if (target_0 && target_1)
23854 +               return SDVO_CMD_STATUS_NOTSUPP;
23855 +
23856 +       if (target_1)
23857 +               targets.target_1 = 1;
23858 +
23859 +       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT,
23860 +                            &targets, sizeof(targets));
23861 +
23862 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
23863 +
23864 +       return status == SDVO_CMD_STATUS_SUCCESS;
23865 +}
23866 +
23867 +/**
23868 + * Return whether each input is trained.
23869 + *
23870 + * This function is making an assumption about the layout of the response,
23871 + * which should be checked against the docs.
23872 + */
23873 +static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output
23874 +                                         *psb_intel_output, bool *input_1,
23875 +                                         bool *input_2)
23876 +{
23877 +       struct psb_intel_sdvo_get_trained_inputs_response response;
23878 +       u8 status;
23879 +
23880 +       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS,
23881 +                            NULL, 0);
23882 +       status =
23883 +           psb_intel_sdvo_read_response(psb_intel_output, &response,
23884 +                                    sizeof(response));
23885 +       if (status != SDVO_CMD_STATUS_SUCCESS)
23886 +               return false;
23887 +
23888 +       *input_1 = response.input0_trained;
23889 +       *input_2 = response.input1_trained;
23890 +       return true;
23891 +}
23892 +
23893 +static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output
23894 +                                         *psb_intel_output, u16 *outputs)
23895 +{
23896 +       u8 status;
23897 +
23898 +       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS,
23899 +                            NULL, 0);
23900 +       status =
23901 +           psb_intel_sdvo_read_response(psb_intel_output, outputs,
23902 +                                    sizeof(*outputs));
23903 +
23904 +       return status == SDVO_CMD_STATUS_SUCCESS;
23905 +}
23906 +
23907 +static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output
23908 +                                         *psb_intel_output, u16 outputs)
23909 +{
23910 +       u8 status;
23911 +
23912 +       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS,
23913 +                            &outputs, sizeof(outputs));
23914 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
23915 +       return status == SDVO_CMD_STATUS_SUCCESS;
23916 +}
23917 +
23918 +static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output
23919 +                                              *psb_intel_output, int mode)
23920 +{
23921 +       u8 status, state = SDVO_ENCODER_STATE_ON;
23922 +
23923 +       switch (mode) {
23924 +       case DRM_MODE_DPMS_ON:
23925 +               state = SDVO_ENCODER_STATE_ON;
23926 +               break;
23927 +       case DRM_MODE_DPMS_STANDBY:
23928 +               state = SDVO_ENCODER_STATE_STANDBY;
23929 +               break;
23930 +       case DRM_MODE_DPMS_SUSPEND:
23931 +               state = SDVO_ENCODER_STATE_SUSPEND;
23932 +               break;
23933 +       case DRM_MODE_DPMS_OFF:
23934 +               state = SDVO_ENCODER_STATE_OFF;
23935 +               break;
23936 +       }
23937 +
23938 +       psb_intel_sdvo_write_cmd(psb_intel_output,
23939 +                            SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
23940 +                            sizeof(state));
23941 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
23942 +
23943 +       return status == SDVO_CMD_STATUS_SUCCESS;
23944 +}
23945 +
23946 +static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output
23947 +                                                  *psb_intel_output,
23948 +                                                  int *clock_min,
23949 +                                                  int *clock_max)
23950 +{
23951 +       struct psb_intel_sdvo_pixel_clock_range clocks;
23952 +       u8 status;
23953 +
23954 +       psb_intel_sdvo_write_cmd(psb_intel_output,
23955 +                            SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL,
23956 +                            0);
23957 +
23958 +       status =
23959 +           psb_intel_sdvo_read_response(psb_intel_output, &clocks,
23960 +                                    sizeof(clocks));
23961 +
23962 +       if (status != SDVO_CMD_STATUS_SUCCESS)
23963 +               return false;
23964 +
23965 +       /* Convert the values from units of 10 kHz to kHz. */
23966 +       *clock_min = clocks.min * 10;
23967 +       *clock_max = clocks.max * 10;
23968 +
23969 +       return true;
23970 +}
23971 +
23972 +static bool psb_intel_sdvo_set_target_output(
23973 +                               struct psb_intel_output *psb_intel_output,
23974 +                               u16 outputs)
23975 +{
23976 +       u8 status;
23977 +
23978 +       psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT,
23979 +                            &outputs, sizeof(outputs));
23980 +
23981 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
23982 +       return status == SDVO_CMD_STATUS_SUCCESS;
23983 +}
23984 +
23985 +static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output,
23986 +                                 u8 cmd, struct psb_intel_sdvo_dtd *dtd)
23987 +{
23988 +       u8 status;
23989 +
23990 +       psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0);
23991 +       status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
23992 +                                         sizeof(dtd->part1));
23993 +       if (status != SDVO_CMD_STATUS_SUCCESS)
23994 +               return false;
23995 +
23996 +       psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0);
23997 +       status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
23998 +                                         sizeof(dtd->part2));
23999 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24000 +               return false;
24001 +
24002 +       return true;
24003 +}
24004 +
24005 +static bool psb_intel_sdvo_get_input_timing(
24006 +                               struct psb_intel_output *psb_intel_output,
24007 +                               struct psb_intel_sdvo_dtd *dtd)
24008 +{
24009 +       return psb_intel_sdvo_get_timing(psb_intel_output,
24010 +                                    SDVO_CMD_GET_INPUT_TIMINGS_PART1,
24011 +                                    dtd);
24012 +}
24013 +#if 0
24014 +static bool psb_intel_sdvo_get_output_timing(
24015 +                               struct psb_intel_output *psb_intel_output,
24016 +                               struct psb_intel_sdvo_dtd *dtd)
24017 +{
24018 +       return psb_intel_sdvo_get_timing(psb_intel_output,
24019 +                                    SDVO_CMD_GET_OUTPUT_TIMINGS_PART1,
24020 +                                    dtd);
24021 +}
24022 +#endif
24023 +static bool psb_intel_sdvo_set_timing(
24024 +                               struct psb_intel_output *psb_intel_output,
24025 +                               u8 cmd,
24026 +                               struct psb_intel_sdvo_dtd *dtd)
24027 +{
24028 +       u8 status;
24029 +
24030 +       psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1,
24031 +                            sizeof(dtd->part1));
24032 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
24033 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24034 +               return false;
24035 +
24036 +       psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2,
24037 +                            sizeof(dtd->part2));
24038 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
24039 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24040 +               return false;
24041 +
24042 +       return true;
24043 +}
24044 +
24045 +static bool psb_intel_sdvo_set_input_timing(
24046 +                               struct psb_intel_output *psb_intel_output,
24047 +                               struct psb_intel_sdvo_dtd *dtd)
24048 +{
24049 +       return psb_intel_sdvo_set_timing(psb_intel_output,
24050 +                                    SDVO_CMD_SET_INPUT_TIMINGS_PART1,
24051 +                                    dtd);
24052 +}
24053 +
24054 +static bool psb_intel_sdvo_set_output_timing(
24055 +                               struct psb_intel_output *psb_intel_output,
24056 +                               struct psb_intel_sdvo_dtd *dtd)
24057 +{
24058 +       return psb_intel_sdvo_set_timing(psb_intel_output,
24059 +                                    SDVO_CMD_SET_OUTPUT_TIMINGS_PART1,
24060 +                                    dtd);
24061 +}
24062 +
24063 +#if 0
24064 +static bool psb_intel_sdvo_get_preferred_input_timing(struct psb_intel_output
24065 +                                                 *psb_intel_output,
24066 +                                                 struct psb_intel_sdvo_dtd
24067 +                                                 *dtd)
24068 +{
24069 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24070 +       u8 status;
24071 +
24072 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24073 +                            SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
24074 +                            NULL, 0);
24075 +
24076 +       status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
24077 +                                         sizeof(dtd->part1));
24078 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24079 +               return false;
24080 +
24081 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24082 +                            SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
24083 +                            NULL, 0);
24084 +       status =
24085 +           psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
24086 +                                    sizeof(dtd->part2));
24087 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24088 +               return false;
24089 +
24090 +       return true;
24091 +}
24092 +#endif
24093 +
24094 +static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output
24095 +                                               *psb_intel_output)
24096 +{
24097 +       u8 response, status;
24098 +
24099 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24100 +                                SDVO_CMD_GET_CLOCK_RATE_MULT,
24101 +                                NULL,
24102 +                                0);
24103 +
24104 +       status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1);
24105 +
24106 +       if (status != SDVO_CMD_STATUS_SUCCESS) {
24107 +               DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
24108 +               return SDVO_CLOCK_RATE_MULT_1X;
24109 +       } else {
24110 +               DRM_DEBUG("Current clock rate multiplier: %d\n", response);
24111 +       }
24112 +
24113 +       return response;
24114 +}
24115 +
24116 +static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output
24117 +                                               *psb_intel_output, u8 val)
24118 +{
24119 +       u8 status;
24120 +
24121 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24122 +                               SDVO_CMD_SET_CLOCK_RATE_MULT,
24123 +                               &val,
24124 +                               1);
24125 +
24126 +       status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
24127 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24128 +               return false;
24129 +
24130 +       return true;
24131 +}
24132 +
24133 +static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output,
24134 +                                         u32 in0outputmask,
24135 +                                         u32 in1outputmask)
24136 +{
24137 +       u8 byArgs[4];
24138 +       u8 status;
24139 +       int i;
24140 +       struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
24141 +
24142 +       /* Make all fields of the  args/ret to zero */
24143 +       memset(byArgs, 0, sizeof(byArgs));
24144 +
24145 +       /* Fill up the arguement values; */
24146 +       byArgs[0] = (u8) (in0outputmask & 0xFF);
24147 +       byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF);
24148 +       byArgs[2] = (u8) (in1outputmask & 0xFF);
24149 +       byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF);
24150 +
24151 +
24152 +       /*save inoutmap arg here*/
24153 +       for (i = 0; i < 4; i++)
24154 +               sdvo_priv->in_out_map[i] = byArgs[0];
24155 +
24156 +       psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4);
24157 +       status = psb_intel_sdvo_read_response(output, NULL, 0);
24158 +
24159 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24160 +               return false;
24161 +       return true;
24162 +}
24163 +
24164 +
24165 +static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output)
24166 +{
24167 +       u32 dwCurrentSDVOIn0 = 0;
24168 +       u32 dwCurrentSDVOIn1 = 0;
24169 +       u32 dwDevMask = 0;
24170 +
24171 +
24172 +       struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
24173 +
24174 +       /* Please DO NOT change the following code. */
24175 +       /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */
24176 +       /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */
24177 +       if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) {
24178 +               switch (sdvo_priv->active_device) {
24179 +               case SDVO_DEVICE_LVDS:
24180 +                       dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
24181 +                       break;
24182 +               case SDVO_DEVICE_TMDS:
24183 +                       dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
24184 +                       break;
24185 +               case SDVO_DEVICE_TV:
24186 +                       dwDevMask =
24187 +                       SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
24188 +                       SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
24189 +                       SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
24190 +                       SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
24191 +                       break;
24192 +               case SDVO_DEVICE_CRT:
24193 +                       dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
24194 +                       break;
24195 +               }
24196 +               dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask);
24197 +       } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) {
24198 +               switch (sdvo_priv->active_device) {
24199 +               case SDVO_DEVICE_LVDS:
24200 +                       dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
24201 +                       break;
24202 +               case SDVO_DEVICE_TMDS:
24203 +                       dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
24204 +                       break;
24205 +               case SDVO_DEVICE_TV:
24206 +                       dwDevMask =
24207 +                       SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
24208 +                       SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
24209 +                       SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
24210 +                       SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
24211 +                       break;
24212 +               case SDVO_DEVICE_CRT:
24213 +                       dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
24214 +                       break;
24215 +               }
24216 +               dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask);
24217 +       }
24218 +
24219 +       psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0,
24220 +                                         dwCurrentSDVOIn1);
24221 +}
24222 +
24223 +
24224 +static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
24225 +                                 struct drm_display_mode *mode,
24226 +                                 struct drm_display_mode *adjusted_mode)
24227 +{
24228 +       /* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
24229 +        * device will be told of the multiplier during mode_set.
24230 +        */
24231 +       adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode);
24232 +       return true;
24233 +}
24234 +
24235 +static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
24236 +                               struct drm_display_mode *mode,
24237 +                               struct drm_display_mode *adjusted_mode)
24238 +{
24239 +       struct drm_device *dev = encoder->dev;
24240 +       struct drm_crtc *crtc = encoder->crtc;
24241 +       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
24242 +       struct psb_intel_output *psb_intel_output =
24243 +                                       enc_to_psb_intel_output(encoder);
24244 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24245 +       u16 width, height;
24246 +       u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
24247 +       u16 h_sync_offset, v_sync_offset;
24248 +       u32 sdvox;
24249 +       struct psb_intel_sdvo_dtd output_dtd;
24250 +       int sdvo_pixel_multiply;
24251 +
24252 +       if (!mode)
24253 +               return;
24254 +
24255 +       psb_intel_sdvo_set_target_output(psb_intel_output, 0);
24256 +
24257 +       width = mode->crtc_hdisplay;
24258 +       height = mode->crtc_vdisplay;
24259 +
24260 +       /* do some mode translations */
24261 +       h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
24262 +       h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
24263 +
24264 +       v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
24265 +       v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
24266 +
24267 +       h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
24268 +       v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
24269 +
24270 +       output_dtd.part1.clock = mode->clock / 10;
24271 +       output_dtd.part1.h_active = width & 0xff;
24272 +       output_dtd.part1.h_blank = h_blank_len & 0xff;
24273 +       output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
24274 +           ((h_blank_len >> 8) & 0xf);
24275 +       output_dtd.part1.v_active = height & 0xff;
24276 +       output_dtd.part1.v_blank = v_blank_len & 0xff;
24277 +       output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
24278 +           ((v_blank_len >> 8) & 0xf);
24279 +
24280 +       output_dtd.part2.h_sync_off = h_sync_offset;
24281 +       output_dtd.part2.h_sync_width = h_sync_len & 0xff;
24282 +       output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
24283 +           (v_sync_len & 0xf);
24284 +       output_dtd.part2.sync_off_width_high =
24285 +           ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) |
24286 +           ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4);
24287 +
24288 +       output_dtd.part2.dtd_flags = 0x18;
24289 +       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
24290 +               output_dtd.part2.dtd_flags |= 0x2;
24291 +       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
24292 +               output_dtd.part2.dtd_flags |= 0x4;
24293 +
24294 +       output_dtd.part2.sdvo_flags = 0;
24295 +       output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
24296 +       output_dtd.part2.reserved = 0;
24297 +
24298 +       /* Set the output timing to the screen */
24299 +       psb_intel_sdvo_set_target_output(psb_intel_output,
24300 +                                    sdvo_priv->active_outputs);
24301 +
24302 +       /* Set the input timing to the screen. Assume always input 0. */
24303 +       psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
24304 +
24305 +       psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd);
24306 +
24307 +       /* We would like to use i830_sdvo_create_preferred_input_timing() to
24308 +        * provide the device with a timing it can support, if it supports that
24309 +        * feature.  However, presumably we would need to adjust the CRTC to
24310 +        * output the preferred timing, and we don't support that currently.
24311 +        */
24312 +#if 0
24313 +       success =
24314 +           psb_intel_sdvo_create_preferred_input_timing(psb_intel_output,
24315 +                                                        clock,
24316 +                                                        width,
24317 +                                                        height);
24318 +       if (success) {
24319 +               struct psb_intel_sdvo_dtd *input_dtd;
24320 +
24321 +               psb_intel_sdvo_get_preferred_input_timing(psb_intel_output,
24322 +                                                     &input_dtd);
24323 +               psb_intel_sdvo_set_input_timing(psb_intel_output, &input_dtd);
24324 +       }
24325 +#else
24326 +       psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd);
24327 +#endif
24328 +
24329 +       switch (psb_intel_sdvo_get_pixel_multiplier(mode)) {
24330 +       case 1:
24331 +               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
24332 +                                              SDVO_CLOCK_RATE_MULT_1X);
24333 +               break;
24334 +       case 2:
24335 +               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
24336 +                                              SDVO_CLOCK_RATE_MULT_2X);
24337 +               break;
24338 +       case 4:
24339 +               psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
24340 +                                              SDVO_CLOCK_RATE_MULT_4X);
24341 +               break;
24342 +       }
24343 +
24344 +       /* Set the SDVO control regs. */
24345 +       if (0 /*IS_I965GM(dev) */) {
24346 +               sdvox = SDVO_BORDER_ENABLE;
24347 +       } else {
24348 +               sdvox = REG_READ(sdvo_priv->output_device);
24349 +               switch (sdvo_priv->output_device) {
24350 +               case SDVOB:
24351 +                       sdvox &= SDVOB_PRESERVE_MASK;
24352 +                       break;
24353 +               case SDVOC:
24354 +                       sdvox &= SDVOC_PRESERVE_MASK;
24355 +                       break;
24356 +               }
24357 +               sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
24358 +       }
24359 +       if (psb_intel_crtc->pipe == 1)
24360 +               sdvox |= SDVO_PIPE_B_SELECT;
24361 +
24362 +       sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode);
24363 +
24364 +#if 0
24365 +       if (IS_I965G(dev)) {
24366 +               /* done in crtc_mode_set as the dpll_md reg must be written
24367 +                * early */
24368 +       } else if (IS_I945G(dev) || IS_I945GM(dev)) {
24369 +               /* done in crtc_mode_set as it lives inside the
24370 +                * dpll register */
24371 +       } else {
24372 +               sdvox |=
24373 +                   (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
24374 +       }
24375 +#endif
24376 +
24377 +       psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox);
24378 +
24379 +        psb_intel_sdvo_set_iomap(psb_intel_output);
24380 +}
24381 +
24382 +static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
24383 +{
24384 +       struct drm_device *dev = encoder->dev;
24385 +       struct psb_intel_output *psb_intel_output =
24386 +                                       enc_to_psb_intel_output(encoder);
24387 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24388 +       u32 temp;
24389 +
24390 +       if (mode != DRM_MODE_DPMS_ON) {
24391 +               psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
24392 +               if (0)
24393 +                       psb_intel_sdvo_set_encoder_power_state(
24394 +                                                       psb_intel_output,
24395 +                                                       mode);
24396 +
24397 +               if (mode == DRM_MODE_DPMS_OFF) {
24398 +                       temp = REG_READ(sdvo_priv->output_device);
24399 +                       if ((temp & SDVO_ENABLE) != 0) {
24400 +                               psb_intel_sdvo_write_sdvox(psb_intel_output,
24401 +                                                      temp &
24402 +                                                      ~SDVO_ENABLE);
24403 +                       }
24404 +               }
24405 +       } else {
24406 +               bool input1, input2;
24407 +               int i;
24408 +               u8 status;
24409 +
24410 +               temp = REG_READ(sdvo_priv->output_device);
24411 +               if ((temp & SDVO_ENABLE) == 0)
24412 +                       psb_intel_sdvo_write_sdvox(psb_intel_output,
24413 +                                              temp | SDVO_ENABLE);
24414 +               for (i = 0; i < 2; i++)
24415 +                       psb_intel_wait_for_vblank(dev);
24416 +
24417 +               status =
24418 +                   psb_intel_sdvo_get_trained_inputs(psb_intel_output,
24419 +                                                       &input1,
24420 +                                                       &input2);
24421 +
24422 +
24423 +               /* Warn if the device reported failure to sync.
24424 +                * A lot of SDVO devices fail to notify of sync, but it's
24425 +                * a given it the status is a success, we succeeded.
24426 +                */
24427 +               if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
24428 +                       DRM_DEBUG
24429 +                           ("First %s output reported failure to sync\n",
24430 +                            SDVO_NAME(sdvo_priv));
24431 +               }
24432 +
24433 +               if (0)
24434 +                       psb_intel_sdvo_set_encoder_power_state(
24435 +                                                       psb_intel_output,
24436 +                                                       mode);
24437 +               psb_intel_sdvo_set_active_outputs(psb_intel_output,
24438 +                                             sdvo_priv->active_outputs);
24439 +       }
24440 +       return;
24441 +}
24442 +
24443 +static void psb_intel_sdvo_save(struct drm_connector *connector)
24444 +{
24445 +       struct drm_device *dev = connector->dev;
24446 +       struct psb_intel_output *psb_intel_output =
24447 +                                       to_psb_intel_output(connector);
24448 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24449 +       /*int o;*/
24450 +
24451 +       sdvo_priv->save_sdvo_mult =
24452 +           psb_intel_sdvo_get_clock_rate_mult(psb_intel_output);
24453 +       psb_intel_sdvo_get_active_outputs(psb_intel_output,
24454 +                                     &sdvo_priv->save_active_outputs);
24455 +
24456 +       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
24457 +               psb_intel_sdvo_set_target_input(psb_intel_output,
24458 +                                               true,
24459 +                                               false);
24460 +               psb_intel_sdvo_get_input_timing(psb_intel_output,
24461 +                                           &sdvo_priv->save_input_dtd_1);
24462 +       }
24463 +
24464 +       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
24465 +               psb_intel_sdvo_set_target_input(psb_intel_output,
24466 +                                               false,
24467 +                                               true);
24468 +               psb_intel_sdvo_get_input_timing(psb_intel_output,
24469 +                                           &sdvo_priv->save_input_dtd_2);
24470 +       }
24471 +
24472 +#if 0
24473 +       for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) {
24474 +               u16 this_output = (1 << o);
24475 +               if (sdvo_priv->caps.output_flags & this_output) {
24476 +                       psb_intel_sdvo_set_target_output(psb_intel_output,
24477 +                                                    this_output);
24478 +                       psb_intel_sdvo_get_output_timing(psb_intel_output,
24479 +                                                    &sdvo_priv->
24480 +                                                    save_output_dtd[o]);
24481 +               }
24482 +       }
24483 +#endif
24484 +
24485 +       sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device);
24486 +
24487 +       /*TODO: save the in_out_map state*/
24488 +}
24489 +
24490 +static void psb_intel_sdvo_restore(struct drm_connector *connector)
24491 +{
24492 +       struct drm_device *dev = connector->dev;
24493 +       struct psb_intel_output *psb_intel_output =
24494 +                                       to_psb_intel_output(connector);
24495 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24496 +       /*int o;*/
24497 +       int i;
24498 +       bool input1, input2;
24499 +       u8 status;
24500 +
24501 +       psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
24502 +
24503 +#if 0
24504 +       for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) {
24505 +               u16 this_output = (1 << o);
24506 +               if (sdvo_priv->caps.output_flags & this_output) {
24507 +                       psb_intel_sdvo_set_target_output(psb_intel_output,
24508 +                                                    this_output);
24509 +                       psb_intel_sdvo_set_output_timing(psb_intel_output,
24510 +                                                    &sdvo_priv->
24511 +                                                    save_output_dtd[o]);
24512 +               }
24513 +       }
24514 +#endif
24515 +
24516 +       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
24517 +               psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
24518 +               psb_intel_sdvo_set_input_timing(psb_intel_output,
24519 +                                           &sdvo_priv->save_input_dtd_1);
24520 +       }
24521 +
24522 +       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
24523 +               psb_intel_sdvo_set_target_input(psb_intel_output, false, true);
24524 +               psb_intel_sdvo_set_input_timing(psb_intel_output,
24525 +                                           &sdvo_priv->save_input_dtd_2);
24526 +       }
24527 +
24528 +       psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
24529 +                                      sdvo_priv->save_sdvo_mult);
24530 +
24531 +       REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
24532 +
24533 +       if (sdvo_priv->save_SDVOX & SDVO_ENABLE) {
24534 +               for (i = 0; i < 2; i++)
24535 +                       psb_intel_wait_for_vblank(dev);
24536 +               status =
24537 +                   psb_intel_sdvo_get_trained_inputs(psb_intel_output,
24538 +                                                       &input1,
24539 +                                                       &input2);
24540 +               if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
24541 +                       DRM_DEBUG
24542 +                           ("First %s output reported failure to sync\n",
24543 +                            SDVO_NAME(sdvo_priv));
24544 +       }
24545 +
24546 +       psb_intel_sdvo_set_active_outputs(psb_intel_output,
24547 +                                     sdvo_priv->save_active_outputs);
24548 +
24549 +       /*TODO: restore in_out_map*/
24550 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24551 +                                SDVO_CMD_SET_IN_OUT_MAP,
24552 +                                sdvo_priv->in_out_map,
24553 +                                4);
24554 +
24555 +       psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
24556 +}
24557 +
24558 +static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
24559 +                                struct drm_display_mode *mode)
24560 +{
24561 +       struct psb_intel_output *psb_intel_output =
24562 +                               to_psb_intel_output(connector);
24563 +       struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
24564 +
24565 +       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
24566 +               return MODE_NO_DBLESCAN;
24567 +
24568 +       if (sdvo_priv->pixel_clock_min > mode->clock)
24569 +               return MODE_CLOCK_LOW;
24570 +
24571 +       if (sdvo_priv->pixel_clock_max < mode->clock)
24572 +               return MODE_CLOCK_HIGH;
24573 +
24574 +       return MODE_OK;
24575 +}
24576 +
24577 +static bool psb_intel_sdvo_get_capabilities(
24578 +                               struct psb_intel_output *psb_intel_output,
24579 +                               struct psb_intel_sdvo_caps *caps)
24580 +{
24581 +       u8 status;
24582 +
24583 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24584 +                                SDVO_CMD_GET_DEVICE_CAPS,
24585 +                                NULL,
24586 +                                0);
24587 +       status = psb_intel_sdvo_read_response(psb_intel_output,
24588 +                                               caps,
24589 +                                               sizeof(*caps));
24590 +       if (status != SDVO_CMD_STATUS_SUCCESS)
24591 +               return false;
24592 +
24593 +       return true;
24594 +}
24595 +
24596 +struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
24597 +{
24598 +       struct drm_connector *connector = NULL;
24599 +       struct psb_intel_output *iout = NULL;
24600 +       struct psb_intel_sdvo_priv *sdvo;
24601 +
24602 +       /* find the sdvo connector */
24603 +       list_for_each_entry(connector, &dev->mode_config.connector_list,
24604 +                           head) {
24605 +               iout = to_psb_intel_output(connector);
24606 +
24607 +               if (iout->type != INTEL_OUTPUT_SDVO)
24608 +                       continue;
24609 +
24610 +               sdvo = iout->dev_priv;
24611 +
24612 +               if (sdvo->output_device == SDVOB && sdvoB)
24613 +                       return connector;
24614 +
24615 +               if (sdvo->output_device == SDVOC && !sdvoB)
24616 +                       return connector;
24617 +
24618 +       }
24619 +
24620 +       return NULL;
24621 +}
24622 +
24623 +int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
24624 +{
24625 +       u8 response[2];
24626 +       u8 status;
24627 +       struct psb_intel_output *psb_intel_output;
24628 +       DRM_DEBUG("\n");
24629 +
24630 +       if (!connector)
24631 +               return 0;
24632 +
24633 +       psb_intel_output = to_psb_intel_output(connector);
24634 +
24635 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24636 +                                SDVO_CMD_GET_HOT_PLUG_SUPPORT,
24637 +                                NULL,
24638 +                                0);
24639 +       status = psb_intel_sdvo_read_response(psb_intel_output,
24640 +                                               &response,
24641 +                                               2);
24642 +
24643 +       if (response[0] != 0)
24644 +               return 1;
24645 +
24646 +       return 0;
24647 +}
24648 +
24649 +void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
24650 +{
24651 +       u8 response[2];
24652 +       u8 status;
24653 +       struct psb_intel_output *psb_intel_output =
24654 +                                       to_psb_intel_output(connector);
24655 +
24656 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24657 +                                SDVO_CMD_GET_ACTIVE_HOT_PLUG,
24658 +                                NULL,
24659 +                                0);
24660 +       psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
24661 +
24662 +       if (on) {
24663 +               psb_intel_sdvo_write_cmd(psb_intel_output,
24664 +                                    SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL,
24665 +                                    0);
24666 +               status = psb_intel_sdvo_read_response(psb_intel_output,
24667 +                                                     &response,
24668 +                                                     2);
24669 +
24670 +               psb_intel_sdvo_write_cmd(psb_intel_output,
24671 +                                    SDVO_CMD_SET_ACTIVE_HOT_PLUG,
24672 +                                    &response, 2);
24673 +       } else {
24674 +               response[0] = 0;
24675 +               response[1] = 0;
24676 +               psb_intel_sdvo_write_cmd(psb_intel_output,
24677 +                                    SDVO_CMD_SET_ACTIVE_HOT_PLUG,
24678 +                                    &response, 2);
24679 +       }
24680 +
24681 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24682 +                                SDVO_CMD_GET_ACTIVE_HOT_PLUG,
24683 +                                NULL,
24684 +                                0);
24685 +       psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
24686 +}
24687 +
24688 +static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector
24689 +                                                  *connector)
24690 +{
24691 +       u8 response[2];
24692 +       u8 status;
24693 +       struct psb_intel_output *psb_intel_output =
24694 +                                       to_psb_intel_output(connector);
24695 +
24696 +       psb_intel_sdvo_write_cmd(psb_intel_output,
24697 +                                SDVO_CMD_GET_ATTACHED_DISPLAYS,
24698 +                                NULL,
24699 +                                0);
24700 +       status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
24701 +
24702 +       DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
24703 +       if ((response[0] != 0) || (response[1] != 0))
24704 +               return connector_status_connected;
24705 +       else
24706 +               return connector_status_disconnected;
24707 +}
24708 +
24709 +static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
24710 +{
24711 +       struct psb_intel_output *psb_intel_output =
24712 +                                       to_psb_intel_output(connector);
24713 +
24714 +       /* set the bus switch and get the modes */
24715 +       psb_intel_sdvo_set_control_bus_switch(psb_intel_output,
24716 +                                         SDVO_CONTROL_BUS_DDC2);
24717 +       psb_intel_ddc_get_modes(psb_intel_output);
24718 +
24719 +       if (list_empty(&connector->probed_modes))
24720 +               return 0;
24721 +       return 1;
24722 +#if 0
24723 +       /* Mac mini hack.  On this device, I get DDC through the analog, which
24724 +        * load-detects as disconnected.  I fail to DDC through the SDVO DDC,
24725 +        * but it does load-detect as connected.  So, just steal the DDC bits
24726 +        * from analog when we fail at finding it the right way.
24727 +        */
24728 +       /* TODO */
24729 +       return NULL;
24730 +
24731 +       return NULL;
24732 +#endif
24733 +}
24734 +
24735 +static void psb_intel_sdvo_destroy(struct drm_connector *connector)
24736 +{
24737 +       struct psb_intel_output *psb_intel_output =
24738 +                               to_psb_intel_output(connector);
24739 +
24740 +       if (psb_intel_output->i2c_bus)
24741 +               psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
24742 +       drm_sysfs_connector_remove(connector);
24743 +       drm_connector_cleanup(connector);
24744 +       kfree(psb_intel_output);
24745 +}
24746 +
24747 +static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
24748 +       .dpms = psb_intel_sdvo_dpms,
24749 +       .mode_fixup = psb_intel_sdvo_mode_fixup,
24750 +       .prepare = psb_intel_encoder_prepare,
24751 +       .mode_set = psb_intel_sdvo_mode_set,
24752 +       .commit = psb_intel_encoder_commit,
24753 +};
24754 +
24755 +static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
24756 +       .dpms = drm_helper_connector_dpms,
24757 +       .save = psb_intel_sdvo_save,
24758 +       .restore = psb_intel_sdvo_restore,
24759 +       .detect = psb_intel_sdvo_detect,
24760 +       .fill_modes = drm_helper_probe_single_connector_modes,
24761 +       .destroy = psb_intel_sdvo_destroy,
24762 +};
24763 +
24764 +static const struct drm_connector_helper_funcs
24765 +    psb_intel_sdvo_connector_helper_funcs = {
24766 +       .get_modes = psb_intel_sdvo_get_modes,
24767 +       .mode_valid = psb_intel_sdvo_mode_valid,
24768 +       .best_encoder = psb_intel_best_encoder,
24769 +};
24770 +
24771 +void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
24772 +{
24773 +       drm_encoder_cleanup(encoder);
24774 +}
24775 +
24776 +static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
24777 +       .destroy = psb_intel_sdvo_enc_destroy,
24778 +};
24779 +
24780 +
24781 +void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
24782 +{
24783 +       struct drm_connector *connector;
24784 +       struct psb_intel_output *psb_intel_output;
24785 +       struct psb_intel_sdvo_priv *sdvo_priv;
24786 +       struct psb_intel_i2c_chan *i2cbus = NULL;
24787 +       int connector_type;
24788 +       u8 ch[0x40];
24789 +       int i;
24790 +       int encoder_type, output_id;
24791 +
24792 +       psb_intel_output =
24793 +           kcalloc(sizeof(struct psb_intel_output) +
24794 +                   sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL);
24795 +       if (!psb_intel_output)
24796 +               return;
24797 +
24798 +       connector = &psb_intel_output->base;
24799 +
24800 +       drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs,
24801 +                          DRM_MODE_CONNECTOR_Unknown);
24802 +       drm_connector_helper_add(connector,
24803 +                                &psb_intel_sdvo_connector_helper_funcs);
24804 +       sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1);
24805 +       psb_intel_output->type = INTEL_OUTPUT_SDVO;
24806 +
24807 +       connector->interlace_allowed = 0;
24808 +       connector->doublescan_allowed = 0;
24809 +
24810 +       /* setup the DDC bus. */
24811 +       if (output_device == SDVOB)
24812 +               i2cbus =
24813 +                   psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
24814 +       else
24815 +               i2cbus =
24816 +                   psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
24817 +
24818 +       if (!i2cbus)
24819 +               goto err_connector;
24820 +
24821 +       sdvo_priv->i2c_bus = i2cbus;
24822 +
24823 +       if (output_device == SDVOB) {
24824 +               output_id = 1;
24825 +               sdvo_priv->by_input_wiring = SDVOB_IN0;
24826 +               sdvo_priv->i2c_bus->slave_addr = 0x38;
24827 +       } else {
24828 +               output_id = 2;
24829 +               sdvo_priv->i2c_bus->slave_addr = 0x39;
24830 +       }
24831 +
24832 +       sdvo_priv->output_device = output_device;
24833 +       psb_intel_output->i2c_bus = i2cbus;
24834 +       psb_intel_output->dev_priv = sdvo_priv;
24835 +
24836 +
24837 +       /* Read the regs to test if we can talk to the device */
24838 +       for (i = 0; i < 0x40; i++) {
24839 +               if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
24840 +                       DRM_DEBUG("No SDVO device found on SDVO%c\n",
24841 +                                 output_device == SDVOB ? 'B' : 'C');
24842 +                       goto err_i2c;
24843 +               }
24844 +       }
24845 +
24846 +       psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps);
24847 +
24848 +       memset(&sdvo_priv->active_outputs, 0,
24849 +              sizeof(sdvo_priv->active_outputs));
24850 +
24851 +       /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
24852 +       if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) {
24853 +               sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
24854 +               sdvo_priv->active_device = SDVO_DEVICE_CRT;
24855 +               connector->display_info.subpixel_order =
24856 +                   SubPixelHorizontalRGB;
24857 +               encoder_type = DRM_MODE_ENCODER_DAC;
24858 +               connector_type = DRM_MODE_CONNECTOR_VGA;
24859 +       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) {
24860 +               sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
24861 +               sdvo_priv->active_outputs = SDVO_DEVICE_CRT;
24862 +               connector->display_info.subpixel_order =
24863 +                   SubPixelHorizontalRGB;
24864 +               encoder_type = DRM_MODE_ENCODER_DAC;
24865 +               connector_type = DRM_MODE_CONNECTOR_VGA;
24866 +       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) {
24867 +               sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
24868 +               sdvo_priv->active_device = SDVO_DEVICE_TMDS;
24869 +               connector->display_info.subpixel_order =
24870 +                   SubPixelHorizontalRGB;
24871 +               encoder_type = DRM_MODE_ENCODER_TMDS;
24872 +               connector_type = DRM_MODE_CONNECTOR_DVID;
24873 +       } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) {
24874 +               sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
24875 +               sdvo_priv->active_device = SDVO_DEVICE_TMDS;
24876 +               connector->display_info.subpixel_order =
24877 +                   SubPixelHorizontalRGB;
24878 +               encoder_type = DRM_MODE_ENCODER_TMDS;
24879 +               connector_type = DRM_MODE_CONNECTOR_DVID;
24880 +       } else {
24881 +               unsigned char bytes[2];
24882 +
24883 +               memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
24884 +               DRM_DEBUG
24885 +                   ("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
24886 +                    SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
24887 +               goto err_i2c;
24888 +       }
24889 +
24890 +       drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs,
24891 +                        encoder_type);
24892 +       drm_encoder_helper_add(&psb_intel_output->enc,
24893 +                              &psb_intel_sdvo_helper_funcs);
24894 +       connector->connector_type = connector_type;
24895 +
24896 +       drm_mode_connector_attach_encoder(&psb_intel_output->base,
24897 +                                         &psb_intel_output->enc);
24898 +       drm_sysfs_connector_add(connector);
24899 +
24900 +       /* Set the input timing to the screen. Assume always input 0. */
24901 +       psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
24902 +
24903 +       psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output,
24904 +                                              &sdvo_priv->pixel_clock_min,
24905 +                                              &sdvo_priv->
24906 +                                              pixel_clock_max);
24907 +
24908 +
24909 +       DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
24910 +                 "clock range %dMHz - %dMHz, "
24911 +                 "input 1: %c, input 2: %c, "
24912 +                 "output 1: %c, output 2: %c\n",
24913 +                 SDVO_NAME(sdvo_priv),
24914 +                 sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
24915 +                 sdvo_priv->caps.device_rev_id,
24916 +                 sdvo_priv->pixel_clock_min / 1000,
24917 +                 sdvo_priv->pixel_clock_max / 1000,
24918 +                 (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
24919 +                 (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
24920 +                 /* check currently supported outputs */
24921 +                 sdvo_priv->caps.output_flags &
24922 +                 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
24923 +                 sdvo_priv->caps.output_flags &
24924 +                 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
24925 +
24926 +       psb_intel_output->ddc_bus = i2cbus;
24927 +
24928 +       return;
24929 +
24930 +err_i2c:
24931 +       psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
24932 +err_connector:
24933 +       drm_connector_cleanup(connector);
24934 +       kfree(psb_intel_output);
24935 +
24936 +       return;
24937 +}
24938 diff --git a/drivers/gpu/drm/mrst/drv/psb_intel_sdvo_regs.h b/drivers/gpu/drm/mrst/drv/psb_intel_sdvo_regs.h
24939 new file mode 100644
24940 index 0000000..ed2f136
24941 --- /dev/null
24942 +++ b/drivers/gpu/drm/mrst/drv/psb_intel_sdvo_regs.h
24943 @@ -0,0 +1,338 @@
24944 +/*
24945 + * SDVO command definitions and structures.
24946 + *  
24947 + * Copyright (c) 2008, Intel Corporation
24948 + *
24949 + * This program is free software; you can redistribute it and/or modify it
24950 + * under the terms and conditions of the GNU General Public License,
24951 + * version 2, as published by the Free Software Foundation.
24952 + *
24953 + * This program is distributed in the hope it will be useful, but WITHOUT
24954 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24955 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
24956 + * more details.
24957 + *
24958 + * You should have received a copy of the GNU General Public License along with
24959 + * this program; if not, write to the Free Software Foundation, Inc., 
24960 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
24961 + *
24962 + * Authors:
24963 + *     Eric Anholt <eric@anholt.net>
24964 + */
24965 +
24966 +#define SDVO_OUTPUT_FIRST   (0)
24967 +#define SDVO_OUTPUT_TMDS0   (1 << 0)
24968 +#define SDVO_OUTPUT_RGB0    (1 << 1)
24969 +#define SDVO_OUTPUT_CVBS0   (1 << 2)
24970 +#define SDVO_OUTPUT_SVID0   (1 << 3)
24971 +#define SDVO_OUTPUT_YPRPB0  (1 << 4)
24972 +#define SDVO_OUTPUT_SCART0  (1 << 5)
24973 +#define SDVO_OUTPUT_LVDS0   (1 << 6)
24974 +#define SDVO_OUTPUT_TMDS1   (1 << 8)
24975 +#define SDVO_OUTPUT_RGB1    (1 << 9)
24976 +#define SDVO_OUTPUT_CVBS1   (1 << 10)
24977 +#define SDVO_OUTPUT_SVID1   (1 << 11)
24978 +#define SDVO_OUTPUT_YPRPB1  (1 << 12)
24979 +#define SDVO_OUTPUT_SCART1  (1 << 13)
24980 +#define SDVO_OUTPUT_LVDS1   (1 << 14)
24981 +#define SDVO_OUTPUT_LAST    (14)
24982 +
24983 +struct psb_intel_sdvo_caps {
24984 +       u8 vendor_id;
24985 +       u8 device_id;
24986 +       u8 device_rev_id;
24987 +       u8 sdvo_version_major;
24988 +       u8 sdvo_version_minor;
24989 +       unsigned int sdvo_inputs_mask:2;
24990 +       unsigned int smooth_scaling:1;
24991 +       unsigned int sharp_scaling:1;
24992 +       unsigned int up_scaling:1;
24993 +       unsigned int down_scaling:1;
24994 +       unsigned int stall_support:1;
24995 +       unsigned int pad:1;
24996 +       u16 output_flags;
24997 +} __attribute__ ((packed));
24998 +
24999 +/** This matches the EDID DTD structure, more or less */
25000 +struct psb_intel_sdvo_dtd {
25001 +       struct {
25002 +               u16 clock;      /**< pixel clock, in 10kHz units */
25003 +               u8 h_active;    /**< lower 8 bits (pixels) */
25004 +               u8 h_blank;     /**< lower 8 bits (pixels) */
25005 +               u8 h_high;      /**< upper 4 bits each h_active, h_blank */
25006 +               u8 v_active;    /**< lower 8 bits (lines) */
25007 +               u8 v_blank;     /**< lower 8 bits (lines) */
25008 +               u8 v_high;      /**< upper 4 bits each v_active, v_blank */
25009 +       } part1;
25010 +
25011 +       struct {
25012 +               u8 h_sync_off;
25013 +                       /**< lower 8 bits, from hblank start */
25014 +               u8 h_sync_width;/**< lower 8 bits (pixels) */
25015 +       /** lower 4 bits each vsync offset, vsync width */
25016 +               u8 v_sync_off_width;
25017 +       /**
25018 +        * 2 high bits of hsync offset, 2 high bits of hsync width,
25019 +        * bits 4-5 of vsync offset, and 2 high bits of vsync width.
25020 +        */
25021 +               u8 sync_off_width_high;
25022 +               u8 dtd_flags;
25023 +               u8 sdvo_flags;
25024 +       /** bits 6-7 of vsync offset at bits 6-7 */
25025 +               u8 v_sync_off_high;
25026 +               u8 reserved;
25027 +       } part2;
25028 +} __attribute__ ((packed));
25029 +
25030 +struct psb_intel_sdvo_pixel_clock_range {
25031 +       u16 min;                /**< pixel clock, in 10kHz units */
25032 +       u16 max;                /**< pixel clock, in 10kHz units */
25033 +} __attribute__ ((packed));
25034 +
25035 +struct psb_intel_sdvo_preferred_input_timing_args {
25036 +       u16 clock;
25037 +       u16 width;
25038 +       u16 height;
25039 +} __attribute__ ((packed));
25040 +
25041 +/* I2C registers for SDVO */
25042 +#define SDVO_I2C_ARG_0                         0x07
25043 +#define SDVO_I2C_ARG_1                         0x06
25044 +#define SDVO_I2C_ARG_2                         0x05
25045 +#define SDVO_I2C_ARG_3                         0x04
25046 +#define SDVO_I2C_ARG_4                         0x03
25047 +#define SDVO_I2C_ARG_5                         0x02
25048 +#define SDVO_I2C_ARG_6                         0x01
25049 +#define SDVO_I2C_ARG_7                         0x00
25050 +#define SDVO_I2C_OPCODE                                0x08
25051 +#define SDVO_I2C_CMD_STATUS                    0x09
25052 +#define SDVO_I2C_RETURN_0                      0x0a
25053 +#define SDVO_I2C_RETURN_1                      0x0b
25054 +#define SDVO_I2C_RETURN_2                      0x0c
25055 +#define SDVO_I2C_RETURN_3                      0x0d
25056 +#define SDVO_I2C_RETURN_4                      0x0e
25057 +#define SDVO_I2C_RETURN_5                      0x0f
25058 +#define SDVO_I2C_RETURN_6                      0x10
25059 +#define SDVO_I2C_RETURN_7                      0x11
25060 +#define SDVO_I2C_VENDOR_BEGIN                  0x20
25061 +
25062 +/* Status results */
25063 +#define SDVO_CMD_STATUS_POWER_ON               0x0
25064 +#define SDVO_CMD_STATUS_SUCCESS                        0x1
25065 +#define SDVO_CMD_STATUS_NOTSUPP                        0x2
25066 +#define SDVO_CMD_STATUS_INVALID_ARG            0x3
25067 +#define SDVO_CMD_STATUS_PENDING                        0x4
25068 +#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED   0x5
25069 +#define SDVO_CMD_STATUS_SCALING_NOT_SUPP       0x6
25070 +
25071 +/* SDVO commands, argument/result registers */
25072 +
25073 +#define SDVO_CMD_RESET                                 0x01
25074 +
25075 +/** Returns a struct psb_intel_sdvo_caps */
25076 +#define SDVO_CMD_GET_DEVICE_CAPS                       0x02
25077 +
25078 +#define SDVO_CMD_GET_FIRMWARE_REV                      0x86
25079 +# define SDVO_DEVICE_FIRMWARE_MINOR                    SDVO_I2C_RETURN_0
25080 +# define SDVO_DEVICE_FIRMWARE_MAJOR                    SDVO_I2C_RETURN_1
25081 +# define SDVO_DEVICE_FIRMWARE_PATCH                    SDVO_I2C_RETURN_2
25082 +
25083 +/**
25084 + * Reports which inputs are trained (managed to sync).
25085 + *
25086 + * Devices must have trained within 2 vsyncs of a mode change.
25087 + */
25088 +#define SDVO_CMD_GET_TRAINED_INPUTS                    0x03
25089 +struct psb_intel_sdvo_get_trained_inputs_response {
25090 +       unsigned int input0_trained:1;
25091 +       unsigned int input1_trained:1;
25092 +       unsigned int pad:6;
25093 +} __attribute__ ((packed));
25094 +
25095 +/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */
25096 +#define SDVO_CMD_GET_ACTIVE_OUTPUTS                    0x04
25097 +
25098 +/**
25099 + * Sets the current set of active outputs.
25100 + *
25101 + * Takes a struct psb_intel_sdvo_output_flags.
25102 + * Must be preceded by a SET_IN_OUT_MAP
25103 + * on multi-output devices.
25104 + */
25105 +#define SDVO_CMD_SET_ACTIVE_OUTPUTS                    0x05
25106 +
25107 +/**
25108 + * Returns the current mapping of SDVO inputs to outputs on the device.
25109 + *
25110 + * Returns two struct psb_intel_sdvo_output_flags structures.
25111 + */
25112 +#define SDVO_CMD_GET_IN_OUT_MAP                                0x06
25113 +
25114 +/**
25115 + * Sets the current mapping of SDVO inputs to outputs on the device.
25116 + *
25117 + * Takes two struct i380_sdvo_output_flags structures.
25118 + */
25119 +#define SDVO_CMD_SET_IN_OUT_MAP                                0x07
25120 +
25121 +/**
25122 + * Returns a struct psb_intel_sdvo_output_flags of attached displays.
25123 + */
25124 +#define SDVO_CMD_GET_ATTACHED_DISPLAYS                 0x0b
25125 +
25126 +/**
25127 + * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging.
25128 + */
25129 +#define SDVO_CMD_GET_HOT_PLUG_SUPPORT                  0x0c
25130 +
25131 +/**
25132 + * Takes a struct psb_intel_sdvo_output_flags.
25133 + */
25134 +#define SDVO_CMD_SET_ACTIVE_HOT_PLUG                   0x0d
25135 +
25136 +/**
25137 + * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug
25138 + * interrupts enabled.
25139 + */
25140 +#define SDVO_CMD_GET_ACTIVE_HOT_PLUG                   0x0e
25141 +
25142 +#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE            0x0f
25143 +struct psb_intel_sdvo_get_interrupt_event_source_response {
25144 +       u16 interrupt_status;
25145 +       unsigned int ambient_light_interrupt:1;
25146 +       unsigned int pad:7;
25147 +} __attribute__ ((packed));
25148 +
25149 +/**
25150 + * Selects which input is affected by future input commands.
25151 + *
25152 + * Commands affected include SET_INPUT_TIMINGS_PART[12],
25153 + * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
25154 + * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
25155 + */
25156 +#define SDVO_CMD_SET_TARGET_INPUT                      0x10
25157 +struct psb_intel_sdvo_set_target_input_args {
25158 +       unsigned int target_1:1;
25159 +       unsigned int pad:7;
25160 +} __attribute__ ((packed));
25161 +
25162 +/**
25163 + * Takes a struct psb_intel_sdvo_output_flags of which outputs are targetted by
25164 + * future output commands.
25165 + *
25166 + * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
25167 + * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
25168 + */
25169 +#define SDVO_CMD_SET_TARGET_OUTPUT                     0x11
25170 +
25171 +#define SDVO_CMD_GET_INPUT_TIMINGS_PART1               0x12
25172 +#define SDVO_CMD_GET_INPUT_TIMINGS_PART2               0x13
25173 +#define SDVO_CMD_SET_INPUT_TIMINGS_PART1               0x14
25174 +#define SDVO_CMD_SET_INPUT_TIMINGS_PART2               0x15
25175 +#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1              0x16
25176 +#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2              0x17
25177 +#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1              0x18
25178 +#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2              0x19
25179 +/* Part 1 */
25180 +# define SDVO_DTD_CLOCK_LOW                            SDVO_I2C_ARG_0
25181 +# define SDVO_DTD_CLOCK_HIGH                           SDVO_I2C_ARG_1
25182 +# define SDVO_DTD_H_ACTIVE                             SDVO_I2C_ARG_2
25183 +# define SDVO_DTD_H_BLANK                              SDVO_I2C_ARG_3
25184 +# define SDVO_DTD_H_HIGH                               SDVO_I2C_ARG_4
25185 +# define SDVO_DTD_V_ACTIVE                             SDVO_I2C_ARG_5
25186 +# define SDVO_DTD_V_BLANK                              SDVO_I2C_ARG_6
25187 +# define SDVO_DTD_V_HIGH                               SDVO_I2C_ARG_7
25188 +/* Part 2 */
25189 +# define SDVO_DTD_HSYNC_OFF                            SDVO_I2C_ARG_0
25190 +# define SDVO_DTD_HSYNC_WIDTH                          SDVO_I2C_ARG_1
25191 +# define SDVO_DTD_VSYNC_OFF_WIDTH                      SDVO_I2C_ARG_2
25192 +# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH                  SDVO_I2C_ARG_3
25193 +# define SDVO_DTD_DTD_FLAGS                            SDVO_I2C_ARG_4
25194 +# define SDVO_DTD_DTD_FLAG_INTERLACED                          (1 << 7)
25195 +# define SDVO_DTD_DTD_FLAG_STEREO_MASK                         (3 << 5)
25196 +# define SDVO_DTD_DTD_FLAG_INPUT_MASK                          (3 << 3)
25197 +# define SDVO_DTD_DTD_FLAG_SYNC_MASK                           (3 << 1)
25198 +# define SDVO_DTD_SDVO_FLAS                            SDVO_I2C_ARG_5
25199 +# define SDVO_DTD_SDVO_FLAG_STALL                              (1 << 7)
25200 +# define SDVO_DTD_SDVO_FLAG_CENTERED                           (0 << 6)
25201 +# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT                         (1 << 6)
25202 +# define SDVO_DTD_SDVO_FLAG_SCALING_MASK                       (3 << 4)
25203 +# define SDVO_DTD_SDVO_FLAG_SCALING_NONE                       (0 << 4)
25204 +# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP                      (1 << 4)
25205 +# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH                     (2 << 4)
25206 +# define SDVO_DTD_VSYNC_OFF_HIGH                       SDVO_I2C_ARG_6
25207 +
25208 +/**
25209 + * Generates a DTD based on the given width, height, and flags.
25210 + *
25211 + * This will be supported by any device supporting scaling or interlaced
25212 + * modes.
25213 + */
25214 +#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING         0x1a
25215 +# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW         SDVO_I2C_ARG_0
25216 +# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH                SDVO_I2C_ARG_1
25217 +# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW         SDVO_I2C_ARG_2
25218 +# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH                SDVO_I2C_ARG_3
25219 +# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW                SDVO_I2C_ARG_4
25220 +# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH       SDVO_I2C_ARG_5
25221 +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS             SDVO_I2C_ARG_6
25222 +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED          (1 << 0)
25223 +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED              (1 << 1)
25224 +
25225 +#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1      0x1b
25226 +#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2      0x1c
25227 +
25228 +/** Returns a struct psb_intel_sdvo_pixel_clock_range */
25229 +#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE           0x1d
25230 +/** Returns a struct psb_intel_sdvo_pixel_clock_range */
25231 +#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE          0x1e
25232 +
25233 +/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
25234 +#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS                0x1f
25235 +
25236 +/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
25237 +#define SDVO_CMD_GET_CLOCK_RATE_MULT                   0x20
25238 +/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
25239 +#define SDVO_CMD_SET_CLOCK_RATE_MULT                   0x21
25240 +# define SDVO_CLOCK_RATE_MULT_1X                               (1 << 0)
25241 +# define SDVO_CLOCK_RATE_MULT_2X                               (1 << 1)
25242 +# define SDVO_CLOCK_RATE_MULT_4X                               (1 << 3)
25243 +
25244 +#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS              0x27
25245 +
25246 +#define SDVO_CMD_GET_TV_FORMAT                         0x28
25247 +
25248 +#define SDVO_CMD_SET_TV_FORMAT                         0x29
25249 +
25250 +#define SDVO_CMD_GET_SUPPORTED_POWER_STATES            0x2a
25251 +#define SDVO_CMD_GET_ENCODER_POWER_STATE               0x2b
25252 +#define SDVO_CMD_SET_ENCODER_POWER_STATE               0x2c
25253 +# define SDVO_ENCODER_STATE_ON                                 (1 << 0)
25254 +# define SDVO_ENCODER_STATE_STANDBY                            (1 << 1)
25255 +# define SDVO_ENCODER_STATE_SUSPEND                            (1 << 2)
25256 +# define SDVO_ENCODER_STATE_OFF                                        (1 << 3)
25257 +
25258 +#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT             0x93
25259 +
25260 +#define SDVO_CMD_SET_CONTROL_BUS_SWITCH                        0x7a
25261 +# define SDVO_CONTROL_BUS_PROM                         0x0
25262 +# define SDVO_CONTROL_BUS_DDC1                         0x1
25263 +# define SDVO_CONTROL_BUS_DDC2                         0x2
25264 +# define SDVO_CONTROL_BUS_DDC3                         0x3
25265 +
25266 +/* SDVO Bus & SDVO Inputs wiring details*/
25267 +/* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/
25268 +/* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/
25269 +/* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/
25270 +/* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/
25271 +#define SDVOB_IN0 0x01
25272 +#define SDVOB_IN1 0x02
25273 +#define SDVOC_IN0 0x04
25274 +#define SDVOC_IN1 0x08
25275 +
25276 +#define SDVO_DEVICE_NONE 0x00
25277 +#define        SDVO_DEVICE_CRT 0x01
25278 +#define        SDVO_DEVICE_TV 0x02
25279 +#define        SDVO_DEVICE_LVDS 0x04
25280 +#define        SDVO_DEVICE_TMDS 0x08
25281 +
25282 diff --git a/drivers/gpu/drm/mrst/drv/psb_mmu.c b/drivers/gpu/drm/mrst/drv/psb_mmu.c
25283 new file mode 100644
25284 index 0000000..cced0a8
25285 --- /dev/null
25286 +++ b/drivers/gpu/drm/mrst/drv/psb_mmu.c
25287 @@ -0,0 +1,1010 @@
25288 +/**************************************************************************
25289 + * Copyright (c) 2007, Intel Corporation.
25290 + *
25291 + * This program is free software; you can redistribute it and/or modify it
25292 + * under the terms and conditions of the GNU General Public License,
25293 + * version 2, as published by the Free Software Foundation.
25294 + *
25295 + * This program is distributed in the hope it will be useful, but WITHOUT
25296 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25297 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
25298 + * more details.
25299 + *
25300 + * You should have received a copy of the GNU General Public License along with
25301 + * this program; if not, write to the Free Software Foundation, Inc., 
25302 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
25303 + *
25304 + **************************************************************************/
25305 +#include <drm/drmP.h>
25306 +#include "psb_drv.h"
25307 +#include "psb_reg.h"
25308 +
25309 +/*
25310 + * Code for the SGX MMU:
25311 + */
25312 +
25313 +/*
25314 + * clflush on one processor only:
25315 + * clflush should apparently flush the cache line on all processors in an
25316 + * SMP system.
25317 + */
25318 +
25319 +/*
25320 + * kmap atomic:
25321 + * The usage of the slots must be completely encapsulated within a spinlock, and
25322 + * no other functions that may be using the locks for other purposed may be
25323 + * called from within the locked region.
25324 + * Since the slots are per processor, this will guarantee that we are the only
25325 + * user.
25326 + */
25327 +
25328 +/*
25329 + * TODO: Inserting ptes from an interrupt handler:
25330 + * This may be desirable for some SGX functionality where the GPU can fault in
25331 + * needed pages. For that, we need to make an atomic insert_pages function, that
25332 + * may fail.
25333 + * If it fails, the caller need to insert the page using a workqueue function,
25334 + * but on average it should be fast.
25335 + */
25336 +
25337 +struct psb_mmu_driver {
25338 +       /* protects driver- and pd structures. Always take in read mode
25339 +        * before taking the page table spinlock.
25340 +        */
25341 +       struct rw_semaphore sem;
25342 +
25343 +       /* protects page tables, directory tables and pt tables.
25344 +        * and pt structures.
25345 +        */
25346 +       spinlock_t lock;
25347 +
25348 +       atomic_t needs_tlbflush;
25349 +
25350 +       uint8_t __iomem *register_map;
25351 +       struct psb_mmu_pd *default_pd;
25352 +       /*uint32_t bif_ctrl;*/
25353 +       int has_clflush;
25354 +       int clflush_add;
25355 +       unsigned long clflush_mask;
25356 +
25357 +       struct drm_psb_private *dev_priv;
25358 +};
25359 +
25360 +struct psb_mmu_pd;
25361 +
25362 +struct psb_mmu_pt {
25363 +       struct psb_mmu_pd *pd;
25364 +       uint32_t index;
25365 +       uint32_t count;
25366 +       struct page *p;
25367 +       uint32_t *v;
25368 +};
25369 +
25370 +struct psb_mmu_pd {
25371 +       struct psb_mmu_driver *driver;
25372 +       int hw_context;
25373 +       struct psb_mmu_pt **tables;
25374 +       struct page *p;
25375 +       struct page *dummy_pt;
25376 +       struct page *dummy_page;
25377 +       uint32_t pd_mask;
25378 +       uint32_t invalid_pde;
25379 +       uint32_t invalid_pte;
25380 +};
25381 +
25382 +static inline uint32_t psb_mmu_pt_index(uint32_t offset)
25383 +{
25384 +       return (offset >> PSB_PTE_SHIFT) & 0x3FF;
25385 +}
25386 +
25387 +static inline uint32_t psb_mmu_pd_index(uint32_t offset)
25388 +{
25389 +       return offset >> PSB_PDE_SHIFT;
25390 +}
25391 +
25392 +#if defined(CONFIG_X86)
25393 +static inline void psb_clflush(void *addr)
25394 +{
25395 +       __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
25396 +}
25397 +
25398 +static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
25399 +                                  void *addr)
25400 +{
25401 +       if (!driver->has_clflush)
25402 +               return;
25403 +
25404 +       mb();
25405 +       psb_clflush(addr);
25406 +       mb();
25407 +}
25408 +#else
25409 +
25410 +static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
25411 +                                  void *addr)
25412 +{;
25413 +}
25414 +
25415 +#endif
25416 +
25417 +static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
25418 +                                   int force)
25419 +{
25420 +       if (atomic_read(&driver->needs_tlbflush) || force) {
25421 +               if (driver->dev_priv) {
25422 +                       atomic_set(&driver->dev_priv->msvdx_mmu_invaldc, 1);
25423 +                       if (IS_MRST(driver->dev_priv->dev))
25424 +                               atomic_set( \
25425 +                               &driver->dev_priv->topaz_mmu_invaldc, 1);
25426 +               }
25427 +       }
25428 +       atomic_set(&driver->needs_tlbflush, 0);
25429 +}
25430 +
25431 +static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
25432 +{
25433 +       down_write(&driver->sem);
25434 +       psb_mmu_flush_pd_locked(driver, force);
25435 +       up_write(&driver->sem);
25436 +}
25437 +
25438 +void psb_mmu_flush(struct psb_mmu_driver *driver)
25439 +{
25440 +       down_write(&driver->sem);
25441 +       if (driver->dev_priv) {
25442 +               atomic_set(&driver->dev_priv->msvdx_mmu_invaldc, 1);
25443 +               if (IS_MRST(driver->dev_priv->dev))
25444 +                       atomic_set(&driver->dev_priv->topaz_mmu_invaldc, 1);
25445 +       }
25446 +
25447 +       up_write(&driver->sem);
25448 +}
25449 +
25450 +void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
25451 +{
25452 +       ttm_tt_cache_flush(&pd->p, 1);
25453 +       down_write(&pd->driver->sem);
25454 +       wmb();
25455 +       psb_mmu_flush_pd_locked(pd->driver, 1);
25456 +       pd->hw_context = hw_context;
25457 +       up_write(&pd->driver->sem);
25458 +
25459 +}
25460 +
25461 +static inline unsigned long psb_pd_addr_end(unsigned long addr,
25462 +                                           unsigned long end)
25463 +{
25464 +
25465 +       addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
25466 +       return (addr < end) ? addr : end;
25467 +}
25468 +
25469 +static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
25470 +{
25471 +       uint32_t mask = PSB_PTE_VALID;
25472 +
25473 +       if (type & PSB_MMU_CACHED_MEMORY)
25474 +               mask |= PSB_PTE_CACHED;
25475 +       if (type & PSB_MMU_RO_MEMORY)
25476 +               mask |= PSB_PTE_RO;
25477 +       if (type & PSB_MMU_WO_MEMORY)
25478 +               mask |= PSB_PTE_WO;
25479 +
25480 +       return (pfn << PAGE_SHIFT) | mask;
25481 +}
25482 +
25483 +struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
25484 +                                   int trap_pagefaults, int invalid_type)
25485 +{
25486 +       struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
25487 +       uint32_t *v;
25488 +       int i;
25489 +
25490 +       if (!pd)
25491 +               return NULL;
25492 +
25493 +       pd->p = alloc_page(GFP_DMA32);
25494 +       if (!pd->p)
25495 +               goto out_err1;
25496 +       pd->dummy_pt = alloc_page(GFP_DMA32);
25497 +       if (!pd->dummy_pt)
25498 +               goto out_err2;
25499 +       pd->dummy_page = alloc_page(GFP_DMA32);
25500 +       if (!pd->dummy_page)
25501 +               goto out_err3;
25502 +
25503 +       if (!trap_pagefaults) {
25504 +               pd->invalid_pde =
25505 +                   psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
25506 +                                    invalid_type);
25507 +               pd->invalid_pte =
25508 +                   psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
25509 +                                    invalid_type);
25510 +       } else {
25511 +               pd->invalid_pde = 0;
25512 +               pd->invalid_pte = 0;
25513 +       }
25514 +
25515 +       v = kmap(pd->dummy_pt);
25516 +       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
25517 +               v[i] = pd->invalid_pte;
25518 +
25519 +       kunmap(pd->dummy_pt);
25520 +
25521 +       v = kmap(pd->p);
25522 +       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
25523 +               v[i] = pd->invalid_pde;
25524 +
25525 +       kunmap(pd->p);
25526 +
25527 +       clear_page(kmap(pd->dummy_page));
25528 +       kunmap(pd->dummy_page);
25529 +
25530 +       pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
25531 +       if (!pd->tables)
25532 +               goto out_err4;
25533 +
25534 +       pd->hw_context = -1;
25535 +       pd->pd_mask = PSB_PTE_VALID;
25536 +       pd->driver = driver;
25537 +
25538 +       return pd;
25539 +
25540 +out_err4:
25541 +       __free_page(pd->dummy_page);
25542 +out_err3:
25543 +       __free_page(pd->dummy_pt);
25544 +out_err2:
25545 +       __free_page(pd->p);
25546 +out_err1:
25547 +       kfree(pd);
25548 +       return NULL;
25549 +}
25550 +
25551 +void psb_mmu_free_pt(struct psb_mmu_pt *pt)
25552 +{
25553 +       __free_page(pt->p);
25554 +       kfree(pt);
25555 +}
25556 +
25557 +void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
25558 +{
25559 +       struct psb_mmu_driver *driver = pd->driver;
25560 +       struct psb_mmu_pt *pt;
25561 +       int i;
25562 +
25563 +       down_write(&driver->sem);
25564 +       if (pd->hw_context != -1)
25565 +               psb_mmu_flush_pd_locked(driver, 1);
25566 +
25567 +       /* Should take the spinlock here, but we don't need to do that
25568 +          since we have the semaphore in write mode. */
25569 +
25570 +       for (i = 0; i < 1024; ++i) {
25571 +               pt = pd->tables[i];
25572 +               if (pt)
25573 +                       psb_mmu_free_pt(pt);
25574 +       }
25575 +
25576 +       vfree(pd->tables);
25577 +       __free_page(pd->dummy_page);
25578 +       __free_page(pd->dummy_pt);
25579 +       __free_page(pd->p);
25580 +       kfree(pd);
25581 +       up_write(&driver->sem);
25582 +}
25583 +
25584 +static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
25585 +{
25586 +       struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
25587 +       void *v;
25588 +       uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
25589 +       uint32_t clflush_count = PAGE_SIZE / clflush_add;
25590 +       spinlock_t *lock = &pd->driver->lock;
25591 +       uint8_t *clf;
25592 +       uint32_t *ptes;
25593 +       int i;
25594 +
25595 +       if (!pt)
25596 +               return NULL;
25597 +
25598 +       pt->p = alloc_page(GFP_DMA32);
25599 +       if (!pt->p) {
25600 +               kfree(pt);
25601 +               return NULL;
25602 +       }
25603 +
25604 +       spin_lock(lock);
25605 +
25606 +       v = kmap_atomic(pt->p, KM_USER0);
25607 +       clf = (uint8_t *) v;
25608 +       ptes = (uint32_t *) v;
25609 +       for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
25610 +               *ptes++ = pd->invalid_pte;
25611 +
25612 +
25613 +#if defined(CONFIG_X86)
25614 +       if (pd->driver->has_clflush && pd->hw_context != -1) {
25615 +               mb();
25616 +               for (i = 0; i < clflush_count; ++i) {
25617 +                       psb_clflush(clf);
25618 +                       clf += clflush_add;
25619 +               }
25620 +               mb();
25621 +       }
25622 +#endif
25623 +       kunmap_atomic(v, KM_USER0);
25624 +       spin_unlock(lock);
25625 +
25626 +       pt->count = 0;
25627 +       pt->pd = pd;
25628 +       pt->index = 0;
25629 +
25630 +       return pt;
25631 +}
25632 +
25633 +struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
25634 +                                            unsigned long addr)
25635 +{
25636 +       uint32_t index = psb_mmu_pd_index(addr);
25637 +       struct psb_mmu_pt *pt;
25638 +       uint32_t *v;
25639 +       spinlock_t *lock = &pd->driver->lock;
25640 +
25641 +       spin_lock(lock);
25642 +       pt = pd->tables[index];
25643 +       while (!pt) {
25644 +               spin_unlock(lock);
25645 +               pt = psb_mmu_alloc_pt(pd);
25646 +               if (!pt)
25647 +                       return NULL;
25648 +               spin_lock(lock);
25649 +
25650 +               if (pd->tables[index]) {
25651 +                       spin_unlock(lock);
25652 +                       psb_mmu_free_pt(pt);
25653 +                       spin_lock(lock);
25654 +                       pt = pd->tables[index];
25655 +                       continue;
25656 +               }
25657 +
25658 +               v = kmap_atomic(pd->p, KM_USER0);
25659 +               pd->tables[index] = pt;
25660 +               v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
25661 +               pt->index = index;
25662 +               kunmap_atomic((void *) v, KM_USER0);
25663 +
25664 +               if (pd->hw_context != -1) {
25665 +                       psb_mmu_clflush(pd->driver, (void *) &v[index]);
25666 +                       atomic_set(&pd->driver->needs_tlbflush, 1);
25667 +               }
25668 +       }
25669 +       pt->v = kmap_atomic(pt->p, KM_USER0);
25670 +       return pt;
25671 +}
25672 +
25673 +static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
25674 +                                             unsigned long addr)
25675 +{
25676 +       uint32_t index = psb_mmu_pd_index(addr);
25677 +       struct psb_mmu_pt *pt;
25678 +       spinlock_t *lock = &pd->driver->lock;
25679 +
25680 +       spin_lock(lock);
25681 +       pt = pd->tables[index];
25682 +       if (!pt) {
25683 +               spin_unlock(lock);
25684 +               return NULL;
25685 +       }
25686 +       pt->v = kmap_atomic(pt->p, KM_USER0);
25687 +       return pt;
25688 +}
25689 +
25690 +static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
25691 +{
25692 +       struct psb_mmu_pd *pd = pt->pd;
25693 +       uint32_t *v;
25694 +
25695 +       kunmap_atomic(pt->v, KM_USER0);
25696 +       if (pt->count == 0) {
25697 +               v = kmap_atomic(pd->p, KM_USER0);
25698 +               v[pt->index] = pd->invalid_pde;
25699 +               pd->tables[pt->index] = NULL;
25700 +
25701 +               if (pd->hw_context != -1) {
25702 +                       psb_mmu_clflush(pd->driver,
25703 +                                       (void *) &v[pt->index]);
25704 +                       atomic_set(&pd->driver->needs_tlbflush, 1);
25705 +               }
25706 +               kunmap_atomic(pt->v, KM_USER0);
25707 +               spin_unlock(&pd->driver->lock);
25708 +               psb_mmu_free_pt(pt);
25709 +               return;
25710 +       }
25711 +       spin_unlock(&pd->driver->lock);
25712 +}
25713 +
25714 +static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
25715 +                                  unsigned long addr, uint32_t pte)
25716 +{
25717 +       pt->v[psb_mmu_pt_index(addr)] = pte;
25718 +}
25719 +
25720 +static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
25721 +                                         unsigned long addr)
25722 +{
25723 +       pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
25724 +}
25725 +
25726 +#if 0
25727 +static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd,
25728 +                                        uint32_t mmu_offset)
25729 +{
25730 +       uint32_t *v;
25731 +       uint32_t pfn;
25732 +
25733 +       v = kmap_atomic(pd->p, KM_USER0);
25734 +       if (!v) {
25735 +               printk(KERN_INFO "Could not kmap pde page.\n");
25736 +               return 0;
25737 +       }
25738 +       pfn = v[psb_mmu_pd_index(mmu_offset)];
25739 +       /*      printk(KERN_INFO "pde is 0x%08x\n",pfn); */
25740 +       kunmap_atomic(v, KM_USER0);
25741 +       if (((pfn & 0x0F) != PSB_PTE_VALID)) {
25742 +               printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n",
25743 +                      mmu_offset, pfn);
25744 +       }
25745 +       v = ioremap(pfn & 0xFFFFF000, 4096);
25746 +       if (!v) {
25747 +               printk(KERN_INFO "Could not kmap pte page.\n");
25748 +               return 0;
25749 +       }
25750 +       pfn = v[psb_mmu_pt_index(mmu_offset)];
25751 +       /* printk(KERN_INFO "pte is 0x%08x\n",pfn); */
25752 +       iounmap(v);
25753 +       if (((pfn & 0x0F) != PSB_PTE_VALID)) {
25754 +               printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n",
25755 +                      mmu_offset, pfn);
25756 +       }
25757 +       return pfn >> PAGE_SHIFT;
25758 +}
25759 +
25760 +static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd,
25761 +                                      uint32_t mmu_offset,
25762 +                                      uint32_t gtt_pages)
25763 +{
25764 +       uint32_t start;
25765 +       uint32_t next;
25766 +
25767 +       printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n",
25768 +              mmu_offset, gtt_pages);
25769 +       down_read(&pd->driver->sem);
25770 +       start = psb_mmu_check_pte_locked(pd, mmu_offset);
25771 +       mmu_offset += PAGE_SIZE;
25772 +       gtt_pages -= 1;
25773 +       while (gtt_pages--) {
25774 +               next = psb_mmu_check_pte_locked(pd, mmu_offset);
25775 +               if (next != start + 1) {
25776 +                       printk(KERN_INFO
25777 +                              "Ptes out of order: 0x%08x, 0x%08x.\n",
25778 +                              start, next);
25779 +               }
25780 +               start = next;
25781 +               mmu_offset += PAGE_SIZE;
25782 +       }
25783 +       up_read(&pd->driver->sem);
25784 +}
25785 +
25786 +#endif
25787 +
25788 +void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
25789 +                       uint32_t mmu_offset, uint32_t gtt_start,
25790 +                       uint32_t gtt_pages)
25791 +{
25792 +       uint32_t *v;
25793 +       uint32_t start = psb_mmu_pd_index(mmu_offset);
25794 +       struct psb_mmu_driver *driver = pd->driver;
25795 +       int num_pages = gtt_pages;
25796 +
25797 +       down_read(&driver->sem);
25798 +       spin_lock(&driver->lock);
25799 +
25800 +       v = kmap_atomic(pd->p, KM_USER0);
25801 +       v += start;
25802 +
25803 +       while (gtt_pages--) {
25804 +               *v++ = gtt_start | pd->pd_mask;
25805 +               gtt_start += PAGE_SIZE;
25806 +       }
25807 +
25808 +       ttm_tt_cache_flush(&pd->p, num_pages);
25809 +       kunmap_atomic(v, KM_USER0);
25810 +       spin_unlock(&driver->lock);
25811 +
25812 +       if (pd->hw_context != -1)
25813 +               atomic_set(&pd->driver->needs_tlbflush, 1);
25814 +
25815 +       up_read(&pd->driver->sem);
25816 +       psb_mmu_flush_pd(pd->driver, 0);
25817 +}
25818 +
25819 +struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
25820 +{
25821 +       struct psb_mmu_pd *pd;
25822 +
25823 +       down_read(&driver->sem);
25824 +       pd = driver->default_pd;
25825 +       up_read(&driver->sem);
25826 +
25827 +       return pd;
25828 +}
25829 +
25830 +/* Returns the physical address of the PD shared by sgx/msvdx */
25831 +uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
25832 +{
25833 +       struct psb_mmu_pd *pd;
25834 +
25835 +       pd = psb_mmu_get_default_pd(driver);
25836 +       return page_to_pfn(pd->p) << PAGE_SHIFT;
25837 +}
25838 +
25839 +void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
25840 +{
25841 +       psb_mmu_free_pagedir(driver->default_pd);
25842 +       kfree(driver);
25843 +}
25844 +
25845 +struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
25846 +                                       int trap_pagefaults,
25847 +                                       int invalid_type,
25848 +                                       struct drm_psb_private *dev_priv)
25849 +{
25850 +       struct psb_mmu_driver *driver;
25851 +
25852 +       driver = kmalloc(sizeof(*driver), GFP_KERNEL);
25853 +
25854 +       if (!driver)
25855 +               return NULL;
25856 +       driver->dev_priv = dev_priv;
25857 +
25858 +       driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
25859 +                                             invalid_type);
25860 +       if (!driver->default_pd)
25861 +               goto out_err1;
25862 +
25863 +       spin_lock_init(&driver->lock);
25864 +       init_rwsem(&driver->sem);
25865 +       down_write(&driver->sem);
25866 +       driver->register_map = registers;
25867 +       atomic_set(&driver->needs_tlbflush, 1);
25868 +
25869 +       driver->has_clflush = 0;
25870 +
25871 +#if defined(CONFIG_X86)
25872 +       if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
25873 +               uint32_t tfms, misc, cap0, cap4, clflush_size;
25874 +
25875 +               /*
25876 +                * clflush size is determined at kernel setup for x86_64
25877 +                *  but not for i386. We have to do it here.
25878 +                */
25879 +
25880 +               cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
25881 +               clflush_size = ((misc >> 8) & 0xff) * 8;
25882 +               driver->has_clflush = 1;
25883 +               driver->clflush_add =
25884 +                   PAGE_SIZE * clflush_size / sizeof(uint32_t);
25885 +               driver->clflush_mask = driver->clflush_add - 1;
25886 +               driver->clflush_mask = ~driver->clflush_mask;
25887 +       }
25888 +#endif
25889 +
25890 +       up_write(&driver->sem);
25891 +       return driver;
25892 +
25893 +out_err1:
25894 +       kfree(driver);
25895 +       return NULL;
25896 +}
25897 +
25898 +#if defined(CONFIG_X86)
25899 +static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
25900 +                              unsigned long address, uint32_t num_pages,
25901 +                              uint32_t desired_tile_stride,
25902 +                              uint32_t hw_tile_stride)
25903 +{
25904 +       struct psb_mmu_pt *pt;
25905 +       uint32_t rows = 1;
25906 +       uint32_t i;
25907 +       unsigned long addr;
25908 +       unsigned long end;
25909 +       unsigned long next;
25910 +       unsigned long add;
25911 +       unsigned long row_add;
25912 +       unsigned long clflush_add = pd->driver->clflush_add;
25913 +       unsigned long clflush_mask = pd->driver->clflush_mask;
25914 +
25915 +       if (!pd->driver->has_clflush) {
25916 +               ttm_tt_cache_flush(&pd->p, num_pages);
25917 +               return;
25918 +       }
25919 +
25920 +       if (hw_tile_stride)
25921 +               rows = num_pages / desired_tile_stride;
25922 +       else
25923 +               desired_tile_stride = num_pages;
25924 +
25925 +       add = desired_tile_stride << PAGE_SHIFT;
25926 +       row_add = hw_tile_stride << PAGE_SHIFT;
25927 +       mb();
25928 +       for (i = 0; i < rows; ++i) {
25929 +
25930 +               addr = address;
25931 +               end = addr + add;
25932 +
25933 +               do {
25934 +                       next = psb_pd_addr_end(addr, end);
25935 +                       pt = psb_mmu_pt_map_lock(pd, addr);
25936 +                       if (!pt)
25937 +                               continue;
25938 +                       do {
25939 +                               psb_clflush(&pt->v
25940 +                                           [psb_mmu_pt_index(addr)]);
25941 +                       } while (addr +=
25942 +                                clflush_add,
25943 +                                (addr & clflush_mask) < next);
25944 +
25945 +                       psb_mmu_pt_unmap_unlock(pt);
25946 +               } while (addr = next, next != end);
25947 +               address += row_add;
25948 +       }
25949 +       mb();
25950 +}
25951 +#else
25952 +static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
25953 +                              unsigned long address, uint32_t num_pages,
25954 +                              uint32_t desired_tile_stride,
25955 +                              uint32_t hw_tile_stride)
25956 +{
25957 +       drm_ttm_cache_flush(&pd->p, num_pages);
25958 +}
25959 +#endif
25960 +
25961 +void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
25962 +                                unsigned long address, uint32_t num_pages)
25963 +{
25964 +       struct psb_mmu_pt *pt;
25965 +       unsigned long addr;
25966 +       unsigned long end;
25967 +       unsigned long next;
25968 +       unsigned long f_address = address;
25969 +
25970 +       down_read(&pd->driver->sem);
25971 +
25972 +       addr = address;
25973 +       end = addr + (num_pages << PAGE_SHIFT);
25974 +
25975 +       do {
25976 +               next = psb_pd_addr_end(addr, end);
25977 +               pt = psb_mmu_pt_alloc_map_lock(pd, addr);
25978 +               if (!pt)
25979 +                       goto out;
25980 +               do {
25981 +                       psb_mmu_invalidate_pte(pt, addr);
25982 +                       --pt->count;
25983 +               } while (addr += PAGE_SIZE, addr < next);
25984 +               psb_mmu_pt_unmap_unlock(pt);
25985 +
25986 +       } while (addr = next, next != end);
25987 +
25988 +out:
25989 +       if (pd->hw_context != -1)
25990 +               psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
25991 +
25992 +       up_read(&pd->driver->sem);
25993 +
25994 +       if (pd->hw_context != -1)
25995 +               psb_mmu_flush(pd->driver);
25996 +
25997 +       return;
25998 +}
25999 +
26000 +void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
26001 +                         uint32_t num_pages, uint32_t desired_tile_stride,
26002 +                         uint32_t hw_tile_stride)
26003 +{
26004 +       struct psb_mmu_pt *pt;
26005 +       uint32_t rows = 1;
26006 +       uint32_t i;
26007 +       unsigned long addr;
26008 +       unsigned long end;
26009 +       unsigned long next;
26010 +       unsigned long add;
26011 +       unsigned long row_add;
26012 +       unsigned long f_address = address;
26013 +
26014 +       if (hw_tile_stride)
26015 +               rows = num_pages / desired_tile_stride;
26016 +       else
26017 +               desired_tile_stride = num_pages;
26018 +
26019 +       add = desired_tile_stride << PAGE_SHIFT;
26020 +       row_add = hw_tile_stride << PAGE_SHIFT;
26021 +
26022 +       down_read(&pd->driver->sem);
26023 +
26024 +       /* Make sure we only need to flush this processor's cache */
26025 +
26026 +       for (i = 0; i < rows; ++i) {
26027 +
26028 +               addr = address;
26029 +               end = addr + add;
26030 +
26031 +               do {
26032 +                       next = psb_pd_addr_end(addr, end);
26033 +                       pt = psb_mmu_pt_map_lock(pd, addr);
26034 +                       if (!pt)
26035 +                               continue;
26036 +                       do {
26037 +                               psb_mmu_invalidate_pte(pt, addr);
26038 +                               --pt->count;
26039 +
26040 +                       } while (addr += PAGE_SIZE, addr < next);
26041 +                       psb_mmu_pt_unmap_unlock(pt);
26042 +
26043 +               } while (addr = next, next != end);
26044 +               address += row_add;
26045 +       }
26046 +       if (pd->hw_context != -1)
26047 +               psb_mmu_flush_ptes(pd, f_address, num_pages,
26048 +                                  desired_tile_stride, hw_tile_stride);
26049 +
26050 +       up_read(&pd->driver->sem);
26051 +
26052 +       if (pd->hw_context != -1)
26053 +               psb_mmu_flush(pd->driver);
26054 +}
26055 +
26056 +int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
26057 +                               unsigned long address, uint32_t num_pages,
26058 +                               int type)
26059 +{
26060 +       struct psb_mmu_pt *pt;
26061 +       uint32_t pte;
26062 +       unsigned long addr;
26063 +       unsigned long end;
26064 +       unsigned long next;
26065 +       unsigned long f_address = address;
26066 +       int ret = 0;
26067 +
26068 +       down_read(&pd->driver->sem);
26069 +
26070 +       addr = address;
26071 +       end = addr + (num_pages << PAGE_SHIFT);
26072 +
26073 +       do {
26074 +               next = psb_pd_addr_end(addr, end);
26075 +               pt = psb_mmu_pt_alloc_map_lock(pd, addr);
26076 +               if (!pt) {
26077 +                       ret = -ENOMEM;
26078 +                       goto out;
26079 +               }
26080 +               do {
26081 +                       pte = psb_mmu_mask_pte(start_pfn++, type);
26082 +                       psb_mmu_set_pte(pt, addr, pte);
26083 +                       pt->count++;
26084 +               } while (addr += PAGE_SIZE, addr < next);
26085 +               psb_mmu_pt_unmap_unlock(pt);
26086 +
26087 +       } while (addr = next, next != end);
26088 +
26089 +out:
26090 +       if (pd->hw_context != -1)
26091 +               psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
26092 +
26093 +       up_read(&pd->driver->sem);
26094 +
26095 +       if (pd->hw_context != -1)
26096 +               psb_mmu_flush(pd->driver);
26097 +
26098 +       return ret;
26099 +}
26100 +
26101 +int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
26102 +                        unsigned long address, uint32_t num_pages,
26103 +                        uint32_t desired_tile_stride,
26104 +                        uint32_t hw_tile_stride, int type)
26105 +{
26106 +       struct psb_mmu_pt *pt;
26107 +       uint32_t rows = 1;
26108 +       uint32_t i;
26109 +       uint32_t pte;
26110 +       unsigned long addr;
26111 +       unsigned long end;
26112 +       unsigned long next;
26113 +       unsigned long add;
26114 +       unsigned long row_add;
26115 +       unsigned long f_address = address;
26116 +       int ret = 0;
26117 +
26118 +       if (hw_tile_stride) {
26119 +               if (num_pages % desired_tile_stride != 0)
26120 +                       return -EINVAL;
26121 +               rows = num_pages / desired_tile_stride;
26122 +       } else {
26123 +               desired_tile_stride = num_pages;
26124 +       }
26125 +
26126 +       add = desired_tile_stride << PAGE_SHIFT;
26127 +       row_add = hw_tile_stride << PAGE_SHIFT;
26128 +
26129 +       down_read(&pd->driver->sem);
26130 +
26131 +       for (i = 0; i < rows; ++i) {
26132 +
26133 +               addr = address;
26134 +               end = addr + add;
26135 +
26136 +               do {
26137 +                       next = psb_pd_addr_end(addr, end);
26138 +                       pt = psb_mmu_pt_alloc_map_lock(pd, addr);
26139 +                       if (!pt) {
26140 +                               ret = -ENOMEM;
26141 +                               goto out;
26142 +                       }
26143 +                       do {
26144 +                               pte =
26145 +                                   psb_mmu_mask_pte(page_to_pfn(*pages++),
26146 +                                                    type);
26147 +                               psb_mmu_set_pte(pt, addr, pte);
26148 +                               pt->count++;
26149 +                       } while (addr += PAGE_SIZE, addr < next);
26150 +                       psb_mmu_pt_unmap_unlock(pt);
26151 +
26152 +               } while (addr = next, next != end);
26153 +
26154 +               address += row_add;
26155 +       }
26156 +out:
26157 +       if (pd->hw_context != -1)
26158 +               psb_mmu_flush_ptes(pd, f_address, num_pages,
26159 +                                  desired_tile_stride, hw_tile_stride);
26160 +
26161 +       up_read(&pd->driver->sem);
26162 +
26163 +       if (pd->hw_context != -1)
26164 +               psb_mmu_flush(pd->driver);
26165 +
26166 +       return ret;
26167 +}
26168 +#if 0 /*comented out, only used in mmu test now*/
26169 +void psb_mmu_enable_requestor(struct psb_mmu_driver *driver, uint32_t mask)
26170 +{
26171 +       mask &= _PSB_MMU_ER_MASK;
26172 +       psb_iowrite32(driver,
26173 +                     psb_ioread32(driver, PSB_CR_BIF_CTRL) & ~mask,
26174 +                     PSB_CR_BIF_CTRL);
26175 +       (void) psb_ioread32(driver, PSB_CR_BIF_CTRL);
26176 +}
26177 +
26178 +void psb_mmu_disable_requestor(struct psb_mmu_driver *driver,
26179 +                              uint32_t mask)
26180 +{
26181 +       mask &= _PSB_MMU_ER_MASK;
26182 +       psb_iowrite32(driver, psb_ioread32(driver, PSB_CR_BIF_CTRL) | mask,
26183 +                     PSB_CR_BIF_CTRL);
26184 +       (void) psb_ioread32(driver, PSB_CR_BIF_CTRL);
26185 +}
26186 +#endif
26187 +int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
26188 +                          unsigned long *pfn)
26189 +{
26190 +       int ret;
26191 +       struct psb_mmu_pt *pt;
26192 +       uint32_t tmp;
26193 +       spinlock_t *lock = &pd->driver->lock;
26194 +
26195 +       down_read(&pd->driver->sem);
26196 +       pt = psb_mmu_pt_map_lock(pd, virtual);
26197 +       if (!pt) {
26198 +               uint32_t *v;
26199 +
26200 +               spin_lock(lock);
26201 +               v = kmap_atomic(pd->p, KM_USER0);
26202 +               tmp = v[psb_mmu_pd_index(virtual)];
26203 +               kunmap_atomic(v, KM_USER0);
26204 +               spin_unlock(lock);
26205 +
26206 +               if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
26207 +                   !(pd->invalid_pte & PSB_PTE_VALID)) {
26208 +                       ret = -EINVAL;
26209 +                       goto out;
26210 +               }
26211 +               ret = 0;
26212 +               *pfn = pd->invalid_pte >> PAGE_SHIFT;
26213 +               goto out;
26214 +       }
26215 +       tmp = pt->v[psb_mmu_pt_index(virtual)];
26216 +       if (!(tmp & PSB_PTE_VALID)) {
26217 +               ret = -EINVAL;
26218 +       } else {
26219 +               ret = 0;
26220 +               *pfn = tmp >> PAGE_SHIFT;
26221 +       }
26222 +       psb_mmu_pt_unmap_unlock(pt);
26223 +out:
26224 +       up_read(&pd->driver->sem);
26225 +       return ret;
26226 +}
26227 +#if 0
26228 +void psb_mmu_test(struct psb_mmu_driver *driver, uint32_t offset)
26229 +{
26230 +       struct page *p;
26231 +       unsigned long pfn;
26232 +       int ret = 0;
26233 +       struct psb_mmu_pd *pd;
26234 +       uint32_t *v;
26235 +       uint32_t *vmmu;
26236 +
26237 +       pd = driver->default_pd;
26238 +       if (!pd)
26239 +               printk(KERN_WARNING "Could not get default pd\n");
26240 +
26241 +
26242 +       p = alloc_page(GFP_DMA32);
26243 +
26244 +       if (!p) {
26245 +               printk(KERN_WARNING "Failed allocating page\n");
26246 +               return;
26247 +       }
26248 +
26249 +       v = kmap(p);
26250 +       memset(v, 0x67, PAGE_SIZE);
26251 +
26252 +       pfn = (offset >> PAGE_SHIFT);
26253 +
26254 +       ret = psb_mmu_insert_pages(pd, &p, pfn << PAGE_SHIFT, 1, 0, 0, 0);
26255 +       if (ret) {
26256 +               printk(KERN_WARNING "Failed inserting mmu page\n");
26257 +               goto out_err1;
26258 +       }
26259 +
26260 +       /* Ioremap the page through the GART aperture */
26261 +
26262 +       vmmu = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
26263 +       if (!vmmu) {
26264 +               printk(KERN_WARNING "Failed ioremapping page\n");
26265 +               goto out_err2;
26266 +       }
26267 +
26268 +       /* Read from the page with mmu disabled. */
26269 +       printk(KERN_INFO "Page first dword is 0x%08x\n", ioread32(vmmu));
26270 +
26271 +       /* Enable the mmu for host accesses and read again. */
26272 +       psb_mmu_enable_requestor(driver, _PSB_MMU_ER_HOST);
26273 +
26274 +       printk(KERN_INFO "MMU Page first dword is (0x67676767) 0x%08x\n",
26275 +              ioread32(vmmu));
26276 +       *v = 0x15243705;
26277 +       printk(KERN_INFO "MMU Page new dword is (0x15243705) 0x%08x\n",
26278 +              ioread32(vmmu));
26279 +       iowrite32(0x16243355, vmmu);
26280 +       (void) ioread32(vmmu);
26281 +       printk(KERN_INFO "Page new dword is (0x16243355) 0x%08x\n", *v);
26282 +
26283 +       printk(KERN_INFO "Int stat is 0x%08x\n",
26284 +              psb_ioread32(driver, PSB_CR_BIF_INT_STAT));
26285 +       printk(KERN_INFO "Fault is 0x%08x\n",
26286 +              psb_ioread32(driver, PSB_CR_BIF_FAULT));
26287 +
26288 +       /* Disable MMU for host accesses and clear page fault register */
26289 +       psb_mmu_disable_requestor(driver, _PSB_MMU_ER_HOST);
26290 +       iounmap(vmmu);
26291 +out_err2:
26292 +       psb_mmu_remove_pages(pd, pfn << PAGE_SHIFT, 1, 0, 0);
26293 +out_err1:
26294 +       kunmap(p);
26295 +       __free_page(p);
26296 +}
26297 +#endif
26298 diff --git a/drivers/gpu/drm/mrst/drv/psb_msvdx.c b/drivers/gpu/drm/mrst/drv/psb_msvdx.c
26299 new file mode 100644
26300 index 0000000..4ad5b31
26301 --- /dev/null
26302 +++ b/drivers/gpu/drm/mrst/drv/psb_msvdx.c
26303 @@ -0,0 +1,1063 @@
26304 +/**************************************************************************
26305 + * MSVDX I/O operations and IRQ handling
26306 + * 
26307 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
26308 + * Copyright (c) Imagination Technologies Limited, UK
26309 + *
26310 + * This program is free software; you can redistribute it and/or modify it
26311 + * under the terms and conditions of the GNU General Public License,
26312 + * version 2, as published by the Free Software Foundation.
26313 + *
26314 + * This program is distributed in the hope it will be useful, but WITHOUT
26315 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26316 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
26317 + * more details.
26318 + *
26319 + * You should have received a copy of the GNU General Public License along with
26320 + * this program; if not, write to the Free Software Foundation, Inc., 
26321 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
26322 + *
26323 + **************************************************************************/
26324 +
26325 +#include <drm/drmP.h>
26326 +#include <drm/drm_os_linux.h>
26327 +#include "psb_drv.h"
26328 +#include "psb_drm.h"
26329 +#include "psb_msvdx.h"
26330 +#include "lnc_topaz.h"
26331 +#include "ospm_power.h"
26332 +#include <linux/io.h>
26333 +#include <linux/delay.h>
26334 +
26335 +#ifndef list_first_entry
26336 +#define list_first_entry(ptr, type, member) \
26337 +       list_entry((ptr)->next, type, member)
26338 +#endif
26339 +
26340 +
26341 +static int psb_msvdx_send(struct drm_device *dev, void *cmd,
26342 +                         unsigned long cmd_size);
26343 +
26344 +static int psb_msvdx_dequeue_send(struct drm_device *dev)
26345 +{
26346 +       struct drm_psb_private *dev_priv = dev->dev_private;
26347 +       struct psb_msvdx_cmd_queue *msvdx_cmd = NULL;
26348 +       int ret = 0;
26349 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
26350 +
26351 +       if (list_empty(&msvdx_priv->msvdx_queue)) {
26352 +               PSB_DEBUG_GENERAL("MSVDXQUE: msvdx list empty.\n");
26353 +               msvdx_priv->msvdx_busy = 0;
26354 +               return -EINVAL;
26355 +       }
26356 +       msvdx_cmd = list_first_entry(&msvdx_priv->msvdx_queue,
26357 +                               struct psb_msvdx_cmd_queue, head);
26358 +       PSB_DEBUG_GENERAL("MSVDXQUE: Queue has id %08x\n", msvdx_cmd->sequence);
26359 +       ret = psb_msvdx_send(dev, msvdx_cmd->cmd, msvdx_cmd->cmd_size);
26360 +       if (ret) {
26361 +               DRM_ERROR("MSVDXQUE: psb_msvdx_send failed\n");
26362 +               ret = -EINVAL;
26363 +       }
26364 +       list_del(&msvdx_cmd->head);
26365 +       kfree(msvdx_cmd->cmd);
26366 +       kfree(msvdx_cmd);
26367 +
26368 +       return ret;
26369 +}
26370 +
26371 +static int psb_msvdx_map_command(struct drm_device *dev,
26372 +                         struct ttm_buffer_object *cmd_buffer,
26373 +                         unsigned long cmd_offset, unsigned long cmd_size,
26374 +                         void **msvdx_cmd, uint32_t sequence, int copy_cmd)
26375 +{
26376 +       struct drm_psb_private *dev_priv = dev->dev_private;
26377 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
26378 +       int ret = 0;
26379 +       unsigned long cmd_page_offset = cmd_offset & ~PAGE_MASK;
26380 +       unsigned long cmd_size_remaining;
26381 +       struct ttm_bo_kmap_obj cmd_kmap, regio_kmap;
26382 +       void *cmd, *tmp, *cmd_start;
26383 +       bool is_iomem;
26384 +
26385 +       /* command buffers may not exceed page boundary */
26386 +       if (cmd_size + cmd_page_offset > PAGE_SIZE)
26387 +               return -EINVAL;
26388 +
26389 +       ret = ttm_bo_kmap(cmd_buffer, cmd_offset >> PAGE_SHIFT, 1, &cmd_kmap);
26390 +       if (ret) {
26391 +               DRM_ERROR("MSVDXQUE:ret:%d\n", ret);
26392 +               return ret;
26393 +       }
26394 +
26395 +       cmd_start = (void *)ttm_kmap_obj_virtual(&cmd_kmap, &is_iomem)
26396 +               + cmd_page_offset;
26397 +       cmd = cmd_start;
26398 +       cmd_size_remaining = cmd_size;
26399 +
26400 +       while (cmd_size_remaining > 0) {
26401 +               uint32_t cur_cmd_size = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_SIZE);
26402 +               uint32_t cur_cmd_id = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_ID);
26403 +               uint32_t mmu_ptd = 0, tmp = 0;
26404 +               struct psb_msvdx_deblock_queue *msvdx_deblock;
26405 +               unsigned long irq_flags;
26406 +
26407 +               PSB_DEBUG_GENERAL("cmd start at %08x cur_cmd_size = %d"
26408 +                               " cur_cmd_id = %02x fence = %08x\n",
26409 +                       (uint32_t) cmd, cur_cmd_size, cur_cmd_id, sequence);
26410 +               if ((cur_cmd_size % sizeof(uint32_t))
26411 +                   || (cur_cmd_size > cmd_size_remaining)) {
26412 +                       ret = -EINVAL;
26413 +                       DRM_ERROR("MSVDX: ret:%d\n", ret);
26414 +                       goto out;
26415 +               }
26416 +
26417 +               switch (cur_cmd_id) {
26418 +               case VA_MSGID_RENDER:
26419 +                       /* Fence ID */
26420 +                       MEMIO_WRITE_FIELD(cmd, FW_VA_RENDER_FENCE_VALUE,
26421 +                                         sequence);
26422 +                       mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
26423 +                       tmp = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
26424 +                                       1, 0);
26425 +                       if (tmp == 1) {
26426 +                               mmu_ptd |= 1;
26427 +                               PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
26428 +                       }
26429 +
26430 +                       /* PTD */
26431 +                       MEMIO_WRITE_FIELD(cmd, FW_VA_RENDER_MMUPTD, mmu_ptd);
26432 +                       break;
26433 +
26434 +               case VA_MSGID_DEBLOCK:
26435 +                       /* Fence ID */
26436 +                       MEMIO_WRITE_FIELD(cmd, FW_DXVA_DEBLOCK_FENCE_VALUE,
26437 +                                         sequence);
26438 +                       mmu_ptd = psb_get_default_pd_addr(dev_priv->mmu);
26439 +                       tmp = atomic_cmpxchg(&dev_priv->msvdx_mmu_invaldc,
26440 +                                       1, 0);
26441 +                       if (tmp == 1) {
26442 +                               mmu_ptd |= 1;
26443 +                               PSB_DEBUG_GENERAL("MSVDX:Set MMU invalidate\n");
26444 +                       }
26445 +
26446 +                       /* PTD */
26447 +                       MEMIO_WRITE_FIELD(cmd,
26448 +                                         FW_DXVA_DEBLOCK_MMUPTD,
26449 +                                         mmu_ptd);
26450 +
26451 +                       /* printk("Got deblock msg\n"); */
26452 +                       /* Deblock message is followed by 32 */
26453 +                       /* bytes of deblock params */
26454 +                       msvdx_deblock = kmalloc(
26455 +                                       sizeof(struct psb_msvdx_deblock_queue),
26456 +                                       GFP_KERNEL);
26457 +
26458 +                       if (msvdx_deblock == NULL) {
26459 +                               DRM_ERROR("DEBLOCK QUE: Out of memory...\n");
26460 +                               ret =  -ENOMEM;
26461 +                               goto out;
26462 +                       }
26463 +
26464 +                       memcpy(&msvdx_deblock->dbParams, cmd + 16, 32);
26465 +
26466 +                       ret = ttm_bo_kmap(
26467 +                               (struct ttm_buffer_object *)
26468 +                                       msvdx_deblock->dbParams.handle,
26469 +                               0,
26470 +                               (msvdx_deblock->dbParams.buffer_size +
26471 +                                       PAGE_SIZE - 1) >> PAGE_SHIFT,
26472 +                               &regio_kmap);
26473 +
26474 +                       /* printk("deblock regio buffer size is 0x%x\n",
26475 +                                       msvdx_deblock->dbParams.buffer_size); */
26476 +
26477 +                       if (likely(!ret)) {
26478 +                               msvdx_deblock->dbParams.pPicparams = kmalloc(
26479 +                                       msvdx_deblock->dbParams.buffer_size,
26480 +                                       GFP_KERNEL);
26481 +
26482 +                               if (msvdx_deblock->dbParams.pPicparams != NULL)
26483 +                                       memcpy(
26484 +                                         msvdx_deblock->dbParams.pPicparams,
26485 +                                         regio_kmap.virtual,
26486 +                                         msvdx_deblock->dbParams.buffer_size);
26487 +                               ttm_bo_kunmap(&regio_kmap);
26488 +                       }
26489 +                       spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
26490 +                       list_add_tail(&msvdx_deblock->head,
26491 +                                     &msvdx_priv->deblock_queue);
26492 +                       spin_unlock_irqrestore(&msvdx_priv->msvdx_lock,
26493 +                                               irq_flags);
26494 +
26495 +                       cmd += 32;
26496 +                       cmd_size_remaining -= 32;
26497 +                       break;
26498 +
26499 +
26500 +               default:
26501 +                       /* Msg not supported */
26502 +                       ret = -EINVAL;
26503 +                       PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
26504 +                       goto out;
26505 +               }
26506 +
26507 +               cmd += cur_cmd_size;
26508 +               cmd_size_remaining -= cur_cmd_size;
26509 +       }
26510 +
26511 +       if (copy_cmd) {
26512 +               PSB_DEBUG_GENERAL("MSVDXQUE:copying command\n");
26513 +
26514 +               tmp = kzalloc(cmd_size, GFP_KERNEL);
26515 +               if (tmp == NULL) {
26516 +                       ret = -ENOMEM;
26517 +                       DRM_ERROR("MSVDX: fail to callc,ret=:%d\n", ret);
26518 +                       goto out;
26519 +               }
26520 +               memcpy(tmp, cmd_start, cmd_size);
26521 +               *msvdx_cmd = tmp;
26522 +       } else {
26523 +               PSB_DEBUG_GENERAL("MSVDXQUE:did NOT copy command\n");
26524 +               ret = psb_msvdx_send(dev, cmd_start, cmd_size);
26525 +               if (ret) {
26526 +                       DRM_ERROR("MSVDXQUE: psb_msvdx_send failed\n");
26527 +                       ret = -EINVAL;
26528 +               }
26529 +       }
26530 +
26531 +out:
26532 +       ttm_bo_kunmap(&cmd_kmap);
26533 +
26534 +       return ret;
26535 +}
26536 +
26537 +int psb_submit_video_cmdbuf(struct drm_device *dev,
26538 +                           struct ttm_buffer_object *cmd_buffer,
26539 +                           unsigned long cmd_offset, unsigned long cmd_size,
26540 +                           struct ttm_fence_object *fence)
26541 +{
26542 +       struct drm_psb_private *dev_priv = dev->dev_private;
26543 +       uint32_t sequence =  dev_priv->sequence[PSB_ENGINE_VIDEO];
26544 +       unsigned long irq_flags;
26545 +       int ret = 0;
26546 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
26547 +       int offset = 0;
26548 +
26549 +       /* psb_schedule_watchdog(dev_priv); */
26550 +
26551 +       spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
26552 +       if (msvdx_priv->msvdx_needs_reset) {
26553 +               spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
26554 +               PSB_DEBUG_GENERAL("MSVDX: will reset msvdx\n");
26555 +               if (psb_msvdx_reset(dev_priv)) {
26556 +                       ret = -EBUSY;
26557 +                       DRM_ERROR("MSVDX: Reset failed\n");
26558 +                       return ret;
26559 +               }
26560 +               msvdx_priv->msvdx_needs_reset = 0;
26561 +               msvdx_priv->msvdx_busy = 0;
26562 +
26563 +               psb_msvdx_init(dev);
26564 +
26565 +               /* restore vec local mem if needed */
26566 +               if (msvdx_priv->vec_local_mem_saved) {
26567 +                       for (offset = 0; offset < VEC_LOCAL_MEM_BYTE_SIZE / 4; ++offset)
26568 +                               PSB_WMSVDX32(msvdx_priv->vec_local_mem_data[offset],
26569 +                                            VEC_LOCAL_MEM_OFFSET + offset * 4);
26570 +
26571 +                       msvdx_priv->vec_local_mem_saved = 0;
26572 +               }
26573 +
26574 +               spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
26575 +       }
26576 +
26577 +       if (!msvdx_priv->msvdx_fw_loaded) {
26578 +               spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
26579 +               PSB_DEBUG_GENERAL("MSVDX:reload FW to MTX\n");
26580 +
26581 +               ret = psb_setup_fw(dev);
26582 +               if (ret) {
26583 +                       DRM_ERROR("MSVDX:fail to load FW\n");
26584 +                       /* FIXME: find a proper return value */
26585 +                       return -EFAULT;
26586 +               }
26587 +               msvdx_priv->msvdx_fw_loaded = 1;
26588 +
26589 +               PSB_DEBUG_GENERAL("MSVDX: load firmware successfully\n");
26590 +               spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
26591 +       }
26592 +
26593 +       if (!msvdx_priv->msvdx_busy) {
26594 +               msvdx_priv->msvdx_busy = 1;
26595 +               spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
26596 +               PSB_DEBUG_GENERAL("MSVDX: commit command to HW,seq=0x%08x\n",
26597 +                               sequence);
26598 +               ret = psb_msvdx_map_command(dev, cmd_buffer, cmd_offset,
26599 +                                       cmd_size, NULL, sequence, 0);
26600 +               if (ret) {
26601 +                       DRM_ERROR("MSVDXQUE: Failed to extract cmd\n");
26602 +                       return ret;
26603 +               }
26604 +       } else {
26605 +               struct psb_msvdx_cmd_queue *msvdx_cmd;
26606 +               void *cmd = NULL;
26607 +
26608 +               spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
26609 +               /* queue the command to be sent when the h/w is ready */
26610 +               PSB_DEBUG_GENERAL("MSVDXQUE: queueing sequence:%08x..\n",
26611 +                               sequence);
26612 +               msvdx_cmd = kzalloc(sizeof(struct psb_msvdx_cmd_queue),
26613 +                               GFP_KERNEL);
26614 +               if (msvdx_cmd == NULL) {
26615 +                       DRM_ERROR("MSVDXQUE: Out of memory...\n");
26616 +                       return -ENOMEM;
26617 +               }
26618 +
26619 +               ret = psb_msvdx_map_command(dev, cmd_buffer, cmd_offset,
26620 +                                       cmd_size, &cmd, sequence, 1);
26621 +               if (ret) {
26622 +                       DRM_ERROR("MSVDXQUE: Failed to extract cmd\n");
26623 +                       kfree(msvdx_cmd
26624 +                               );
26625 +                       return ret;
26626 +               }
26627 +               msvdx_cmd->cmd = cmd;
26628 +               msvdx_cmd->cmd_size = cmd_size;
26629 +               msvdx_cmd->sequence = sequence;
26630 +               spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
26631 +               list_add_tail(&msvdx_cmd->head, &msvdx_priv->msvdx_queue);
26632 +               if (!msvdx_priv->msvdx_busy) {
26633 +                       msvdx_priv->msvdx_busy = 1;
26634 +                       PSB_DEBUG_GENERAL("MSVDXQUE: Need immediate dequeue\n");
26635 +                       psb_msvdx_dequeue_send(dev);
26636 +               }
26637 +               spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
26638 +       }
26639 +
26640 +       return ret;
26641 +}
26642 +
26643 +int psb_cmdbuf_video(struct drm_file *priv,
26644 +                    struct list_head *validate_list,
26645 +                    uint32_t fence_type,
26646 +                    struct drm_psb_cmdbuf_arg *arg,
26647 +                    struct ttm_buffer_object *cmd_buffer,
26648 +                    struct psb_ttm_fence_rep *fence_arg)
26649 +{
26650 +       struct drm_device *dev = priv->minor->dev;
26651 +       struct ttm_fence_object *fence;
26652 +       int ret;
26653 +
26654 +       /*
26655 +        * Check this. Doesn't seem right. Have fencing done AFTER command
26656 +        * submission and make sure drm_psb_idle idles the MSVDX completely.
26657 +        */
26658 +       ret =
26659 +               psb_submit_video_cmdbuf(dev, cmd_buffer, arg->cmdbuf_offset,
26660 +                                       arg->cmdbuf_size, NULL);
26661 +       if (ret)
26662 +               return ret;
26663 +
26664 +
26665 +       /* DRM_ERROR("Intel: Fix video fencing!!\n"); */
26666 +       psb_fence_or_sync(priv, PSB_ENGINE_VIDEO, fence_type,
26667 +                         arg->fence_flags, validate_list, fence_arg,
26668 +                       &fence);
26669 +
26670 +       ttm_fence_object_unref(&fence);
26671 +       mutex_lock(&cmd_buffer->mutex);
26672 +       if (cmd_buffer->sync_obj != NULL)
26673 +               ttm_fence_sync_obj_unref(&cmd_buffer->sync_obj);
26674 +       mutex_unlock(&cmd_buffer->mutex);
26675 +
26676 +       return 0;
26677 +}
26678 +
26679 +
26680 +static int psb_msvdx_send(struct drm_device *dev, void *cmd,
26681 +                       unsigned long cmd_size)
26682 +{
26683 +       int ret = 0;
26684 +       struct drm_psb_private *dev_priv = dev->dev_private;
26685 +
26686 +       while (cmd_size > 0) {
26687 +               uint32_t cur_cmd_size = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_SIZE);
26688 +               uint32_t cur_cmd_id = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_ID);
26689 +               if (cur_cmd_size > cmd_size) {
26690 +                       ret = -EINVAL;
26691 +                       DRM_ERROR("MSVDX:cmd_size %lu cur_cmd_size %lu\n",
26692 +                               cmd_size, (unsigned long)cur_cmd_size);
26693 +                       goto out;
26694 +               }
26695 +
26696 +               /* Send the message to h/w */
26697 +               ret = psb_mtx_send(dev_priv, cmd);
26698 +               if (ret) {
26699 +                       PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
26700 +                       goto out;
26701 +               }
26702 +               cmd += cur_cmd_size;
26703 +               cmd_size -= cur_cmd_size;
26704 +               if (cur_cmd_id ==  VA_MSGID_DEBLOCK) {
26705 +                       cmd += 32;
26706 +                       cmd_size -= 32;
26707 +               }
26708 +       }
26709 +
26710 +out:
26711 +       PSB_DEBUG_GENERAL("MSVDX: ret:%d\n", ret);
26712 +       return ret;
26713 +}
26714 +
26715 +int psb_mtx_send(struct drm_psb_private *dev_priv, const void *msg)
26716 +{
26717 +       static uint32_t pad_msg[FWRK_PADMSG_SIZE];
26718 +       const uint32_t *p_msg = (uint32_t *) msg;
26719 +       uint32_t msg_num, words_free, ridx, widx, buf_size, buf_offset;
26720 +       int ret = 0;
26721 +
26722 +       PSB_DEBUG_GENERAL("MSVDX: psb_mtx_send\n");
26723 +
26724 +       /* we need clocks enabled before we touch VEC local ram */
26725 +       PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
26726 +
26727 +       msg_num = (MEMIO_READ_FIELD(msg, FWRK_GENMSG_SIZE) + 3) / 4;
26728 +
26729 +       buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) & ((1 << 16) - 1);
26730 +
26731 +       if (msg_num > buf_size) {
26732 +               ret = -EINVAL;
26733 +               DRM_ERROR("MSVDX: message exceed maximum,ret:%d\n", ret);
26734 +               goto out;
26735 +       }
26736 +
26737 +       ridx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_RD_INDEX);
26738 +       widx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_WRT_INDEX);
26739 +
26740 +
26741 +       buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) & ((1 << 16) - 1);
26742 +       /*0x2000 is VEC Local Ram offset*/
26743 +       buf_offset =
26744 +               (PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_BUF_SIZE) >> 16) + 0x2000;
26745 +
26746 +       /* message would wrap, need to send a pad message */
26747 +       if (widx + msg_num > buf_size) {
26748 +               /* Shouldn't happen for a PAD message itself */
26749 +               BUG_ON(MEMIO_READ_FIELD(msg, FWRK_GENMSG_ID)
26750 +                       == FWRK_MSGID_PADDING);
26751 +
26752 +               /* if the read pointer is at zero then we must wait for it to
26753 +                * change otherwise the write pointer will equal the read
26754 +                * pointer,which should only happen when the buffer is empty
26755 +                *
26756 +                * This will only happens if we try to overfill the queue,
26757 +                * queue management should make
26758 +                * sure this never happens in the first place.
26759 +                */
26760 +               BUG_ON(0 == ridx);
26761 +               if (0 == ridx) {
26762 +                       ret = -EINVAL;
26763 +                       DRM_ERROR("MSVDX: RIndex=0, ret:%d\n", ret);
26764 +                       goto out;
26765 +               }
26766 +
26767 +               /* Send a pad message */
26768 +               MEMIO_WRITE_FIELD(pad_msg, FWRK_GENMSG_SIZE,
26769 +                                 (buf_size - widx) << 2);
26770 +               MEMIO_WRITE_FIELD(pad_msg, FWRK_GENMSG_ID,
26771 +                                 FWRK_MSGID_PADDING);
26772 +               psb_mtx_send(dev_priv, pad_msg);
26773 +               widx = PSB_RMSVDX32(MSVDX_COMMS_TO_MTX_WRT_INDEX);
26774 +       }
26775 +
26776 +       if (widx >= ridx)
26777 +               words_free = buf_size - (widx - ridx);
26778 +       else
26779 +               words_free = ridx - widx;
26780 +
26781 +       BUG_ON(msg_num > words_free);
26782 +       if (msg_num > words_free) {
26783 +               ret = -EINVAL;
26784 +               DRM_ERROR("MSVDX: msg_num > words_free, ret:%d\n", ret);
26785 +               goto out;
26786 +       }
26787 +       while (msg_num > 0) {
26788 +               PSB_WMSVDX32(*p_msg++, buf_offset + (widx << 2));
26789 +               msg_num--;
26790 +               widx++;
26791 +               if (buf_size == widx)
26792 +                       widx = 0;
26793 +       }
26794 +
26795 +       PSB_WMSVDX32(widx, MSVDX_COMMS_TO_MTX_WRT_INDEX);
26796 +
26797 +       /* Make sure clocks are enabled before we kick */
26798 +       PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
26799 +
26800 +       PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
26801 +
26802 +       /* signal an interrupt to let the mtx know there is a new message */
26803 +       /* PSB_WMSVDX32(1, MSVDX_MTX_KICKI); */
26804 +       PSB_WMSVDX32(1, MSVDX_MTX_KICK);
26805 +
26806 +       /* Read MSVDX Register several times in case Idle signal assert */
26807 +       PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
26808 +       PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
26809 +       PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
26810 +       PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
26811 +
26812 +
26813 +out:
26814 +       return ret;
26815 +}
26816 +
26817 +static int psb_msvdx_towpass_deblock(struct drm_device *dev,
26818 +                                       uint32_t *pPicparams)
26819 +{
26820 +       struct drm_psb_private *dev_priv =
26821 +               (struct drm_psb_private *)dev->dev_private;
26822 +       uint32_t cmd_size, cmd_count = 0;
26823 +       uint32_t cmd_id, reg, value, wait, tmp, read = 0, ret = 0;
26824 +
26825 +       cmd_size = *pPicparams++;
26826 +       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: deblock get cmd size %d\n", cmd_size);
26827 +       /* printk("MSVDX DEBLOCK: deblock get cmd size %d\n", cmd_size); */
26828 +
26829 +       do {
26830 +               cmd_id = (*pPicparams) & 0xf0000000;
26831 +               reg = (*pPicparams++)  & 0x0fffffff;
26832 +               switch (cmd_id) {
26833 +               case MSVDX_DEBLOCK_REG_SET: {
26834 +                       value = *pPicparams++;
26835 +                       PSB_WMSVDX32(value, reg);
26836 +                       cmd_count += 2;
26837 +                       break;
26838 +               }
26839 +               case MSVDX_DEBLOCK_REG_GET: {
26840 +                       read = PSB_RMSVDX32(reg);
26841 +                       cmd_count += 1;
26842 +                       break;
26843 +               }
26844 +               case MSVDX_DEBLOCK_REG_POLLn: {
26845 +                       value = *pPicparams++;
26846 +                       wait = 0;
26847 +
26848 +                       do {
26849 +                               tmp = PSB_RMSVDX32(reg);
26850 +                       } while ((wait++ < 20000) && (value > tmp));
26851 +
26852 +                       if (wait >= 20000) {
26853 +                               ret = 1;
26854 +                               PSB_DEBUG_GENERAL(
26855 +                               "MSVDX DEBLOCK: polln cmd space time out!\n");
26856 +                               goto finish_deblock;
26857 +                       }
26858 +                       cmd_count += 2;
26859 +                       break;
26860 +               }
26861 +               case MSVDX_DEBLOCK_REG_POLLx: {
26862 +                       wait = 0;
26863 +
26864 +                       do {
26865 +                               tmp = PSB_RMSVDX32(reg);
26866 +                       } while ((wait++ < 20000) && (read > tmp));
26867 +
26868 +                       if (wait >= 20000) {
26869 +                               ret = 1;
26870 +                               PSB_DEBUG_GENERAL(
26871 +                               "MSVDX DEBLOCK: pollx cmd space time out!\n");
26872 +                               goto finish_deblock;
26873 +                       }
26874 +
26875 +                       cmd_count += 1;
26876 +                       break;
26877 +               }
26878 +               default:
26879 +                       ret = 1;
26880 +                       PSB_DEBUG_GENERAL(
26881 +                               "MSVDX DEBLOCK: get error cmd_id: 0x%x!\n",
26882 +                               cmd_id);
26883 +                       PSB_DEBUG_GENERAL(
26884 +                               "MSVDX DEBLOCK: execute cmd num is %d\n",
26885 +                               cmd_count);
26886 +                       /* printk("MSVDX DEBLOCK: get error cmd_id: 0x%x!\n",
26887 +                                       cmd_id); */
26888 +                       /* printk("MSVDX DEBLOCK: execute cmd num is %d\n",
26889 +                                       cmd_count); */
26890 +                       goto finish_deblock;
26891 +               }
26892 +       } while (cmd_count < cmd_size);
26893 +
26894 +
26895 +finish_deblock:
26896 +       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: execute cmd num is %d\n", cmd_count);
26897 +       return ret;
26898 +}
26899 +
26900 +/*
26901 + * MSVDX MTX interrupt
26902 + */
26903 +static void psb_msvdx_mtx_interrupt(struct drm_device *dev)
26904 +{
26905 +       struct drm_psb_private *dev_priv =
26906 +               (struct drm_psb_private *)dev->dev_private;
26907 +       static uint32_t buf[128]; /* message buffer */
26908 +       uint32_t ridx, widx, buf_size, buf_offset;
26909 +       uint32_t num, ofs; /* message num and offset */
26910 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
26911 +
26912 +       PSB_DEBUG_GENERAL("MSVDX:Got a MSVDX MTX interrupt\n");
26913 +
26914 +       /* Are clocks enabled  - If not enable before
26915 +        * attempting to read from VLR
26916 +        */
26917 +       if (PSB_RMSVDX32(MSVDX_MAN_CLK_ENABLE) != (clk_enable_all)) {
26918 +               PSB_DEBUG_GENERAL("MSVDX:Clocks disabled when Interupt set\n");
26919 +               PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
26920 +       }
26921 +
26922 +loop: /* just for coding style check */
26923 +       ridx = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_RD_INDEX);
26924 +       widx = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_WRT_INDEX);
26925 +
26926 +       /* Get out of here if nothing */
26927 +       if (ridx == widx)
26928 +               goto done;
26929 +
26930 +
26931 +       buf_size = PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_BUF_SIZE) & ((1 << 16) - 1);
26932 +       /*0x2000 is VEC Local Ram offset*/
26933 +       buf_offset =
26934 +               (PSB_RMSVDX32(MSVDX_COMMS_TO_HOST_BUF_SIZE) >> 16) + 0x2000;
26935 +
26936 +       ofs = 0;
26937 +       buf[ofs] = PSB_RMSVDX32(buf_offset + (ridx << 2));
26938 +
26939 +       /* round to nearest word */
26940 +       num = (MEMIO_READ_FIELD(buf, FWRK_GENMSG_SIZE) + 3) / 4;
26941 +
26942 +       /* ASSERT(num <= sizeof(buf) / sizeof(uint32_t)); */
26943 +
26944 +       if (++ridx >= buf_size)
26945 +               ridx = 0;
26946 +
26947 +       for (ofs++; ofs < num; ofs++) {
26948 +               buf[ofs] = PSB_RMSVDX32(buf_offset + (ridx << 2));
26949 +
26950 +               if (++ridx >= buf_size)
26951 +                       ridx = 0;
26952 +       }
26953 +
26954 +       /* Update the Read index */
26955 +       PSB_WMSVDX32(ridx, MSVDX_COMMS_TO_HOST_RD_INDEX);
26956 +
26957 +       if (msvdx_priv->msvdx_needs_reset)
26958 +               goto loop;
26959 +
26960 +       switch (MEMIO_READ_FIELD(buf, FWRK_GENMSG_ID)) {
26961 +       case VA_MSGID_CMD_HW_PANIC:
26962 +       case VA_MSGID_CMD_FAILED: {
26963 +               uint32_t fence = MEMIO_READ_FIELD(buf,
26964 +                                       FW_VA_CMD_FAILED_FENCE_VALUE);
26965 +               uint32_t fault = MEMIO_READ_FIELD(buf,
26966 +                                       FW_VA_CMD_FAILED_IRQSTATUS);
26967 +               uint32_t msg_id = MEMIO_READ_FIELD(buf, FWRK_GENMSG_ID);
26968 +               uint32_t diff = 0;
26969 +
26970 +               (void) fault;
26971 +               if (msg_id == VA_MSGID_CMD_HW_PANIC)
26972 +                       PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_CMD_HW_PANIC:"
26973 +                                       "Fault detected"
26974 +                                       " - Fence: %08x, Status: %08x"
26975 +                                       " - resetting and ignoring error\n",
26976 +                                       fence, fault);
26977 +               else
26978 +                       PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_CMD_FAILED:"
26979 +                                       "Fault detected"
26980 +                                       " - Fence: %08x, Status: %08x"
26981 +                                       " - resetting and ignoring error\n",
26982 +                                       fence, fault);
26983 +
26984 +               msvdx_priv->msvdx_needs_reset = 1;
26985 +
26986 +               if (msg_id == VA_MSGID_CMD_HW_PANIC) {
26987 +                       diff = msvdx_priv->msvdx_current_sequence
26988 +                               - dev_priv->sequence[PSB_ENGINE_VIDEO];
26989 +
26990 +                       if (diff > 0x0FFFFFFF)
26991 +                               msvdx_priv->msvdx_current_sequence++;
26992 +
26993 +                       PSB_DEBUG_GENERAL("MSVDX: Fence ID missing, "
26994 +                                       "assuming %08x\n",
26995 +                                       msvdx_priv->msvdx_current_sequence);
26996 +               } else {
26997 +                       msvdx_priv->msvdx_current_sequence = fence;
26998 +               }
26999 +
27000 +               psb_fence_error(dev, PSB_ENGINE_VIDEO,
27001 +                               msvdx_priv->msvdx_current_sequence,
27002 +                               _PSB_FENCE_TYPE_EXE, DRM_CMD_FAILED);
27003 +
27004 +               /* Flush the command queue */
27005 +               psb_msvdx_flush_cmd_queue(dev);
27006 +
27007 +               goto done;
27008 +       }
27009 +       case VA_MSGID_CMD_COMPLETED: {
27010 +               uint32_t fence = MEMIO_READ_FIELD(buf,
27011 +                                       FW_VA_CMD_COMPLETED_FENCE_VALUE);
27012 +               uint32_t flags = MEMIO_READ_FIELD(buf,
27013 +                                               FW_VA_CMD_COMPLETED_FLAGS);
27014 +
27015 +               PSB_DEBUG_GENERAL("MSVDX:VA_MSGID_CMD_COMPLETED: "
27016 +                               "FenceID: %08x, flags: 0x%x\n",
27017 +                               fence, flags);
27018 +
27019 +               msvdx_priv->msvdx_current_sequence = fence;
27020 +
27021 +               psb_fence_handler(dev, PSB_ENGINE_VIDEO);
27022 +
27023 +               if (flags & FW_VA_RENDER_HOST_INT) {
27024 +                       /*Now send the next command from the msvdx cmd queue */
27025 +                       psb_msvdx_dequeue_send(dev);
27026 +                       goto done;
27027 +               }
27028 +
27029 +               break;
27030 +       }
27031 +       case VA_MSGID_CMD_COMPLETED_BATCH: {
27032 +               uint32_t fence = MEMIO_READ_FIELD(buf,
27033 +                                       FW_VA_CMD_COMPLETED_FENCE_VALUE);
27034 +               uint32_t tickcnt = MEMIO_READ_FIELD(buf,
27035 +                                       FW_VA_CMD_COMPLETED_NO_TICKS);
27036 +               (void)tickcnt;
27037 +               /* we have the fence value in the message */
27038 +               PSB_DEBUG_GENERAL("MSVDX:VA_MSGID_CMD_COMPLETED_BATCH:"
27039 +                       " FenceID: %08x, TickCount: %08x\n",
27040 +                       fence, tickcnt);
27041 +               msvdx_priv->msvdx_current_sequence = fence;
27042 +
27043 +               break;
27044 +       }
27045 +       case VA_MSGID_ACK:
27046 +               PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_ACK\n");
27047 +               break;
27048 +
27049 +       case VA_MSGID_TEST1:
27050 +               PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_TEST1\n");
27051 +               break;
27052 +
27053 +       case VA_MSGID_TEST2:
27054 +               PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_TEST2\n");
27055 +               break;
27056 +               /* Don't need to do anything with these messages */
27057 +
27058 +       case VA_MSGID_DEBLOCK_REQUIRED: {
27059 +               uint32_t ctxid = MEMIO_READ_FIELD(buf,
27060 +                                       FW_VA_DEBLOCK_REQUIRED_CONTEXT);
27061 +               struct psb_msvdx_deblock_queue *msvdx_deblock;
27062 +
27063 +               PSB_DEBUG_GENERAL("MSVDX: VA_MSGID_DEBLOCK_REQUIRED"
27064 +                               " Context=%08x\n", ctxid);
27065 +               if (list_empty(&msvdx_priv->deblock_queue)) {
27066 +                       PSB_DEBUG_GENERAL(
27067 +                               "DEBLOCKQUE: deblock param list is empty\n");
27068 +                       PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
27069 +                       PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
27070 +                       goto done;
27071 +               }
27072 +               msvdx_deblock = list_first_entry(&msvdx_priv->deblock_queue,
27073 +                                       struct psb_msvdx_deblock_queue, head);
27074 +
27075 +               if (0) {
27076 +                       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: by pass \n");
27077 +                       /* try to unblock rendec */
27078 +                       PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
27079 +                       PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
27080 +                       kfree(msvdx_deblock->dbParams.pPicparams);
27081 +                       list_del(&msvdx_deblock->head);
27082 +                       goto done;
27083 +               }
27084 +
27085 +
27086 +               if (ctxid != msvdx_deblock->dbParams.ctxid) {
27087 +                       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: wrong ctxid, may "
27088 +                                         "caused by multiple context since "
27089 +                                         "it's not supported yet\n");
27090 +                       /* try to unblock rendec */
27091 +                       PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
27092 +                       PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
27093 +                       kfree(msvdx_deblock->dbParams.pPicparams);
27094 +                       list_del(&msvdx_deblock->head);
27095 +                       goto done;
27096 +               }
27097 +
27098 +               if (msvdx_deblock->dbParams.pPicparams) {
27099 +                       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: start deblocking\n");
27100 +                       /* printk("MSVDX DEBLOCK: start deblocking\n"); */
27101 +
27102 +                       if (psb_msvdx_towpass_deblock(dev,
27103 +                                       msvdx_deblock->dbParams.pPicparams)) {
27104 +
27105 +                               PSB_DEBUG_GENERAL(
27106 +                                       "MSVDX DEBLOCK: deblock fail!\n");
27107 +                               PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
27108 +                               PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
27109 +                       }
27110 +                       kfree(msvdx_deblock->dbParams.pPicparams);
27111 +               } else {
27112 +                       PSB_DEBUG_GENERAL("MSVDX DEBLOCK: deblock abort!\n");
27113 +                       /* printk("MSVDX DEBLOCK: deblock abort!\n"); */
27114 +                       PSB_WMSVDX32(0, MSVDX_CMDS_END_SLICE_PICTURE);
27115 +                       PSB_WMSVDX32(1, MSVDX_CMDS_END_SLICE_PICTURE);
27116 +               }
27117 +
27118 +               list_del(&msvdx_deblock->head);
27119 +               kfree(msvdx_deblock);
27120 +               break;
27121 +       }
27122 +       default:
27123 +               DRM_ERROR("ERROR: msvdx Unknown message from MTX \n");
27124 +               goto done;
27125 +       }
27126 +
27127 +done:
27128 +       /* we get a frame/slice done, try to save some power*/
27129 +       if (drm_msvdx_pmpolicy != PSB_PMPOLICY_NOPM)
27130 +               schedule_delayed_work(&dev_priv->scheduler.msvdx_suspend_wq, 0);
27131 +
27132 +       DRM_MEMORYBARRIER();    /* TBD check this... */
27133 +}
27134 +
27135 +
27136 +/*
27137 + * MSVDX interrupt.
27138 + */
27139 +IMG_BOOL psb_msvdx_interrupt(IMG_VOID *pvData)
27140 +{
27141 +       struct drm_device *dev;
27142 +       struct drm_psb_private *dev_priv;
27143 +       struct msvdx_private *msvdx_priv;
27144 +       uint32_t msvdx_stat;
27145 +
27146 +       if (pvData == IMG_NULL) {
27147 +               DRM_ERROR("ERROR: msvdx %s, Invalid params\n", __func__);
27148 +               return IMG_FALSE;
27149 +       }
27150 +
27151 +       if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
27152 +               DRM_ERROR("ERROR: interrupt arrived but HW is power off\n");
27153 +               return IMG_FALSE;
27154 +       }
27155 +
27156 +       dev = (struct drm_device *)pvData;
27157 +       dev_priv = (struct drm_psb_private *) dev->dev_private;
27158 +       msvdx_priv = dev_priv->msvdx_private;
27159 +
27160 +       msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
27161 +
27162 +       msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);
27163 +
27164 +       if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK) {
27165 +               /*Ideally we should we should never get to this */
27166 +               PSB_DEBUG_IRQ("MSVDX:MMU Fault:0x%x\n", msvdx_stat);
27167 +
27168 +               /* Pause MMU */
27169 +               PSB_WMSVDX32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK,
27170 +                            MSVDX_MMU_CONTROL0);
27171 +               DRM_WRITEMEMORYBARRIER();
27172 +
27173 +               /* Clear this interupt bit only */
27174 +               PSB_WMSVDX32(MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK,
27175 +                            MSVDX_INTERRUPT_CLEAR);
27176 +               PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
27177 +               DRM_READMEMORYBARRIER();
27178 +
27179 +               msvdx_priv->msvdx_needs_reset = 1;
27180 +       } else if (msvdx_stat & MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK) {
27181 +               PSB_DEBUG_IRQ
27182 +                   ("MSVDX: msvdx_stat: 0x%x(MTX)\n", msvdx_stat);
27183 +
27184 +               /* Clear all interupt bits */
27185 +               PSB_WMSVDX32(0xffff, MSVDX_INTERRUPT_CLEAR);
27186 +               PSB_RMSVDX32(MSVDX_INTERRUPT_CLEAR);
27187 +               DRM_READMEMORYBARRIER();
27188 +
27189 +               psb_msvdx_mtx_interrupt(dev);
27190 +       }
27191 +
27192 +       return IMG_TRUE;
27193 +}
27194 +
27195 +
27196 +void psb_msvdx_lockup(struct drm_psb_private *dev_priv,
27197 +               int *msvdx_lockup, int *msvdx_idle)
27198 +{
27199 +       int tmp;
27200 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
27201 +
27202 +       *msvdx_lockup = 0;
27203 +       *msvdx_idle = 1;
27204 +
27205 +#if 0
27206 +       PSB_DEBUG_GENERAL("MSVDXTimer: current_sequence:%d "
27207 +                       "last_sequence:%d and last_submitted_sequence :%d\n",
27208 +                       msvdx_priv->msvdx_current_sequence,
27209 +                       msvdx_priv->msvdx_last_sequence,
27210 +                       dev_priv->sequence[PSB_ENGINE_VIDEO]);
27211 +#endif
27212 +
27213 +       tmp = msvdx_priv->msvdx_current_sequence -
27214 +               dev_priv->sequence[PSB_ENGINE_VIDEO];
27215 +
27216 +       if (tmp > 0x0FFFFFFF) {
27217 +               if (msvdx_priv->msvdx_current_sequence ==
27218 +                       msvdx_priv->msvdx_last_sequence) {
27219 +                       DRM_ERROR("MSVDXTimer:locked-up for sequence:%d\n",
27220 +                               msvdx_priv->msvdx_current_sequence);
27221 +                       *msvdx_lockup = 1;
27222 +               } else {
27223 +                       PSB_DEBUG_GENERAL("MSVDXTimer: "
27224 +                                       "msvdx responded fine so far\n");
27225 +                       msvdx_priv->msvdx_last_sequence =
27226 +                               msvdx_priv->msvdx_current_sequence;
27227 +                       *msvdx_idle = 0;
27228 +               }
27229 +       }
27230 +}
27231 +
27232 +int psb_check_msvdx_idle(struct drm_device *dev)
27233 +{
27234 +       struct drm_psb_private *dev_priv =
27235 +               (struct drm_psb_private *)dev->dev_private;
27236 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
27237 +
27238 +       if (msvdx_priv->msvdx_fw_loaded == 0)
27239 +               return 0;
27240 +
27241 +       if (msvdx_priv->msvdx_busy) {
27242 +               PSB_DEBUG_PM("MSVDX: psb_check_msvdx_idle returns busy\n");
27243 +               return -EBUSY;
27244 +       }
27245 +
27246 +       if (msvdx_priv->msvdx_hw_busy) {
27247 +               PSB_DEBUG_PM("MSVDX: %s, HW is busy\n", __func__);
27248 +               return -EBUSY;
27249 +       }
27250 +
27251 +       return 0;
27252 +}
27253 +
27254 +int lnc_video_getparam(struct drm_device *dev, void *data,
27255 +                       struct drm_file *file_priv)
27256 +{
27257 +       struct drm_lnc_video_getparam_arg *arg = data;
27258 +       int ret = 0;
27259 +       struct drm_psb_private *dev_priv =
27260 +               (struct drm_psb_private *)file_priv->minor->dev->dev_private;
27261 +#if defined(CONFIG_MRST_RAR_HANDLER)
27262 +       struct RAR_buffer rar_buf;
27263 +       size_t rar_status;
27264 +#endif
27265 +       void *rar_handler;
27266 +       uint32_t offset = 0;
27267 +       uint32_t device_info = 0;
27268 +       uint32_t rar_ci_info[2];
27269 +
27270 +       switch (arg->key) {
27271 +       case LNC_VIDEO_GETPARAM_RAR_INFO:
27272 +               rar_ci_info[0] = dev_priv->rar_region_start;
27273 +               rar_ci_info[1] = dev_priv->rar_region_size;
27274 +               ret = copy_to_user((void __user *) ((unsigned long)arg->value),
27275 +                                  &rar_ci_info[0],
27276 +                                  sizeof(rar_ci_info));
27277 +               break;
27278 +       case LNC_VIDEO_GETPARAM_CI_INFO:
27279 +               rar_ci_info[0] = dev_priv->ci_region_start;
27280 +               rar_ci_info[1] = dev_priv->ci_region_size;
27281 +               ret = copy_to_user((void __user *) ((unsigned long)arg->value),
27282 +                                  &rar_ci_info[0],
27283 +                                  sizeof(rar_ci_info));
27284 +               break;
27285 +       case LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET:
27286 +               ret = copy_from_user(&rar_handler,
27287 +                                    (void __user *)((unsigned long)arg->arg),
27288 +                                    sizeof(rar_handler));
27289 +               if (ret)
27290 +                       break;
27291 +
27292 +#if defined(CONFIG_MRST_RAR_HANDLER)
27293 +               rar_buf.info.handle = (__u32)rar_handler;
27294 +               rar_buf.bus_address = (dma_addr_t)dev_priv->rar_region_start;
27295 +               rar_status = 1;
27296 +
27297 +               rar_status = rar_handle_to_bus(&rar_buf, 1);
27298 +               if (rar_status != 1) {
27299 +                       DRM_ERROR("MSVDX:rar_handle_to_bus failed\n");
27300 +                       ret = -1;
27301 +                       break;
27302 +               }
27303 +                rar_status = rar_release(&rar_buf, 1);
27304 +               if (rar_status != 1)
27305 +                       DRM_ERROR("MSVDX:rar_release failed\n");
27306 +                
27307 +               offset = (uint32_t) rar_buf.bus_address - dev_priv->rar_region_start;
27308 +               PSB_DEBUG_GENERAL("MSVDX:RAR handler %p, bus address=0x%08x,"
27309 +                               "RAR region=0x%08x\n",
27310 +                               rar_handler,
27311 +                                (uint32_t)rar_buf.bus_address,
27312 +                               dev_priv->rar_region_start);
27313 +#endif
27314 +               ret = copy_to_user((void __user *)((unsigned long)arg->value),
27315 +                                  &offset,
27316 +                                  sizeof(offset));
27317 +               break;
27318 +       case LNC_VIDEO_FRAME_SKIP:
27319 +               ret = lnc_video_frameskip(dev, arg->value);
27320 +               break;
27321 +       case LNC_VIDEO_DEVICE_INFO:
27322 +               device_info = 0xffff & dev_priv->video_device_fuse;
27323 +               device_info |= (0xffff & dev->pci_device) << 16;
27324 +
27325 +               ret = copy_to_user((void __user *) ((unsigned long)arg->value),
27326 +                                  &device_info, sizeof(device_info));
27327 +               break;
27328 +       default:
27329 +               ret = -EFAULT;
27330 +               break;
27331 +       }
27332 +
27333 +       if (ret)
27334 +               return -EFAULT;
27335 +
27336 +       return 0;
27337 +}
27338 +
27339 +inline int psb_try_power_down_msvdx(struct drm_device *dev)
27340 +{
27341 +       ospm_apm_power_down_msvdx(dev);
27342 +       return 0;
27343 +}
27344 +
27345 +int psb_msvdx_save_context(struct drm_device *dev)
27346 +{
27347 +       struct drm_psb_private *dev_priv =
27348 +               (struct drm_psb_private *)dev->dev_private;
27349 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
27350 +       int offset = 0;
27351 +
27352 +       msvdx_priv->msvdx_needs_reset = 1;
27353 +
27354 +       for (offset = 0; offset < VEC_LOCAL_MEM_BYTE_SIZE / 4; ++offset)
27355 +               msvdx_priv->vec_local_mem_data[offset] =
27356 +                       PSB_RMSVDX32(VEC_LOCAL_MEM_OFFSET + offset * 4);
27357 +
27358 +       msvdx_priv->vec_local_mem_saved = 1;
27359 +
27360 +       return 0;
27361 +}
27362 +
27363 +int psb_msvdx_restore_context(struct drm_device *dev)
27364 +{
27365 +       return 0;
27366 +}
27367 diff --git a/drivers/gpu/drm/mrst/drv/psb_msvdx.h b/drivers/gpu/drm/mrst/drv/psb_msvdx.h
27368 new file mode 100644
27369 index 0000000..c067203
27370 --- /dev/null
27371 +++ b/drivers/gpu/drm/mrst/drv/psb_msvdx.h
27372 @@ -0,0 +1,610 @@
27373 +/**************************************************************************
27374 + *
27375 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
27376 + * Copyright (c) Imagination Technologies Limited, UK
27377 + *
27378 + * This program is free software; you can redistribute it and/or modify it
27379 + * under the terms and conditions of the GNU General Public License,
27380 + * version 2, as published by the Free Software Foundation.
27381 + *
27382 + * This program is distributed in the hope it will be useful, but WITHOUT
27383 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27384 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
27385 + * more details.
27386 + *
27387 + * You should have received a copy of the GNU General Public License along with
27388 + * this program; if not, write to the Free Software Foundation, Inc., 
27389 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
27390 + *
27391 + **************************************************************************/
27392 +
27393 +#ifndef _PSB_MSVDX_H_
27394 +#define _PSB_MSVDX_H_
27395 +
27396 +#include "psb_drv.h"
27397 +#include "img_types.h"
27398 +
27399 +#if defined(CONFIG_MRST_RAR_HANDLER)
27400 +#include "rar/memrar.h"
27401 +#endif
27402 +
27403 +extern int drm_msvdx_pmpolicy;
27404 +
27405 +int psb_wait_for_register(struct drm_psb_private *dev_priv,
27406 +                         uint32_t offset,
27407 +                         uint32_t value,
27408 +                         uint32_t enable);
27409 +
27410 +IMG_BOOL psb_msvdx_interrupt(IMG_VOID *pvData);
27411 +
27412 +int psb_msvdx_init(struct drm_device *dev);
27413 +int psb_msvdx_uninit(struct drm_device *dev);
27414 +int psb_msvdx_reset(struct drm_psb_private *dev_priv);
27415 +uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver);
27416 +int psb_mtx_send(struct drm_psb_private *dev_priv, const void *pvMsg);
27417 +void psb_msvdx_flush_cmd_queue(struct drm_device *dev);
27418 +void psb_msvdx_lockup(struct drm_psb_private *dev_priv,
27419 +               int *msvdx_lockup, int *msvdx_idle);
27420 +int psb_setup_fw(struct drm_device *dev);
27421 +int psb_check_msvdx_idle(struct drm_device *dev);
27422 +int psb_wait_msvdx_idle(struct drm_device *dev);
27423 +int psb_cmdbuf_video(struct drm_file *priv,
27424 +               struct list_head *validate_list,
27425 +               uint32_t fence_type,
27426 +               struct drm_psb_cmdbuf_arg *arg,
27427 +               struct ttm_buffer_object *cmd_buffer,
27428 +               struct psb_ttm_fence_rep *fence_arg);
27429 +int psb_msvdx_save_context(struct drm_device *dev);
27430 +int psb_msvdx_restore_context(struct drm_device *dev);
27431 +
27432 +bool
27433 +psb_host_second_pass(struct drm_device *dev,
27434 +               uint32_t ui32OperatingModeCmd,
27435 +               void     *pvParamBase,
27436 +               uint32_t PicWidthInMbs,
27437 +               uint32_t FrameHeightInMbs,
27438 +               uint32_t ui32DeblockSourceY,
27439 +               uint32_t ui32DeblockSourceUV);
27440 +
27441 +/*  Non-Optimal Invalidation is not default */
27442 +#define MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV 2
27443 +#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK   (0x00000100)
27444 +
27445 +#define FW_VA_RENDER_HOST_INT          0x00004000
27446 +#define MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION    0x00000020
27447 +
27448 +/* There is no work currently underway on the hardware */
27449 +#define MSVDX_FW_STATUS_HW_IDLE        0x00000001
27450 +#define MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE    0x00000200
27451 +#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0 \
27452 +       (MSVDX_DEVICE_NODE_FLAGS_MMU_NONOPT_INV |                       \
27453 +               MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION |           \
27454 +               MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
27455 +
27456 +#define MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1 \
27457 +       (MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION |                  \
27458 +               MSVDX_DEVICE_NODE_FLAG_BRN23154_BLOCK_ON_FE)
27459 +
27460 +#define POULSBO_D0     0x5
27461 +#define POULSBO_D1     0x6
27462 +#define PSB_REVID_OFFSET 0x8
27463 +
27464 +#define MTX_CODE_BASE          (0x80900000)
27465 +#define MTX_DATA_BASE          (0x82880000)
27466 +#define PC_START_ADDRESS       (0x80900000)
27467 +
27468 +#define MTX_CORE_CODE_MEM      (0x10)
27469 +#define MTX_CORE_DATA_MEM      (0x18)
27470 +
27471 +#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK         (0x00000100)
27472 +#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_SHIFT                (8)
27473 +#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK        \
27474 +       (0x00010000)
27475 +#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK        \
27476 +       (0x00100000)
27477 +#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK \
27478 +       (0x01000000)
27479 +#define MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK \
27480 +       (0x10000000)
27481 +
27482 +#define clk_enable_all \
27483 +(MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK        | \
27484 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK | \
27485 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK | \
27486 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK  | \
27487 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK | \
27488 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK | \
27489 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK)
27490 +
27491 +#define clk_enable_minimal \
27492 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
27493 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
27494 +
27495 +#define clk_enable_auto        \
27496 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_AUTO_CLK_ENABLE_MASK        | \
27497 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_AUTO_CLK_ENABLE_MASK | \
27498 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_AUTO_CLK_ENABLE_MASK                | \
27499 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_AUTO_CLK_ENABLE_MASK  | \
27500 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_AUTO_CLK_ENABLE_MASK  | \
27501 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK         | \
27502 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
27503 +
27504 +#define msvdx_sw_reset_all \
27505 +(MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK |          \
27506 +MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_FE_SOFT_RESET_MASK |        \
27507 +MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_BE_SOFT_RESET_MASK        |               \
27508 +MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_MEMIF_SOFT_RESET_MASK |       \
27509 +MSVDX_CORE_CR_MSVDX_CONTROL_CR_MSVDX_VEC_RENDEC_DEC_SOFT_RESET_MASK)
27510 +
27511 +#define MTX_INTERNAL_REG(R_SPECIFIER , U_SPECIFIER)    \
27512 +       (((R_SPECIFIER)<<4) | (U_SPECIFIER))
27513 +#define MTX_PC         MTX_INTERNAL_REG(0, 5)
27514 +
27515 +#define RENDEC_A_SIZE  (4 * 1024 * 1024)
27516 +#define RENDEC_B_SIZE  (1024 * 1024)
27517 +
27518 +#define MEMIO_READ_FIELD(vpMem, field)   \
27519 +       ((uint32_t)(((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) \
27520 +                       & field##_MASK) >> field##_SHIFT))
27521 +
27522 +#define MEMIO_WRITE_FIELD(vpMem, field, value)                         \
27523 +       (*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) =      \
27524 +               ((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) \
27525 +                       & (field##_TYPE)~field##_MASK) |                \
27526 +       (field##_TYPE)(((uint32_t)(value) << field##_SHIFT) & field##_MASK);
27527 +
27528 +#define MEMIO_WRITE_FIELD_LITE(vpMem, field, value)                    \
27529 +        (*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) =     \
27530 +       ((*((field##_TYPE*)(((uint32_t)vpMem) + field##_OFFSET))) |     \
27531 +               (field##_TYPE)(((uint32_t)(value) << field##_SHIFT)));
27532 +
27533 +#define REGIO_READ_FIELD(reg_val, reg, field)                          \
27534 +       ((reg_val & reg##_##field##_MASK) >> reg##_##field##_SHIFT)
27535 +
27536 +#define REGIO_WRITE_FIELD(reg_val, reg, field, value)                  \
27537 +       (reg_val) =                                                     \
27538 +       ((reg_val) & ~(reg##_##field##_MASK)) |                         \
27539 +               (((value) << (reg##_##field##_SHIFT)) & (reg##_##field##_MASK));
27540 +
27541 +#define REGIO_WRITE_FIELD_LITE(reg_val, reg, field, value)             \
27542 +       (reg_val) =                                                     \
27543 +       ((reg_val) | ((value) << (reg##_##field##_SHIFT)));
27544 +
27545 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK \
27546 +       (0x00000001)
27547 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK \
27548 +       (0x00000002)
27549 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK \
27550 +       (0x00000004)
27551 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK \
27552 +                       (0x00000008)
27553 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK \
27554 +       (0x00000010)
27555 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK \
27556 +       (0x00000020)
27557 +#define MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK  \
27558 +       (0x00000040)
27559 +
27560 +#define clk_enable_all \
27561 +       (MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
27562 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_PROCESS_MAN_CLK_ENABLE_MASK | \
27563 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDEB_ACCESS_MAN_CLK_ENABLE_MASK | \
27564 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VDMC_MAN_CLK_ENABLE_MASK  | \
27565 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ENTDEC_MAN_CLK_ENABLE_MASK | \
27566 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_VEC_ITRANS_MAN_CLK_ENABLE_MASK | \
27567 +MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK)
27568 +
27569 +#define clk_enable_minimal \
27570 +       MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_CORE_MAN_CLK_ENABLE_MASK | \
27571 +       MSVDX_CORE_CR_MSVDX_MAN_CLK_ENABLE_CR_MTX_MAN_CLK_ENABLE_MASK
27572 +
27573 +/* MTX registers */
27574 +#define MSVDX_MTX_ENABLE               (0x0000)
27575 +#define MSVDX_MTX_KICKI                        (0x0088)
27576 +#define MSVDX_MTX_KICK                 (0x0080)
27577 +#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST  (0x00FC)
27578 +#define MSVDX_MTX_REGISTER_READ_WRITE_DATA     (0x00F8)
27579 +#define MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER     (0x0104)
27580 +#define MSVDX_MTX_RAM_ACCESS_CONTROL   (0x0108)
27581 +#define MSVDX_MTX_RAM_ACCESS_STATUS    (0x010C)
27582 +#define MSVDX_MTX_SOFT_RESET           (0x0200)
27583 +
27584 +/* MSVDX registers */
27585 +#define MSVDX_CONTROL                  (0x0600)
27586 +#define MSVDX_INTERRUPT_CLEAR          (0x060C)
27587 +#define MSVDX_INTERRUPT_STATUS         (0x0608)
27588 +#define MSVDX_HOST_INTERRUPT_ENABLE    (0x0610)
27589 +#define MSVDX_MMU_CONTROL0             (0x0680)
27590 +#define MSVDX_MTX_RAM_BANK             (0x06F0)
27591 +#define MSVDX_MAN_CLK_ENABLE           (0x0620)
27592 +
27593 +/* RENDEC registers */
27594 +#define MSVDX_RENDEC_CONTROL0          (0x0868)
27595 +#define MSVDX_RENDEC_CONTROL1          (0x086C)
27596 +#define MSVDX_RENDEC_BUFFER_SIZE       (0x0870)
27597 +#define MSVDX_RENDEC_BASE_ADDR0                (0x0874)
27598 +#define MSVDX_RENDEC_BASE_ADDR1                (0x0878)
27599 +#define MSVDX_RENDEC_READ_DATA         (0x0898)
27600 +#define MSVDX_RENDEC_CONTEXT0          (0x0950)
27601 +#define MSVDX_RENDEC_CONTEXT1          (0x0954)
27602 +#define MSVDX_RENDEC_CONTEXT2          (0x0958)
27603 +#define MSVDX_RENDEC_CONTEXT3          (0x095C)
27604 +#define MSVDX_RENDEC_CONTEXT4          (0x0960)
27605 +#define MSVDX_RENDEC_CONTEXT5          (0x0964)
27606 +
27607 +/* CMD */
27608 +#define MSVDX_CMDS_END_SLICE_PICTURE   (0x1404)
27609 +
27610 +/*
27611 + * This defines the MSVDX communication buffer
27612 + */
27613 +#define MSVDX_COMMS_SIGNATURE_VALUE    (0xA5A5A5A5)    /*!< Signature value */
27614 +/*!< Host buffer size (in 32-bit words) */
27615 +#define NUM_WORDS_HOST_BUF             (100)
27616 +/*!< MTX buffer size (in 32-bit words) */
27617 +#define NUM_WORDS_MTX_BUF              (100)
27618 +
27619 +/* There is no work currently underway on the hardware */
27620 +#define MSVDX_FW_STATUS_HW_IDLE        0x00000001
27621 +
27622 +#define MSVDX_COMMS_AREA_ADDR (0x02fe0)
27623 +
27624 +#define MSVDX_COMMS_OFFSET_FLAGS               (MSVDX_COMMS_AREA_ADDR + 0x18)
27625 +#define        MSVDX_COMMS_MSG_COUNTER                 (MSVDX_COMMS_AREA_ADDR - 0x04)
27626 +#define MSVDX_COMMS_FW_STATUS                  (MSVDX_COMMS_AREA_ADDR - 0x10)
27627 +#define        MSVDX_COMMS_SIGNATURE                   (MSVDX_COMMS_AREA_ADDR + 0x00)
27628 +#define        MSVDX_COMMS_TO_HOST_BUF_SIZE            (MSVDX_COMMS_AREA_ADDR + 0x04)
27629 +#define MSVDX_COMMS_TO_HOST_RD_INDEX           (MSVDX_COMMS_AREA_ADDR + 0x08)
27630 +#define MSVDX_COMMS_TO_HOST_WRT_INDEX          (MSVDX_COMMS_AREA_ADDR + 0x0C)
27631 +#define MSVDX_COMMS_TO_MTX_BUF_SIZE            (MSVDX_COMMS_AREA_ADDR + 0x10)
27632 +#define MSVDX_COMMS_TO_MTX_RD_INDEX            (MSVDX_COMMS_AREA_ADDR + 0x14)
27633 +#define MSVDX_COMMS_TO_MTX_CB_RD_INDEX         (MSVDX_COMMS_AREA_ADDR + 0x18)
27634 +#define MSVDX_COMMS_TO_MTX_WRT_INDEX           (MSVDX_COMMS_AREA_ADDR + 0x1C)
27635 +#define MSVDX_COMMS_TO_HOST_BUF                        (MSVDX_COMMS_AREA_ADDR + 0x20)
27636 +#define MSVDX_COMMS_TO_MTX_BUF \
27637 +       (MSVDX_COMMS_TO_HOST_BUF + (NUM_WORDS_HOST_BUF << 2))
27638 +
27639 +/*
27640 +#define MSVDX_COMMS_AREA_END   \
27641 +       (MSVDX_COMMS_TO_MTX_BUF + (NUM_WORDS_HOST_BUF << 2))
27642 +*/
27643 +#define MSVDX_COMMS_AREA_END 0x03000
27644 +
27645 +#if (MSVDX_COMMS_AREA_END != 0x03000)
27646 +#error
27647 +#endif
27648 +
27649 +#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK  (0x80000000)
27650 +#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_SHIFT (31)
27651 +
27652 +#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_MASK     (0x00010000)
27653 +#define MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_RNW_SHIFT    (16)
27654 +
27655 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_MASK            (0x0FF00000)
27656 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMID_SHIFT           (20)
27657 +
27658 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_MASK (0x000FFFFC)
27659 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCM_ADDR_SHIFT        (2)
27660 +
27661 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_MASK    (0x00000002)
27662 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMAI_SHIFT   (1)
27663 +
27664 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_MASK     (0x00000001)
27665 +#define MSVDX_MTX_RAM_ACCESS_CONTROL_MTX_MCMR_SHIFT    (0)
27666 +
27667 +#define MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK            (0x00000001)
27668 +#define MSVDX_MTX_SOFT_RESET_MTX_RESET_SHIFT           (0)
27669 +
27670 +#define MSVDX_MTX_ENABLE_MTX_ENABLE_MASK               (0x00000001)
27671 +#define MSVDX_MTX_ENABLE_MTX_ENABLE_SHIFT              (0)
27672 +
27673 +#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK         (0x00000100)
27674 +#define MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_SHIFT                (8)
27675 +
27676 +#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_MASK   (0x00000F00)
27677 +#define MSVDX_INTERRUPT_STATUS_CR_MMU_FAULT_IRQ_SHIFT  (8)
27678 +
27679 +#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_MASK         (0x00004000)
27680 +#define MSVDX_INTERRUPT_STATUS_CR_MTX_IRQ_SHIFT                (14)
27681 +
27682 +#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK                   (0x00000002)
27683 +#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_SHIFT                  (1)
27684 +
27685 +#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_MASK           (0x000F0000)
27686 +#define MSVDX_MTX_RAM_BANK_CR_MTX_RAM_BANK_SIZE_SHIFT          (16)
27687 +
27688 +#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_MASK      (0x0000FFFF)
27689 +#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE0_SHIFT     (0)
27690 +
27691 +#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_MASK      (0xFFFF0000)
27692 +#define MSVDX_RENDEC_BUFFER_SIZE_RENDEC_BUFFER_SIZE1_SHIFT     (16)
27693 +
27694 +#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_MASK    (0x000000FF)
27695 +#define MSVDX_RENDEC_CONTROL1_RENDEC_DECODE_START_SIZE_SHIFT   (0)
27696 +
27697 +#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_MASK         (0x000C0000)
27698 +#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_W_SHIFT                (18)
27699 +
27700 +#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_MASK         (0x00030000)
27701 +#define MSVDX_RENDEC_CONTROL1_RENDEC_BURST_SIZE_R_SHIFT                (16)
27702 +
27703 +#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_MASK      (0x01000000)
27704 +#define MSVDX_RENDEC_CONTROL1_RENDEC_EXTERNAL_MEMORY_SHIFT     (24)
27705 +
27706 +#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_MASK           (0x00000001)
27707 +#define MSVDX_RENDEC_CONTROL0_RENDEC_INITIALISE_SHIFT          (0)
27708 +
27709 +#define VEC_SHIFTREG_CONTROL_SR_MASTER_SELECT_MASK         (0x00000300)
27710 +#define VEC_SHIFTREG_CONTROL_SR_MASTER_SELECT_SHIFT                (8)
27711 +
27712 +/* Start of parser specific Host->MTX messages. */
27713 +#define        FWRK_MSGID_START_PSR_HOSTMTX_MSG        (0x80)
27714 +
27715 +/* Start of parser specific MTX->Host messages. */
27716 +#define        FWRK_MSGID_START_PSR_MTXHOST_MSG        (0xC0)
27717 +
27718 +#define FWRK_MSGID_PADDING                     (0)
27719 +
27720 +#define FWRK_GENMSG_SIZE_TYPE          uint8_t
27721 +#define FWRK_GENMSG_SIZE_MASK          (0xFF)
27722 +#define FWRK_GENMSG_SIZE_SHIFT         (0)
27723 +#define FWRK_GENMSG_SIZE_OFFSET                (0x0000)
27724 +#define FWRK_GENMSG_ID_TYPE            uint8_t
27725 +#define FWRK_GENMSG_ID_MASK            (0xFF)
27726 +#define FWRK_GENMSG_ID_SHIFT           (0)
27727 +#define FWRK_GENMSG_ID_OFFSET          (0x0001)
27728 +#define FWRK_PADMSG_SIZE               (2)
27729 +
27730 +/* Deblock CMD_ID */
27731 +#define MSVDX_DEBLOCK_REG_SET   0x10000000
27732 +#define MSVDX_DEBLOCK_REG_GET   0x20000000
27733 +#define MSVDX_DEBLOCK_REG_POLLn 0x30000000
27734 +#define MSVDX_DEBLOCK_REG_POLLx 0x40000000
27735 +
27736 +/* vec local MEM save/restore */
27737 +#define VEC_LOCAL_MEM_BYTE_SIZE (4 * 1024)
27738 +#define VEC_LOCAL_MEM_OFFSET 0x2000
27739 +
27740 +/* This type defines the framework specified message ids */
27741 +enum {
27742 +       /* ! Sent by the DXVA driver on the host to the mtx firmware.
27743 +        */
27744 +       VA_MSGID_INIT = FWRK_MSGID_START_PSR_HOSTMTX_MSG,
27745 +       VA_MSGID_RENDER,
27746 +       VA_MSGID_DEBLOCK,
27747 +       VA_MSGID_BUBBLE,
27748 +
27749 +       /* Test Messages */
27750 +       VA_MSGID_TEST1,
27751 +       VA_MSGID_TEST2,
27752 +
27753 +       /*! Sent by the mtx firmware to itself.
27754 +        */
27755 +       VA_MSGID_RENDER_MC_INTERRUPT,
27756 +
27757 +       /*! Sent by the DXVA firmware on the MTX to the host.
27758 +        */
27759 +       VA_MSGID_CMD_COMPLETED = FWRK_MSGID_START_PSR_MTXHOST_MSG,
27760 +       VA_MSGID_CMD_COMPLETED_BATCH,
27761 +       VA_MSGID_DEBLOCK_REQUIRED,
27762 +       VA_MSGID_TEST_RESPONCE,
27763 +       VA_MSGID_ACK,
27764 +
27765 +       VA_MSGID_CMD_FAILED,
27766 +       VA_MSGID_CMD_UNSUPPORTED,
27767 +       VA_MSGID_CMD_HW_PANIC,
27768 +};
27769 +
27770 +/* Deblock parameters */
27771 +struct DEBLOCKPARAMS {
27772 +       uint32_t handle;        /* struct ttm_buffer_object * of REGIO */
27773 +       uint32_t buffer_size;
27774 +       uint32_t ctxid;
27775 +
27776 +       uint32_t *pPicparams;
27777 +       struct ttm_bo_kmap_obj *regio_kmap;     /* virtual of regio */
27778 +       uint32_t pad[3];
27779 +};
27780 +
27781 +struct psb_msvdx_deblock_queue {
27782 +
27783 +       struct list_head head;
27784 +       struct DEBLOCKPARAMS dbParams;
27785 +};
27786 +
27787 +/* MSVDX private structure */
27788 +struct msvdx_private {
27789 +       int msvdx_needs_reset;
27790 +
27791 +       unsigned int pmstate;
27792 +
27793 +       struct sysfs_dirent *sysfs_pmstate;
27794 +
27795 +       uint32_t msvdx_current_sequence;
27796 +       uint32_t msvdx_last_sequence;
27797 +
27798 +       /*
27799 +        *MSVDX Rendec Memory
27800 +        */
27801 +       struct ttm_buffer_object *ccb0;
27802 +       uint32_t base_addr0;
27803 +       struct ttm_buffer_object *ccb1;
27804 +       uint32_t base_addr1;
27805 +
27806 +       /*
27807 +        *msvdx command queue
27808 +        */
27809 +       spinlock_t msvdx_lock;
27810 +       struct mutex msvdx_mutex;
27811 +       struct list_head msvdx_queue;
27812 +       int msvdx_busy;
27813 +       int msvdx_fw_loaded;
27814 +       void *msvdx_fw;
27815 +       int msvdx_fw_size;
27816 +
27817 +       struct list_head deblock_queue; /* deblock parameter list */
27818 +
27819 +       uint32_t msvdx_hw_busy;
27820 +
27821 +       uint32_t *vec_local_mem_data;
27822 +       uint32_t vec_local_mem_size;
27823 +       uint32_t vec_local_mem_saved;
27824 +};
27825 +
27826 +/* MSVDX Firmware interface */
27827 +#define FW_VA_INIT_SIZE                        (8)
27828 +#define FW_VA_DEBUG_TEST2_SIZE         (4)
27829 +
27830 +/* FW_VA_DEBUG_TEST2     MSG_SIZE */
27831 +#define FW_VA_DEBUG_TEST2_MSG_SIZE_TYPE                uint8_t
27832 +#define FW_VA_DEBUG_TEST2_MSG_SIZE_MASK                (0xFF)
27833 +#define FW_VA_DEBUG_TEST2_MSG_SIZE_OFFSET      (0x0000)
27834 +#define FW_VA_DEBUG_TEST2_MSG_SIZE_SHIFT       (0)
27835 +
27836 +/* FW_VA_DEBUG_TEST2     ID */
27837 +#define FW_VA_DEBUG_TEST2_ID_TYPE              uint8_t
27838 +#define FW_VA_DEBUG_TEST2_ID_MASK              (0xFF)
27839 +#define FW_VA_DEBUG_TEST2_ID_OFFSET            (0x0001)
27840 +#define FW_VA_DEBUG_TEST2_ID_SHIFT             (0)
27841 +
27842 +/* FW_VA_CMD_FAILED     FENCE_VALUE */
27843 +#define FW_VA_CMD_FAILED_FENCE_VALUE_TYPE      uint32_t
27844 +#define FW_VA_CMD_FAILED_FENCE_VALUE_MASK      (0xFFFFFFFF)
27845 +#define FW_VA_CMD_FAILED_FENCE_VALUE_OFFSET    (0x0004)
27846 +#define FW_VA_CMD_FAILED_FENCE_VALUE_SHIFT     (0)
27847 +
27848 +/* FW_VA_CMD_FAILED     IRQSTATUS */
27849 +#define FW_VA_CMD_FAILED_IRQSTATUS_TYPE                uint32_t
27850 +#define FW_VA_CMD_FAILED_IRQSTATUS_MASK                (0xFFFFFFFF)
27851 +#define FW_VA_CMD_FAILED_IRQSTATUS_OFFSET      (0x0008)
27852 +#define FW_VA_CMD_FAILED_IRQSTATUS_SHIFT       (0)
27853 +
27854 +/* FW_VA_CMD_COMPLETED     FENCE_VALUE */
27855 +#define FW_VA_CMD_COMPLETED_FENCE_VALUE_TYPE   uint32_t
27856 +#define FW_VA_CMD_COMPLETED_FENCE_VALUE_MASK   (0xFFFFFFFF)
27857 +#define FW_VA_CMD_COMPLETED_FENCE_VALUE_OFFSET (0x0004)
27858 +#define FW_VA_CMD_COMPLETED_FENCE_VALUE_SHIFT  (0)
27859 +
27860 +/* FW_VA_CMD_COMPLETED     FLAGS */
27861 +#define FW_VA_CMD_COMPLETED_FLAGS_ALIGNMENT            (4)
27862 +#define FW_VA_CMD_COMPLETED_FLAGS_TYPE         uint32_t
27863 +#define FW_VA_CMD_COMPLETED_FLAGS_MASK         (0xFFFFFFFF)
27864 +#define FW_VA_CMD_COMPLETED_FLAGS_LSBMASK              (0xFFFFFFFF)
27865 +#define FW_VA_CMD_COMPLETED_FLAGS_OFFSET               (0x0008)
27866 +#define FW_VA_CMD_COMPLETED_FLAGS_SHIFT                (0)
27867 +
27868 +/* FW_VA_CMD_COMPLETED     NO_TICKS */
27869 +#define FW_VA_CMD_COMPLETED_NO_TICKS_TYPE      uint16_t
27870 +#define FW_VA_CMD_COMPLETED_NO_TICKS_MASK      (0xFFFF)
27871 +#define FW_VA_CMD_COMPLETED_NO_TICKS_OFFSET    (0x0002)
27872 +#define FW_VA_CMD_COMPLETED_NO_TICKS_SHIFT     (0)
27873 +
27874 +/* FW_VA_DEBLOCK_REQUIRED     CONTEXT */
27875 +#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_TYPE    uint32_t
27876 +#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_MASK    (0xFFFFFFFF)
27877 +#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_OFFSET  (0x0004)
27878 +#define FW_VA_DEBLOCK_REQUIRED_CONTEXT_SHIFT   (0)
27879 +
27880 +/* FW_VA_INIT     GLOBAL_PTD */
27881 +#define FW_VA_INIT_GLOBAL_PTD_TYPE             uint32_t
27882 +#define FW_VA_INIT_GLOBAL_PTD_MASK             (0xFFFFFFFF)
27883 +#define FW_VA_INIT_GLOBAL_PTD_OFFSET           (0x0004)
27884 +#define FW_VA_INIT_GLOBAL_PTD_SHIFT            (0)
27885 +
27886 +/* FW_VA_RENDER     FENCE_VALUE */
27887 +#define FW_VA_RENDER_FENCE_VALUE_TYPE          uint32_t
27888 +#define FW_VA_RENDER_FENCE_VALUE_MASK          (0xFFFFFFFF)
27889 +#define FW_VA_RENDER_FENCE_VALUE_OFFSET                (0x0010)
27890 +#define FW_VA_RENDER_FENCE_VALUE_SHIFT         (0)
27891 +
27892 +/* FW_VA_RENDER     MMUPTD */
27893 +#define FW_VA_RENDER_MMUPTD_TYPE               uint32_t
27894 +#define FW_VA_RENDER_MMUPTD_MASK               (0xFFFFFFFF)
27895 +#define FW_VA_RENDER_MMUPTD_OFFSET             (0x0004)
27896 +#define FW_VA_RENDER_MMUPTD_SHIFT              (0)
27897 +
27898 +/* FW_VA_RENDER     BUFFER_ADDRESS */
27899 +#define FW_VA_RENDER_BUFFER_ADDRESS_TYPE       uint32_t
27900 +#define FW_VA_RENDER_BUFFER_ADDRESS_MASK       (0xFFFFFFFF)
27901 +#define FW_VA_RENDER_BUFFER_ADDRESS_OFFSET     (0x0008)
27902 +#define FW_VA_RENDER_BUFFER_ADDRESS_SHIFT      (0)
27903 +
27904 +/* FW_VA_RENDER     BUFFER_SIZE */
27905 +#define FW_VA_RENDER_BUFFER_SIZE_TYPE           uint16_t
27906 +#define FW_VA_RENDER_BUFFER_SIZE_MASK           (0x0FFF)
27907 +#define FW_VA_RENDER_BUFFER_SIZE_OFFSET         (0x0002)
27908 +#define FW_VA_RENDER_BUFFER_SIZE_SHIFT          (0)
27909 +
27910 + /* FW_DXVA_DEBLOCK     MSG_SIZE */
27911 +#define FW_DXVA_DEBLOCK_MSG_SIZE_ALIGNMENT              (1)
27912 +#define FW_DXVA_DEBLOCK_MSG_SIZE_TYPE           uint8_t
27913 +#define FW_DXVA_DEBLOCK_MSG_SIZE_MASK           (0xFF)
27914 +#define FW_DXVA_DEBLOCK_MSG_SIZE_LSBMASK                (0xFF)
27915 +#define FW_DXVA_DEBLOCK_MSG_SIZE_OFFSET         (0x0000)
27916 +#define FW_DXVA_DEBLOCK_MSG_SIZE_SHIFT          (0)
27917 +
27918 +/* FW_DXVA_DEBLOCK     ID */
27919 +#define FW_DXVA_DEBLOCK_ID_ALIGNMENT            (1)
27920 +#define FW_DXVA_DEBLOCK_ID_TYPE         uint8_t
27921 +#define FW_DXVA_DEBLOCK_ID_MASK         (0xFF)
27922 +#define FW_DXVA_DEBLOCK_ID_LSBMASK              (0xFF)
27923 +#define FW_DXVA_DEBLOCK_ID_OFFSET               (0x0001)
27924 +#define FW_DXVA_DEBLOCK_ID_SHIFT                (0)
27925 +
27926 +/* FW_DXVA_DEBLOCK     FENCE_VALUE */
27927 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_ALIGNMENT           (4)
27928 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_TYPE                uint32_t
27929 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_MASK                (0xFFFFFFFF)
27930 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_LSBMASK             (0xFFFFFFFF)
27931 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_OFFSET              (0x0008)
27932 +#define FW_DXVA_DEBLOCK_FENCE_VALUE_SHIFT               (0)
27933 +
27934 +/* FW_DXVA_DEBLOCK     MMUPTD */
27935 +#define FW_DXVA_DEBLOCK_MMUPTD_ALIGNMENT                (4)
27936 +#define FW_DXVA_DEBLOCK_MMUPTD_TYPE             uint32_t
27937 +#define FW_DXVA_DEBLOCK_MMUPTD_MASK             (0xFFFFFFFF)
27938 +#define FW_DXVA_DEBLOCK_MMUPTD_LSBMASK          (0xFFFFFFFF)
27939 +#define FW_DXVA_DEBLOCK_MMUPTD_OFFSET           (0x000C)
27940 +#define FW_DXVA_DEBLOCK_MMUPTD_SHIFT            (0)
27941 +
27942 +
27943 +static inline void psb_msvdx_clearirq(struct drm_device *dev)
27944 +{
27945 +       struct drm_psb_private *dev_priv = dev->dev_private;
27946 +       unsigned long mtx_int = 0;
27947 +
27948 +       PSB_DEBUG_IRQ("MSVDX: clear IRQ\n");
27949 +
27950 +       /* Clear MTX interrupt */
27951 +       REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
27952 +                              1);
27953 +       PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
27954 +}
27955 +
27956 +
27957 +static inline void psb_msvdx_disableirq(struct drm_device *dev)
27958 +{
27959 +       /* nothing */
27960 +}
27961 +
27962 +
27963 +static inline void psb_msvdx_enableirq(struct drm_device *dev)
27964 +{
27965 +       struct drm_psb_private *dev_priv = dev->dev_private;
27966 +       unsigned long enables = 0;
27967 +
27968 +       PSB_DEBUG_IRQ("MSVDX: enable MSVDX MTX IRQ\n");
27969 +       REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
27970 +                       1);
27971 +       PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE);
27972 +}
27973 +
27974 +#define MSVDX_NEW_PMSTATE(drm_dev, msvdx_priv, new_state)              \
27975 +do {                                                                   \
27976 +       msvdx_priv->pmstate = new_state;                                \
27977 +       sysfs_notify_dirent(msvdx_priv->sysfs_pmstate);                 \
27978 +       PSB_DEBUG_PM("MSVDX: %s\n",                                     \
27979 +               (new_state == PSB_PMSTATE_POWERUP) ? "powerup": "powerdown"); \
27980 +} while (0)
27981 +
27982 +#endif
27983 diff --git a/drivers/gpu/drm/mrst/drv/psb_msvdxinit.c b/drivers/gpu/drm/mrst/drv/psb_msvdxinit.c
27984 new file mode 100644
27985 index 0000000..a543778
27986 --- /dev/null
27987 +++ b/drivers/gpu/drm/mrst/drv/psb_msvdxinit.c
27988 @@ -0,0 +1,770 @@
27989 +/**************************************************************************
27990 + * psb_msvdxinit.c
27991 + * MSVDX initialization and mtx-firmware upload
27992 + *
27993 + * Copyright (c) 2007 Intel Corporation, Hillsboro, OR, USA
27994 + * Copyright (c) Imagination Technologies Limited, UK
27995 + *
27996 + * This program is free software; you can redistribute it and/or modify it
27997 + * under the terms and conditions of the GNU General Public License,
27998 + * version 2, as published by the Free Software Foundation.
27999 + *
28000 + * This program is distributed in the hope it will be useful, but WITHOUT
28001 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28002 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
28003 + * more details.
28004 + *
28005 + * You should have received a copy of the GNU General Public License along with
28006 + * this program; if not, write to the Free Software Foundation, Inc., 
28007 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
28008 + *
28009 + **************************************************************************/
28010 +
28011 +#include <drm/drmP.h>
28012 +#include <drm/drm.h>
28013 +#include "psb_drv.h"
28014 +#include "psb_msvdx.h"
28015 +#include <linux/firmware.h>
28016 +
28017 +#define MSVDX_REG (dev_priv->msvdx_reg)
28018 +uint8_t psb_rev_id;
28019 +/*MSVDX FW header*/
28020 +struct msvdx_fw {
28021 +       uint32_t ver;
28022 +       uint32_t text_size;
28023 +       uint32_t data_size;
28024 +       uint32_t data_location;
28025 +};
28026 +
28027 +int psb_wait_for_register(struct drm_psb_private *dev_priv,
28028 +                         uint32_t offset, uint32_t value, uint32_t enable)
28029 +{
28030 +       uint32_t tmp;
28031 +       uint32_t poll_cnt = 10000;
28032 +       while (poll_cnt) {
28033 +               tmp = PSB_RMSVDX32(offset);
28034 +               if (value == (tmp & enable))    /* All the bits are reset   */
28035 +                       return 0;       /* So exit                      */
28036 +
28037 +               /* Wait a bit */
28038 +               DRM_UDELAY(1000);
28039 +               poll_cnt--;
28040 +       }
28041 +       DRM_ERROR("MSVDX: Timeout while waiting for register %08x:"
28042 +                 " expecting %08x (mask %08x), got %08x\n",
28043 +                 offset, value, enable, tmp);
28044 +
28045 +       return 1;
28046 +}
28047 +
28048 +int psb_poll_mtx_irq(struct drm_psb_private *dev_priv)
28049 +{
28050 +       int ret = 0;
28051 +       uint32_t mtx_int = 0;
28052 +
28053 +       REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS, CR_MTX_IRQ,
28054 +                              1);
28055 +
28056 +       ret = psb_wait_for_register(dev_priv, MSVDX_INTERRUPT_STATUS,
28057 +                                   /* Required value */
28058 +                                   mtx_int,
28059 +                                   /* Enabled bits */
28060 +                                   mtx_int);
28061 +
28062 +       if (ret) {
28063 +               DRM_ERROR("MSVDX: Error Mtx did not return"
28064 +                         " int within a resonable time\n");
28065 +               return ret;
28066 +       }
28067 +
28068 +       PSB_DEBUG_IRQ("MSVDX: Got MTX Int\n");
28069 +
28070 +       /* Got it so clear the bit */
28071 +       PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
28072 +
28073 +       return ret;
28074 +}
28075 +
28076 +void psb_write_mtx_core_reg(struct drm_psb_private *dev_priv,
28077 +                           const uint32_t core_reg, const uint32_t val)
28078 +{
28079 +       uint32_t reg = 0;
28080 +
28081 +       /* Put data in MTX_RW_DATA */
28082 +       PSB_WMSVDX32(val, MSVDX_MTX_REGISTER_READ_WRITE_DATA);
28083 +
28084 +       /* DREADY is set to 0 and request a write */
28085 +       reg = core_reg;
28086 +       REGIO_WRITE_FIELD_LITE(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
28087 +                              MTX_RNW, 0);
28088 +       REGIO_WRITE_FIELD_LITE(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
28089 +                              MTX_DREADY, 0);
28090 +       PSB_WMSVDX32(reg, MSVDX_MTX_REGISTER_READ_WRITE_REQUEST);
28091 +
28092 +       psb_wait_for_register(dev_priv,
28093 +                       MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
28094 +                       MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK,
28095 +                       MSVDX_MTX_REGISTER_READ_WRITE_REQUEST_MTX_DREADY_MASK);
28096 +}
28097 +
28098 +void psb_upload_fw(struct drm_psb_private *dev_priv,
28099 +                  const uint32_t data_mem, uint32_t ram_bank_size,
28100 +                  uint32_t address, const unsigned int words,
28101 +                  const uint32_t * const data)
28102 +{
28103 +       uint32_t loop, ctrl, ram_id, addr, cur_bank = (uint32_t) ~0;
28104 +       uint32_t access_ctrl;
28105 +
28106 +       /* Save the access control register... */
28107 +       access_ctrl = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_CONTROL);
28108 +
28109 +       /* Wait for MCMSTAT to become be idle 1 */
28110 +       psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
28111 +                             1,        /* Required Value */
28112 +                             0xffffffff /* Enables */);
28113 +
28114 +       for (loop = 0; loop < words; loop++) {
28115 +               ram_id = data_mem + (address / ram_bank_size);
28116 +               if (ram_id != cur_bank) {
28117 +                       addr = address >> 2;
28118 +                       ctrl = 0;
28119 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28120 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28121 +                                              MTX_MCMID, ram_id);
28122 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28123 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28124 +                                              MTX_MCM_ADDR, addr);
28125 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28126 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28127 +                                              MTX_MCMAI, 1);
28128 +                       PSB_WMSVDX32(ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
28129 +                       cur_bank = ram_id;
28130 +               }
28131 +               address += 4;
28132 +
28133 +               PSB_WMSVDX32(data[loop],
28134 +                            MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
28135 +
28136 +               /* Wait for MCMSTAT to become be idle 1 */
28137 +               psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
28138 +                                     1,        /* Required Value */
28139 +                                     0xffffffff /* Enables */);
28140 +       }
28141 +       PSB_DEBUG_GENERAL("MSVDX: Upload done\n");
28142 +
28143 +       /* Restore the access control register... */
28144 +       PSB_WMSVDX32(access_ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
28145 +}
28146 +
28147 +static int psb_verify_fw(struct drm_psb_private *dev_priv,
28148 +                        const uint32_t ram_bank_size,
28149 +                        const uint32_t data_mem, uint32_t address,
28150 +                        const uint32_t words, const uint32_t * const data)
28151 +{
28152 +       uint32_t loop, ctrl, ram_id, addr, cur_bank = (uint32_t) ~0;
28153 +       uint32_t access_ctrl;
28154 +       int ret = 0;
28155 +
28156 +       /* Save the access control register... */
28157 +       access_ctrl = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_CONTROL);
28158 +
28159 +       /* Wait for MCMSTAT to become be idle 1 */
28160 +       psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
28161 +                             1,        /* Required Value */
28162 +                             0xffffffff /* Enables */);
28163 +
28164 +       for (loop = 0; loop < words; loop++) {
28165 +               uint32_t tmp;
28166 +               ram_id = data_mem + (address / ram_bank_size);
28167 +
28168 +               if (ram_id != cur_bank) {
28169 +                       addr = address >> 2;
28170 +                       ctrl = 0;
28171 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28172 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28173 +                                              MTX_MCMID, ram_id);
28174 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28175 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28176 +                                              MTX_MCM_ADDR, addr);
28177 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28178 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28179 +                                              MTX_MCMAI, 1);
28180 +                       REGIO_WRITE_FIELD_LITE(ctrl,
28181 +                                              MSVDX_MTX_RAM_ACCESS_CONTROL,
28182 +                                              MTX_MCMR, 1);
28183 +
28184 +                       PSB_WMSVDX32(ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
28185 +
28186 +                       cur_bank = ram_id;
28187 +               }
28188 +               address += 4;
28189 +
28190 +               /* Wait for MCMSTAT to become be idle 1 */
28191 +               psb_wait_for_register(dev_priv, MSVDX_MTX_RAM_ACCESS_STATUS,
28192 +                                     1,        /* Required Value */
28193 +                                     0xffffffff /* Enables */);
28194 +
28195 +               tmp = PSB_RMSVDX32(MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
28196 +               if (data[loop] != tmp) {
28197 +                       DRM_ERROR("psb: Firmware validation fails"
28198 +                                 " at index=%08x\n", loop);
28199 +                       ret = 1;
28200 +                       break;
28201 +               }
28202 +       }
28203 +
28204 +       /* Restore the access control register... */
28205 +       PSB_WMSVDX32(access_ctrl, MSVDX_MTX_RAM_ACCESS_CONTROL);
28206 +
28207 +       return ret;
28208 +}
28209 +
28210 +static uint32_t *msvdx_get_fw(struct drm_device *dev,
28211 +                             const struct firmware **raw, uint8_t *name)
28212 +{
28213 +       struct drm_psb_private *dev_priv = dev->dev_private;
28214 +       int rc, fw_size;
28215 +       int *ptr = NULL;
28216 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
28217 +
28218 +       rc = request_firmware(raw, name, &dev->pdev->dev);
28219 +       if (rc < 0) {
28220 +               DRM_ERROR("MSVDX: %s request_firmware failed: Reason %d\n",
28221 +                         name, rc);
28222 +               return NULL;
28223 +       }
28224 +
28225 +       if ((*raw)->size < sizeof(struct msvdx_fw)) {
28226 +               DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
28227 +                         name, (*raw)->size);
28228 +               return NULL;
28229 +       }
28230 +
28231 +       ptr = (int *) ((*raw))->data;
28232 +
28233 +       if (!ptr) {
28234 +               DRM_ERROR("MSVDX: Failed to load %s\n", name);
28235 +               return NULL;
28236 +       }
28237 +
28238 +       /* another sanity check... */
28239 +       fw_size = sizeof(struct msvdx_fw) +
28240 +           sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->text_size +
28241 +           sizeof(uint32_t) * ((struct msvdx_fw *) ptr)->data_size;
28242 +       if ((*raw)->size != fw_size) {
28243 +               DRM_ERROR("MSVDX: %s is is not correct size(%zd)\n",
28244 +                         name, (*raw)->size);
28245 +               return NULL;
28246 +       }
28247 +       msvdx_priv->msvdx_fw = kzalloc(fw_size, GFP_KERNEL);
28248 +       if (msvdx_priv->msvdx_fw == NULL)
28249 +               DRM_ERROR("MSVDX: allocate FW buffer failed\n");
28250 +       else {
28251 +               memcpy(msvdx_priv->msvdx_fw, ptr, fw_size);
28252 +               msvdx_priv->msvdx_fw_size = fw_size;
28253 +       }
28254 +
28255 +       PSB_DEBUG_GENERAL("MSVDX: releasing firmware resouces\n");
28256 +       release_firmware(*raw);
28257 +
28258 +       return msvdx_priv->msvdx_fw;
28259 +}
28260 +
28261 +int psb_setup_fw(struct drm_device *dev)
28262 +{
28263 +       struct drm_psb_private *dev_priv = dev->dev_private;
28264 +       int ret = 0;
28265 +
28266 +       uint32_t ram_bank_size;
28267 +       struct msvdx_fw *fw;
28268 +       uint32_t *fw_ptr = NULL;
28269 +       uint32_t *text_ptr = NULL;
28270 +       uint32_t *data_ptr = NULL;
28271 +       const struct firmware *raw = NULL;
28272 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
28273 +
28274 +       /* todo : Assert the clock is on - if not turn it on to upload code */
28275 +       PSB_DEBUG_GENERAL("MSVDX: psb_setup_fw\n");
28276 +       PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
28277 +
28278 +       /* Reset MTX */
28279 +       PSB_WMSVDX32(MSVDX_MTX_SOFT_RESET_MTX_RESET_MASK,
28280 +                    MSVDX_MTX_SOFT_RESET);
28281 +
28282 +       /* Initialses Communication controll area to 0 */
28283 +/*
28284 +       if (psb_rev_id >= POULSBO_D1) {
28285 +               PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D1"
28286 +                                 " or later revision.\n");
28287 +               PSB_WMSVDX32(MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1,
28288 +                            MSVDX_COMMS_OFFSET_FLAGS);
28289 +       } else {
28290 +               PSB_DEBUG_GENERAL("MSVDX: Detected Poulsbo D0"
28291 +                                 " or earlier revision.\n");
28292 +               PSB_WMSVDX32(MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0,
28293 +                            MSVDX_COMMS_OFFSET_FLAGS);
28294 +       }
28295 +*/
28296 +
28297 +       PSB_WMSVDX32(0, MSVDX_COMMS_MSG_COUNTER);
28298 +       PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE);
28299 +       PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_RD_INDEX);
28300 +       PSB_WMSVDX32(0, MSVDX_COMMS_TO_HOST_WRT_INDEX);
28301 +       PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_RD_INDEX);
28302 +       PSB_WMSVDX32(0, MSVDX_COMMS_TO_MTX_WRT_INDEX);
28303 +       PSB_WMSVDX32(0, MSVDX_COMMS_FW_STATUS);
28304 +       PSB_WMSVDX32(0, MSVDX_COMMS_OFFSET_FLAGS);
28305 +       PSB_WMSVDX32(0, MSVDX_COMMS_SIGNATURE);
28306 +       /* read register bank size */
28307 +       {
28308 +               uint32_t bank_size, reg;
28309 +               reg = PSB_RMSVDX32(MSVDX_MTX_RAM_BANK);
28310 +               bank_size =
28311 +                   REGIO_READ_FIELD(reg, MSVDX_MTX_RAM_BANK,
28312 +                                    CR_MTX_RAM_BANK_SIZE);
28313 +               ram_bank_size = (uint32_t) (1 << (bank_size + 2));
28314 +       }
28315 +
28316 +       PSB_DEBUG_GENERAL("MSVDX: RAM bank size = %d bytes\n",
28317 +                         ram_bank_size);
28318 +
28319 +       /* if FW already loaded from storage */
28320 +       if (msvdx_priv->msvdx_fw)
28321 +               fw_ptr = msvdx_priv->msvdx_fw;
28322 +       else {
28323 +               PSB_DEBUG_GENERAL("MSVDX:load msvdx_fw.bin by udevd\n");
28324 +               fw_ptr = msvdx_get_fw(dev, &raw, "msvdx_fw.bin");
28325 +       }
28326 +
28327 +       if (!fw_ptr) {
28328 +               DRM_ERROR("MSVDX:load msvdx_fw.bin failed,is udevd running?\n");
28329 +               ret = 1;
28330 +               goto out;
28331 +       }
28332 +
28333 +       fw = (struct msvdx_fw *) fw_ptr;
28334 +       if (fw->ver != 0x02) {
28335 +               DRM_ERROR("psb: msvdx_fw.bin firmware version mismatch,"
28336 +                         "got version=%02x expected version=%02x\n",
28337 +                         fw->ver, 0x02);
28338 +               ret = 1;
28339 +               goto out;
28340 +       }
28341 +
28342 +       text_ptr =
28343 +           (uint32_t *) ((uint8_t *) fw_ptr + sizeof(struct msvdx_fw));
28344 +       data_ptr = text_ptr + fw->text_size;
28345 +
28346 +       if (fw->text_size == 2858)
28347 +               PSB_DEBUG_GENERAL(
28348 +                       "MSVDX: FW ver 1.00.10.0187 of SliceSwitch variant\n");
28349 +       else if (fw->text_size == 3021)
28350 +               PSB_DEBUG_GENERAL(
28351 +                       "MSVDX: FW ver 1.00.10.0187 of FrameSwitch variant\n");
28352 +       else if (fw->text_size == 2841)
28353 +               PSB_DEBUG_GENERAL("MSVDX: FW ver 1.00.10.0788\n");
28354 +       else
28355 +               PSB_DEBUG_GENERAL("MSVDX: FW ver unknown\n");
28356 +
28357 +
28358 +       PSB_DEBUG_GENERAL("MSVDX: Retrieved pointers for firmware\n");
28359 +       PSB_DEBUG_GENERAL("MSVDX: text_size: %d\n", fw->text_size);
28360 +       PSB_DEBUG_GENERAL("MSVDX: data_size: %d\n", fw->data_size);
28361 +       PSB_DEBUG_GENERAL("MSVDX: data_location: 0x%x\n",
28362 +                         fw->data_location);
28363 +       PSB_DEBUG_GENERAL("MSVDX: First 4 bytes of text: 0x%x\n",
28364 +                         *text_ptr);
28365 +       PSB_DEBUG_GENERAL("MSVDX: First 4 bytes of data: 0x%x\n",
28366 +                         *data_ptr);
28367 +
28368 +       PSB_DEBUG_GENERAL("MSVDX: Uploading firmware\n");
28369 +       psb_upload_fw(dev_priv, MTX_CORE_CODE_MEM, ram_bank_size,
28370 +                     PC_START_ADDRESS - MTX_CODE_BASE, fw->text_size,
28371 +                     text_ptr);
28372 +       psb_upload_fw(dev_priv, MTX_CORE_DATA_MEM, ram_bank_size,
28373 +                     fw->data_location - MTX_DATA_BASE, fw->data_size,
28374 +                     data_ptr);
28375 +
28376 +#if 0
28377 +       /* todo :  Verify code upload possibly only in debug */
28378 +       ret = psb_verify_fw(dev_priv, ram_bank_size,
28379 +                           MTX_CORE_CODE_MEM,
28380 +                           PC_START_ADDRESS - MTX_CODE_BASE,
28381 +                           fw->text_size, text_ptr);
28382 +       if (ret) {
28383 +               /* Firmware code upload failed */
28384 +               ret = 1;
28385 +               goto out;
28386 +       }
28387 +
28388 +       ret = psb_verify_fw(dev_priv, ram_bank_size, MTX_CORE_DATA_MEM,
28389 +                           fw->data_location - MTX_DATA_BASE,
28390 +                           fw->data_size, data_ptr);
28391 +       if (ret) {
28392 +               /* Firmware data upload failed */
28393 +               ret = 1;
28394 +               goto out;
28395 +       }
28396 +#else
28397 +       (void)psb_verify_fw;
28398 +#endif
28399 +       /*      -- Set starting PC address      */
28400 +       psb_write_mtx_core_reg(dev_priv, MTX_PC, PC_START_ADDRESS);
28401 +
28402 +       /*      -- Turn on the thread   */
28403 +       PSB_WMSVDX32(MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, MSVDX_MTX_ENABLE);
28404 +
28405 +       /* Wait for the signature value to be written back */
28406 +       ret = psb_wait_for_register(dev_priv, MSVDX_COMMS_SIGNATURE,
28407 +                               MSVDX_COMMS_SIGNATURE_VALUE, /*Required value*/
28408 +                               0xffffffff /* Enabled bits */);
28409 +       if (ret) {
28410 +               DRM_ERROR("MSVDX: firmware fails to initialize.\n");
28411 +               goto out;
28412 +       }
28413 +
28414 +       PSB_DEBUG_GENERAL("MSVDX: MTX Initial indications OK\n");
28415 +       PSB_DEBUG_GENERAL("MSVDX: MSVDX_COMMS_AREA_ADDR = %08x\n",
28416 +                         MSVDX_COMMS_AREA_ADDR);
28417 +#if 0
28418 +
28419 +       /* Send test message */
28420 +       {
28421 +               uint32_t msg_buf[FW_VA_DEBUG_TEST2_SIZE >> 2];
28422 +
28423 +               MEMIO_WRITE_FIELD(msg_buf, FW_VA_DEBUG_TEST2_MSG_SIZE,
28424 +                                 FW_VA_DEBUG_TEST2_SIZE);
28425 +               MEMIO_WRITE_FIELD(msg_buf, FW_VA_DEBUG_TEST2_ID,
28426 +                                 VA_MSGID_TEST2);
28427 +
28428 +               ret = psb_mtx_send(dev_priv, msg_buf);
28429 +               if (ret) {
28430 +                       DRM_ERROR("psb: MSVDX sending fails.\n");
28431 +                       goto out;
28432 +               }
28433 +
28434 +               /* Wait for Mtx to ack this message */
28435 +               psb_poll_mtx_irq(dev_priv);
28436 +
28437 +       }
28438 +#endif
28439 +out:
28440 +
28441 +       return ret;
28442 +}
28443 +
28444 +
28445 +static void psb_free_ccb(struct ttm_buffer_object **ccb)
28446 +{
28447 +       ttm_bo_unref(ccb);
28448 +       *ccb = NULL;
28449 +}
28450 +
28451 +/**
28452 + * Reset chip and disable interrupts.
28453 + * Return 0 success, 1 failure
28454 + */
28455 +int psb_msvdx_reset(struct drm_psb_private *dev_priv)
28456 +{
28457 +       int ret = 0;
28458 +
28459 +       /* Issue software reset */
28460 +       PSB_WMSVDX32(msvdx_sw_reset_all, MSVDX_CONTROL);
28461 +
28462 +       ret = psb_wait_for_register(dev_priv, MSVDX_CONTROL, 0,
28463 +                                   MSVDX_CONTROL_CR_MSVDX_SOFT_RESET_MASK);
28464 +
28465 +       if (!ret) {
28466 +               /* Clear interrupt enabled flag */
28467 +               PSB_WMSVDX32(0, MSVDX_HOST_INTERRUPT_ENABLE);
28468 +
28469 +               /* Clear any pending interrupt flags */
28470 +               PSB_WMSVDX32(0xFFFFFFFF, MSVDX_INTERRUPT_CLEAR);
28471 +       }
28472 +
28473 +       /* mutex_destroy(&msvdx_priv->msvdx_mutex); */
28474 +
28475 +       return ret;
28476 +}
28477 +
28478 +static int psb_allocate_ccb(struct drm_device *dev,
28479 +                           struct ttm_buffer_object **ccb,
28480 +                           uint32_t *base_addr, unsigned long size)
28481 +{
28482 +       struct drm_psb_private *dev_priv = psb_priv(dev);
28483 +       struct ttm_bo_device *bdev = &dev_priv->bdev;
28484 +       int ret;
28485 +       struct ttm_bo_kmap_obj tmp_kmap;
28486 +       bool is_iomem;
28487 +
28488 +       PSB_DEBUG_INIT("MSVDX: allocate CCB\n");
28489 +
28490 +       ret = ttm_buffer_object_create(bdev, size,
28491 +                                      ttm_bo_type_kernel,
28492 +                                      DRM_PSB_FLAG_MEM_MMU |
28493 +                                      TTM_PL_FLAG_NO_EVICT, 0, 0, 0,
28494 +                                      NULL, ccb);
28495 +       if (ret) {
28496 +               DRM_ERROR("MSVDX:failed to allocate CCB.\n");
28497 +               *ccb = NULL;
28498 +               return 1;
28499 +       }
28500 +
28501 +       ret = ttm_bo_kmap(*ccb, 0, (*ccb)->num_pages, &tmp_kmap);
28502 +       if (ret) {
28503 +               PSB_DEBUG_GENERAL("ttm_bo_kmap failed ret: %d\n", ret);
28504 +               ttm_bo_unref(ccb);
28505 +               *ccb = NULL;
28506 +               return 1;
28507 +       }
28508 +/*
28509 +       memset(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), 0,
28510 +              RENDEC_A_SIZE);
28511 +*/
28512 +       memset(ttm_kmap_obj_virtual(&tmp_kmap, &is_iomem), 0,
28513 +              size);
28514 +       ttm_bo_kunmap(&tmp_kmap);
28515 +
28516 +       *base_addr = (*ccb)->offset;
28517 +       return 0;
28518 +}
28519 +
28520 +static ssize_t psb_msvdx_pmstate_show(struct device *dev,
28521 +                               struct device_attribute *attr, char *buf)
28522 +{
28523 +       struct drm_device *drm_dev = dev_get_drvdata(dev);
28524 +       struct drm_psb_private *dev_priv;
28525 +       struct msvdx_private *msvdx_priv;
28526 +       unsigned int pmstate;
28527 +       unsigned long flags;
28528 +       int ret = -EINVAL;
28529 +
28530 +       if (drm_dev == NULL)
28531 +               return 0;
28532 +
28533 +       dev_priv = drm_dev->dev_private;
28534 +       msvdx_priv = dev_priv->msvdx_private;
28535 +       pmstate = msvdx_priv->pmstate;
28536 +
28537 +       spin_lock_irqsave(&msvdx_priv->msvdx_lock, flags);
28538 +       ret = sprintf(buf, "%s\n",
28539 +               (pmstate == PSB_PMSTATE_POWERUP) ? "powerup" : "powerdown");
28540 +       spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, flags);
28541 +
28542 +       return ret;
28543 +}
28544 +
28545 +static DEVICE_ATTR(msvdx_pmstate, 0444, psb_msvdx_pmstate_show, NULL);
28546 +
28547 +int psb_msvdx_init(struct drm_device *dev)
28548 +{
28549 +       struct drm_psb_private *dev_priv = dev->dev_private;
28550 +       /* uint32_t clk_gate_ctrl = clk_enable_all; */
28551 +       uint32_t cmd;
28552 +       int ret;
28553 +       struct msvdx_private *msvdx_priv;
28554 +
28555 +       if (!dev_priv->msvdx_private) {
28556 +               msvdx_priv = kmalloc(sizeof(struct msvdx_private), GFP_KERNEL);
28557 +               if (msvdx_priv == NULL)
28558 +                       goto err_exit;
28559 +
28560 +               dev_priv->msvdx_private = msvdx_priv;
28561 +               memset(msvdx_priv, 0, sizeof(struct msvdx_private));
28562 +
28563 +               /* get device --> drm_device --> drm_psb_private --> msvdx_priv
28564 +                * for psb_msvdx_pmstate_show: msvdx_pmpolicy
28565 +                * if not pci_set_drvdata, can't get drm_device from device
28566 +                */
28567 +               /* pci_set_drvdata(dev->pdev, dev); */
28568 +               if (device_create_file(&dev->pdev->dev,
28569 +                                       &dev_attr_msvdx_pmstate))
28570 +                       DRM_ERROR("MSVDX: could not create sysfs file\n");
28571 +               msvdx_priv->sysfs_pmstate = sysfs_get_dirent(
28572 +                       dev->pdev->dev.kobj.sd, "msvdx_pmstate");
28573 +       }
28574 +
28575 +       msvdx_priv = dev_priv->msvdx_private;
28576 +       if (!msvdx_priv->ccb0) { /* one for the first time */
28577 +               /* Initialize comand msvdx queueing */
28578 +               INIT_LIST_HEAD(&msvdx_priv->msvdx_queue);
28579 +               INIT_LIST_HEAD(&msvdx_priv->deblock_queue);
28580 +               mutex_init(&msvdx_priv->msvdx_mutex);
28581 +               spin_lock_init(&msvdx_priv->msvdx_lock);
28582 +               /*figure out the stepping */
28583 +               pci_read_config_byte(dev->pdev, PSB_REVID_OFFSET, &psb_rev_id);
28584 +       }
28585 +
28586 +       msvdx_priv->vec_local_mem_size = VEC_LOCAL_MEM_BYTE_SIZE;
28587 +       if (!msvdx_priv->vec_local_mem_data) {
28588 +               msvdx_priv->vec_local_mem_data = 
28589 +                       kmalloc(msvdx_priv->vec_local_mem_size, GFP_KERNEL);
28590 +               memset(msvdx_priv->vec_local_mem_data, 0, msvdx_priv->vec_local_mem_size);
28591 +       }
28592 +
28593 +       msvdx_priv->msvdx_busy = 0;
28594 +       msvdx_priv->msvdx_hw_busy = 1;
28595 +
28596 +       /* Enable Clocks */
28597 +       PSB_DEBUG_GENERAL("Enabling clocks\n");
28598 +       PSB_WMSVDX32(clk_enable_all, MSVDX_MAN_CLK_ENABLE);
28599 +
28600 +
28601 +       /* Enable MMU by removing all bypass bits */
28602 +       PSB_WMSVDX32(0, MSVDX_MMU_CONTROL0);
28603 +
28604 +       /* move firmware loading to the place receiving first command buffer */
28605 +
28606 +       PSB_DEBUG_GENERAL("MSVDX: Setting up RENDEC,allocate CCB 0/1\n");
28607 +       /* Allocate device virtual memory as required by rendec.... */
28608 +       if (!msvdx_priv->ccb0) {
28609 +               ret = psb_allocate_ccb(dev, &msvdx_priv->ccb0,
28610 +                                      &msvdx_priv->base_addr0,
28611 +                                      RENDEC_A_SIZE);
28612 +               if (ret) {
28613 +                       PSB_DEBUG_GENERAL("Allocate Rendec A fail\n");
28614 +                       goto err_exit;
28615 +               }
28616 +       }
28617 +
28618 +       if (!msvdx_priv->ccb1) {
28619 +               ret = psb_allocate_ccb(dev, &msvdx_priv->ccb1,
28620 +                                      &msvdx_priv->base_addr1,
28621 +                                      RENDEC_B_SIZE);
28622 +               if (ret)
28623 +                       goto err_exit;
28624 +       }
28625 +
28626 +
28627 +       PSB_DEBUG_GENERAL("MSVDX: RENDEC A: %08x RENDEC B: %08x\n",
28628 +                         msvdx_priv->base_addr0, msvdx_priv->base_addr1);
28629 +
28630 +       PSB_WMSVDX32(msvdx_priv->base_addr0, MSVDX_RENDEC_BASE_ADDR0);
28631 +       PSB_WMSVDX32(msvdx_priv->base_addr1, MSVDX_RENDEC_BASE_ADDR1);
28632 +
28633 +       cmd = 0;
28634 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE,
28635 +                         RENDEC_BUFFER_SIZE0, RENDEC_A_SIZE / 4096);
28636 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_BUFFER_SIZE,
28637 +                         RENDEC_BUFFER_SIZE1, RENDEC_B_SIZE / 4096);
28638 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_BUFFER_SIZE);
28639 +
28640 +
28641 +       cmd = 0;
28642 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
28643 +                         RENDEC_DECODE_START_SIZE, 0);
28644 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
28645 +                         RENDEC_BURST_SIZE_W, 1);
28646 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
28647 +                         RENDEC_BURST_SIZE_R, 1);
28648 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL1,
28649 +                         RENDEC_EXTERNAL_MEMORY, 1);
28650 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL1);
28651 +
28652 +       cmd = 0x00101010;
28653 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT0);
28654 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT1);
28655 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT2);
28656 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT3);
28657 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT4);
28658 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTEXT5);
28659 +
28660 +       cmd = 0;
28661 +       REGIO_WRITE_FIELD(cmd, MSVDX_RENDEC_CONTROL0, RENDEC_INITIALISE,
28662 +                         1);
28663 +       PSB_WMSVDX32(cmd, MSVDX_RENDEC_CONTROL0);
28664 +
28665 +       /* PSB_WMSVDX32(clk_enable_minimal, MSVDX_MAN_CLK_ENABLE); */
28666 +       PSB_DEBUG_INIT("MSVDX:defer firmware loading to the"
28667 +                      " place when receiving user space commands\n");
28668 +
28669 +       msvdx_priv->msvdx_fw_loaded = 0; /* need to load firware */
28670 +
28671 +       psb_msvdx_clearirq(dev);
28672 +       psb_msvdx_enableirq(dev);
28673 +
28674 +       if (IS_MRST(dev)) {
28675 +               PSB_DEBUG_INIT("MSDVX:old clock gating disable = 0x%08x\n",
28676 +                       PSB_RVDC32(PSB_MSVDX_CLOCKGATING));
28677 +       }
28678 +
28679 +       {
28680 +               cmd = 0;
28681 +               cmd = PSB_RMSVDX32(0x818); /* VEC_SHIFTREG_CONTROL */
28682 +               REGIO_WRITE_FIELD(cmd,
28683 +                                 VEC_SHIFTREG_CONTROL,
28684 +                                 SR_MASTER_SELECT,
28685 +                                 1);  /* Host */
28686 +               PSB_WMSVDX32(cmd, 0x818);
28687 +       }
28688 +
28689 +#if 0
28690 +       ret = psb_setup_fw(dev);
28691 +       if (ret)
28692 +               goto err_exit;
28693 +       /* Send Initialisation message to firmware */
28694 +       if (0) {
28695 +               uint32_t msg_init[FW_VA_INIT_SIZE >> 2];
28696 +               MEMIO_WRITE_FIELD(msg_init, FWRK_GENMSG_SIZE,
28697 +                                 FW_VA_INIT_SIZE);
28698 +               MEMIO_WRITE_FIELD(msg_init, FWRK_GENMSG_ID, VA_MSGID_INIT);
28699 +
28700 +               /* Need to set this for all but A0 */
28701 +               MEMIO_WRITE_FIELD(msg_init, FW_VA_INIT_GLOBAL_PTD,
28702 +                                 psb_get_default_pd_addr(dev_priv->mmu));
28703 +
28704 +               ret = psb_mtx_send(dev_priv, msg_init);
28705 +               if (ret)
28706 +                       goto err_exit;
28707 +
28708 +               psb_poll_mtx_irq(dev_priv);
28709 +       }
28710 +#endif
28711 +
28712 +       return 0;
28713 +
28714 +err_exit:
28715 +       DRM_ERROR("MSVDX: initialization failed\n");
28716 +       if (msvdx_priv->ccb0)
28717 +               psb_free_ccb(&msvdx_priv->ccb0);
28718 +       if (msvdx_priv->ccb1)
28719 +               psb_free_ccb(&msvdx_priv->ccb1);
28720 +       kfree(dev_priv->msvdx_private);
28721 +
28722 +       return 1;
28723 +}
28724 +
28725 +int psb_msvdx_uninit(struct drm_device *dev)
28726 +{
28727 +       struct drm_psb_private *dev_priv = dev->dev_private;
28728 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
28729 +
28730 +       /* Reset MSVDX chip */
28731 +       psb_msvdx_reset(dev_priv);
28732 +
28733 +       /* PSB_WMSVDX32 (clk_enable_minimal, MSVDX_MAN_CLK_ENABLE); */
28734 +       PSB_DEBUG_INIT("MSVDX:set the msvdx clock to 0\n");
28735 +       PSB_WMSVDX32(0, MSVDX_MAN_CLK_ENABLE);
28736 +
28737 +       if (msvdx_priv->ccb0)
28738 +               psb_free_ccb(&msvdx_priv->ccb0);
28739 +       if (msvdx_priv->ccb1)
28740 +               psb_free_ccb(&msvdx_priv->ccb1);
28741 +       if (msvdx_priv->msvdx_fw)
28742 +               kfree(msvdx_priv->msvdx_fw
28743 +                       );
28744 +       if (msvdx_priv->vec_local_mem_data)
28745 +               kfree(msvdx_priv->vec_local_mem_data);
28746 +
28747 +       if (msvdx_priv) {
28748 +               /* pci_set_drvdata(dev->pdev, NULL); */
28749 +               device_remove_file(&dev->pdev->dev, &dev_attr_msvdx_pmstate);
28750 +               sysfs_put(msvdx_priv->sysfs_pmstate);
28751 +               msvdx_priv->sysfs_pmstate = NULL;
28752 +
28753 +               kfree(msvdx_priv);
28754 +               dev_priv->msvdx_private = NULL;
28755 +       }
28756 +
28757 +       return 0;
28758 +}
28759 diff --git a/drivers/gpu/drm/mrst/drv/psb_pvr_glue.c b/drivers/gpu/drm/mrst/drv/psb_pvr_glue.c
28760 new file mode 100644
28761 index 0000000..cb11475
28762 --- /dev/null
28763 +++ b/drivers/gpu/drm/mrst/drv/psb_pvr_glue.c
28764 @@ -0,0 +1,74 @@
28765 +/*
28766 + * Copyright (c) 2009, Intel Corporation.
28767 + *
28768 + * This program is free software; you can redistribute it and/or modify it
28769 + * under the terms and conditions of the GNU General Public License,
28770 + * version 2, as published by the Free Software Foundation.
28771 + *
28772 + * This program is distributed in the hope it will be useful, but WITHOUT
28773 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28774 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
28775 + * more details.
28776 + *
28777 + * You should have received a copy of the GNU General Public License along with
28778 + * this program; if not, write to the Free Software Foundation, Inc., 
28779 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
28780 + *
28781 + */
28782 +
28783 +#include "psb_pvr_glue.h"
28784 +
28785 +/**
28786 + * FIXME: should NOT use these file under env/linux directly
28787 + */
28788 +#include "mm.h"
28789 +
28790 +int psb_get_meminfo_by_handle(IMG_HANDLE hKernelMemInfo,
28791 +                               PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
28792 +{
28793 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
28794 +       PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
28795 +       PVRSRV_ERROR eError;
28796 +
28797 +       psPerProc = PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
28798 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
28799 +                                   (IMG_VOID *)&psKernelMemInfo,
28800 +                                   hKernelMemInfo,
28801 +                                   PVRSRV_HANDLE_TYPE_MEM_INFO);
28802 +       if (eError != PVRSRV_OK) {
28803 +               DRM_ERROR("Cannot find kernel meminfo for handle %lx\n",
28804 +                         (IMG_UINT32)hKernelMemInfo);
28805 +               return -EINVAL;
28806 +       }
28807 +
28808 +       *ppsKernelMemInfo = psKernelMemInfo;
28809 +
28810 +       DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
28811 +                 (IMG_UINT32)hKernelMemInfo);
28812 +       return 0;
28813 +}
28814 +
28815 +IMG_UINT32 psb_get_tgid(void)
28816 +{
28817 +       return OSGetCurrentProcessIDKM();
28818 +}
28819 +
28820 +int psb_get_pages_by_mem_handle(IMG_HANDLE hOSMemHandle, struct page ***pages)
28821 +{
28822 +       LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
28823 +       struct page **page_list;
28824 +
28825 +       if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) {
28826 +               DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n");
28827 +               return -EINVAL;
28828 +       }
28829 +
28830 +       page_list = psLinuxMemArea->uData.sPageList.pvPageList;
28831 +       if (!page_list) {
28832 +               DRM_DEBUG("Page List is NULL\n");
28833 +               return -ENOMEM;
28834 +       }
28835 +
28836 +       *pages = page_list;
28837 +       return 0;
28838 +}
28839 diff --git a/drivers/gpu/drm/mrst/drv/psb_pvr_glue.h b/drivers/gpu/drm/mrst/drv/psb_pvr_glue.h
28840 new file mode 100644
28841 index 0000000..3c2ae45
28842 --- /dev/null
28843 +++ b/drivers/gpu/drm/mrst/drv/psb_pvr_glue.h
28844 @@ -0,0 +1,26 @@
28845 +/*
28846 + * Copyright (c) 2009, Intel Corporation.
28847 + *
28848 + * This program is free software; you can redistribute it and/or modify it
28849 + * under the terms and conditions of the GNU General Public License,
28850 + * version 2, as published by the Free Software Foundation.
28851 + *
28852 + * This program is distributed in the hope it will be useful, but WITHOUT
28853 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28854 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
28855 + * more details.
28856 + *
28857 + * You should have received a copy of the GNU General Public License along with
28858 + * this program; if not, write to the Free Software Foundation, Inc., 
28859 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
28860 + *
28861 + */
28862 +
28863 +#include "psb_drv.h"
28864 +#include "services_headers.h"
28865 +
28866 +extern int psb_get_meminfo_by_handle(IMG_HANDLE hKernelMemInfo,
28867 +                               PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
28868 +extern IMG_UINT32 psb_get_tgid(void);
28869 +extern int psb_get_pages_by_mem_handle(IMG_HANDLE hOSMemHandle,
28870 +                                       struct page ***pages);
28871 diff --git a/drivers/gpu/drm/mrst/drv/psb_reg.h b/drivers/gpu/drm/mrst/drv/psb_reg.h
28872 new file mode 100644
28873 index 0000000..ea1e812
28874 --- /dev/null
28875 +++ b/drivers/gpu/drm/mrst/drv/psb_reg.h
28876 @@ -0,0 +1,570 @@
28877 +/**************************************************************************
28878 + *
28879 + * Copyright (c) (2005-2007) Imagination Technologies Limited.
28880 + * Copyright (c) 2007, Intel Corporation.
28881 + * All Rights Reserved.
28882 + *
28883 + * This program is free software; you can redistribute it and/or modify it
28884 + * under the terms and conditions of the GNU General Public License,
28885 + * version 2, as published by the Free Software Foundation.
28886 + *
28887 + * This program is distributed in the hope it will be useful, but WITHOUT
28888 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28889 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
28890 + * more details.
28891 + *
28892 + * You should have received a copy of the GNU General Public License along with
28893 + * this program; if not, write to the Free Software Foundation, Inc., 
28894 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA..
28895 + *
28896 + **************************************************************************/
28897 +
28898 +#ifndef _PSB_REG_H_
28899 +#define _PSB_REG_H_
28900 +
28901 +#define PSB_CR_CLKGATECTL                0x0000
28902 +#define _PSB_C_CLKGATECTL_AUTO_MAN_REG   (1 << 24)
28903 +#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
28904 +#define _PSB_C_CLKGATECTL_USE_CLKG_MASK  (0x3 << 20)
28905 +#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
28906 +#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK  (0x3 << 16)
28907 +#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT  (12)
28908 +#define _PSB_C_CLKGATECTL_TA_CLKG_MASK   (0x3 << 12)
28909 +#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
28910 +#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK  (0x3 << 8)
28911 +#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
28912 +#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK  (0x3 << 4)
28913 +#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT  (0)
28914 +#define _PSB_C_CLKGATECTL_2D_CLKG_MASK   (0x3 << 0)
28915 +#define _PSB_C_CLKGATECTL_CLKG_ENABLED   (0)
28916 +#define _PSB_C_CLKGATECTL_CLKG_DISABLED  (1)
28917 +#define _PSB_C_CLKGATECTL_CLKG_AUTO      (2)
28918 +
28919 +#define PSB_CR_CORE_ID                   0x0010
28920 +#define _PSB_CC_ID_ID_SHIFT              (16)
28921 +#define _PSB_CC_ID_ID_MASK               (0xFFFF << 16)
28922 +#define _PSB_CC_ID_CONFIG_SHIFT          (0)
28923 +#define _PSB_CC_ID_CONFIG_MASK           (0xFFFF << 0)
28924 +
28925 +#define PSB_CR_CORE_REVISION               0x0014
28926 +#define _PSB_CC_REVISION_DESIGNER_SHIFT    (24)
28927 +#define _PSB_CC_REVISION_DESIGNER_MASK     (0xFF << 24)
28928 +#define _PSB_CC_REVISION_MAJOR_SHIFT       (16)
28929 +#define _PSB_CC_REVISION_MAJOR_MASK        (0xFF << 16)
28930 +#define _PSB_CC_REVISION_MINOR_SHIFT       (8)
28931 +#define _PSB_CC_REVISION_MINOR_MASK        (0xFF << 8)
28932 +#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
28933 +#define _PSB_CC_REVISION_MAINTENANCE_MASK  (0xFF << 0)
28934 +
28935 +#define PSB_CR_DESIGNER_REV_FIELD1       0x0018
28936 +
28937 +#define PSB_CR_SOFT_RESET                0x0080
28938 +#define _PSB_CS_RESET_TSP_RESET          (1 << 6)
28939 +#define _PSB_CS_RESET_ISP_RESET          (1 << 5)
28940 +#define _PSB_CS_RESET_USE_RESET          (1 << 4)
28941 +#define _PSB_CS_RESET_TA_RESET           (1 << 3)
28942 +#define _PSB_CS_RESET_DPM_RESET          (1 << 2)
28943 +#define _PSB_CS_RESET_TWOD_RESET         (1 << 1)
28944 +#define _PSB_CS_RESET_BIF_RESET          (1 << 0)
28945 +
28946 +#define PSB_CR_DESIGNER_REV_FIELD2       0x001C
28947 +
28948 +#define PSB_CR_EVENT_HOST_ENABLE2        0x0110
28949 +
28950 +#define PSB_CR_EVENT_STATUS2             0x0118
28951 +
28952 +#define PSB_CR_EVENT_HOST_CLEAR2         0x0114
28953 +#define _PSB_CE2_BIF_REQUESTER_FAULT     (1 << 4)
28954 +
28955 +#define PSB_CR_EVENT_STATUS              0x012C
28956 +
28957 +#define PSB_CR_EVENT_HOST_ENABLE         0x0130
28958 +
28959 +#define PSB_CR_EVENT_HOST_CLEAR          0x0134
28960 +#define _PSB_CE_MASTER_INTERRUPT         (1 << 31)
28961 +#define _PSB_CE_TA_DPM_FAULT             (1 << 28)
28962 +#define _PSB_CE_TWOD_COMPLETE            (1 << 27)
28963 +#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS    (1 << 25)
28964 +#define _PSB_CE_DPM_TA_MEM_FREE          (1 << 24)
28965 +#define _PSB_CE_PIXELBE_END_RENDER       (1 << 18)
28966 +#define _PSB_CE_SW_EVENT                 (1 << 14)
28967 +#define _PSB_CE_TA_FINISHED              (1 << 13)
28968 +#define _PSB_CE_TA_TERMINATE             (1 << 12)
28969 +#define _PSB_CE_DPM_REACHED_MEM_THRESH   (1 << 3)
28970 +#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL    (1 << 2)
28971 +#define _PSB_CE_DPM_OUT_OF_MEMORY_MT     (1 << 1)
28972 +#define _PSB_CE_DPM_3D_MEM_FREE          (1 << 0)
28973 +
28974 +
28975 +#define PSB_USE_OFFSET_MASK              0x0007FFFF
28976 +#define PSB_USE_OFFSET_SIZE              (PSB_USE_OFFSET_MASK + 1)
28977 +#define PSB_CR_USE_CODE_BASE0            0x0A0C
28978 +#define PSB_CR_USE_CODE_BASE1            0x0A10
28979 +#define PSB_CR_USE_CODE_BASE2            0x0A14
28980 +#define PSB_CR_USE_CODE_BASE3            0x0A18
28981 +#define PSB_CR_USE_CODE_BASE4            0x0A1C
28982 +#define PSB_CR_USE_CODE_BASE5            0x0A20
28983 +#define PSB_CR_USE_CODE_BASE6            0x0A24
28984 +#define PSB_CR_USE_CODE_BASE7            0x0A28
28985 +#define PSB_CR_USE_CODE_BASE8            0x0A2C
28986 +#define PSB_CR_USE_CODE_BASE9            0x0A30
28987 +#define PSB_CR_USE_CODE_BASE10           0x0A34
28988 +#define PSB_CR_USE_CODE_BASE11           0x0A38
28989 +#define PSB_CR_USE_CODE_BASE12           0x0A3C
28990 +#define PSB_CR_USE_CODE_BASE13           0x0A40
28991 +#define PSB_CR_USE_CODE_BASE14           0x0A44
28992 +#define PSB_CR_USE_CODE_BASE15           0x0A48
28993 +#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
28994 +#define _PSB_CUC_BASE_DM_SHIFT           (25)
28995 +#define _PSB_CUC_BASE_DM_MASK            (0x3 << 25)
28996 +#define _PSB_CUC_BASE_ADDR_SHIFT         (0)   /* 1024-bit aligned address? */
28997 +#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT    (7)
28998 +#define _PSB_CUC_BASE_ADDR_MASK          (0x1FFFFFF << 0)
28999 +#define _PSB_CUC_DM_VERTEX              (0)
29000 +#define _PSB_CUC_DM_PIXEL               (1)
29001 +#define _PSB_CUC_DM_RESERVED            (2)
29002 +#define _PSB_CUC_DM_EDM                         (3)
29003 +
29004 +#define PSB_CR_PDS_EXEC_BASE             0x0AB8
29005 +#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20)  /* 1MB aligned address */
29006 +#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
29007 +
29008 +#define PSB_CR_EVENT_KICKER              0x0AC4
29009 +#define _PSB_CE_KICKER_ADDRESS_SHIFT     (4)   /* 128-bit aligned address */
29010 +
29011 +#define PSB_CR_EVENT_KICK                0x0AC8
29012 +#define _PSB_CE_KICK_NOW                 (1 << 0)
29013 +
29014 +
29015 +#define PSB_CR_BIF_DIR_LIST_BASE1        0x0C38
29016 +
29017 +#define PSB_CR_BIF_CTRL                  0x0C00
29018 +#define _PSB_CB_CTRL_CLEAR_FAULT         (1 << 4)
29019 +#define _PSB_CB_CTRL_INVALDC             (1 << 3)
29020 +#define _PSB_CB_CTRL_FLUSH               (1 << 2)
29021 +
29022 +#define PSB_CR_BIF_INT_STAT              0x0C04
29023 +
29024 +#define PSB_CR_BIF_FAULT                 0x0C08
29025 +#define _PSB_CBI_STAT_PF_N_RW            (1 << 14)
29026 +#define _PSB_CBI_STAT_FAULT_SHIFT        (0)
29027 +#define _PSB_CBI_STAT_FAULT_MASK         (0x3FFF << 0)
29028 +#define _PSB_CBI_STAT_FAULT_CACHE        (1 << 1)
29029 +#define _PSB_CBI_STAT_FAULT_TA           (1 << 2)
29030 +#define _PSB_CBI_STAT_FAULT_VDM          (1 << 3)
29031 +#define _PSB_CBI_STAT_FAULT_2D           (1 << 4)
29032 +#define _PSB_CBI_STAT_FAULT_PBE          (1 << 5)
29033 +#define _PSB_CBI_STAT_FAULT_TSP          (1 << 6)
29034 +#define _PSB_CBI_STAT_FAULT_ISP          (1 << 7)
29035 +#define _PSB_CBI_STAT_FAULT_USSEPDS      (1 << 8)
29036 +#define _PSB_CBI_STAT_FAULT_HOST         (1 << 9)
29037 +
29038 +#define PSB_CR_BIF_BANK0                 0x0C78
29039 +
29040 +#define PSB_CR_BIF_BANK1                 0x0C7C
29041 +
29042 +#define PSB_CR_BIF_DIR_LIST_BASE0        0x0C84
29043 +
29044 +#define PSB_CR_BIF_TWOD_REQ_BASE         0x0C88
29045 +#define PSB_CR_BIF_3D_REQ_BASE           0x0CAC
29046 +
29047 +#define PSB_CR_2D_SOCIF                  0x0E18
29048 +#define _PSB_C2_SOCIF_FREESPACE_SHIFT    (0)
29049 +#define _PSB_C2_SOCIF_FREESPACE_MASK     (0xFF << 0)
29050 +#define _PSB_C2_SOCIF_EMPTY              (0x80 << 0)
29051 +
29052 +#define PSB_CR_2D_BLIT_STATUS            0x0E04
29053 +#define _PSB_C2B_STATUS_BUSY             (1 << 24)
29054 +#define _PSB_C2B_STATUS_COMPLETE_SHIFT   (0)
29055 +#define _PSB_C2B_STATUS_COMPLETE_MASK    (0xFFFFFF << 0)
29056 +
29057 +/*
29058 + * 2D defs.
29059 + */
29060 +
29061 +/*
29062 + * 2D Slave Port Data : Block Header's Object Type
29063 + */
29064 +
29065 +#define        PSB_2D_CLIP_BH                   (0x00000000)
29066 +#define        PSB_2D_PAT_BH                    (0x10000000)
29067 +#define        PSB_2D_CTRL_BH                   (0x20000000)
29068 +#define        PSB_2D_SRC_OFF_BH                (0x30000000)
29069 +#define        PSB_2D_MASK_OFF_BH               (0x40000000)
29070 +#define        PSB_2D_RESERVED1_BH              (0x50000000)
29071 +#define        PSB_2D_RESERVED2_BH              (0x60000000)
29072 +#define        PSB_2D_FENCE_BH                  (0x70000000)
29073 +#define        PSB_2D_BLIT_BH                   (0x80000000)
29074 +#define        PSB_2D_SRC_SURF_BH               (0x90000000)
29075 +#define        PSB_2D_DST_SURF_BH               (0xA0000000)
29076 +#define        PSB_2D_PAT_SURF_BH               (0xB0000000)
29077 +#define        PSB_2D_SRC_PAL_BH                (0xC0000000)
29078 +#define        PSB_2D_PAT_PAL_BH                (0xD0000000)
29079 +#define        PSB_2D_MASK_SURF_BH              (0xE0000000)
29080 +#define        PSB_2D_FLUSH_BH                  (0xF0000000)
29081 +
29082 +/*
29083 + * Clip Definition block (PSB_2D_CLIP_BH)
29084 + */
29085 +#define PSB_2D_CLIPCOUNT_MAX             (1)
29086 +#define PSB_2D_CLIPCOUNT_MASK            (0x00000000)
29087 +#define PSB_2D_CLIPCOUNT_CLRMASK         (0xFFFFFFFF)
29088 +#define PSB_2D_CLIPCOUNT_SHIFT           (0)
29089 +/* clip rectangle min & max */
29090 +#define PSB_2D_CLIP_XMAX_MASK            (0x00FFF000)
29091 +#define PSB_2D_CLIP_XMAX_CLRMASK         (0xFF000FFF)
29092 +#define PSB_2D_CLIP_XMAX_SHIFT           (12)
29093 +#define PSB_2D_CLIP_XMIN_MASK            (0x00000FFF)
29094 +#define PSB_2D_CLIP_XMIN_CLRMASK         (0x00FFF000)
29095 +#define PSB_2D_CLIP_XMIN_SHIFT           (0)
29096 +/* clip rectangle offset */
29097 +#define PSB_2D_CLIP_YMAX_MASK            (0x00FFF000)
29098 +#define PSB_2D_CLIP_YMAX_CLRMASK         (0xFF000FFF)
29099 +#define PSB_2D_CLIP_YMAX_SHIFT           (12)
29100 +#define PSB_2D_CLIP_YMIN_MASK            (0x00000FFF)
29101 +#define PSB_2D_CLIP_YMIN_CLRMASK         (0x00FFF000)
29102 +#define PSB_2D_CLIP_YMIN_SHIFT           (0)
29103 +
29104 +/*
29105 + * Pattern Control (PSB_2D_PAT_BH)
29106 + */
29107 +#define PSB_2D_PAT_HEIGHT_MASK           (0x0000001F)
29108 +#define PSB_2D_PAT_HEIGHT_SHIFT          (0)
29109 +#define PSB_2D_PAT_WIDTH_MASK            (0x000003E0)
29110 +#define PSB_2D_PAT_WIDTH_SHIFT           (5)
29111 +#define PSB_2D_PAT_YSTART_MASK           (0x00007C00)
29112 +#define PSB_2D_PAT_YSTART_SHIFT          (10)
29113 +#define PSB_2D_PAT_XSTART_MASK           (0x000F8000)
29114 +#define PSB_2D_PAT_XSTART_SHIFT          (15)
29115 +
29116 +/*
29117 + * 2D Control block (PSB_2D_CTRL_BH)
29118 + */
29119 +/* Present Flags */
29120 +#define PSB_2D_SRCCK_CTRL                (0x00000001)
29121 +#define PSB_2D_DSTCK_CTRL                (0x00000002)
29122 +#define PSB_2D_ALPHA_CTRL                (0x00000004)
29123 +/* Colour Key Colour (SRC/DST)*/
29124 +#define PSB_2D_CK_COL_MASK               (0xFFFFFFFF)
29125 +#define PSB_2D_CK_COL_CLRMASK            (0x00000000)
29126 +#define PSB_2D_CK_COL_SHIFT              (0)
29127 +/* Colour Key Mask (SRC/DST)*/
29128 +#define PSB_2D_CK_MASK_MASK              (0xFFFFFFFF)
29129 +#define PSB_2D_CK_MASK_CLRMASK           (0x00000000)
29130 +#define PSB_2D_CK_MASK_SHIFT             (0)
29131 +/* Alpha Control (Alpha/RGB)*/
29132 +#define PSB_2D_GBLALPHA_MASK             (0x000FF000)
29133 +#define PSB_2D_GBLALPHA_CLRMASK          (0xFFF00FFF)
29134 +#define PSB_2D_GBLALPHA_SHIFT            (12)
29135 +#define PSB_2D_SRCALPHA_OP_MASK          (0x00700000)
29136 +#define PSB_2D_SRCALPHA_OP_CLRMASK       (0xFF8FFFFF)
29137 +#define PSB_2D_SRCALPHA_OP_SHIFT         (20)
29138 +#define PSB_2D_SRCALPHA_OP_ONE           (0x00000000)
29139 +#define PSB_2D_SRCALPHA_OP_SRC           (0x00100000)
29140 +#define PSB_2D_SRCALPHA_OP_DST           (0x00200000)
29141 +#define PSB_2D_SRCALPHA_OP_SG            (0x00300000)
29142 +#define PSB_2D_SRCALPHA_OP_DG            (0x00400000)
29143 +#define PSB_2D_SRCALPHA_OP_GBL           (0x00500000)
29144 +#define PSB_2D_SRCALPHA_OP_ZERO          (0x00600000)
29145 +#define PSB_2D_SRCALPHA_INVERT           (0x00800000)
29146 +#define PSB_2D_SRCALPHA_INVERT_CLR       (0xFF7FFFFF)
29147 +#define PSB_2D_DSTALPHA_OP_MASK          (0x07000000)
29148 +#define PSB_2D_DSTALPHA_OP_CLRMASK       (0xF8FFFFFF)
29149 +#define PSB_2D_DSTALPHA_OP_SHIFT         (24)
29150 +#define PSB_2D_DSTALPHA_OP_ONE           (0x00000000)
29151 +#define PSB_2D_DSTALPHA_OP_SRC           (0x01000000)
29152 +#define PSB_2D_DSTALPHA_OP_DST           (0x02000000)
29153 +#define PSB_2D_DSTALPHA_OP_SG            (0x03000000)
29154 +#define PSB_2D_DSTALPHA_OP_DG            (0x04000000)
29155 +#define PSB_2D_DSTALPHA_OP_GBL           (0x05000000)
29156 +#define PSB_2D_DSTALPHA_OP_ZERO          (0x06000000)
29157 +#define PSB_2D_DSTALPHA_INVERT           (0x08000000)
29158 +#define PSB_2D_DSTALPHA_INVERT_CLR       (0xF7FFFFFF)
29159 +
29160 +#define PSB_2D_PRE_MULTIPLICATION_ENABLE  (0x10000000)
29161 +#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
29162 +#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE   (0x20000000)
29163 +#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK  (0xDFFFFFFF)
29164 +
29165 +/*
29166 + *Source Offset (PSB_2D_SRC_OFF_BH)
29167 + */
29168 +#define PSB_2D_SRCOFF_XSTART_MASK        ((0x00000FFF) << 12)
29169 +#define PSB_2D_SRCOFF_XSTART_SHIFT       (12)
29170 +#define PSB_2D_SRCOFF_YSTART_MASK        (0x00000FFF)
29171 +#define PSB_2D_SRCOFF_YSTART_SHIFT       (0)
29172 +
29173 +/*
29174 + * Mask Offset (PSB_2D_MASK_OFF_BH)
29175 + */
29176 +#define PSB_2D_MASKOFF_XSTART_MASK       ((0x00000FFF) << 12)
29177 +#define PSB_2D_MASKOFF_XSTART_SHIFT      (12)
29178 +#define PSB_2D_MASKOFF_YSTART_MASK       (0x00000FFF)
29179 +#define PSB_2D_MASKOFF_YSTART_SHIFT      (0)
29180 +
29181 +/*
29182 + * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
29183 + */
29184 +
29185 +/*
29186 + *Blit Rectangle (PSB_2D_BLIT_BH)
29187 + */
29188 +
29189 +#define PSB_2D_ROT_MASK                  (3<<25)
29190 +#define PSB_2D_ROT_CLRMASK               (~PSB_2D_ROT_MASK)
29191 +#define PSB_2D_ROT_NONE                  (0<<25)
29192 +#define PSB_2D_ROT_90DEGS                (1<<25)
29193 +#define PSB_2D_ROT_180DEGS               (2<<25)
29194 +#define PSB_2D_ROT_270DEGS               (3<<25)
29195 +
29196 +#define PSB_2D_COPYORDER_MASK            (3<<23)
29197 +#define PSB_2D_COPYORDER_CLRMASK         (~PSB_2D_COPYORDER_MASK)
29198 +#define PSB_2D_COPYORDER_TL2BR           (0<<23)
29199 +#define PSB_2D_COPYORDER_BR2TL           (1<<23)
29200 +#define PSB_2D_COPYORDER_TR2BL           (2<<23)
29201 +#define PSB_2D_COPYORDER_BL2TR           (3<<23)
29202 +
29203 +#define PSB_2D_DSTCK_CLRMASK             (0xFF9FFFFF)
29204 +#define PSB_2D_DSTCK_DISABLE             (0x00000000)
29205 +#define PSB_2D_DSTCK_PASS                (0x00200000)
29206 +#define PSB_2D_DSTCK_REJECT              (0x00400000)
29207 +
29208 +#define PSB_2D_SRCCK_CLRMASK             (0xFFE7FFFF)
29209 +#define PSB_2D_SRCCK_DISABLE             (0x00000000)
29210 +#define PSB_2D_SRCCK_PASS                (0x00080000)
29211 +#define PSB_2D_SRCCK_REJECT              (0x00100000)
29212 +
29213 +#define PSB_2D_CLIP_ENABLE               (0x00040000)
29214 +
29215 +#define PSB_2D_ALPHA_ENABLE              (0x00020000)
29216 +
29217 +#define PSB_2D_PAT_CLRMASK               (0xFFFEFFFF)
29218 +#define PSB_2D_PAT_MASK                  (0x00010000)
29219 +#define PSB_2D_USE_PAT                   (0x00010000)
29220 +#define PSB_2D_USE_FILL                  (0x00000000)
29221 +/*
29222 + * Tungsten Graphics note on rop codes: If rop A and rop B are
29223 + * identical, the mask surface will not be read and need not be
29224 + * set up.
29225 + */
29226 +
29227 +#define PSB_2D_ROP3B_MASK                (0x0000FF00)
29228 +#define PSB_2D_ROP3B_CLRMASK             (0xFFFF00FF)
29229 +#define PSB_2D_ROP3B_SHIFT               (8)
29230 +/* rop code A */
29231 +#define PSB_2D_ROP3A_MASK                (0x000000FF)
29232 +#define PSB_2D_ROP3A_CLRMASK             (0xFFFFFF00)
29233 +#define PSB_2D_ROP3A_SHIFT               (0)
29234 +
29235 +#define PSB_2D_ROP4_MASK                 (0x0000FFFF)
29236 +/*
29237 + *     DWORD0: (Only pass if Pattern control == Use Fill Colour)
29238 + *     Fill Colour RGBA8888
29239 + */
29240 +#define PSB_2D_FILLCOLOUR_MASK           (0xFFFFFFFF)
29241 +#define PSB_2D_FILLCOLOUR_SHIFT          (0)
29242 +/*
29243 + *     DWORD1: (Always Present)
29244 + *     X Start (Dest)
29245 + *     Y Start (Dest)
29246 + */
29247 +#define PSB_2D_DST_XSTART_MASK           (0x00FFF000)
29248 +#define PSB_2D_DST_XSTART_CLRMASK        (0xFF000FFF)
29249 +#define PSB_2D_DST_XSTART_SHIFT          (12)
29250 +#define PSB_2D_DST_YSTART_MASK           (0x00000FFF)
29251 +#define PSB_2D_DST_YSTART_CLRMASK        (0xFFFFF000)
29252 +#define PSB_2D_DST_YSTART_SHIFT          (0)
29253 +/*
29254 + *     DWORD2: (Always Present)
29255 + *     X Size (Dest)
29256 + *     Y Size (Dest)
29257 + */
29258 +#define PSB_2D_DST_XSIZE_MASK            (0x00FFF000)
29259 +#define PSB_2D_DST_XSIZE_CLRMASK         (0xFF000FFF)
29260 +#define PSB_2D_DST_XSIZE_SHIFT           (12)
29261 +#define PSB_2D_DST_YSIZE_MASK            (0x00000FFF)
29262 +#define PSB_2D_DST_YSIZE_CLRMASK         (0xFFFFF000)
29263 +#define PSB_2D_DST_YSIZE_SHIFT           (0)
29264 +
29265 +/*
29266 + * Source Surface (PSB_2D_SRC_SURF_BH)
29267 + */
29268 +/*
29269 + *      WORD 0
29270 + */
29271 +
29272 +#define PSB_2D_SRC_FORMAT_MASK           (0x00078000)
29273 +#define PSB_2D_SRC_1_PAL                 (0x00000000)
29274 +#define PSB_2D_SRC_2_PAL                 (0x00008000)
29275 +#define PSB_2D_SRC_4_PAL                 (0x00010000)
29276 +#define PSB_2D_SRC_8_PAL                 (0x00018000)
29277 +#define PSB_2D_SRC_8_ALPHA               (0x00020000)
29278 +#define PSB_2D_SRC_4_ALPHA               (0x00028000)
29279 +#define PSB_2D_SRC_332RGB                (0x00030000)
29280 +#define PSB_2D_SRC_4444ARGB              (0x00038000)
29281 +#define PSB_2D_SRC_555RGB                (0x00040000)
29282 +#define PSB_2D_SRC_1555ARGB              (0x00048000)
29283 +#define PSB_2D_SRC_565RGB                (0x00050000)
29284 +#define PSB_2D_SRC_0888ARGB              (0x00058000)
29285 +#define PSB_2D_SRC_8888ARGB              (0x00060000)
29286 +#define PSB_2D_SRC_8888UYVY              (0x00068000)
29287 +#define PSB_2D_SRC_RESERVED              (0x00070000)
29288 +#define PSB_2D_SRC_1555ARGB_LOOKUP       (0x00078000)
29289 +
29290 +
29291 +#define PSB_2D_SRC_STRIDE_MASK           (0x00007FFF)
29292 +#define PSB_2D_SRC_STRIDE_CLRMASK        (0xFFFF8000)
29293 +#define PSB_2D_SRC_STRIDE_SHIFT          (0)
29294 +/*
29295 + *  WORD 1 - Base Address
29296 + */
29297 +#define PSB_2D_SRC_ADDR_MASK             (0x0FFFFFFC)
29298 +#define PSB_2D_SRC_ADDR_CLRMASK          (0x00000003)
29299 +#define PSB_2D_SRC_ADDR_SHIFT            (2)
29300 +#define PSB_2D_SRC_ADDR_ALIGNSHIFT       (2)
29301 +
29302 +/*
29303 + * Pattern Surface (PSB_2D_PAT_SURF_BH)
29304 + */
29305 +/*
29306 + *  WORD 0
29307 + */
29308 +
29309 +#define PSB_2D_PAT_FORMAT_MASK           (0x00078000)
29310 +#define PSB_2D_PAT_1_PAL                 (0x00000000)
29311 +#define PSB_2D_PAT_2_PAL                 (0x00008000)
29312 +#define PSB_2D_PAT_4_PAL                 (0x00010000)
29313 +#define PSB_2D_PAT_8_PAL                 (0x00018000)
29314 +#define PSB_2D_PAT_8_ALPHA               (0x00020000)
29315 +#define PSB_2D_PAT_4_ALPHA               (0x00028000)
29316 +#define PSB_2D_PAT_332RGB                (0x00030000)
29317 +#define PSB_2D_PAT_4444ARGB              (0x00038000)
29318 +#define PSB_2D_PAT_555RGB                (0x00040000)
29319 +#define PSB_2D_PAT_1555ARGB              (0x00048000)
29320 +#define PSB_2D_PAT_565RGB                (0x00050000)
29321 +#define PSB_2D_PAT_0888ARGB              (0x00058000)
29322 +#define PSB_2D_PAT_8888ARGB              (0x00060000)
29323 +
29324 +#define PSB_2D_PAT_STRIDE_MASK           (0x00007FFF)
29325 +#define PSB_2D_PAT_STRIDE_CLRMASK        (0xFFFF8000)
29326 +#define PSB_2D_PAT_STRIDE_SHIFT          (0)
29327 +/*
29328 + *  WORD 1 - Base Address
29329 + */
29330 +#define PSB_2D_PAT_ADDR_MASK             (0x0FFFFFFC)
29331 +#define PSB_2D_PAT_ADDR_CLRMASK          (0x00000003)
29332 +#define PSB_2D_PAT_ADDR_SHIFT            (2)
29333 +#define PSB_2D_PAT_ADDR_ALIGNSHIFT       (2)
29334 +
29335 +/*
29336 + * Destination Surface (PSB_2D_DST_SURF_BH)
29337 + */
29338 +/*
29339 + * WORD 0
29340 + */
29341 +
29342 +#define PSB_2D_DST_FORMAT_MASK           (0x00078000)
29343 +#define PSB_2D_DST_332RGB                (0x00030000)
29344 +#define PSB_2D_DST_4444ARGB              (0x00038000)
29345 +#define PSB_2D_DST_555RGB                (0x00040000)
29346 +#define PSB_2D_DST_1555ARGB              (0x00048000)
29347 +#define PSB_2D_DST_565RGB                (0x00050000)
29348 +#define PSB_2D_DST_0888ARGB              (0x00058000)
29349 +#define PSB_2D_DST_8888ARGB              (0x00060000)
29350 +#define PSB_2D_DST_8888AYUV              (0x00070000)
29351 +
29352 +#define PSB_2D_DST_STRIDE_MASK           (0x00007FFF)
29353 +#define PSB_2D_DST_STRIDE_CLRMASK        (0xFFFF8000)
29354 +#define PSB_2D_DST_STRIDE_SHIFT          (0)
29355 +/*
29356 + * WORD 1 - Base Address
29357 + */
29358 +#define PSB_2D_DST_ADDR_MASK             (0x0FFFFFFC)
29359 +#define PSB_2D_DST_ADDR_CLRMASK          (0x00000003)
29360 +#define PSB_2D_DST_ADDR_SHIFT            (2)
29361 +#define PSB_2D_DST_ADDR_ALIGNSHIFT       (2)
29362 +
29363 +/*
29364 + * Mask Surface (PSB_2D_MASK_SURF_BH)
29365 + */
29366 +/*
29367 + * WORD 0
29368 + */
29369 +#define PSB_2D_MASK_STRIDE_MASK          (0x00007FFF)
29370 +#define PSB_2D_MASK_STRIDE_CLRMASK       (0xFFFF8000)
29371 +#define PSB_2D_MASK_STRIDE_SHIFT         (0)
29372 +/*
29373 + *  WORD 1 - Base Address
29374 + */
29375 +#define PSB_2D_MASK_ADDR_MASK            (0x0FFFFFFC)
29376 +#define PSB_2D_MASK_ADDR_CLRMASK         (0x00000003)
29377 +#define PSB_2D_MASK_ADDR_SHIFT           (2)
29378 +#define PSB_2D_MASK_ADDR_ALIGNSHIFT      (2)
29379 +
29380 +/*
29381 + * Source Palette (PSB_2D_SRC_PAL_BH)
29382 + */
29383 +
29384 +#define PSB_2D_SRCPAL_ADDR_SHIFT         (0)
29385 +#define PSB_2D_SRCPAL_ADDR_CLRMASK       (0xF0000007)
29386 +#define PSB_2D_SRCPAL_ADDR_MASK          (0x0FFFFFF8)
29387 +#define PSB_2D_SRCPAL_BYTEALIGN          (1024)
29388 +
29389 +/*
29390 + * Pattern Palette (PSB_2D_PAT_PAL_BH)
29391 + */
29392 +
29393 +#define PSB_2D_PATPAL_ADDR_SHIFT         (0)
29394 +#define PSB_2D_PATPAL_ADDR_CLRMASK       (0xF0000007)
29395 +#define PSB_2D_PATPAL_ADDR_MASK          (0x0FFFFFF8)
29396 +#define PSB_2D_PATPAL_BYTEALIGN          (1024)
29397 +
29398 +/*
29399 + * Rop3 Codes (2 LS bytes)
29400 + */
29401 +
29402 +#define PSB_2D_ROP3_SRCCOPY              (0xCCCC)
29403 +#define PSB_2D_ROP3_PATCOPY              (0xF0F0)
29404 +#define PSB_2D_ROP3_WHITENESS            (0xFFFF)
29405 +#define PSB_2D_ROP3_BLACKNESS            (0x0000)
29406 +#define PSB_2D_ROP3_SRC                  (0xCC)
29407 +#define PSB_2D_ROP3_PAT                  (0xF0)
29408 +#define PSB_2D_ROP3_DST                  (0xAA)
29409 +
29410 +
29411 +/*
29412 + * Sizes.
29413 + */
29414 +
29415 +#define PSB_SCENE_HW_COOKIE_SIZE 16
29416 +#define PSB_TA_MEM_HW_COOKIE_SIZE 16
29417 +
29418 +/*
29419 + * Scene stuff.
29420 + */
29421 +
29422 +#define PSB_NUM_HW_SCENES          2
29423 +
29424 +/*
29425 + * Scheduler completion actions.
29426 + */
29427 +
29428 +#define PSB_RASTER_BLOCK 0
29429 +#define PSB_RASTER       1
29430 +#define PSB_RETURN       2
29431 +#define PSB_TA       3
29432 +
29433 +
29434 +/*Power management*/
29435 +#define PSB_PUNIT_PORT             0x04
29436 +#define PSB_APMBA                  0x7a
29437 +#define PSB_APM_CMD                0x0
29438 +#define PSB_APM_STS                0x04
29439 +#define PSB_PWRGT_GFX_MASK         0x3
29440 +#define PSB_PWRGT_VID_ENC_MASK     0x30
29441 +#define PSB_PWRGT_VID_DEC_MASK     0xc
29442 +
29443 +#define PSB_PM_SSC                 0x20
29444 +#define PSB_PM_SSS                 0x30
29445 +#define PSB_PWRGT_DISPLAY_MASK     0xc /*on a different BA than video/gfx*/
29446 +#endif
29447 diff --git a/drivers/gpu/drm/mrst/drv/psb_reset.c b/drivers/gpu/drm/mrst/drv/psb_reset.c
29448 new file mode 100644
29449 index 0000000..eba85ea
29450 --- /dev/null
29451 +++ b/drivers/gpu/drm/mrst/drv/psb_reset.c
29452 @@ -0,0 +1,209 @@
29453 +/**************************************************************************
29454 + * Copyright (c) 2007, Intel Corporation.
29455 + *
29456 + * This program is free software; you can redistribute it and/or modify it
29457 + * under the terms and conditions of the GNU General Public License,
29458 + * version 2, as published by the Free Software Foundation.
29459 + *
29460 + * This program is distributed in the hope it will be useful, but WITHOUT
29461 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29462 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
29463 + * more details.
29464 + *
29465 + * You should have received a copy of the GNU General Public License along with
29466 + * this program; if not, write to the Free Software Foundation, Inc., 
29467 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
29468 + *
29469 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
29470 + **************************************************************************/
29471 +
29472 +#include <drm/drmP.h>
29473 +#include "psb_drv.h"
29474 +#include "psb_reg.h"
29475 +#include "psb_intel_reg.h"
29476 +#include "psb_msvdx.h"
29477 +#include "lnc_topaz.h"
29478 +#include <linux/spinlock.h>
29479 +
29480 +
29481 +void psb_schedule_watchdog(struct drm_psb_private *dev_priv)
29482 +{
29483 +       struct timer_list *wt = &dev_priv->watchdog_timer;
29484 +       unsigned long irq_flags;
29485 +
29486 +       spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
29487 +       if (dev_priv->timer_available && !timer_pending(wt)) {
29488 +               wt->expires = jiffies + PSB_WATCHDOG_DELAY;
29489 +               add_timer(wt);
29490 +       }
29491 +       spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
29492 +}
29493 +
29494 +
29495 +static void psb_watchdog_func(unsigned long data)
29496 +{
29497 +       struct drm_psb_private *dev_priv = (struct drm_psb_private *) data;
29498 +       int msvdx_lockup;
29499 +       int msvdx_idle;
29500 +       unsigned long irq_flags;
29501 +
29502 +       psb_msvdx_lockup(dev_priv, &msvdx_lockup, &msvdx_idle);
29503 +
29504 +       if (msvdx_lockup) {
29505 +               spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
29506 +               dev_priv->timer_available = 0;
29507 +               spin_unlock_irqrestore(&dev_priv->watchdog_lock,
29508 +                                      irq_flags);
29509 +               if (msvdx_lockup)
29510 +                       schedule_work(&dev_priv->msvdx_watchdog_wq);
29511 +       }
29512 +       if (!msvdx_idle)
29513 +               psb_schedule_watchdog(dev_priv);
29514 +}
29515 +
29516 +void psb_msvdx_flush_cmd_queue(struct drm_device *dev)
29517 +{
29518 +       struct drm_psb_private *dev_priv = dev->dev_private;
29519 +       struct psb_msvdx_cmd_queue *msvdx_cmd;
29520 +       struct list_head *list, *next;
29521 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
29522 +
29523 +       /*Flush the msvdx cmd queue and signal all fences in the queue */
29524 +       list_for_each_safe(list, next, &msvdx_priv->msvdx_queue) {
29525 +               msvdx_cmd =
29526 +                   list_entry(list, struct psb_msvdx_cmd_queue, head);
29527 +               PSB_DEBUG_GENERAL("MSVDXQUE: flushing sequence:%d\n",
29528 +                                 msvdx_cmd->sequence);
29529 +               msvdx_priv->msvdx_current_sequence = msvdx_cmd->sequence;
29530 +               psb_fence_error(dev, PSB_ENGINE_VIDEO,
29531 +                               msvdx_priv->msvdx_current_sequence,
29532 +                               _PSB_FENCE_TYPE_EXE, DRM_CMD_HANG);
29533 +               list_del(list);
29534 +               kfree(msvdx_cmd->cmd);
29535 +               kfree(msvdx_cmd
29536 +                        );
29537 +       }
29538 +}
29539 +
29540 +static void psb_msvdx_reset_wq(struct work_struct *work)
29541 +{
29542 +       struct drm_psb_private *dev_priv =
29543 +           container_of(work, struct drm_psb_private, msvdx_watchdog_wq);
29544 +       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
29545 +
29546 +       struct psb_scheduler *scheduler = &dev_priv->scheduler;
29547 +       unsigned long irq_flags;
29548 +
29549 +       mutex_lock(&msvdx_priv->msvdx_mutex);
29550 +       msvdx_priv->msvdx_needs_reset = 1;
29551 +       msvdx_priv->msvdx_current_sequence++;
29552 +       PSB_DEBUG_GENERAL
29553 +           ("MSVDXFENCE: incremented msvdx_current_sequence to :%d\n",
29554 +            msvdx_priv->msvdx_current_sequence);
29555 +
29556 +       psb_fence_error(scheduler->dev, PSB_ENGINE_VIDEO,
29557 +                       msvdx_priv->msvdx_current_sequence,
29558 +                       _PSB_FENCE_TYPE_EXE, DRM_CMD_HANG);
29559 +
29560 +       spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
29561 +       dev_priv->timer_available = 1;
29562 +       spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
29563 +
29564 +       spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
29565 +       psb_msvdx_flush_cmd_queue(scheduler->dev);
29566 +       spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
29567 +
29568 +       psb_schedule_watchdog(dev_priv);
29569 +       mutex_unlock(&msvdx_priv->msvdx_mutex);
29570 +}
29571 +
29572 +void psb_watchdog_init(struct drm_psb_private *dev_priv)
29573 +{
29574 +       struct timer_list *wt = &dev_priv->watchdog_timer;
29575 +       unsigned long irq_flags;
29576 +
29577 +       spin_lock_init(&dev_priv->watchdog_lock);
29578 +       spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
29579 +       init_timer(wt);
29580 +       INIT_WORK(&dev_priv->msvdx_watchdog_wq, &psb_msvdx_reset_wq);
29581 +       wt->data = (unsigned long) dev_priv;
29582 +       wt->function = &psb_watchdog_func;
29583 +       dev_priv->timer_available = 1;
29584 +       spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
29585 +}
29586 +
29587 +void psb_watchdog_takedown(struct drm_psb_private *dev_priv)
29588 +{
29589 +       unsigned long irq_flags;
29590 +
29591 +       spin_lock_irqsave(&dev_priv->watchdog_lock, irq_flags);
29592 +       dev_priv->timer_available = 0;
29593 +       spin_unlock_irqrestore(&dev_priv->watchdog_lock, irq_flags);
29594 +       (void) del_timer_sync(&dev_priv->watchdog_timer);
29595 +}
29596 +
29597 +static void psb_lid_timer_func(unsigned long data)
29598 +{
29599 +       struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
29600 +       struct drm_device *dev = (struct drm_device *)dev_priv->dev;
29601 +       struct timer_list *lid_timer = &dev_priv->lid_timer;
29602 +       unsigned long irq_flags;
29603 +       u32 *lid_state = dev_priv->lid_state;
29604 +       u32 pp_status;
29605 +
29606 +       if (*lid_state == dev_priv->lid_last_state)
29607 +               goto lid_timer_schedule;
29608 +
29609 +       if ((*lid_state) & 0x01) {
29610 +               /*lid state is open*/
29611 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
29612 +               do {
29613 +                       pp_status = REG_READ(PP_STATUS);
29614 +               } while ((pp_status & PP_ON) == 0);
29615 +
29616 +               /*FIXME: should be backlight level before*/
29617 +               psb_intel_lvds_set_brightness(dev, 100);
29618 +       } else {
29619 +               psb_intel_lvds_set_brightness(dev, 0);
29620 +
29621 +               REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
29622 +               do {
29623 +                       pp_status = REG_READ(PP_STATUS);
29624 +               } while ((pp_status & PP_ON) == 0);
29625 +       }
29626 +               /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */
29627 +
29628 +       dev_priv->lid_last_state =  *lid_state;
29629 +
29630 +lid_timer_schedule:
29631 +       spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
29632 +       if (!timer_pending(lid_timer)) {
29633 +               lid_timer->expires = jiffies + PSB_LID_DELAY;
29634 +               add_timer(lid_timer);
29635 +       }
29636 +       spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
29637 +}
29638 +
29639 +void psb_lid_timer_init(struct drm_psb_private *dev_priv)
29640 +{
29641 +       struct timer_list *lid_timer = &dev_priv->lid_timer;
29642 +       unsigned long irq_flags;
29643 +
29644 +       spin_lock_init(&dev_priv->lid_lock);
29645 +       spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
29646 +
29647 +       init_timer(lid_timer);
29648 +
29649 +       lid_timer->data = (unsigned long)dev_priv;
29650 +       lid_timer->function = psb_lid_timer_func;
29651 +       lid_timer->expires = jiffies + PSB_LID_DELAY;
29652 +
29653 +       add_timer(lid_timer);
29654 +       spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
29655 +}
29656 +
29657 +void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
29658 +{
29659 +       del_timer_sync(&dev_priv->lid_timer);
29660 +}
29661 +
29662 diff --git a/drivers/gpu/drm/mrst/drv/psb_schedule.c b/drivers/gpu/drm/mrst/drv/psb_schedule.c
29663 new file mode 100644
29664 index 0000000..4e2127c
29665 --- /dev/null
29666 +++ b/drivers/gpu/drm/mrst/drv/psb_schedule.c
29667 @@ -0,0 +1,70 @@
29668 +/**************************************************************************
29669 + * Copyright (c) 2007, Intel Corporation.
29670 + *
29671 + * This program is free software; you can redistribute it and/or modify it
29672 + * under the terms and conditions of the GNU General Public License,
29673 + * version 2, as published by the Free Software Foundation.
29674 + *
29675 + * This program is distributed in the hope it will be useful, but WITHOUT
29676 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29677 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
29678 + * more details.
29679 + *
29680 + * You should have received a copy of the GNU General Public License along with
29681 + * this program; if not, write to the Free Software Foundation, Inc., 
29682 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
29683 + *
29684 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
29685 + **************************************************************************/
29686 +
29687 +#include <drm/drmP.h>
29688 +#include "psb_drm.h"
29689 +#include "psb_drv.h"
29690 +#include "psb_reg.h"
29691 +#include "ttm/ttm_execbuf_util.h"
29692 +
29693 +
29694 +static void psb_powerdown_topaz(struct work_struct *work)
29695 +{
29696 +       struct psb_scheduler *scheduler =
29697 +           container_of(work, struct psb_scheduler, topaz_suspend_wq.work);
29698 +       struct drm_psb_private *dev_priv =
29699 +           (struct drm_psb_private *) scheduler->dev->dev_private;
29700 +
29701 +       if (!dev_priv->topaz_disabled) {        
29702 +               if (!mutex_trylock(&scheduler->topaz_power_mutex))
29703 +                       return;
29704 +
29705 +               psb_try_power_down_topaz(scheduler->dev);
29706 +               mutex_unlock(&scheduler->topaz_power_mutex);
29707 +       }
29708 +}
29709 +
29710 +static void psb_powerdown_msvdx(struct work_struct *work)
29711 +{
29712 +       struct psb_scheduler *scheduler =
29713 +           container_of(work, struct psb_scheduler, msvdx_suspend_wq.work);
29714 +
29715 +       if (!mutex_trylock(&scheduler->msvdx_power_mutex))
29716 +               return;
29717 +
29718 +       psb_try_power_down_msvdx(scheduler->dev);
29719 +       mutex_unlock(&scheduler->msvdx_power_mutex);
29720 +}
29721 +
29722 +int psb_scheduler_init(struct drm_device *dev,
29723 +                      struct psb_scheduler *scheduler)
29724 +{
29725 +       memset(scheduler, 0, sizeof(*scheduler));
29726 +       scheduler->dev = dev;
29727 +       mutex_init(&scheduler->topaz_power_mutex);
29728 +       mutex_init(&scheduler->msvdx_power_mutex);
29729 +
29730 +       INIT_DELAYED_WORK(&scheduler->topaz_suspend_wq,
29731 +                         &psb_powerdown_topaz);
29732 +       INIT_DELAYED_WORK(&scheduler->msvdx_suspend_wq,
29733 +                         &psb_powerdown_msvdx);
29734 +
29735 +       return 0;
29736 +}
29737 +
29738 diff --git a/drivers/gpu/drm/mrst/drv/psb_schedule.h b/drivers/gpu/drm/mrst/drv/psb_schedule.h
29739 new file mode 100644
29740 index 0000000..764eb29
29741 --- /dev/null
29742 +++ b/drivers/gpu/drm/mrst/drv/psb_schedule.h
29743 @@ -0,0 +1,81 @@
29744 +/**************************************************************************
29745 + * Copyright (c) 2007, Intel Corporation.
29746 + *
29747 + * This program is free software; you can redistribute it and/or modify it
29748 + * under the terms and conditions of the GNU General Public License,
29749 + * version 2, as published by the Free Software Foundation.
29750 + *
29751 + * This program is distributed in the hope it will be useful, but WITHOUT
29752 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29753 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
29754 + * more details.
29755 + *
29756 + * You should have received a copy of the GNU General Public License along with
29757 + * this program; if not, write to the Free Software Foundation, Inc., 
29758 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
29759 + *
29760 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
29761 + **************************************************************************/
29762 +#ifndef _PSB_SCHEDULE_H_
29763 +#define _PSB_SCHEDULE_H_
29764 +
29765 +#include <drm/drmP.h>
29766 +
29767 +struct psb_context;
29768 +
29769 +enum psb_task_type {
29770 +       psb_flip_task
29771 +};
29772 +
29773 +struct drm_psb_private;
29774 +
29775 +/*struct psb_scheduler_seq {
29776 +       uint32_t sequence;
29777 +       int reported;
29778 +};*/
29779 +
29780 +struct psb_scheduler {
29781 +       struct drm_device *dev;
29782 +       /*struct psb_scheduler_seq seq[_PSB_ENGINE_TA_FENCE_TYPES];
29783 +       struct psb_hw_scene hs[PSB_NUM_HW_SCENES];
29784 +       struct mutex task_wq_mutex;*/
29785 +       struct mutex topaz_power_mutex;
29786 +       struct mutex msvdx_power_mutex;
29787 +       /*spinlock_t lock;
29788 +       struct list_head hw_scenes;
29789 +       struct list_head ta_queue;
29790 +       struct list_head raster_queue;
29791 +       struct list_head hp_raster_queue;
29792 +       struct list_head task_done_queue;
29793 +       struct psb_task *current_task[PSB_SCENE_NUM_ENGINES];
29794 +       struct psb_task *feedback_task;
29795 +       int ta_state;
29796 +       struct psb_hw_scene *pending_hw_scene;
29797 +       uint32_t pending_hw_scene_seq;
29798 +       struct delayed_work wq*/;
29799 +       struct delayed_work topaz_suspend_wq;
29800 +       struct delayed_work msvdx_suspend_wq;
29801 +       /*struct psb_scene_pool *pool;
29802 +       uint32_t idle_count;
29803 +       int idle;
29804 +       wait_queue_head_t idle_queue;
29805 +       unsigned long ta_end_jiffies;
29806 +       unsigned long total_ta_jiffies;
29807 +       unsigned long raster_end_jiffies;
29808 +       unsigned long total_raster_jiffies;*/
29809 +};
29810 +
29811 +/*#define PSB_RF_FIRE_TA       (1 << 0)
29812 +#define PSB_RF_OOM           (1 << 1)
29813 +#define PSB_RF_OOM_REPLY     (1 << 2)
29814 +#define PSB_RF_TERMINATE     (1 << 3)
29815 +#define PSB_RF_TA_DONE       (1 << 4)
29816 +#define PSB_RF_FIRE_RASTER   (1 << 5)
29817 +#define PSB_RF_RASTER_DONE   (1 << 6)
29818 +#define PSB_RF_DEALLOC       (1 << 7)
29819 +*/
29820 +
29821 +extern int psb_scheduler_init(struct drm_device *dev,
29822 +                             struct psb_scheduler *scheduler);
29823 +
29824 +#endif
29825 diff --git a/drivers/gpu/drm/mrst/drv/psb_setup.c b/drivers/gpu/drm/mrst/drv/psb_setup.c
29826 new file mode 100644
29827 index 0000000..7bf2dcf
29828 --- /dev/null
29829 +++ b/drivers/gpu/drm/mrst/drv/psb_setup.c
29830 @@ -0,0 +1,35 @@
29831 +/*
29832 + * Copyright (c) 2009, Intel Corporation
29833 + *
29834 + * This program is free software; you can redistribute it and/or modify it
29835 + * under the terms and conditions of the GNU General Public License,
29836 + * version 2, as published by the Free Software Foundation.
29837 + *
29838 + * This program is distributed in the hope it will be useful, but WITHOUT
29839 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29840 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
29841 + * more details.
29842 + *
29843 + * You should have received a copy of the GNU General Public License along with
29844 + * this program; if not, write to the Free Software Foundation, Inc., 
29845 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
29846 + */
29847 +
29848 +#include <drm/drmP.h>
29849 +#include <drm/drm.h>
29850 +#include <drm/drm_crtc.h>
29851 +#include <drm/drm_edid.h>
29852 +#include "psb_intel_drv.h"
29853 +#include "psb_drv.h"
29854 +#include "psb_intel_reg.h"
29855 +
29856 +/* Fixed name */
29857 +#define ACPI_EDID_LCD  "\\_SB_.PCI0.GFX0.DD04._DDC"
29858 +#define ACPI_DOD       "\\_SB_.PCI0.GFX0._DOD"
29859 +
29860 +#include "psb_intel_i2c.c"
29861 +#include "psb_intel_sdvo.c"
29862 +#include "psb_intel_modes.c"
29863 +#include "psb_intel_lvds.c"
29864 +#include "psb_intel_dsi.c"
29865 +#include "psb_intel_display.c"
29866 diff --git a/drivers/gpu/drm/mrst/drv/psb_sgx.c b/drivers/gpu/drm/mrst/drv/psb_sgx.c
29867 new file mode 100644
29868 index 0000000..6bc821a
29869 --- /dev/null
29870 +++ b/drivers/gpu/drm/mrst/drv/psb_sgx.c
29871 @@ -0,0 +1,929 @@
29872 +/**************************************************************************
29873 + * Copyright (c) 2007, Intel Corporation.
29874 + * All Rights Reserved.
29875 + * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA.
29876 + * All Rights Reserved.
29877 + *
29878 + * This program is free software; you can redistribute it and/or modify it
29879 + * under the terms and conditions of the GNU General Public License,
29880 + * version 2, as published by the Free Software Foundation.
29881 + *
29882 + * This program is distributed in the hope it will be useful, but WITHOUT
29883 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29884 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
29885 + * more details.
29886 + *
29887 + * You should have received a copy of the GNU General Public License along with
29888 + * this program; if not, write to the Free Software Foundation, Inc., 
29889 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
29890 + *
29891 + **************************************************************************/
29892 +
29893 +#include <drm/drmP.h>
29894 +#include "psb_drv.h"
29895 +#include "psb_drm.h"
29896 +#include "psb_reg.h"
29897 +#include "psb_msvdx.h"
29898 +#include "lnc_topaz.h"
29899 +#include "ttm/ttm_bo_api.h"
29900 +#include "ttm/ttm_execbuf_util.h"
29901 +#include "ttm/ttm_userobj_api.h"
29902 +#include "ttm/ttm_placement_common.h"
29903 +#include "psb_sgx.h"
29904 +#include "psb_intel_reg.h"
29905 +#include "ospm_power.h"
29906 +
29907 +
29908 +static inline int psb_same_page(unsigned long offset,
29909 +                               unsigned long offset2)
29910 +{
29911 +       return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
29912 +}
29913 +
29914 +static inline unsigned long psb_offset_end(unsigned long offset,
29915 +                                             unsigned long end)
29916 +{
29917 +       offset = (offset + PAGE_SIZE) & PAGE_MASK;
29918 +       return (end < offset) ? end : offset;
29919 +}
29920 +
29921 +static void psb_idle_engine(struct drm_device *dev, int engine);
29922 +
29923 +struct psb_dstbuf_cache {
29924 +       unsigned int dst;
29925 +       struct ttm_buffer_object *dst_buf;
29926 +       unsigned long dst_offset;
29927 +       uint32_t *dst_page;
29928 +       unsigned int dst_page_offset;
29929 +       struct ttm_bo_kmap_obj dst_kmap;
29930 +       bool dst_is_iomem;
29931 +};
29932 +
29933 +struct psb_validate_buffer {
29934 +       struct ttm_validate_buffer base;
29935 +       struct psb_validate_req req;
29936 +       int ret;
29937 +       struct psb_validate_arg __user *user_val_arg;
29938 +       uint32_t flags;
29939 +       uint32_t offset;
29940 +       int po_correct;
29941 +};
29942 +
29943 +static int psb_check_presumed(struct psb_validate_req *req,
29944 +                             struct ttm_buffer_object *bo,
29945 +                             struct psb_validate_arg __user *data,
29946 +                             int *presumed_ok)
29947 +{
29948 +       struct psb_validate_req __user *user_req = &(data->d.req);
29949 +
29950 +       *presumed_ok = 0;
29951 +
29952 +       if (bo->mem.mem_type == TTM_PL_SYSTEM) {
29953 +               *presumed_ok = 1;
29954 +               return 0;
29955 +       }
29956 +
29957 +       if (unlikely(!(req->presumed_flags & PSB_USE_PRESUMED)))
29958 +               return 0;
29959 +
29960 +       if (bo->offset == req->presumed_gpu_offset) {
29961 +               *presumed_ok = 1;
29962 +               return 0;
29963 +       }
29964 +
29965 +       return __put_user(req->presumed_flags & ~PSB_USE_PRESUMED,
29966 +                         &user_req->presumed_flags);
29967 +}
29968 +
29969 +
29970 +static void psb_unreference_buffers(struct psb_context *context)
29971 +{
29972 +       struct ttm_validate_buffer *entry, *next;
29973 +       struct psb_validate_buffer *vbuf;
29974 +       struct list_head *list = &context->validate_list;
29975 +
29976 +       list_for_each_entry_safe(entry, next, list, head) {
29977 +               vbuf =
29978 +                   container_of(entry, struct psb_validate_buffer, base);
29979 +               list_del(&entry->head);
29980 +               ttm_bo_unref(&entry->bo);
29981 +       }
29982 +
29983 +       list = &context->kern_validate_list;
29984 +
29985 +       list_for_each_entry_safe(entry, next, list, head) {
29986 +               vbuf =
29987 +                   container_of(entry, struct psb_validate_buffer, base);
29988 +               list_del(&entry->head);
29989 +               ttm_bo_unref(&entry->bo);
29990 +       }
29991 +}
29992 +
29993 +
29994 +static int psb_lookup_validate_buffer(struct drm_file *file_priv,
29995 +                                     uint64_t data,
29996 +                                     struct psb_validate_buffer *item)
29997 +{
29998 +       struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
29999 +
30000 +       item->user_val_arg =
30001 +           (struct psb_validate_arg __user *) (unsigned long) data;
30002 +
30003 +       if (unlikely(copy_from_user(&item->req, &item->user_val_arg->d.req,
30004 +                                   sizeof(item->req)) != 0)) {
30005 +               DRM_ERROR("Lookup copy fault.\n");
30006 +               return -EFAULT;
30007 +       }
30008 +
30009 +       item->base.bo =
30010 +           ttm_buffer_object_lookup(tfile, item->req.buffer_handle);
30011 +
30012 +       if (unlikely(item->base.bo == NULL)) {
30013 +               DRM_ERROR("Bo lookup fault.\n");
30014 +               return -EINVAL;
30015 +       }
30016 +
30017 +       return 0;
30018 +}
30019 +
30020 +static int psb_reference_buffers(struct drm_file *file_priv,
30021 +                                uint64_t data,
30022 +                                struct psb_context *context)
30023 +{
30024 +       struct psb_validate_buffer *item;
30025 +       int ret;
30026 +
30027 +       while (likely(data != 0)) {
30028 +               if (unlikely(context->used_buffers >=
30029 +                            PSB_NUM_VALIDATE_BUFFERS)) {
30030 +                       DRM_ERROR("Too many buffers "
30031 +                                 "on validate list.\n");
30032 +                       ret = -EINVAL;
30033 +                       goto out_err0;
30034 +               }
30035 +
30036 +               item = &context->buffers[context->used_buffers];
30037 +
30038 +               ret = psb_lookup_validate_buffer(file_priv, data, item);
30039 +               if (unlikely(ret != 0))
30040 +                       goto out_err0;
30041 +
30042 +               item->base.reserved = 0;
30043 +               list_add_tail(&item->base.head, &context->validate_list);
30044 +               context->used_buffers++;
30045 +               data = item->req.next;
30046 +       }
30047 +       return 0;
30048 +
30049 +out_err0:
30050 +       psb_unreference_buffers(context);
30051 +       return ret;
30052 +}
30053 +
30054 +static int
30055 +psb_placement_fence_type(struct ttm_buffer_object *bo,
30056 +                        uint64_t set_val_flags,
30057 +                        uint64_t clr_val_flags,
30058 +                        uint32_t new_fence_class,
30059 +                        uint32_t *new_fence_type)
30060 +{
30061 +       int ret;
30062 +       uint32_t n_fence_type;
30063 +       uint32_t set_flags = set_val_flags & 0xFFFFFFFF;
30064 +       uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF;
30065 +       struct ttm_fence_object *old_fence;
30066 +       uint32_t old_fence_type;
30067 +
30068 +       if (unlikely
30069 +           (!(set_val_flags &
30070 +              (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) {
30071 +               DRM_ERROR
30072 +                   ("GPU access type (read / write) is not indicated.\n");
30073 +               return -EINVAL;
30074 +       }
30075 +
30076 +       ret = ttm_bo_check_placement(bo, set_flags, clr_flags);
30077 +       if (unlikely(ret != 0))
30078 +               return ret;
30079 +
30080 +       switch (new_fence_class) {
30081 +       default:
30082 +               n_fence_type = _PSB_FENCE_TYPE_EXE;
30083 +       }
30084 +
30085 +       *new_fence_type = n_fence_type;
30086 +       old_fence = (struct ttm_fence_object *) bo->sync_obj;
30087 +       old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg;
30088 +
30089 +       if (old_fence && ((new_fence_class != old_fence->fence_class) ||
30090 +                         ((n_fence_type ^ old_fence_type) &
30091 +                          old_fence_type))) {
30092 +               ret = ttm_bo_wait(bo, 0, 1, 0);
30093 +               if (unlikely(ret != 0))
30094 +                       return ret;
30095 +       }
30096 +
30097 +       bo->proposed_flags = (bo->proposed_flags | set_flags)
30098 +               & ~clr_flags & TTM_PL_MASK_MEMTYPE;
30099 +
30100 +       return 0;
30101 +}
30102 +
30103 +int psb_validate_kernel_buffer(struct psb_context *context,
30104 +                              struct ttm_buffer_object *bo,
30105 +                              uint32_t fence_class,
30106 +                              uint64_t set_flags, uint64_t clr_flags)
30107 +{
30108 +       struct psb_validate_buffer *item;
30109 +       uint32_t cur_fence_type;
30110 +       int ret;
30111 +
30112 +       if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) {
30113 +               DRM_ERROR("Out of free validation buffer entries for "
30114 +                         "kernel buffer validation.\n");
30115 +               return -ENOMEM;
30116 +       }
30117 +
30118 +       item = &context->buffers[context->used_buffers];
30119 +       item->user_val_arg = NULL;
30120 +       item->base.reserved = 0;
30121 +
30122 +       ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq);
30123 +       if (unlikely(ret != 0))
30124 +               goto out_unlock;
30125 +
30126 +       mutex_lock(&bo->mutex);
30127 +       ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class,
30128 +                                      &cur_fence_type);
30129 +       if (unlikely(ret != 0)) {
30130 +               ttm_bo_unreserve(bo);
30131 +               goto out_unlock;
30132 +       }
30133 +
30134 +       item->base.bo = ttm_bo_reference(bo);
30135 +       item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type;
30136 +       item->base.reserved = 1;
30137 +
30138 +       list_add_tail(&item->base.head, &context->kern_validate_list);
30139 +       context->used_buffers++;
30140 +
30141 +       ret = ttm_buffer_object_validate(bo, 1, 0);
30142 +       if (unlikely(ret != 0))
30143 +               goto out_unlock;
30144 +
30145 +       item->offset = bo->offset;
30146 +       item->flags = bo->mem.flags;
30147 +       context->fence_types |= cur_fence_type;
30148 +
30149 +out_unlock:
30150 +       mutex_unlock(&bo->mutex);
30151 +       return ret;
30152 +}
30153 +
30154 +
30155 +static int psb_validate_buffer_list(struct drm_file *file_priv,
30156 +                                   uint32_t fence_class,
30157 +                                   struct psb_context *context,
30158 +                                   int *po_correct)
30159 +{
30160 +       struct psb_validate_buffer *item;
30161 +       struct ttm_buffer_object *bo;
30162 +       int ret;
30163 +       struct psb_validate_req *req;
30164 +       uint32_t fence_types = 0;
30165 +       uint32_t cur_fence_type;
30166 +       struct ttm_validate_buffer *entry;
30167 +       struct list_head *list = &context->validate_list;
30168 +
30169 +       *po_correct = 1;
30170 +
30171 +       list_for_each_entry(entry, list, head) {
30172 +               item =
30173 +                   container_of(entry, struct psb_validate_buffer, base);
30174 +               bo = entry->bo;
30175 +               item->ret = 0;
30176 +               req = &item->req;
30177 +
30178 +               mutex_lock(&bo->mutex);
30179 +               ret = psb_placement_fence_type(bo,
30180 +                                              req->set_flags,
30181 +                                              req->clear_flags,
30182 +                                              fence_class,
30183 +                                              &cur_fence_type);
30184 +               if (unlikely(ret != 0))
30185 +                       goto out_err;
30186 +
30187 +               ret = ttm_buffer_object_validate(bo, 1, 0);
30188 +
30189 +               if (unlikely(ret != 0))
30190 +                       goto out_err;
30191 +
30192 +               fence_types |= cur_fence_type;
30193 +               entry->new_sync_obj_arg = (void *)
30194 +                       (unsigned long) cur_fence_type;
30195 +
30196 +               item->offset = bo->offset;
30197 +               item->flags = bo->mem.flags;
30198 +               mutex_unlock(&bo->mutex);
30199 +
30200 +               ret =
30201 +                   psb_check_presumed(&item->req, bo, item->user_val_arg,
30202 +                                      &item->po_correct);
30203 +               if (unlikely(ret != 0))
30204 +                       goto out_err;
30205 +
30206 +               if (unlikely(!item->po_correct))
30207 +                       *po_correct = 0;
30208 +
30209 +               item++;
30210 +       }
30211 +
30212 +       context->fence_types |= fence_types;
30213 +
30214 +       return 0;
30215 +out_err:
30216 +       mutex_unlock(&bo->mutex);
30217 +       item->ret = ret;
30218 +       return ret;
30219 +}
30220 +
30221 +static void psb_clear_dstbuf_cache(struct psb_dstbuf_cache *dst_cache)
30222 +{
30223 +       if (dst_cache->dst_page) {
30224 +               ttm_bo_kunmap(&dst_cache->dst_kmap);
30225 +               dst_cache->dst_page = NULL;
30226 +       }
30227 +       dst_cache->dst_buf = NULL;
30228 +       dst_cache->dst = ~0;
30229 +}
30230 +
30231 +static int psb_update_dstbuf_cache(struct psb_dstbuf_cache *dst_cache,
30232 +                                  struct psb_validate_buffer *buffers,
30233 +                                  unsigned int dst,
30234 +                                  unsigned long dst_offset)
30235 +{
30236 +       int ret;
30237 +
30238 +       PSB_DEBUG_GENERAL("Destination buffer is %d.\n", dst);
30239 +
30240 +       if (unlikely(dst != dst_cache->dst || NULL == dst_cache->dst_buf)) {
30241 +               psb_clear_dstbuf_cache(dst_cache);
30242 +               dst_cache->dst = dst;
30243 +               dst_cache->dst_buf = buffers[dst].base.bo;
30244 +       }
30245 +
30246 +       if (unlikely
30247 +           (dst_offset > dst_cache->dst_buf->num_pages * PAGE_SIZE)) {
30248 +               DRM_ERROR("Relocation destination out of bounds.\n");
30249 +               return -EINVAL;
30250 +       }
30251 +
30252 +       if (!psb_same_page(dst_cache->dst_offset, dst_offset) ||
30253 +           NULL == dst_cache->dst_page) {
30254 +               if (NULL != dst_cache->dst_page) {
30255 +                       ttm_bo_kunmap(&dst_cache->dst_kmap);
30256 +                       dst_cache->dst_page = NULL;
30257 +               }
30258 +
30259 +               ret =
30260 +                   ttm_bo_kmap(dst_cache->dst_buf,
30261 +                               dst_offset >> PAGE_SHIFT, 1,
30262 +                               &dst_cache->dst_kmap);
30263 +               if (ret) {
30264 +                       DRM_ERROR("Could not map destination buffer for "
30265 +                                 "relocation.\n");
30266 +                       return ret;
30267 +               }
30268 +
30269 +               dst_cache->dst_page =
30270 +                   ttm_kmap_obj_virtual(&dst_cache->dst_kmap,
30271 +                                        &dst_cache->dst_is_iomem);
30272 +               dst_cache->dst_offset = dst_offset & PAGE_MASK;
30273 +               dst_cache->dst_page_offset = dst_cache->dst_offset >> 2;
30274 +       }
30275 +       return 0;
30276 +}
30277 +
30278 +static int psb_apply_reloc(struct drm_psb_private *dev_priv,
30279 +                          uint32_t fence_class,
30280 +                          const struct drm_psb_reloc *reloc,
30281 +                          struct psb_validate_buffer *buffers,
30282 +                          int num_buffers,
30283 +                          struct psb_dstbuf_cache *dst_cache,
30284 +                          int no_wait, int interruptible)
30285 +{
30286 +       uint32_t val;
30287 +       uint32_t background;
30288 +       unsigned int index;
30289 +       int ret;
30290 +       unsigned int shift;
30291 +       unsigned int align_shift;
30292 +       struct ttm_buffer_object *reloc_bo;
30293 +
30294 +
30295 +       PSB_DEBUG_GENERAL("Reloc type %d\n"
30296 +                         "\t where 0x%04x\n"
30297 +                         "\t buffer 0x%04x\n"
30298 +                         "\t mask 0x%08x\n"
30299 +                         "\t shift 0x%08x\n"
30300 +                         "\t pre_add 0x%08x\n"
30301 +                         "\t background 0x%08x\n"
30302 +                         "\t dst_buffer 0x%08x\n"
30303 +                         "\t arg0 0x%08x\n"
30304 +                         "\t arg1 0x%08x\n",
30305 +                         reloc->reloc_op,
30306 +                         reloc->where,
30307 +                         reloc->buffer,
30308 +                         reloc->mask,
30309 +                         reloc->shift,
30310 +                         reloc->pre_add,
30311 +                         reloc->background,
30312 +                         reloc->dst_buffer, reloc->arg0, reloc->arg1);
30313 +
30314 +       if (unlikely(reloc->buffer >= num_buffers)) {
30315 +               DRM_ERROR("Illegal relocation buffer %d.\n",
30316 +                         reloc->buffer);
30317 +               return -EINVAL;
30318 +       }
30319 +
30320 +       if (buffers[reloc->buffer].po_correct)
30321 +               return 0;
30322 +
30323 +       if (unlikely(reloc->dst_buffer >= num_buffers)) {
30324 +               DRM_ERROR
30325 +                   ("Illegal destination buffer for relocation %d.\n",
30326 +                    reloc->dst_buffer);
30327 +               return -EINVAL;
30328 +       }
30329 +
30330 +       ret =
30331 +           psb_update_dstbuf_cache(dst_cache, buffers, reloc->dst_buffer,
30332 +                                   reloc->where << 2);
30333 +       if (ret)
30334 +               return ret;
30335 +
30336 +       reloc_bo = buffers[reloc->buffer].base.bo;
30337 +
30338 +       if (unlikely(reloc->pre_add > (reloc_bo->num_pages << PAGE_SHIFT))) {
30339 +               DRM_ERROR("Illegal relocation offset add.\n");
30340 +               return -EINVAL;
30341 +       }
30342 +
30343 +       switch (reloc->reloc_op) {
30344 +       case PSB_RELOC_OP_OFFSET:
30345 +               val = reloc_bo->offset + reloc->pre_add;
30346 +               break;
30347 +       default:
30348 +               DRM_ERROR("Unimplemented relocation.\n");
30349 +               return -EINVAL;
30350 +       }
30351 +
30352 +       shift =
30353 +           (reloc->shift & PSB_RELOC_SHIFT_MASK) >> PSB_RELOC_SHIFT_SHIFT;
30354 +       align_shift =
30355 +           (reloc->
30356 +            shift & PSB_RELOC_ALSHIFT_MASK) >> PSB_RELOC_ALSHIFT_SHIFT;
30357 +
30358 +       val = ((val >> align_shift) << shift);
30359 +       index = reloc->where - dst_cache->dst_page_offset;
30360 +
30361 +       background = reloc->background;
30362 +       val = (background & ~reloc->mask) | (val & reloc->mask);
30363 +       dst_cache->dst_page[index] = val;
30364 +
30365 +       PSB_DEBUG_GENERAL("Reloc buffer %d index 0x%08x, value 0x%08x\n",
30366 +                         reloc->dst_buffer, index,
30367 +                         dst_cache->dst_page[index]);
30368 +
30369 +       return 0;
30370 +}
30371 +
30372 +static int psb_ok_to_map_reloc(struct drm_psb_private *dev_priv,
30373 +                              unsigned int num_pages)
30374 +{
30375 +       int ret = 0;
30376 +
30377 +       spin_lock(&dev_priv->reloc_lock);
30378 +       if (dev_priv->rel_mapped_pages + num_pages <= PSB_MAX_RELOC_PAGES) {
30379 +               dev_priv->rel_mapped_pages += num_pages;
30380 +               ret = 1;
30381 +       }
30382 +       spin_unlock(&dev_priv->reloc_lock);
30383 +       return ret;
30384 +}
30385 +
30386 +static int psb_fixup_relocs(struct drm_file *file_priv,
30387 +                           uint32_t fence_class,
30388 +                           unsigned int num_relocs,
30389 +                           unsigned int reloc_offset,
30390 +                           uint32_t reloc_handle,
30391 +                           struct psb_context *context,
30392 +                           int no_wait, int interruptible)
30393 +{
30394 +       struct drm_device *dev = file_priv->minor->dev;
30395 +       struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
30396 +       struct drm_psb_private *dev_priv =
30397 +           (struct drm_psb_private *) dev->dev_private;
30398 +       struct ttm_buffer_object *reloc_buffer = NULL;
30399 +       unsigned int reloc_num_pages;
30400 +       unsigned int reloc_first_page;
30401 +       unsigned int reloc_last_page;
30402 +       struct psb_dstbuf_cache dst_cache;
30403 +       struct drm_psb_reloc *reloc;
30404 +       struct ttm_bo_kmap_obj reloc_kmap;
30405 +       bool reloc_is_iomem;
30406 +       int count;
30407 +       int ret = 0;
30408 +       int registered = 0;
30409 +       uint32_t num_buffers = context->used_buffers;
30410 +
30411 +       if (num_relocs == 0)
30412 +               return 0;
30413 +
30414 +       memset(&dst_cache, 0, sizeof(dst_cache));
30415 +       memset(&reloc_kmap, 0, sizeof(reloc_kmap));
30416 +
30417 +       reloc_buffer = ttm_buffer_object_lookup(tfile, reloc_handle);
30418 +       if (!reloc_buffer)
30419 +               goto out;
30420 +
30421 +       if (unlikely(atomic_read(&reloc_buffer->reserved) != 1)) {
30422 +               DRM_ERROR("Relocation buffer was not on validate list.\n");
30423 +               ret = -EINVAL;
30424 +               goto out;
30425 +       }
30426 +
30427 +       reloc_first_page = reloc_offset >> PAGE_SHIFT;
30428 +       reloc_last_page =
30429 +           (reloc_offset +
30430 +            num_relocs * sizeof(struct drm_psb_reloc)) >> PAGE_SHIFT;
30431 +       reloc_num_pages = reloc_last_page - reloc_first_page + 1;
30432 +       reloc_offset &= ~PAGE_MASK;
30433 +
30434 +       if (reloc_num_pages > PSB_MAX_RELOC_PAGES) {
30435 +               DRM_ERROR("Relocation buffer is too large\n");
30436 +               ret = -EINVAL;
30437 +               goto out;
30438 +       }
30439 +
30440 +       DRM_WAIT_ON(ret, dev_priv->rel_mapped_queue, 3 * DRM_HZ,
30441 +                   (registered =
30442 +                    psb_ok_to_map_reloc(dev_priv, reloc_num_pages)));
30443 +
30444 +       if (ret == -EINTR) {
30445 +               ret = -ERESTART;
30446 +               goto out;
30447 +       }
30448 +       if (ret) {
30449 +               DRM_ERROR("Error waiting for space to map "
30450 +                         "relocation buffer.\n");
30451 +               goto out;
30452 +       }
30453 +
30454 +       ret = ttm_bo_kmap(reloc_buffer, reloc_first_page,
30455 +                         reloc_num_pages, &reloc_kmap);
30456 +
30457 +       if (ret) {
30458 +               DRM_ERROR("Could not map relocation buffer.\n"
30459 +                         "\tReloc buffer id 0x%08x.\n"
30460 +                         "\tReloc first page %d.\n"
30461 +                         "\tReloc num pages %d.\n",
30462 +                         reloc_handle, reloc_first_page, reloc_num_pages);
30463 +               goto out;
30464 +       }
30465 +
30466 +       reloc = (struct drm_psb_reloc *)
30467 +           ((unsigned long)
30468 +            ttm_kmap_obj_virtual(&reloc_kmap,
30469 +                                 &reloc_is_iomem) + reloc_offset);
30470 +
30471 +       for (count = 0; count < num_relocs; ++count) {
30472 +               ret = psb_apply_reloc(dev_priv, fence_class,
30473 +                                     reloc, context->buffers,
30474 +                                     num_buffers, &dst_cache,
30475 +                                     no_wait, interruptible);
30476 +               if (ret)
30477 +                       goto out1;
30478 +               reloc++;
30479 +       }
30480 +
30481 +out1:
30482 +       ttm_bo_kunmap(&reloc_kmap);
30483 +out:
30484 +       if (registered) {
30485 +               spin_lock(&dev_priv->reloc_lock);
30486 +               dev_priv->rel_mapped_pages -= reloc_num_pages;
30487 +               spin_unlock(&dev_priv->reloc_lock);
30488 +               DRM_WAKEUP(&dev_priv->rel_mapped_queue);
30489 +       }
30490 +
30491 +       psb_clear_dstbuf_cache(&dst_cache);
30492 +       if (reloc_buffer)
30493 +               ttm_bo_unref(&reloc_buffer);
30494 +       return ret;
30495 +}
30496 +
30497 +void psb_fence_or_sync(struct drm_file *file_priv,
30498 +                      uint32_t engine,
30499 +                      uint32_t fence_types,
30500 +                      uint32_t fence_flags,
30501 +                      struct list_head *list,
30502 +                      struct psb_ttm_fence_rep *fence_arg,
30503 +                      struct ttm_fence_object **fence_p)
30504 +{
30505 +       struct drm_device *dev = file_priv->minor->dev;
30506 +       struct drm_psb_private *dev_priv = psb_priv(dev);
30507 +       struct ttm_fence_device *fdev = &dev_priv->fdev;
30508 +       int ret;
30509 +       struct ttm_fence_object *fence;
30510 +       struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
30511 +       uint32_t handle;
30512 +
30513 +       ret = ttm_fence_user_create(fdev, tfile,
30514 +                                   engine, fence_types,
30515 +                                   TTM_FENCE_FLAG_EMIT, &fence, &handle);
30516 +       if (ret) {
30517 +
30518 +               /*
30519 +                * Fence creation failed.
30520 +                * Fall back to synchronous operation and idle the engine.
30521 +                */
30522 +
30523 +               psb_idle_engine(dev, engine);
30524 +               if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
30525 +
30526 +                       /*
30527 +                        * Communicate to user-space that
30528 +                        * fence creation has failed and that
30529 +                        * the engine is idle.
30530 +                        */
30531 +
30532 +                       fence_arg->handle = ~0;
30533 +                       fence_arg->error = ret;
30534 +               }
30535 +
30536 +               ttm_eu_backoff_reservation(list);
30537 +               if (fence_p)
30538 +                       *fence_p = NULL;
30539 +               return;
30540 +       }
30541 +
30542 +       ttm_eu_fence_buffer_objects(list, fence);
30543 +       if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
30544 +               struct ttm_fence_info info = ttm_fence_get_info(fence);
30545 +               fence_arg->handle = handle;
30546 +               fence_arg->fence_class = ttm_fence_class(fence);
30547 +               fence_arg->fence_type = ttm_fence_types(fence);
30548 +               fence_arg->signaled_types = info.signaled_types;
30549 +               fence_arg->error = 0;
30550 +       } else {
30551 +               ret =
30552 +                   ttm_ref_object_base_unref(tfile, handle,
30553 +                                             ttm_fence_type);
30554 +               BUG_ON(ret);
30555 +       }
30556 +
30557 +       if (fence_p)
30558 +               *fence_p = fence;
30559 +       else if (fence)
30560 +               ttm_fence_object_unref(&fence);
30561 +}
30562 +
30563 +
30564 +#if 0
30565 +static int psb_dump_page(struct ttm_buffer_object *bo,
30566 +                        unsigned int page_offset, unsigned int num)
30567 +{
30568 +       struct ttm_bo_kmap_obj kmobj;
30569 +       int is_iomem;
30570 +       uint32_t *p;
30571 +       int ret;
30572 +       unsigned int i;
30573 +
30574 +       ret = ttm_bo_kmap(bo, page_offset, 1, &kmobj);
30575 +       if (ret)
30576 +               return ret;
30577 +
30578 +       p = ttm_kmap_obj_virtual(&kmobj, &is_iomem);
30579 +       for (i = 0; i < num; ++i)
30580 +               PSB_DEBUG_GENERAL("0x%04x: 0x%08x\n", i, *p++);
30581 +
30582 +       ttm_bo_kunmap(&kmobj);
30583 +       return 0;
30584 +}
30585 +#endif
30586 +
30587 +static void psb_idle_engine(struct drm_device *dev, int engine)
30588 +{
30589 +       /*Fix me add video engile support*/
30590 +       return;
30591 +}
30592 +
30593 +static int psb_handle_copyback(struct drm_device *dev,
30594 +                              struct psb_context *context,
30595 +                              int ret)
30596 +{
30597 +       int err = ret;
30598 +       struct ttm_validate_buffer *entry;
30599 +       struct psb_validate_arg arg;
30600 +       struct list_head *list = &context->validate_list;
30601 +
30602 +       if (ret) {
30603 +               ttm_eu_backoff_reservation(list);
30604 +               ttm_eu_backoff_reservation(&context->kern_validate_list);
30605 +       }
30606 +
30607 +
30608 +       if (ret != -EAGAIN && ret != -EINTR && ret != -ERESTART) {
30609 +               list_for_each_entry(entry, list, head) {
30610 +                       struct psb_validate_buffer *vbuf =
30611 +                           container_of(entry, struct psb_validate_buffer,
30612 +                                        base);
30613 +                       arg.handled = 1;
30614 +                       arg.ret = vbuf->ret;
30615 +                       if (!arg.ret) {
30616 +                               struct ttm_buffer_object *bo = entry->bo;
30617 +                               mutex_lock(&bo->mutex);
30618 +                               arg.d.rep.gpu_offset = bo->offset;
30619 +                               arg.d.rep.placement = bo->mem.flags;
30620 +                               arg.d.rep.fence_type_mask =
30621 +                                       (uint32_t) (unsigned long)
30622 +                                       entry->new_sync_obj_arg;
30623 +                               mutex_unlock(&bo->mutex);
30624 +                       }
30625 +
30626 +                       if (__copy_to_user(vbuf->user_val_arg,
30627 +                                          &arg, sizeof(arg)))
30628 +                               err = -EFAULT;
30629 +
30630 +                       if (arg.ret)
30631 +                               break;
30632 +               }
30633 +       }
30634 +
30635 +       return err;
30636 +}
30637 +
30638 +int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
30639 +                    struct drm_file *file_priv)
30640 +{
30641 +       struct drm_psb_cmdbuf_arg *arg = data;
30642 +       int ret = 0;
30643 +       struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
30644 +       struct ttm_buffer_object *cmd_buffer = NULL;
30645 +       struct psb_ttm_fence_rep fence_arg;
30646 +       struct drm_psb_private *dev_priv =
30647 +           (struct drm_psb_private *)file_priv->minor->dev->dev_private;
30648 +       int engine;
30649 +       int po_correct;
30650 +       struct psb_context *context;
30651 +       unsigned num_buffers;
30652 +
30653 +       num_buffers = PSB_NUM_VALIDATE_BUFFERS;
30654 +
30655 +       ret = ttm_read_lock(&dev_priv->ttm_lock, true);
30656 +       if (unlikely(ret != 0))
30657 +               return ret;
30658 +
30659 +       if (arg->engine == PSB_ENGINE_VIDEO) {
30660 +               if (!ospm_power_using_hw_begin(OSPM_VIDEO_DEC_ISLAND,
30661 +                                               OSPM_UHB_FORCE_POWER_ON))
30662 +                       return -EBUSY;
30663 +       } else if (arg->engine == LNC_ENGINE_ENCODE) {
30664 +               if (dev_priv->topaz_disabled)
30665 +                       return -ENODEV;
30666 +
30667 +               if (!ospm_power_using_hw_begin(OSPM_VIDEO_ENC_ISLAND,
30668 +                                               OSPM_UHB_FORCE_POWER_ON))
30669 +                       return -EBUSY;
30670 +       }
30671 +
30672 +
30673 +       ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
30674 +       if (unlikely(ret != 0))
30675 +               goto out_err0;
30676 +
30677 +
30678 +       context = &dev_priv->context;
30679 +       context->used_buffers = 0;
30680 +       context->fence_types = 0;
30681 +       BUG_ON(!list_empty(&context->validate_list));
30682 +       BUG_ON(!list_empty(&context->kern_validate_list));
30683 +
30684 +       if (unlikely(context->buffers == NULL)) {
30685 +               context->buffers = vmalloc(PSB_NUM_VALIDATE_BUFFERS *
30686 +                                          sizeof(*context->buffers));
30687 +               if (unlikely(context->buffers == NULL)) {
30688 +                       ret = -ENOMEM;
30689 +                       goto out_err1;
30690 +               }
30691 +       }
30692 +
30693 +       ret = psb_reference_buffers(file_priv,
30694 +                                   arg->buffer_list,
30695 +                                   context);
30696 +
30697 +       if (unlikely(ret != 0))
30698 +               goto out_err1;
30699 +
30700 +       context->val_seq = atomic_add_return(1, &dev_priv->val_seq);
30701 +
30702 +       ret = ttm_eu_reserve_buffers(&context->validate_list,
30703 +                                    context->val_seq);
30704 +       if (unlikely(ret != 0))
30705 +               goto out_err2;
30706 +
30707 +       engine = arg->engine;
30708 +       ret = psb_validate_buffer_list(file_priv, engine,
30709 +                                      context, &po_correct);
30710 +       if (unlikely(ret != 0))
30711 +               goto out_err3;
30712 +
30713 +       if (!po_correct) {
30714 +               ret = psb_fixup_relocs(file_priv, engine, arg->num_relocs,
30715 +                                      arg->reloc_offset,
30716 +                                      arg->reloc_handle, context, 0, 1);
30717 +               if (unlikely(ret != 0))
30718 +                       goto out_err3;
30719 +
30720 +       }
30721 +
30722 +       cmd_buffer = ttm_buffer_object_lookup(tfile, arg->cmdbuf_handle);
30723 +       if (unlikely(cmd_buffer == NULL)) {
30724 +               ret = -EINVAL;
30725 +               goto out_err4;
30726 +       }
30727 +
30728 +       switch (arg->engine) {
30729 +       case PSB_ENGINE_VIDEO:
30730 +               if (arg->cmdbuf_size == (16 + 32)) {
30731 +                       /* Identify deblock msg cmdbuf */
30732 +                       /* according to cmdbuf_size */
30733 +                       struct ttm_bo_kmap_obj cmd_kmap;
30734 +                       struct ttm_buffer_object *deblock;
30735 +                       uint32_t *cmd;
30736 +                       bool is_iomem;
30737 +
30738 +                       /* write regIO BO's address after deblcok msg */
30739 +                       ret = ttm_bo_kmap(cmd_buffer, 0, 1, &cmd_kmap);
30740 +                       if (unlikely(ret != 0))
30741 +                               goto out_err4;
30742 +                       cmd = (uint32_t *)(ttm_kmap_obj_virtual(&cmd_kmap,
30743 +                                                       &is_iomem) + 16);
30744 +                       deblock = ttm_buffer_object_lookup(tfile,
30745 +                                                          (uint32_t)(*cmd));
30746 +                       *cmd = (uint32_t)deblock;
30747 +                       ttm_bo_kunmap(&cmd_kmap);
30748 +               }
30749 +
30750 +               ret = psb_cmdbuf_video(file_priv, &context->validate_list,
30751 +                                      context->fence_types, arg,
30752 +                                      cmd_buffer, &fence_arg);
30753 +
30754 +               if (unlikely(ret != 0))
30755 +                       goto out_err4;
30756 +               break;
30757 +       case LNC_ENGINE_ENCODE:
30758 +               ret = lnc_cmdbuf_video(file_priv, &context->validate_list,
30759 +                                      context->fence_types, arg,
30760 +                                      cmd_buffer, &fence_arg);
30761 +               if (unlikely(ret != 0))
30762 +                       goto out_err4;
30763 +               break;
30764 +
30765 +
30766 +       default:
30767 +               DRM_ERROR
30768 +                   ("Unimplemented command submission mechanism (%x).\n",
30769 +                    arg->engine);
30770 +               ret = -EINVAL;
30771 +               goto out_err4;
30772 +       }
30773 +
30774 +       if (!(arg->fence_flags & DRM_PSB_FENCE_NO_USER)) {
30775 +               ret = copy_to_user((void __user *)
30776 +                                  ((unsigned long) arg->fence_arg),
30777 +                                  &fence_arg, sizeof(fence_arg));
30778 +       }
30779 +
30780 +out_err4:
30781 +       if (cmd_buffer)
30782 +               ttm_bo_unref(&cmd_buffer);
30783 +out_err3:
30784 +       ret = psb_handle_copyback(dev, context, ret);
30785 +out_err2:
30786 +       psb_unreference_buffers(context);
30787 +out_err1:
30788 +       mutex_unlock(&dev_priv->cmdbuf_mutex);
30789 +out_err0:
30790 +       ttm_read_unlock(&dev_priv->ttm_lock);
30791 +
30792 +       if (arg->engine == PSB_ENGINE_VIDEO)
30793 +               ospm_power_using_hw_end(OSPM_VIDEO_DEC_ISLAND);
30794 +
30795 +       if (arg->engine == LNC_ENGINE_ENCODE)
30796 +               ospm_power_using_hw_end(OSPM_VIDEO_ENC_ISLAND);
30797 +
30798 +       return ret;
30799 +}
30800 +
30801 diff --git a/drivers/gpu/drm/mrst/drv/psb_sgx.h b/drivers/gpu/drm/mrst/drv/psb_sgx.h
30802 new file mode 100644
30803 index 0000000..2934e5d
30804 --- /dev/null
30805 +++ b/drivers/gpu/drm/mrst/drv/psb_sgx.h
30806 @@ -0,0 +1,32 @@
30807 +/*
30808 + * Copyright (c) 2008, Intel Corporation
30809 + *
30810 + * This program is free software; you can redistribute it and/or modify it
30811 + * under the terms and conditions of the GNU General Public License,
30812 + * version 2, as published by the Free Software Foundation.
30813 + *
30814 + * This program is distributed in the hope it will be useful, but WITHOUT
30815 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30816 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
30817 + * more details.
30818 + *
30819 + * You should have received a copy of the GNU General Public License along with
30820 + * this program; if not, write to the Free Software Foundation, Inc., 
30821 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
30822 + *
30823 + * Authors:
30824 + *    Eric Anholt <eric@anholt.net>
30825 + *
30826 + **/
30827 +#ifndef _PSB_SGX_H_
30828 +#define _PSB_SGX_H_
30829 +
30830 +extern int psb_submit_video_cmdbuf(struct drm_device *dev,
30831 +                              struct ttm_buffer_object *cmd_buffer,
30832 +                              unsigned long cmd_offset,
30833 +                              unsigned long cmd_size,
30834 +                              struct ttm_fence_object *fence);
30835 +
30836 +extern int drm_idle_check_interval;
30837 +
30838 +#endif
30839 diff --git a/drivers/gpu/drm/mrst/drv/psb_socket.c b/drivers/gpu/drm/mrst/drv/psb_socket.c
30840 new file mode 100644
30841 index 0000000..8bb12cf
30842 --- /dev/null
30843 +++ b/drivers/gpu/drm/mrst/drv/psb_socket.c
30844 @@ -0,0 +1,376 @@
30845 +/*
30846 + * Copyright (c) 2009, Intel Corporation.
30847 + *
30848 + * This program is free software; you can redistribute it and/or modify it
30849 + * under the terms and conditions of the GNU General Public License,
30850 + * version 2, as published by the Free Software Foundation.
30851 + *
30852 + * This program is distributed in the hope it will be useful, but WITHOUT
30853 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30854 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
30855 + * more details.
30856 + *
30857 + * You should have received a copy of the GNU General Public License along with
30858 + * this program; if not, write to the Free Software Foundation, Inc., 
30859 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
30860 + *
30861 + * Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
30862 + * Copyright (C) 2004 Novell, Inc.  All rights reserved.
30863 + * Copyright (C) 2004 IBM, Inc. All rights reserved.
30864 + * Copyright (C) 2009 Intel Corporation.  All rights reserved.
30865 + *
30866 + * Licensed under the GNU GPL v2.
30867 + *
30868 + * Authors:
30869 + *     Robert Love             <rml@novell.com>
30870 + *     Kay Sievers             <kay.sievers@vrfy.org>
30871 + *     Arjan van de Ven        <arjanv@redhat.com>
30872 + *     Greg Kroah-Hartman      <greg@kroah.com>
30873 + *
30874 + * Notes:
30875 + *      Adapted from existing kobj event socket code to enable
30876 + *      mutlicast usermode communication for gfx driver to mutiple
30877 + *      usermode threads via different socket broadcast groups.
30878 + *      Original kobject uevent code does not allow for different
30879 + *      broadcast groups.  Due to the frequency of usermode events
30880 + *      generated by some gfx subsystems it is necessary to open
30881 + *      a new dedicated socket with multicast group support.  In
30882 + *      the future it is hoped that this code can be removed
30883 + *      and either a new netlink protocol type added for graphics
30884 + *      or conversely to simply enable group routing to be leveraged
30885 + *      on the existing kobject uevent infrastructure.
30886 + */
30887 +
30888 +#include <linux/spinlock.h>
30889 +#include <linux/string.h>
30890 +#include <linux/kobject.h>
30891 +#include <linux/module.h>
30892 +#include <linux/socket.h>
30893 +#include <linux/skbuff.h>
30894 +#include <linux/netlink.h>
30895 +#include <net/sock.h>
30896 +#include "psb_umevents.h"
30897 +
30898 +#define NETLINK_PSB_KOBJECT_UEVENT     31
30899 +
30900 +u64 psb_uevent_seqnum;
30901 +char psb_uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
30902 +static DEFINE_SPINLOCK(sequence_lock);
30903 +#if defined(CONFIG_NET)
30904 +static struct sock *uevent_sock;
30905 +#endif
30906 +
30907 +/* the strings here must match the enum in include/linux/kobject.h */
30908 +static const char *psb_kobject_actions[] = {
30909 +       [KOBJ_ADD] =            "add",
30910 +       [KOBJ_REMOVE] =         "remove",
30911 +       [KOBJ_CHANGE] =         "change",
30912 +       [KOBJ_MOVE] =           "move",
30913 +       [KOBJ_ONLINE] =         "online",
30914 +       [KOBJ_OFFLINE] =        "offline",
30915 +};
30916 +
30917 +/**
30918 + * kobject_action_type - translate action string to numeric type
30919 + *
30920 + * @buf: buffer containing the action string, newline is ignored
30921 + * @len: length of buffer
30922 + * @type: pointer to the location to store the action type
30923 + *
30924 + * Returns 0 if the action string was recognized.
30925 + */
30926 +int psb_kobject_action_type(const char *buf, size_t count,
30927 +                       enum kobject_action *type)
30928 +{
30929 +       enum kobject_action action;
30930 +       int ret = -EINVAL;
30931 +
30932 +       if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
30933 +               count--;
30934 +
30935 +       if (!count)
30936 +               goto out;
30937 +
30938 +       for (action = 0; action < ARRAY_SIZE(psb_kobject_actions); action++) {
30939 +               if (strncmp(psb_kobject_actions[action], buf, count) != 0)
30940 +                       continue;
30941 +               if (psb_kobject_actions[action][count] != '\0')
30942 +                       continue;
30943 +               *type = action;
30944 +               ret = 0;
30945 +               break;
30946 +       }
30947 +out:
30948 +       return ret;
30949 +}
30950 +
30951 +/**
30952 + * psb_kobject_uevent_env - send an uevent with environmental data
30953 + *
30954 + * @action: action that is happening
30955 + * @kobj: struct kobject that the action is happening to
30956 + * @envp_ext: pointer to environmental data
30957 + *
30958 + * Returns 0 if kobject_uevent() is completed with success or the
30959 + * corresponding error when it fails.
30960 + */
30961 +int psb_kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
30962 +                          char *envp_ext[], int dst_group_id)
30963 +{
30964 +       struct kobj_uevent_env *env;
30965 +       const char *action_string = psb_kobject_actions[action];
30966 +       const char *devpath = NULL;
30967 +       const char *subsystem;
30968 +       struct kobject *top_kobj;
30969 +       struct kset *kset;
30970 +       struct kset_uevent_ops *uevent_ops;
30971 +       u64 seq;
30972 +       int i = 0;
30973 +       int retval = 0;
30974 +
30975 +       pr_debug("kobject: '%s' (%p): %s\n",
30976 +                kobject_name(kobj), kobj, __func__);
30977 +
30978 +       /* search the kset we belong to */
30979 +       top_kobj = kobj;
30980 +       while (!top_kobj->kset && top_kobj->parent)
30981 +               top_kobj = top_kobj->parent;
30982 +
30983 +       if (!top_kobj->kset) {
30984 +               pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "
30985 +                        "without kset!\n", kobject_name(kobj), kobj,
30986 +                        __func__);
30987 +               return -EINVAL;
30988 +       }
30989 +
30990 +       kset = top_kobj->kset;
30991 +       uevent_ops = kset->uevent_ops;
30992 +
30993 +       /* skip the event, if uevent_suppress is set*/
30994 +       if (kobj->uevent_suppress) {
30995 +               pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
30996 +                                "caused the event to drop!\n",
30997 +                                kobject_name(kobj), kobj, __func__);
30998 +               return 0;
30999 +       }
31000 +       /* skip the event, if the filter returns zero. */
31001 +       if (uevent_ops && uevent_ops->filter)
31002 +               if (!uevent_ops->filter(kset, kobj)) {
31003 +                       pr_debug("kobject: '%s' (%p): %s: filter function "
31004 +                                "caused the event to drop!\n",
31005 +                                kobject_name(kobj), kobj, __func__);
31006 +                       return 0;
31007 +               }
31008 +
31009 +       /* originating subsystem */
31010 +       if (uevent_ops && uevent_ops->name)
31011 +               subsystem = uevent_ops->name(kset, kobj);
31012 +       else
31013 +               subsystem = kobject_name(&kset->kobj);
31014 +       if (!subsystem) {
31015 +               pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "
31016 +                        "event to drop!\n", kobject_name(kobj), kobj,
31017 +                        __func__);
31018 +               return 0;
31019 +       }
31020 +
31021 +       /* environment buffer */
31022 +       env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
31023 +       if (!env)
31024 +               return -ENOMEM;
31025 +
31026 +       /* complete object path */
31027 +       devpath = kobject_get_path(kobj, GFP_KERNEL);
31028 +       if (!devpath) {
31029 +               retval = -ENOENT;
31030 +               goto exit;
31031 +       }
31032 +
31033 +       /* default keys */
31034 +       retval = add_uevent_var(env, "ACTION=%s", action_string);
31035 +       if (retval)
31036 +               goto exit;
31037 +       retval = add_uevent_var(env, "DEVPATH=%s", devpath);
31038 +       if (retval)
31039 +               goto exit;
31040 +       retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
31041 +       if (retval)
31042 +               goto exit;
31043 +
31044 +       /* keys passed in from the caller */
31045 +       if (envp_ext) {
31046 +               for (i = 0; envp_ext[i]; i++) {
31047 +                       retval = add_uevent_var(env, "%s", envp_ext[i]);
31048 +                       if (retval)
31049 +                               goto exit;
31050 +               }
31051 +       }
31052 +
31053 +       /* let the kset specific function add its stuff */
31054 +       if (uevent_ops && uevent_ops->uevent) {
31055 +               retval = uevent_ops->uevent(kset, kobj, env);
31056 +               if (retval) {
31057 +                       pr_debug("kobject: '%s' (%p): %s: uevent() returned "
31058 +                                "%d\n", kobject_name(kobj), kobj,
31059 +                                __func__, retval);
31060 +                       goto exit;
31061 +               }
31062 +       }
31063 +
31064 +       /*
31065 +        * Mark "add" and "remove" events in the object to ensure proper
31066 +        * events to userspace during automatic cleanup. If the object did
31067 +        * send an "add" event, "remove" will automatically generated by
31068 +        * the core, if not already done by the caller.
31069 +        */
31070 +       if (action == KOBJ_ADD)
31071 +               kobj->state_add_uevent_sent = 1;
31072 +       else if (action == KOBJ_REMOVE)
31073 +               kobj->state_remove_uevent_sent = 1;
31074 +
31075 +       /* we will send an event, so request a new sequence number */
31076 +       spin_lock(&sequence_lock);
31077 +       seq = ++psb_uevent_seqnum;
31078 +       spin_unlock(&sequence_lock);
31079 +       retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
31080 +       if (retval)
31081 +               goto exit;
31082 +
31083 +#if defined(CONFIG_NET)
31084 +       /* send netlink message */
31085 +       if (uevent_sock) {
31086 +               struct sk_buff *skb;
31087 +               size_t len;
31088 +
31089 +               /* allocate message with the maximum possible size */
31090 +               len = strlen(action_string) + strlen(devpath) + 2;
31091 +               skb = alloc_skb(len + env->buflen, GFP_KERNEL);
31092 +               if (skb) {
31093 +                       char *scratch;
31094 +
31095 +                       /* add header */
31096 +                       scratch = skb_put(skb, len);
31097 +                       sprintf(scratch, "%s@%s", action_string, devpath);
31098 +
31099 +                       /* copy keys to our continuous event payload buffer */
31100 +                       for (i = 0; i < env->envp_idx; i++) {
31101 +                               len = strlen(env->envp[i]) + 1;
31102 +                               scratch = skb_put(skb, len);
31103 +                               strcpy(scratch, env->envp[i]);
31104 +                       }
31105 +
31106 +                       NETLINK_CB(skb).dst_group = dst_group_id;
31107 +                       retval = netlink_broadcast(uevent_sock, skb, 0,
31108 +                                                  dst_group_id,
31109 +                                                  GFP_KERNEL);
31110 +
31111 +                       /* ENOBUFS should be handled in userspace */
31112 +                       if (retval == -ENOBUFS)
31113 +                               retval = 0;
31114 +               } else
31115 +                       retval = -ENOMEM;
31116 +       }
31117 +#endif
31118 +
31119 +       /* call psb_uevent_helper, usually only enabled during early boot */
31120 +       if (psb_uevent_helper[0]) {
31121 +               char *argv[3];
31122 +
31123 +               argv[0] = psb_uevent_helper;
31124 +               argv[1] = (char *)subsystem;
31125 +               argv[2] = NULL;
31126 +               retval = add_uevent_var(env, "HOME=/");
31127 +               if (retval)
31128 +                       goto exit;
31129 +               retval = add_uevent_var(env,
31130 +                                       "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
31131 +               if (retval)
31132 +                       goto exit;
31133 +
31134 +               retval = call_usermodehelper(argv[0], argv,
31135 +                                            env->envp, UMH_WAIT_EXEC);
31136 +       }
31137 +
31138 +exit:
31139 +       kfree(devpath);
31140 +       kfree(env);
31141 +       return retval;
31142 +}
31143 +EXPORT_SYMBOL_GPL(psb_kobject_uevent_env);
31144 +
31145 +/**
31146 + * psb_kobject_uevent - notify userspace by ending an uevent
31147 + *
31148 + * @action: action that is happening
31149 + * @kobj: struct kobject that the action is happening to
31150 + *
31151 + * Returns 0 if psb_kobject_uevent() is completed with success or the
31152 + * corresponding error when it fails.
31153 + */
31154 +int psb_kobject_uevent(struct kobject *kobj, enum kobject_action action,
31155 +                      int dst_group_id)
31156 +{
31157 +       return psb_kobject_uevent_env(kobj, action, NULL, dst_group_id);
31158 +}
31159 +EXPORT_SYMBOL_GPL(psb_kobject_uevent);
31160 +
31161 +/**
31162 + * psb_add_uevent_var - add key value string to the environment buffer
31163 + * @env: environment buffer structure
31164 + * @format: printf format for the key=value pair
31165 + *
31166 + * Returns 0 if environment variable was added successfully or -ENOMEM
31167 + * if no space was available.
31168 + */
31169 +int psb_add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
31170 +{
31171 +       va_list args;
31172 +       int len;
31173 +
31174 +       if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
31175 +               WARN(1, KERN_ERR "psb_add_uevent_var: too many keys\n");
31176 +               return -ENOMEM;
31177 +       }
31178 +
31179 +       va_start(args, format);
31180 +       len = vsnprintf(&env->buf[env->buflen],
31181 +                       sizeof(env->buf) - env->buflen,
31182 +                       format, args);
31183 +       va_end(args);
31184 +
31185 +       if (len >= (sizeof(env->buf) - env->buflen)) {
31186 +               WARN(1,
31187 +                    KERN_ERR "psb_add_uevent_var: buffer size too small\n");
31188 +               return -ENOMEM;
31189 +       }
31190 +
31191 +       env->envp[env->envp_idx++] = &env->buf[env->buflen];
31192 +       env->buflen += len + 1;
31193 +       return 0;
31194 +}
31195 +EXPORT_SYMBOL_GPL(psb_add_uevent_var);
31196 +
31197 +#if defined(CONFIG_NET)
31198 +static int __init psb_kobject_uevent_init(void)
31199 +{
31200 +       /* This should be the 15, but 3 seems to work better.  Why? WHY!? */
31201 +       /* uevent_sock = netlink_kernel_create(&init_net,
31202 +                                           NETLINK_PSB_KOBJECT_UEVENT,
31203 +                                           DRM_GFX_SOCKET_GROUPS,
31204 +                                           NULL, NULL, THIS_MODULE); */
31205 +       uevent_sock = netlink_kernel_create(&init_net,
31206 +                                           NETLINK_PSB_KOBJECT_UEVENT,
31207 +                                           0x1, /* 3 is for hotplug & dpst */
31208 +                                           NULL, NULL, THIS_MODULE);
31209 +
31210 +       if (!uevent_sock) {
31211 +               printk(KERN_ERR "psb_kobject_uevent: failed create socket!\n");
31212 +               return -ENODEV;
31213 +       }
31214 +       netlink_set_nonroot(NETLINK_PSB_KOBJECT_UEVENT, NL_NONROOT_RECV);
31215 +
31216 +       return 0;
31217 +}
31218 +
31219 +postcore_initcall(psb_kobject_uevent_init);
31220 +#endif
31221 diff --git a/drivers/gpu/drm/mrst/drv/psb_ttm_glue.c b/drivers/gpu/drm/mrst/drv/psb_ttm_glue.c
31222 new file mode 100644
31223 index 0000000..ad0e6ee
31224 --- /dev/null
31225 +++ b/drivers/gpu/drm/mrst/drv/psb_ttm_glue.c
31226 @@ -0,0 +1,344 @@
31227 +/**************************************************************************
31228 + * Copyright (c) 2008, Intel Corporation.
31229 + * All Rights Reserved.
31230 + * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
31231 + * All Rights Reserved.
31232 + *
31233 + * This program is free software; you can redistribute it and/or modify it
31234 + * under the terms and conditions of the GNU General Public License,
31235 + * version 2, as published by the Free Software Foundation.
31236 + *
31237 + * This program is distributed in the hope it will be useful, but WITHOUT
31238 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31239 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
31240 + * more details.
31241 + *
31242 + * You should have received a copy of the GNU General Public License along with
31243 + * this program; if not, write to the Free Software Foundation, Inc., 
31244 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
31245 + *
31246 + **************************************************************************/
31247 +
31248 +
31249 +#include <drm/drmP.h>
31250 +#include "psb_drv.h"
31251 +#include "ttm/ttm_userobj_api.h"
31252 +#include <linux/io.h>
31253 +
31254 +/*IMG Headers*/
31255 +#include "private_data.h"
31256 +
31257 +extern int PVRMMap(struct file *pFile, struct vm_area_struct *ps_vma);
31258 +
31259 +static struct vm_operations_struct psb_ttm_vm_ops;
31260 +
31261 +/**
31262 + * NOTE: driver_private of drm_file is now a PVRSRV_FILE_PRIVATE_DATA struct
31263 + * pPriv in PVRSRV_FILE_PRIVATE_DATA contains the original psb_fpriv;
31264 + */
31265 +int psb_open(struct inode *inode, struct file *filp)
31266 +{
31267 +       struct drm_file *file_priv;
31268 +       struct drm_psb_private *dev_priv;
31269 +       struct psb_fpriv *psb_fp;
31270 +       PVRSRV_FILE_PRIVATE_DATA *pvr_file_priv;
31271 +       int ret;
31272 +
31273 +       DRM_DEBUG("\n");
31274 +
31275 +       ret = drm_open(inode, filp);
31276 +       if (unlikely(ret))
31277 +               return ret;
31278 +
31279 +       psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL);
31280 +
31281 +       if (unlikely(psb_fp == NULL))
31282 +               goto out_err0;
31283 +
31284 +       file_priv = (struct drm_file *) filp->private_data;
31285 +       dev_priv = psb_priv(file_priv->minor->dev);
31286 +
31287 +       DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0);
31288 +
31289 +       psb_fp->tfile = ttm_object_file_init(dev_priv->tdev,
31290 +                                            PSB_FILE_OBJECT_HASH_ORDER);
31291 +       if (unlikely(psb_fp->tfile == NULL))
31292 +               goto out_err1;
31293 +
31294 +       pvr_file_priv = (PVRSRV_FILE_PRIVATE_DATA *)file_priv->driver_priv;
31295 +       if (!pvr_file_priv) {
31296 +               DRM_ERROR("drm file private is NULL\n");
31297 +               goto out_err1;
31298 +       }
31299 +
31300 +       pvr_file_priv->pPriv = psb_fp;
31301 +
31302 +       if (unlikely(dev_priv->bdev.dev_mapping == NULL))
31303 +               dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping;
31304 +
31305 +       return 0;
31306 +
31307 +out_err1:
31308 +       kfree(psb_fp);
31309 +out_err0:
31310 +       (void) drm_release(inode, filp);
31311 +       return ret;
31312 +}
31313 +
31314 +int psb_release(struct inode *inode, struct file *filp)
31315 +{
31316 +       struct drm_file *file_priv;
31317 +       struct psb_fpriv *psb_fp;
31318 +       struct drm_psb_private *dev_priv;
31319 +       int ret;
31320 +       uint32_t ui32_reg_value = 0;
31321 +
31322 +       file_priv = (struct drm_file *) filp->private_data;
31323 +       psb_fp = psb_fpriv(file_priv);
31324 +       dev_priv = psb_priv(file_priv->minor->dev);
31325 +
31326 +       ttm_object_file_release(&psb_fp->tfile);
31327 +       kfree(psb_fp);
31328 +
31329 +       if (IS_MRST(dev_priv->dev))
31330 +       {
31331 +               schedule_delayed_work(&dev_priv->scheduler.topaz_suspend_wq, 10);
31332 +               /* FIXME: workaround for HSD3469585  
31333 +                *        re-enable DRAM Self Refresh Mode 
31334 +                *        by setting DUNIT.DPMC0 
31335 +                */
31336 +               ui32_reg_value = MSG_READ32(0x1, 0x4);
31337 +               MSG_WRITE32(0x1, 0x4, (ui32_reg_value | (0x1 << 7)));
31338 +       }
31339 +
31340 +       if (IS_MRST(dev_priv->dev))
31341 +               schedule_delayed_work(&dev_priv->scheduler.msvdx_suspend_wq, 10);
31342 +
31343 +       ret = drm_release(inode, filp);
31344 +
31345 +       return ret;
31346 +}
31347 +
31348 +int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
31349 +                            struct drm_file *file_priv)
31350 +{
31351 +
31352 +       return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data);
31353 +}
31354 +
31355 +int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
31356 +                          struct drm_file *file_priv)
31357 +{
31358 +       return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data);
31359 +}
31360 +
31361 +int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
31362 +                         struct drm_file *file_priv)
31363 +{
31364 +       return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
31365 +}
31366 +
31367 +int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
31368 +                         struct drm_file *file_priv)
31369 +{
31370 +       return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data);
31371 +}
31372 +
31373 +int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
31374 +                          struct drm_file *file_priv)
31375 +{
31376 +       return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile,
31377 +                                     &psb_priv(dev)->ttm_lock, data);
31378 +
31379 +}
31380 +
31381 +int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
31382 +                        struct drm_file *file_priv)
31383 +{
31384 +       return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data);
31385 +}
31386 +
31387 +int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
31388 +                      struct drm_file *file_priv)
31389 +{
31390 +       return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
31391 +
31392 +}
31393 +
31394 +int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
31395 +                          struct drm_file *file_priv)
31396 +{
31397 +       return  ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data);
31398 +
31399 +}
31400 +
31401 +int psb_pl_create_ioctl(struct drm_device *dev, void *data,
31402 +                       struct drm_file *file_priv)
31403 +{
31404 +       struct drm_psb_private *dev_priv = psb_priv(dev);
31405 +
31406 +       return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile,
31407 +                                  &dev_priv->bdev, &dev_priv->ttm_lock, data);
31408 +
31409 +}
31410 +
31411 +/**
31412 + * psb_ttm_fault - Wrapper around the ttm fault method.
31413 + *
31414 + * @vma: The struct vm_area_struct as in the vm fault() method.
31415 + * @vmf: The struct vm_fault as in the vm fault() method.
31416 + *
31417 + * Since ttm_fault() will reserve buffers while faulting,
31418 + * we need to take the ttm read lock around it, as this driver
31419 + * relies on the ttm_lock in write mode to exclude all threads from
31420 + * reserving and thus validating buffers in aperture- and memory shortage
31421 + * situations.
31422 + */
31423 +
31424 +static int psb_ttm_fault(struct vm_area_struct *vma,
31425 +                        struct vm_fault *vmf)
31426 +{
31427 +       struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
31428 +               vma->vm_private_data;
31429 +       struct drm_psb_private *dev_priv =
31430 +               container_of(bo->bdev, struct drm_psb_private, bdev);
31431 +       int ret;
31432 +
31433 +       ret = ttm_read_lock(&dev_priv->ttm_lock, true);
31434 +       if (unlikely(ret != 0))
31435 +               return VM_FAULT_NOPAGE;
31436 +
31437 +       ret = dev_priv->ttm_vm_ops->fault(vma, vmf);
31438 +
31439 +       ttm_read_unlock(&dev_priv->ttm_lock);
31440 +       return ret;
31441 +}
31442 +
31443 +/**
31444 + * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to
31445 + * PVRMMap
31446 + */
31447 +int psb_mmap(struct file *filp, struct vm_area_struct *vma)
31448 +{
31449 +       struct drm_file *file_priv;
31450 +       struct drm_psb_private *dev_priv;
31451 +       int ret;
31452 +
31453 +       if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET ||
31454 +           vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET)
31455 +               return PVRMMap(filp, vma);
31456 +
31457 +       file_priv = (struct drm_file *) filp->private_data;
31458 +       dev_priv = psb_priv(file_priv->minor->dev);
31459 +
31460 +       ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev);
31461 +       if (unlikely(ret != 0))
31462 +               return ret;
31463 +
31464 +       if (unlikely(dev_priv->ttm_vm_ops == NULL)) {
31465 +               dev_priv->ttm_vm_ops = (struct vm_operations_struct *)vma->vm_ops;
31466 +               psb_ttm_vm_ops = *vma->vm_ops;
31467 +               psb_ttm_vm_ops.fault = &psb_ttm_fault;
31468 +       }
31469 +
31470 +       vma->vm_ops = &psb_ttm_vm_ops;
31471 +
31472 +       return 0;
31473 +}
31474 +
31475 +ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
31476 +                     size_t count, loff_t *f_pos)
31477 +{
31478 +       struct drm_file *file_priv = (struct drm_file *)filp->private_data;
31479 +       struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
31480 +
31481 +       return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1);
31482 +}
31483 +
31484 +ssize_t psb_ttm_read(struct file *filp, char __user *buf,
31485 +                    size_t count, loff_t *f_pos)
31486 +{
31487 +       struct drm_file *file_priv = (struct drm_file *)filp->private_data;
31488 +       struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
31489 +
31490 +       return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1);
31491 +}
31492 +
31493 +int psb_verify_access(struct ttm_buffer_object *bo,
31494 +                     struct file *filp)
31495 +{
31496 +       struct drm_file *file_priv = (struct drm_file *)filp->private_data;
31497 +
31498 +       if (capable(CAP_SYS_ADMIN))
31499 +               return 0;
31500 +
31501 +       if (unlikely(!file_priv->authenticated))
31502 +               return -EPERM;
31503 +
31504 +       return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile);
31505 +}
31506 +
31507 +static int psb_ttm_mem_global_init(struct drm_global_reference *ref)
31508 +{
31509 +       return ttm_mem_global_init(ref->object);
31510 +}
31511 +
31512 +static void psb_ttm_mem_global_release(struct drm_global_reference *ref)
31513 +{
31514 +       ttm_mem_global_release(ref->object);
31515 +}
31516 +
31517 +int psb_ttm_global_init(struct drm_psb_private *dev_priv)
31518 +{
31519 +       struct drm_global_reference *global_ref;
31520 +       int ret;
31521 +
31522 +       global_ref = &dev_priv->mem_global_ref;
31523 +       global_ref->global_type = DRM_GLOBAL_TTM_MEM;
31524 +       global_ref->size = sizeof(struct ttm_mem_global);
31525 +       global_ref->init = &psb_ttm_mem_global_init;
31526 +       global_ref->release = &psb_ttm_mem_global_release;
31527 +
31528 +       ret = drm_global_item_ref(global_ref);
31529 +       if (unlikely(ret != 0)) {
31530 +               DRM_ERROR("Failed referencing a global TTM memory object.\n");
31531 +               return ret;
31532 +       }
31533 +
31534 +       return 0;
31535 +}
31536 +
31537 +void psb_ttm_global_release(struct drm_psb_private *dev_priv)
31538 +{
31539 +       drm_global_item_unref(&dev_priv->mem_global_ref);
31540 +}
31541 +
31542 +int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
31543 +               struct drm_file *file_priv)
31544 +{
31545 +       struct drm_psb_getpageaddrs_arg *arg = data;
31546 +       struct ttm_buffer_object *bo;
31547 +       struct ttm_tt *ttm;
31548 +       struct page **tt_pages;
31549 +       unsigned long i, num_pages;
31550 +       unsigned long *p = arg->page_addrs;
31551 +       int ret = 0;
31552 +
31553 +       bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile,
31554 +                                       arg->handle);
31555 +       if (unlikely(bo == NULL)) {
31556 +               printk(KERN_ERR
31557 +                       "Could not find buffer object for getpageaddrs.\n");
31558 +               return -EINVAL;
31559 +       }
31560 +
31561 +       arg->gtt_offset = bo->offset;
31562 +       ttm = bo->ttm;
31563 +       num_pages = ttm->num_pages;
31564 +       tt_pages = ttm->pages;
31565 +
31566 +       for (i = 0; i < num_pages; i++)
31567 +               p[i] = (unsigned long)page_to_phys(tt_pages[i]);
31568 +
31569 +       return ret;
31570 +}
31571 diff --git a/drivers/gpu/drm/mrst/drv/psb_umevents.c b/drivers/gpu/drm/mrst/drv/psb_umevents.c
31572 new file mode 100644
31573 index 0000000..d9bf3c1
31574 --- /dev/null
31575 +++ b/drivers/gpu/drm/mrst/drv/psb_umevents.c
31576 @@ -0,0 +1,485 @@
31577 +/*
31578 + * Copyright Â© 2009 Intel Corporation
31579 + *
31580 + * This program is free software; you can redistribute it and/or modify it
31581 + * under the terms and conditions of the GNU General Public License,
31582 + * version 2, as published by the Free Software Foundation.
31583 + *
31584 + * This program is distributed in the hope it will be useful, but WITHOUT
31585 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31586 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
31587 + * more details.
31588 + *
31589 + * You should have received a copy of the GNU General Public License along with
31590 + * this program; if not, write to the Free Software Foundation, Inc., 
31591 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
31592 + *
31593 + * Authors:
31594 + *    James C. Gualario <james.c.gualario@intel.com>
31595 + *
31596 + */
31597 +#include "psb_umevents.h"
31598 +/**
31599 + * define sysfs operations supported by umevent objects.
31600 + *
31601 + */
31602 +static struct sysfs_ops umevent_obj_sysfs_ops = {
31603 +       .show = psb_umevent_attr_show,
31604 +       .store = psb_umevent_attr_store,
31605 +};
31606 +/**
31607 + * define the data attributes we will expose through sysfs.
31608 + *
31609 + */
31610 +static struct umevent_attribute data_0 =
31611 +       __ATTR(data_0_val, 0666, psb_umevent_attr_show_imp,
31612 +              psb_umevent_attr_store_imp);
31613 +static struct umevent_attribute data_1 =
31614 +       __ATTR(data_1_val, 0666, psb_umevent_attr_show_imp,
31615 +              psb_umevent_attr_store_imp);
31616 +static struct umevent_attribute data_2 =
31617 +       __ATTR(data_2_val, 0666, psb_umevent_attr_show_imp,
31618 +              psb_umevent_attr_store_imp);
31619 +static struct umevent_attribute data_3 =
31620 +       __ATTR(data_3_val, 0666, psb_umevent_attr_show_imp,
31621 +              psb_umevent_attr_store_imp);
31622 +static struct umevent_attribute data_4 =
31623 +       __ATTR(data_4_val, 0666, psb_umevent_attr_show_imp,
31624 +              psb_umevent_attr_store_imp);
31625 +static struct umevent_attribute data_5 =
31626 +       __ATTR(data_5_val, 0666, psb_umevent_attr_show_imp,
31627 +              psb_umevent_attr_store_imp);
31628 +static struct umevent_attribute data_6 =
31629 +       __ATTR(data_6_val, 0666, psb_umevent_attr_show_imp,
31630 +              psb_umevent_attr_store_imp);
31631 +static struct umevent_attribute data_7 =
31632 +       __ATTR(data_7_val, 0666, psb_umevent_attr_show_imp,
31633 +              psb_umevent_attr_store_imp);
31634 +/**
31635 + * define the structure used to seed our ktype.
31636 + *
31637 + */
31638 +static struct attribute *umevent_obj_default_attrs[] = {
31639 +       &data_0.attr,
31640 +       &data_1.attr,
31641 +       &data_2.attr,
31642 +       &data_3.attr,
31643 +       &data_4.attr,
31644 +       &data_5.attr,
31645 +       &data_6.attr,
31646 +       &data_7.attr,
31647 +       NULL,   /* need to NULL terminate the list of attributes */
31648 +};
31649 +/**
31650 + * specify the ktype for our kobjects.
31651 + *
31652 + */
31653 +static struct kobj_type umevent_obj_ktype = {
31654 +       .sysfs_ops = &umevent_obj_sysfs_ops,
31655 +       .release = psb_umevent_obj_release,
31656 +       .default_attrs = umevent_obj_default_attrs,
31657 +};
31658 +/**
31659 + * psb_umevent_attr_show - default kobject show function
31660 + *
31661 + * @kobj: kobject associated with the show operation
31662 + * @attr: attribute being requested
31663 + * @buf: pointer to the return buffer
31664 + *
31665 + */
31666 +ssize_t psb_umevent_attr_show(struct kobject *kobj,
31667 +                            struct attribute *attr,
31668 +                            char *buf)
31669 +{
31670 +       struct umevent_attribute *attribute;
31671 +       struct umevent_obj *any_umevent_obj;
31672 +       attribute = to_umevent_attr(attr);
31673 +       any_umevent_obj = to_umevent_obj(kobj);
31674 +       if (!attribute->show)
31675 +               return -EIO;
31676 +
31677 +       return attribute->show(any_umevent_obj, attribute, buf);
31678 +}
31679 +/**
31680 + * psb_umevent_attr_store - default kobject store function
31681 + *
31682 + * @kobj: kobject associated with the store operation
31683 + * @attr: attribute being requested
31684 + * @buf: input data to write to attribute
31685 + * @len: character count
31686 + *
31687 + */
31688 +ssize_t psb_umevent_attr_store(struct kobject *kobj,
31689 +                             struct attribute *attr,
31690 +                             const char *buf, size_t len)
31691 +{
31692 +       struct umevent_attribute *attribute;
31693 +       struct umevent_obj *any_umevent_obj;
31694 +       attribute = to_umevent_attr(attr);
31695 +       any_umevent_obj = to_umevent_obj(kobj);
31696 +       if (!attribute->store)
31697 +               return -EIO;
31698 +
31699 +       return attribute->store(any_umevent_obj, attribute, buf, len);
31700 +}
31701 +/**
31702 + * psb_umevent_obj_release - kobject release funtion
31703 + *
31704 + * @kobj: kobject to be released.
31705 + */
31706 +void psb_umevent_obj_release(struct kobject *kobj)
31707 +{
31708 +       struct umevent_obj *any_umevent_obj;
31709 +       any_umevent_obj = to_umevent_obj(kobj);
31710 +       kfree(any_umevent_obj);
31711 +}
31712 +/**
31713 + *  psb_umevent_attr_show_imp - attribute show implementation
31714 + *
31715 + * @any_umevent_obj: kobject managed data to read from
31716 + * @attr: attribute being requested
31717 + * @buf: pointer to the return buffer
31718 + *
31719 + */
31720 +ssize_t psb_umevent_attr_show_imp(struct umevent_obj
31721 +                                    *any_umevent_obj,
31722 +                                    struct umevent_attribute *attr,
31723 +                                    char *buf)
31724 +{
31725 +       int var;
31726 +
31727 +       if (strcmp(attr->attr.name, "data_0_val") == 0)
31728 +               var = any_umevent_obj->data_0_val;
31729 +       else if (strcmp(attr->attr.name, "data_1_val") == 0)
31730 +               var = any_umevent_obj->data_1_val;
31731 +       else if (strcmp(attr->attr.name, "data_2_val") == 0)
31732 +               var = any_umevent_obj->data_2_val;
31733 +       else if (strcmp(attr->attr.name, "data_3_val") == 0)
31734 +               var = any_umevent_obj->data_3_val;
31735 +       else if (strcmp(attr->attr.name, "data_4_val") == 0)
31736 +               var = any_umevent_obj->data_4_val;
31737 +       else if (strcmp(attr->attr.name, "data_5_val") == 0)
31738 +               var = any_umevent_obj->data_5_val;
31739 +       else if (strcmp(attr->attr.name, "data_6_val") == 0)
31740 +               var = any_umevent_obj->data_6_val;
31741 +       else
31742 +               var = any_umevent_obj->data_7_val;
31743 +
31744 +       return sprintf(buf, "%d\n", var);
31745 +}
31746 +/**
31747 + * psb_umevent_attr_store_imp - attribute store implementation
31748 + *
31749 + * @any_umevent_obj: kobject managed data to write to
31750 + * @attr: attribute being requested
31751 + * @buf: input data to write to attribute
31752 + * @count: character count
31753 + *
31754 + */
31755 +ssize_t psb_umevent_attr_store_imp(struct umevent_obj
31756 +                                     *any_umevent_obj,
31757 +                                     struct umevent_attribute *attr,
31758 +                                     const char *buf, size_t count)
31759 +{
31760 +       int var;
31761 +
31762 +       sscanf(buf, "%du", &var);
31763 +       if (strcmp(attr->attr.name, "data_0_val") == 0)
31764 +               any_umevent_obj->data_0_val = var;
31765 +       else if (strcmp(attr->attr.name, "data_1_val") == 0)
31766 +               any_umevent_obj->data_1_val = var;
31767 +       else if (strcmp(attr->attr.name, "data_2_val") == 0)
31768 +               any_umevent_obj->data_2_val = var;
31769 +       else if (strcmp(attr->attr.name, "data_3_val") == 0)
31770 +               any_umevent_obj->data_3_val = var;
31771 +       else if (strcmp(attr->attr.name, "data_4_val") == 0)
31772 +               any_umevent_obj->data_4_val = var;
31773 +       else if (strcmp(attr->attr.name, "data_5_val") == 0)
31774 +               any_umevent_obj->data_5_val = var;
31775 +       else if (strcmp(attr->attr.name, "data_6_val") == 0)
31776 +               any_umevent_obj->data_6_val = var;
31777 +       else
31778 +               any_umevent_obj->data_7_val = var;
31779 +       return count;
31780 +}
31781 +/**
31782 + * psb_create_umevent_obj - create and track new event objects
31783 + *
31784 + * @name: name to give to new sysfs / kobject entry
31785 + * @list: event object list to track the kobject in
31786 + */
31787 +struct umevent_obj *psb_create_umevent_obj(const char *name,
31788 +                                               struct umevent_list
31789 +                                                       *list)
31790 +{
31791 +       struct umevent_obj *new_umevent_obj;
31792 +       int retval;
31793 +       new_umevent_obj = kzalloc(sizeof(*new_umevent_obj),
31794 +                                      GFP_KERNEL);
31795 +       if (!new_umevent_obj)
31796 +               return NULL;
31797 +
31798 +       new_umevent_obj->kobj.kset = list->umevent_disp_pool;
31799 +       retval = kobject_init_and_add(&new_umevent_obj->kobj,
31800 +                                     &umevent_obj_ktype, NULL,
31801 +                                     "%s", name);
31802 +       if (retval) {
31803 +               kobject_put(&new_umevent_obj->kobj);
31804 +               return NULL;
31805 +       }
31806 +       psb_umevent_add_to_list(list, new_umevent_obj);
31807 +       return new_umevent_obj;
31808 +}
31809 +EXPORT_SYMBOL(psb_create_umevent_obj);
31810 +/**
31811 + * psb_umevent_notify - info user mode of a new device
31812 + *
31813 + * @notify_disp_obj: event object to perform notification for
31814 + *
31815 + */
31816 +void psb_umevent_notify(struct umevent_obj *notify_disp_obj)
31817 +{
31818 +       kobject_uevent(&notify_disp_obj->kobj, KOBJ_ADD);
31819 +}
31820 +EXPORT_SYMBOL(psb_umevent_notify);
31821 +/**
31822 + * psb_umevent_notify_change - notify user mode of a change to a device
31823 + *
31824 + * @notify_disp_obj: event object to perform notification for
31825 + *
31826 + */
31827 +void psb_umevent_notify_change(struct umevent_obj *notify_disp_obj)
31828 +{
31829 +       kobject_uevent(&notify_disp_obj->kobj, KOBJ_CHANGE);
31830 +}
31831 +EXPORT_SYMBOL(psb_umevent_notify_change);
31832 +/**
31833 + * psb_umevent_notify_change - notify user mode of a change to a device
31834 + *
31835 + * @notify_disp_obj: event object to perform notification for
31836 + *
31837 + */
31838 +void psb_umevent_notify_change_gfxsock(struct umevent_obj *notify_disp_obj,
31839 +                                       int dst_group_id)
31840 +{
31841 +       psb_kobject_uevent(&notify_disp_obj->kobj, KOBJ_CHANGE, dst_group_id);
31842 +}
31843 +EXPORT_SYMBOL(psb_umevent_notify_change_gfxsock);
31844 +/**
31845 + * psb_destroy_umvent_obj - decrement ref count on event so kernel can kill it
31846 + *
31847 + * @any_umevent_obj: event object to destroy
31848 + *
31849 + */
31850 +void psb_destroy_umevent_obj(struct umevent_obj
31851 +                                    *any_umevent_obj)
31852 +{
31853 +       kobject_put(&any_umevent_obj->kobj);
31854 +}
31855 +/**
31856 + *
31857 + * psb_umevent_init - init the event pool
31858 + *
31859 + * @parent_kobj: parent kobject to associate new kset with
31860 + * @new_umevent_list: event list to associate kset with
31861 + * @name: name to give to new sysfs entry
31862 + *
31863 + */
31864 +int psb_umevent_init(struct kobject *parent_kobj,
31865 +                    struct umevent_list *new_umevent_list,
31866 +                    const char *name)
31867 +{
31868 +       psb_umevent_init_list(new_umevent_list);
31869 +       new_umevent_list->umevent_disp_pool = kset_create_and_add(name, NULL,
31870 +                                                    parent_kobj);
31871 +       if (!new_umevent_list->umevent_disp_pool)
31872 +               return -ENOMEM;
31873 +
31874 +       return 0;
31875 +}
31876 +EXPORT_SYMBOL(psb_umevent_init);
31877 +/**
31878 + *
31879 + * psb_umevent_cleanup - cleanup all event objects
31880 + *
31881 + * @kill_list: list of events to destroy
31882 + *
31883 + */
31884 +void psb_umevent_cleanup(struct umevent_list *kill_list)
31885 +{
31886 +       psb_umevent_destroy_list(kill_list);
31887 +}
31888 +EXPORT_SYMBOL(psb_umevent_cleanup);
31889 +/**
31890 + * psb_umevent_add_to_list - add an event to the event list
31891 + *
31892 + * @list: list to add the event to
31893 + * @umevent_obj_to_add: event to add
31894 + *
31895 + */
31896 +void psb_umevent_add_to_list(struct umevent_list *list,
31897 +                             struct umevent_obj *umevent_obj_to_add)
31898 +{
31899 +       unsigned long flags;
31900 +       spin_lock_irqsave(&list->list_lock, flags);
31901 +       list_add(&umevent_obj_to_add->head, &list->head);
31902 +       spin_unlock_irqrestore(&list->list_lock, flags);
31903 +}
31904 +/**
31905 + * psb_umevent_init_list - initialize event list
31906 + *
31907 + * @list: list to initialize
31908 + *
31909 + */
31910 +void psb_umevent_init_list(struct umevent_list *list)
31911 +{
31912 +       spin_lock_init(&list->list_lock);
31913 +       INIT_LIST_HEAD(&list->head);
31914 +}
31915 +/**
31916 + * psb_umevent_create_list - allocate an event list
31917 + *
31918 + */
31919 +struct umevent_list *psb_umevent_create_list()
31920 +{
31921 +       struct umevent_list *new_umevent_list;
31922 +       new_umevent_list = NULL;
31923 +       new_umevent_list =  kmalloc(sizeof(struct umevent_list),
31924 +                                        GFP_ATOMIC);
31925 +       return new_umevent_list;
31926 +}
31927 +EXPORT_SYMBOL(psb_umevent_create_list);
31928 +/**
31929 + * psb_umevent_destroy_list - destroy a list and clean up all mem
31930 + *
31931 + * @list: list to destroy and clean up after
31932 + *
31933 + */
31934 +void psb_umevent_destroy_list(struct umevent_list *list)
31935 +{
31936 +       struct umevent_obj *umevent_obj_curr;
31937 +       struct list_head *node;
31938 +       struct list_head *node_kill;
31939 +       int i;
31940 +       i = 0;
31941 +       node = NULL;
31942 +       node_kill = NULL;
31943 +       node = list->head.next;
31944 +       while (node != (&list->head)) {
31945 +               umevent_obj_curr = list_entry(node,
31946 +                               struct umevent_obj,
31947 +                                                  head);
31948 +               node_kill = node;
31949 +               node = umevent_obj_curr->head.next;
31950 +               psb_destroy_umevent_obj(umevent_obj_curr);
31951 +               umevent_obj_curr = NULL;
31952 +               list_del(node_kill);
31953 +               i++;
31954 +       }
31955 +       kset_unregister(list->umevent_disp_pool);
31956 +       kfree(list);
31957 +}
31958 +/**
31959 + * psb_umevent_remove_from_list - remove an event from tracking list
31960 + *
31961 + * @list: list to remove the event from
31962 + * @disp_to_remove: name of event to remove.
31963 + *
31964 + */
31965 +void psb_umevent_remove_from_list(struct umevent_list *list,
31966 +                                  const char *disp_to_remove)
31967 +{
31968 +       struct umevent_obj *umevent_obj_curr = NULL;
31969 +       struct list_head *node = NULL;
31970 +       struct list_head *node_kill = NULL;
31971 +       int i = 0;
31972 +       int found_match = 0;
31973 +       i = 0;
31974 +       node = NULL;
31975 +       node_kill = NULL;
31976 +       node = list->head.next;
31977 +       while (node != (&list->head)) {
31978 +               umevent_obj_curr = list_entry(node,
31979 +                               struct umevent_obj, head);
31980 +               if (strcmp(umevent_obj_curr->kobj.name,
31981 +                         disp_to_remove) == 0) {
31982 +                       found_match = 1;
31983 +                       break;
31984 +               }
31985 +               node = NULL;
31986 +               node = umevent_obj_curr->head.next;
31987 +               i++;
31988 +       }
31989 +       if (found_match == 1) {
31990 +               node_kill = node;
31991 +               node = umevent_obj_curr->head.next;
31992 +               psb_destroy_umevent_obj(umevent_obj_curr);
31993 +               umevent_obj_curr = NULL;
31994 +               list_del(node_kill);
31995 +       }
31996 +}
31997 +EXPORT_SYMBOL(psb_umevent_remove_from_list);
31998 +/**
31999 + * psb_umevent_find_obj - find an event in a tracking list
32000 + *
32001 + * @name: name of the event to find
32002 + * @list: list to find the event in
32003 + *
32004 + */
32005 +struct umevent_obj *psb_umevent_find_obj(const char *name,
32006 +                                 struct umevent_list *list)
32007 +{
32008 +       struct umevent_obj *umevent_obj_curr = NULL;
32009 +       struct list_head *node = NULL;
32010 +       struct list_head *node_find = NULL;
32011 +       int i = 0;
32012 +       int found_match = 0;
32013 +       i = 0;
32014 +       node = NULL;
32015 +       node_find = NULL;
32016 +       node = list->head.next;
32017 +       while (node != (&list->head)) {
32018 +               umevent_obj_curr = list_entry(node,
32019 +                               struct umevent_obj, head);
32020 +               if (strcmp(umevent_obj_curr->kobj.name,
32021 +                         name) == 0) {
32022 +                       found_match = 1;
32023 +                       break;
32024 +               }
32025 +               node = NULL;
32026 +               node = umevent_obj_curr->head.next;
32027 +               i++;
32028 +       }
32029 +       if (found_match == 1)
32030 +               return umevent_obj_curr;
32031 +
32032 +       return NULL;
32033 +}
32034 +EXPORT_SYMBOL(psb_umevent_find_obj);
32035 +/**
32036 + * psb_umevent_debug_dump_list - debug list dump
32037 + *
32038 + * @list: list to dump
32039 + *
32040 + */
32041 +void psb_umevent_debug_dump_list(struct umevent_list *list)
32042 +{
32043 +       struct umevent_obj *umevent_obj_curr;
32044 +       unsigned long flags;
32045 +       struct list_head *node;
32046 +       int i;
32047 +       spin_lock_irqsave(&list->list_lock, flags);
32048 +       i = 0;
32049 +       node = NULL;
32050 +       node = list->head.next;
32051 +       while (node != (&list->head)) {
32052 +               umevent_obj_curr = list_entry(node,
32053 +                                                  struct umevent_obj,
32054 +                                                  head);
32055 +               /*TBD: DUMP ANY REQUIRED VALUES WITH PRINTK*/
32056 +               node = NULL;
32057 +               node = umevent_obj_curr->head.next;
32058 +               i++;
32059 +       }
32060 +       spin_unlock_irqrestore(&list->list_lock, flags);
32061 +}
32062 diff --git a/drivers/gpu/drm/mrst/drv/psb_umevents.h b/drivers/gpu/drm/mrst/drv/psb_umevents.h
32063 new file mode 100644
32064 index 0000000..868bee4
32065 --- /dev/null
32066 +++ b/drivers/gpu/drm/mrst/drv/psb_umevents.h
32067 @@ -0,0 +1,154 @@
32068 +/*
32069 + * Copyright (c) 2009, Intel Corporation.
32070 + *
32071 + * This program is free software; you can redistribute it and/or modify it
32072 + * under the terms and conditions of the GNU General Public License,
32073 + * version 2, as published by the Free Software Foundation.
32074 + *
32075 + * This program is distributed in the hope it will be useful, but WITHOUT
32076 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32077 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
32078 + * more details.
32079 + *
32080 + * You should have received a copy of the GNU General Public License along with
32081 + * this program; if not, write to the Free Software Foundation, Inc., 
32082 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
32083 + *
32084 + * Authors:
32085 + *    James C. Gualario <james.c.gualario@intel.com>
32086 + *
32087 + */
32088 +#ifndef _PSB_UMEVENT_H_
32089 +#define _PSB_UMEVENT_H_
32090 +/**
32091 + * required includes
32092 + *
32093 + */
32094 +#include <linux/init.h>
32095 +#include <linux/module.h>
32096 +#include <linux/slab.h>
32097 +#include <drm/drmP.h>
32098 +#include <drm/drm_core.h>
32099 +#include <drm/drm_pciids.h>
32100 +#include <linux/spinlock.h>
32101 +/**
32102 + * event groups for routing to different user mode threads
32103 + *
32104 + */
32105 +#define DRM_DPST_SOCKET_GROUP_ID 1
32106 +#define DRM_HOTPLUG_SOCKET_GROUP_ID 2
32107 +#define DRM_HDMI_AUDIO_SOCKET_GROUP 4
32108 +#define DRM_HDMI_HDCP_SOCKET_GROUP 8
32109 +#define DRM_GFX_SOCKET_GROUPS 15
32110 +/**
32111 + * event structure managed by kobjects
32112 + *
32113 + */
32114 +struct umevent_obj {
32115 +       struct kobject kobj;
32116 +       struct list_head head;
32117 +       int data_0_val;
32118 +       int data_1_val;
32119 +       int data_2_val;
32120 +       int data_3_val;
32121 +       int data_4_val;
32122 +       int data_5_val;
32123 +       int data_6_val;
32124 +       int data_7_val;
32125 +};
32126 +/**
32127 + * event tracking list element
32128 + *
32129 + */
32130 +struct umevent_list{
32131 +       struct list_head head;
32132 +       struct kset *umevent_disp_pool;
32133 +       spinlock_t list_lock;
32134 +};
32135 +/**
32136 + * to go back and forth between kobjects and their main container
32137 + *
32138 + */
32139 +#define to_umevent_obj(x) \
32140 +       container_of(x, struct umevent_obj, kobj)
32141 +
32142 +/**
32143 + * event attributes exposed via sysfs
32144 + *
32145 + */
32146 +struct umevent_attribute {
32147 +       struct attribute attr;
32148 +       ssize_t (*show)(struct umevent_obj *any_umevent_obj,
32149 +                       struct umevent_attribute *attr, char *buf);
32150 +       ssize_t (*store)(struct umevent_obj *any_umevent_obj,
32151 +                        struct umevent_attribute *attr,
32152 +                        const char *buf, size_t count);
32153 +};
32154 +/**
32155 + * to go back and forth between the attribute passed to us by the OS
32156 + * and the umevent_attribute
32157 + *
32158 + */
32159 +#define to_umevent_attr(x) \
32160 +       container_of(x, struct umevent_attribute, \
32161 +       attr)
32162 +
32163 +/**
32164 + * umevent function prototypes
32165 + *
32166 + */
32167 +extern struct umevent_obj *psb_create_umevent_obj(const char *name,
32168 +                                               struct umevent_list
32169 +                                                       *list);
32170 +extern ssize_t psb_umevent_attr_show(struct kobject *kobj,
32171 +                                     struct attribute *attr, char *buf);
32172 +extern ssize_t psb_umevent_attr_store(struct kobject *kobj,
32173 +                                      struct attribute *attr,
32174 +                                      const char *buf, size_t len);
32175 +extern ssize_t psb_umevent_attr_show_imp(struct umevent_obj
32176 +                                    *any_umevent_obj,
32177 +                                    struct umevent_attribute *attr,
32178 +                                    char *buf);
32179 +extern ssize_t psb_umevent_attr_store_imp(struct umevent_obj
32180 +                                     *any_umevent_obj,
32181 +                                     struct umevent_attribute *attr,
32182 +                                     const char *buf, size_t count);
32183 +extern void psb_umevent_cleanup(struct umevent_list *kill_list);
32184 +extern int psb_umevent_init(struct kobject *parent_kobj,
32185 +                           struct umevent_list *new_umevent_list,
32186 +                           const char *name);
32187 +extern void psb_umevent_init_list(struct umevent_list *list);
32188 +extern void psb_umevent_debug_dump_list(struct umevent_list *list);
32189 +extern void psb_umevent_add_to_list(struct umevent_list *list,
32190 +                                    struct umevent_obj
32191 +                                    *umevent_obj_to_add);
32192 +extern void psb_umevent_destroy_list(struct umevent_list *list);
32193 +extern struct umevent_list *psb_umevent_create_list(void);
32194 +extern void psb_umevent_notify(struct umevent_obj *notify_disp_obj);
32195 +extern void psb_umevent_obj_release(struct kobject *kobj);
32196 +extern void psb_umevent_remove_from_list(struct umevent_list *list,
32197 +                                         const char *disp_to_remove);
32198 +extern void psb_umevent_workqueue_dispatch(int work_type, const char *name,
32199 +                                      struct umevent_list *list);
32200 +extern void psb_umevent_notify_change(struct umevent_obj *notify_disp_obj);
32201 +extern void psb_umevent_notify_change_gfxsock(struct umevent_obj
32202 +                                             *notify_disp_obj,
32203 +                                             int dst_group_id);
32204 +extern struct umevent_obj *psb_umevent_find_obj(const char *name,
32205 +                                               struct umevent_list
32206 +                                                       *list);
32207 +/**
32208 + * socket function prototypes
32209 + *
32210 + */
32211 +extern int psb_kobject_uevent(struct kobject *kobj,
32212 +                             enum kobject_action action, int dst_group_id);
32213 +extern int psb_kobject_uevent_env(struct kobject *kobj,
32214 +                                 enum kobject_action action,
32215 +                                 char *envp[], int dst_group_id);
32216 +int psb_add_uevent_var(struct kobj_uevent_env *env,
32217 +                      const char *format, ...)
32218 +       __attribute__((format (printf, 2, 3)));
32219 +int psb_kobject_action_type(const char *buf,
32220 +                           size_t count, enum kobject_action *type);
32221 +#endif
32222 diff --git a/drivers/gpu/drm/mrst/drv/topaz_power.c b/drivers/gpu/drm/mrst/drv/topaz_power.c
32223 new file mode 100644
32224 index 0000000..7481390
32225 --- /dev/null
32226 +++ b/drivers/gpu/drm/mrst/drv/topaz_power.c
32227 @@ -0,0 +1,173 @@
32228 +/*
32229 + * Copyright (c) 2009, Intel Corporation.
32230 + *
32231 + * This program is free software; you can redistribute it and/or modify it
32232 + * under the terms and conditions of the GNU General Public License,
32233 + * version 2, as published by the Free Software Foundation.
32234 + *
32235 + * This program is distributed in the hope it will be useful, but WITHOUT
32236 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32237 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
32238 + * more details.
32239 + *
32240 + * You should have received a copy of the GNU General Public License along with
32241 + * this program; if not, write to the Free Software Foundation, Inc., 
32242 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
32243 + *
32244 + * Author:binglin.chen@intel.com
32245 + */
32246 +
32247 +#include "topaz_power.h"
32248 +#include "lnc_topaz.h"
32249 +#include "psb_drv.h"
32250 +#include "sysirq.h"
32251 +#include "ospm_power.h"
32252 +
32253 +#include "services_headers.h"
32254 +#include "sysconfig.h"
32255 +
32256 +static PVRSRV_ERROR DevInitTOPAZPart1(IMG_VOID *pvDeviceNode)
32257 +{
32258 +       PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
32259 +       PVRSRV_ERROR eError;
32260 +       PVRSRV_DEV_POWER_STATE eDefaultPowerState;
32261 +
32262 +       /* register power operation function */
32263 +       /* FIXME: this should be in part2 init function, but
32264 +        * currently here only OSPM needs IMG device... */
32265 +       eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
32266 +       eError = PVRSRVRegisterPowerDevice(psDeviceNode->sDevId.ui32DeviceIndex,
32267 +                                          TOPAZPrePowerState,
32268 +                                          TOPAZPostPowerState,
32269 +                                          TOPAZPreClockSpeedChange,
32270 +                                          TOPAZPostClockSpeedChange,
32271 +                                          (IMG_HANDLE)psDeviceNode,
32272 +                                          PVRSRV_DEV_POWER_STATE_ON,
32273 +                                          eDefaultPowerState);
32274 +       if (eError != PVRSRV_OK) {
32275 +               PVR_DPF((PVR_DBG_ERROR, "DevInitTOPAZPart1: failed to "
32276 +                        "register device with power manager"));
32277 +               return eError;
32278 +       }
32279 +
32280 +       return PVRSRV_OK;
32281 +}
32282 +
32283 +static PVRSRV_ERROR DevDeInitTOPAZ(IMG_VOID *pvDeviceNode)
32284 +{
32285 +       PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
32286 +       PVRSRV_ERROR eError;
32287 +
32288 +       /* should deinit all resource */
32289 +
32290 +       eError = PVRSRVRemovePowerDevice(psDeviceNode->sDevId.ui32DeviceIndex);
32291 +       if (eError != PVRSRV_OK)
32292 +               return eError;
32293 +
32294 +       return PVRSRV_OK;
32295 +}
32296 +
32297 +PVRSRV_ERROR TOPAZDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
32298 +{
32299 +       /* version check */
32300 +
32301 +       return PVRSRV_OK;
32302 +}
32303 +
32304 +PVRSRV_ERROR TOPAZRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
32305 +{
32306 +       psDeviceNode->sDevId.eDeviceType        = PVRSRV_DEVICE_TYPE_TOPAZ;
32307 +       psDeviceNode->sDevId.eDeviceClass       = PVRSRV_DEVICE_CLASS_VIDEO;
32308 +
32309 +       psDeviceNode->pfnInitDevice             = DevInitTOPAZPart1;
32310 +       psDeviceNode->pfnDeInitDevice           = DevDeInitTOPAZ;
32311 +
32312 +       psDeviceNode->pfnInitDeviceCompatCheck  = TOPAZDevInitCompatCheck;
32313 +
32314 +       psDeviceNode->pfnDeviceISR = lnc_topaz_interrupt;
32315 +       psDeviceNode->pvISRData = (IMG_VOID *)gpDrmDevice;
32316 +
32317 +       return PVRSRV_OK;
32318 +}
32319 +
32320 +PVRSRV_ERROR TOPAZPrePowerState(IMG_HANDLE             hDevHandle,
32321 +                                PVRSRV_DEV_POWER_STATE eNewPowerState,
32322 +                                PVRSRV_DEV_POWER_STATE eCurrentPowerState)
32323 +{
32324 +       /* ask for a change not power on*/
32325 +       if ((eNewPowerState != eCurrentPowerState) &&
32326 +           (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
32327 +               struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
32328 +               struct topaz_private *topaz_priv = dev_priv->topaz_private;
32329 +               TOPAZ_NEW_PMSTATE(gpDrmDevice, topaz_priv, PSB_PMSTATE_POWERDOWN);
32330 +
32331 +               /* context save */
32332 +               /* context save require irq disable first */
32333 +               sysirq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
32334 +               lnc_topaz_save_mtx_state(gpDrmDevice);
32335 +
32336 +               /* internally close the device */
32337 +
32338 +               /* ask for power off */
32339 +               if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
32340 +                       /* here will deinitialize the driver if needed */
32341 +                       lnc_unmap_topaz_reg(gpDrmDevice);
32342 +               } else {
32343 +                       PVR_DPF((PVR_DBG_MESSAGE,
32344 +                               "%s no action for transform from %d to %d",
32345 +                               __func__,
32346 +                               eCurrentPowerState,
32347 +                               eNewPowerState));
32348 +               }
32349 +       }
32350 +
32351 +       return PVRSRV_OK;
32352 +}
32353 +
32354 +PVRSRV_ERROR TOPAZPostPowerState(IMG_HANDLE            hDevHandle,
32355 +                               PVRSRV_DEV_POWER_STATE  eNewPowerState,
32356 +                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState)
32357 +{
32358 +       /* if ask for change & current status is not on */
32359 +       if ((eNewPowerState != eCurrentPowerState) &&
32360 +           (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON)) {
32361 +               /* internally open device */
32362 +               struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
32363 +               struct topaz_private *topaz_priv = dev_priv->topaz_private;
32364 +               TOPAZ_NEW_PMSTATE(gpDrmDevice, topaz_priv, PSB_PMSTATE_POWERUP);
32365 +
32366 +               if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) {
32367 +                       /* here will initialize the driver if needed */
32368 +                       lnc_map_topaz_reg(gpDrmDevice);
32369 +               } else {
32370 +                       PVR_DPF((PVR_DBG_MESSAGE,
32371 +                               "%s no action for transform from %d to %d",
32372 +                               __func__,
32373 +                               eCurrentPowerState,
32374 +                               eNewPowerState));
32375 +               }
32376 +
32377 +               /* context restore */
32378 +               sysirq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
32379 +               lnc_topaz_restore_mtx_state(gpDrmDevice);
32380 +               sysirq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
32381 +               sysirq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
32382 +
32383 +       }
32384 +
32385 +       return PVRSRV_OK;
32386 +}
32387 +
32388 +PVRSRV_ERROR TOPAZPreClockSpeedChange(IMG_HANDLE       hDevHandle,
32389 +                               IMG_BOOL                bIdleDevice,
32390 +                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState)
32391 +{
32392 +       return PVRSRV_OK;
32393 +}
32394 +
32395 +PVRSRV_ERROR TOPAZPostClockSpeedChange(IMG_HANDLE      hDevHandle,
32396 +                               IMG_BOOL                bIdleDevice,
32397 +                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState)
32398 +{
32399 +       return PVRSRV_OK;
32400 +}
32401 diff --git a/drivers/gpu/drm/mrst/drv/topaz_power.h b/drivers/gpu/drm/mrst/drv/topaz_power.h
32402 new file mode 100644
32403 index 0000000..beb6114
32404 --- /dev/null
32405 +++ b/drivers/gpu/drm/mrst/drv/topaz_power.h
32406 @@ -0,0 +1,53 @@
32407 +/*
32408 +** topaz_power.h
32409 +** Login : <binglin.chen@intel.com>
32410 +** Started on  Mon Nov 16 13:31:42 2009 brady
32411 +**
32412 +** Copyright (C) 2009 brady
32413 +** This program is free software; you can redistribute it and/or modify
32414 +** it under the terms of the GNU General Public License as published by
32415 +** the Free Software Foundation; either version 2 of the License, or
32416 +** (at your option) any later version.
32417 +**
32418 +** This program is distributed in the hope that it will be useful,
32419 +** but WITHOUT ANY WARRANTY; without even the implied warranty of
32420 +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32421 +** GNU General Public License for more details.
32422 +**
32423 +** You should have received a copy of the GNU General Public License
32424 +** along with this program; if not, write to the Free Software
32425 +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32426 +*/
32427 +
32428 +#ifndef TOPAZ_POWER_H_
32429 +#define TOPAZ_POWER_H_
32430 +
32431 +#include "services_headers.h"
32432 +#include "sysconfig.h"
32433 +
32434 +extern struct drm_device *gpDrmDevice;
32435 +
32436 +/* function define */
32437 +PVRSRV_ERROR TOPAZRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
32438 +PVRSRV_ERROR TOPAZDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
32439 +
32440 +/* power function define */
32441 +PVRSRV_ERROR TOPAZPrePowerState(
32442 +                       IMG_HANDLE              hDevHandle,
32443 +                       PVRSRV_DEV_POWER_STATE  eNewPowerState,
32444 +                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
32445 +PVRSRV_ERROR TOPAZPostPowerState(
32446 +                       IMG_HANDLE              hDevHandle,
32447 +                       PVRSRV_DEV_POWER_STATE  eNewPowerState,
32448 +                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
32449 +PVRSRV_ERROR TOPAZPreClockSpeedChange(
32450 +                       IMG_HANDLE              hDevHandle,
32451 +                       IMG_BOOL                bIdleDevice,
32452 +                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
32453 +PVRSRV_ERROR TOPAZPostClockSpeedChange(
32454 +                       IMG_HANDLE              hDevHandle,
32455 +                       IMG_BOOL                bIdleDevice,
32456 +                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
32457 +PVRSRV_ERROR TOPAZInitOSPM(PVRSRV_DEVICE_NODE *psDeviceNode);
32458 +
32459 +#endif /* !TOPAZ_POWER_H_ */
32460 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_agp_backend.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_agp_backend.c
32461 new file mode 100644
32462 index 0000000..8eb830a
32463 --- /dev/null
32464 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_agp_backend.c
32465 @@ -0,0 +1,144 @@
32466 +/**************************************************************************
32467 + *
32468 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
32469 + * All Rights Reserved.
32470 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
32471 + * All Rights Reserved.
32472 + *
32473 + * This program is free software; you can redistribute it and/or modify it
32474 + * under the terms and conditions of the GNU General Public License,
32475 + * version 2, as published by the Free Software Foundation.
32476 + *
32477 + * This program is distributed in the hope it will be useful, but WITHOUT
32478 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32479 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
32480 + * more details.
32481 + *
32482 + * You should have received a copy of the GNU General Public License along with
32483 + * this program; if not, write to the Free Software Foundation, Inc., 
32484 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
32485 + *
32486 + **************************************************************************/
32487 +/*
32488 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
32489 + *          Keith Packard.
32490 + */
32491 +
32492 +#include "ttm_bo_driver.h"
32493 +#ifdef TTM_HAS_AGP
32494 +#include "ttm_placement_common.h"
32495 +#include <linux/agp_backend.h>
32496 +#include <asm/agp.h>
32497 +#include <linux/io.h>
32498 +
32499 +struct ttm_agp_backend {
32500 +       struct ttm_backend backend;
32501 +       struct agp_memory *mem;
32502 +       struct agp_bridge_data *bridge;
32503 +};
32504 +
32505 +static int ttm_agp_populate(struct ttm_backend *backend,
32506 +                           unsigned long num_pages, struct page **pages,
32507 +                           struct page *dummy_read_page)
32508 +{
32509 +       struct ttm_agp_backend *agp_be =
32510 +           container_of(backend, struct ttm_agp_backend, backend);
32511 +       struct page **cur_page, **last_page = pages + num_pages;
32512 +       struct agp_memory *mem;
32513 +
32514 +       mem = agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY);
32515 +       if (unlikely(mem == NULL))
32516 +               return -ENOMEM;
32517 +
32518 +       mem->page_count = 0;
32519 +       for (cur_page = pages; cur_page < last_page; ++cur_page) {
32520 +               struct page *page = *cur_page;
32521 +               if (!page)
32522 +                       page = dummy_read_page;
32523 +
32524 +               #if 0
32525 +               mem->memory[mem->page_count++] =
32526 +                   phys_to_gart(page_to_phys(page));
32527 +               #endif
32528 +       }
32529 +       agp_be->mem = mem;
32530 +       return 0;
32531 +}
32532 +
32533 +static int ttm_agp_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem)
32534 +{
32535 +       struct ttm_agp_backend *agp_be =
32536 +           container_of(backend, struct ttm_agp_backend, backend);
32537 +       struct agp_memory *mem = agp_be->mem;
32538 +       int cached = (bo_mem->flags & TTM_PL_FLAG_CACHED);
32539 +       int ret;
32540 +
32541 +       mem->is_flushed = 1;
32542 +       mem->type = (cached) ? AGP_USER_CACHED_MEMORY : AGP_USER_MEMORY;
32543 +
32544 +       ret = agp_bind_memory(mem, bo_mem->mm_node->start);
32545 +       if (ret)
32546 +               printk(KERN_ERR "AGP Bind memory failed.\n");
32547 +
32548 +       return ret;
32549 +}
32550 +
32551 +static int ttm_agp_unbind(struct ttm_backend *backend)
32552 +{
32553 +       struct ttm_agp_backend *agp_be =
32554 +           container_of(backend, struct ttm_agp_backend, backend);
32555 +
32556 +       if (agp_be->mem->is_bound)
32557 +               return agp_unbind_memory(agp_be->mem);
32558 +       else
32559 +               return 0;
32560 +}
32561 +
32562 +static void ttm_agp_clear(struct ttm_backend *backend)
32563 +{
32564 +       struct ttm_agp_backend *agp_be =
32565 +           container_of(backend, struct ttm_agp_backend, backend);
32566 +       struct agp_memory *mem = agp_be->mem;
32567 +
32568 +       if (mem) {
32569 +               ttm_agp_unbind(backend);
32570 +               agp_free_memory(mem);
32571 +       }
32572 +       agp_be->mem = NULL;
32573 +}
32574 +
32575 +static void ttm_agp_destroy(struct ttm_backend *backend)
32576 +{
32577 +       struct ttm_agp_backend *agp_be =
32578 +           container_of(backend, struct ttm_agp_backend, backend);
32579 +
32580 +       if (agp_be->mem)
32581 +               ttm_agp_clear(backend);
32582 +       kfree(agp_be);
32583 +}
32584 +
32585 +static struct ttm_backend_func ttm_agp_func = {
32586 +       .populate = ttm_agp_populate,
32587 +       .clear = ttm_agp_clear,
32588 +       .bind = ttm_agp_bind,
32589 +       .unbind = ttm_agp_unbind,
32590 +       .destroy = ttm_agp_destroy,
32591 +};
32592 +
32593 +struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev,
32594 +                                        struct agp_bridge_data *bridge)
32595 +{
32596 +       struct ttm_agp_backend *agp_be;
32597 +
32598 +       agp_be = kmalloc(sizeof(*agp_be), GFP_KERNEL);
32599 +       if (!agp_be)
32600 +               return NULL;
32601 +
32602 +       agp_be->mem = NULL;
32603 +       agp_be->bridge = bridge;
32604 +       agp_be->backend.func = &ttm_agp_func;
32605 +       agp_be->backend.bdev = bdev;
32606 +       return &agp_be->backend;
32607 +}
32608 +
32609 +#endif
32610 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_bo.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo.c
32611 new file mode 100644
32612 index 0000000..2d738b6
32613 --- /dev/null
32614 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo.c
32615 @@ -0,0 +1,1729 @@
32616 +/**************************************************************************
32617 + *
32618 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
32619 + * All Rights Reserved.
32620 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
32621 + * All Rights Reserved.
32622 + *
32623 + * This program is free software; you can redistribute it and/or modify it
32624 + * under the terms and conditions of the GNU General Public License,
32625 + * version 2, as published by the Free Software Foundation.
32626 + *
32627 + * This program is distributed in the hope it will be useful, but WITHOUT
32628 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32629 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
32630 + * more details.
32631 + *
32632 + * You should have received a copy of the GNU General Public License along with
32633 + * this program; if not, write to the Free Software Foundation, Inc., 
32634 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
32635 + *
32636 + **************************************************************************/
32637 +/*
32638 + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
32639 + */
32640 +
32641 +#include "ttm_bo_driver.h"
32642 +#include "ttm_placement_common.h"
32643 +#include <linux/jiffies.h>
32644 +#include <linux/slab.h>
32645 +#include <linux/sched.h>
32646 +#include <linux/mm.h>
32647 +#include <linux/file.h>
32648 +
32649 +#define TTM_ASSERT_LOCKED(param)
32650 +#define TTM_DEBUG(fmt, arg...)
32651 +#define TTM_BO_HASH_ORDER 13
32652 +
32653 +static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
32654 +static void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo);
32655 +static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
32656 +
32657 +static inline uint32_t ttm_bo_type_flags(unsigned type)
32658 +{
32659 +       uint32_t return_type = 1 << (type);
32660 +       return return_type;
32661 +}
32662 +
32663 +static void ttm_bo_release_list(struct kref *list_kref)
32664 +{
32665 +       struct ttm_buffer_object *bo =
32666 +           container_of(list_kref, struct ttm_buffer_object, list_kref);
32667 +       struct ttm_bo_device *bdev = bo->bdev;
32668 +
32669 +       BUG_ON(atomic_read(&bo->list_kref.refcount));
32670 +       BUG_ON(atomic_read(&bo->kref.refcount));
32671 +       BUG_ON(atomic_read(&bo->cpu_writers));
32672 +       BUG_ON(bo->sync_obj != NULL);
32673 +       BUG_ON(bo->mem.mm_node != NULL);
32674 +       BUG_ON(!list_empty(&bo->lru));
32675 +       BUG_ON(!list_empty(&bo->ddestroy));
32676 +
32677 +       if (bo->ttm)
32678 +               ttm_tt_destroy(bo->ttm);
32679 +       if (bo->destroy)
32680 +               bo->destroy(bo);
32681 +       else {
32682 +               ttm_mem_global_free(bdev->mem_glob, bo->acc_size, false);
32683 +               kfree(bo);
32684 +       }
32685 +}
32686 +
32687 +int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, bool interruptible)
32688 +{
32689 +
32690 +       if (interruptible) {
32691 +               int ret = 0;
32692 +
32693 +               ret = wait_event_interruptible(bo->event_queue,
32694 +                                              atomic_read(&bo->reserved) == 0);
32695 +               if (unlikely(ret != 0))
32696 +                       return -ERESTART;
32697 +       } else {
32698 +               wait_event(bo->event_queue, atomic_read(&bo->reserved) == 0);
32699 +       }
32700 +       return 0;
32701 +}
32702 +
32703 +static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
32704 +{
32705 +       struct ttm_bo_device *bdev = bo->bdev;
32706 +       struct ttm_mem_type_manager *man;
32707 +
32708 +       BUG_ON(!atomic_read(&bo->reserved));
32709 +
32710 +       if (!(bo->mem.flags & TTM_PL_FLAG_NO_EVICT)) {
32711 +
32712 +               BUG_ON(!list_empty(&bo->lru));
32713 +
32714 +               man = &bdev->man[bo->mem.mem_type];
32715 +               list_add_tail(&bo->lru, &man->lru);
32716 +               kref_get(&bo->list_kref);
32717 +
32718 +               if (bo->ttm != NULL) {
32719 +                       list_add_tail(&bo->swap, &bdev->swap_lru);
32720 +                       kref_get(&bo->list_kref);
32721 +               }
32722 +       }
32723 +}
32724 +
32725 +/*
32726 + * Call with bdev->lru_lock and bdev->global->swap_lock held..
32727 + */
32728 +
32729 +static int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
32730 +{
32731 +       int put_count = 0;
32732 +
32733 +       if (!list_empty(&bo->swap)) {
32734 +               list_del_init(&bo->swap);
32735 +               ++put_count;
32736 +       }
32737 +       if (!list_empty(&bo->lru)) {
32738 +               list_del_init(&bo->lru);
32739 +               ++put_count;
32740 +       }
32741 +
32742 +       /*
32743 +        * TODO: Add a driver hook to delete from
32744 +        * driver-specific LRU's here.
32745 +        */
32746 +
32747 +       return put_count;
32748 +}
32749 +
32750 +int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
32751 +                         bool interruptible,
32752 +                         bool no_wait, bool use_sequence, uint32_t sequence)
32753 +{
32754 +       struct ttm_bo_device *bdev = bo->bdev;
32755 +       int ret;
32756 +
32757 +       while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
32758 +               if (use_sequence && bo->seq_valid &&
32759 +                       (sequence - bo->val_seq < (1 << 31))) {
32760 +                       return -EAGAIN;
32761 +               }
32762 +
32763 +               if (no_wait)
32764 +                       return -EBUSY;
32765 +
32766 +               spin_unlock(&bdev->lru_lock);
32767 +               ret = ttm_bo_wait_unreserved(bo, interruptible);
32768 +               spin_lock(&bdev->lru_lock);
32769 +
32770 +               if (unlikely(ret))
32771 +                       return ret;
32772 +       }
32773 +
32774 +       if (use_sequence) {
32775 +               bo->val_seq = sequence;
32776 +               bo->seq_valid = true;
32777 +       } else {
32778 +               bo->seq_valid = false;
32779 +       }
32780 +
32781 +       return 0;
32782 +}
32783 +
32784 +static void ttm_bo_ref_bug(struct kref *list_kref)
32785 +{
32786 +       BUG();
32787 +}
32788 +
32789 +int ttm_bo_reserve(struct ttm_buffer_object *bo,
32790 +                  bool interruptible,
32791 +                  bool no_wait, bool use_sequence, uint32_t sequence)
32792 +{
32793 +       struct ttm_bo_device *bdev = bo->bdev;
32794 +       int put_count = 0;
32795 +       int ret;
32796 +
32797 +       spin_lock(&bdev->lru_lock);
32798 +       ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence,
32799 +                                   sequence);
32800 +       if (likely(ret == 0))
32801 +               put_count = ttm_bo_del_from_lru(bo);
32802 +       spin_unlock(&bdev->lru_lock);
32803 +
32804 +       while (put_count--)
32805 +               kref_put(&bo->list_kref, ttm_bo_ref_bug);
32806 +
32807 +       return ret;
32808 +}
32809 +
32810 +void ttm_bo_unreserve(struct ttm_buffer_object *bo)
32811 +{
32812 +       struct ttm_bo_device *bdev = bo->bdev;
32813 +
32814 +       spin_lock(&bdev->lru_lock);
32815 +       ttm_bo_add_to_lru(bo);
32816 +       atomic_set(&bo->reserved, 0);
32817 +       wake_up_all(&bo->event_queue);
32818 +       spin_unlock(&bdev->lru_lock);
32819 +}
32820 +
32821 +/*
32822 + * Call bo->mutex locked.
32823 + */
32824 +
32825 +static int ttm_bo_add_ttm(struct ttm_buffer_object *bo)
32826 +{
32827 +       struct ttm_bo_device *bdev = bo->bdev;
32828 +       int ret = 0;
32829 +       uint32_t page_flags = 0;
32830 +
32831 +       TTM_ASSERT_LOCKED(&bo->mutex);
32832 +       bo->ttm = NULL;
32833 +
32834 +       switch (bo->type) {
32835 +       case ttm_bo_type_device:
32836 +       case ttm_bo_type_kernel:
32837 +               bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
32838 +                                       page_flags, bdev->dummy_read_page);
32839 +               if (unlikely(bo->ttm == NULL))
32840 +                       ret = -ENOMEM;
32841 +               break;
32842 +       case ttm_bo_type_user:
32843 +               bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
32844 +                                       page_flags | TTM_PAGE_FLAG_USER,
32845 +                                       bdev->dummy_read_page);
32846 +               if (unlikely(bo->ttm == NULL))
32847 +                       ret = -ENOMEM;
32848 +               break;
32849 +
32850 +               ret = ttm_tt_set_user(bo->ttm, current,
32851 +                                     bo->buffer_start, bo->num_pages);
32852 +               if (unlikely(ret != 0))
32853 +                       ttm_tt_destroy(bo->ttm);
32854 +               break;
32855 +       default:
32856 +               printk(KERN_ERR "Illegal buffer object type\n");
32857 +               ret = -EINVAL;
32858 +               break;
32859 +       }
32860 +
32861 +       return ret;
32862 +}
32863 +
32864 +static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
32865 +                                 struct ttm_mem_reg *mem,
32866 +                                 bool evict, bool interruptible, bool no_wait)
32867 +{
32868 +       struct ttm_bo_device *bdev = bo->bdev;
32869 +       bool old_is_pci = ttm_mem_reg_is_pci(bdev, &bo->mem);
32870 +       bool new_is_pci = ttm_mem_reg_is_pci(bdev, mem);
32871 +       struct ttm_mem_type_manager *old_man = &bdev->man[bo->mem.mem_type];
32872 +       struct ttm_mem_type_manager *new_man = &bdev->man[mem->mem_type];
32873 +       int ret = 0;
32874 +
32875 +       if (old_is_pci || new_is_pci ||
32876 +           ((mem->flags & bo->mem.flags & TTM_PL_MASK_CACHING) == 0))
32877 +               ttm_bo_unmap_virtual(bo);
32878 +
32879 +       /*
32880 +        * Create and bind a ttm if required.
32881 +        */
32882 +
32883 +       if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) {
32884 +               ret = ttm_bo_add_ttm(bo);
32885 +               if (ret)
32886 +                       goto out_err;
32887 +
32888 +               ret = ttm_tt_set_placement_caching(bo->ttm, mem->flags);
32889 +               if (ret)
32890 +                       return ret;
32891 +
32892 +               if (mem->mem_type != TTM_PL_SYSTEM) {
32893 +                       ret = ttm_tt_bind(bo->ttm, mem);
32894 +                       if (ret)
32895 +                               goto out_err;
32896 +               }
32897 +
32898 +               if (bo->mem.mem_type == TTM_PL_SYSTEM) {
32899 +
32900 +                       struct ttm_mem_reg *old_mem = &bo->mem;
32901 +                       uint32_t save_flags = old_mem->flags;
32902 +                       uint32_t save_proposed_flags = old_mem->proposed_flags;
32903 +
32904 +                       *old_mem = *mem;
32905 +                       mem->mm_node = NULL;
32906 +                       old_mem->proposed_flags = save_proposed_flags;
32907 +                       ttm_flag_masked(&save_flags, mem->flags,
32908 +                                       TTM_PL_MASK_MEMTYPE);
32909 +                       goto moved;
32910 +               }
32911 +
32912 +       }
32913 +
32914 +       if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
32915 +           !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
32916 +               ret = ttm_bo_move_ttm(bo, evict, no_wait, mem);
32917 +       else if (bdev->driver->move)
32918 +               ret = bdev->driver->move(bo, evict, interruptible,
32919 +                                        no_wait, mem);
32920 +       else
32921 +               ret = ttm_bo_move_memcpy(bo, evict, no_wait, mem);
32922 +
32923 +       if (ret)
32924 +               goto out_err;
32925 +
32926 +moved:
32927 +       if (bo->priv_flags & TTM_BO_PRIV_FLAG_EVICTED) {
32928 +               ret = bdev->driver->invalidate_caches(bdev, bo->mem.flags);
32929 +               if (ret)
32930 +                       printk(KERN_ERR "Can not flush read caches\n");
32931 +       }
32932 +
32933 +       ttm_flag_masked(&bo->priv_flags,
32934 +                       (evict) ? TTM_BO_PRIV_FLAG_EVICTED : 0,
32935 +                       TTM_BO_PRIV_FLAG_EVICTED);
32936 +
32937 +       if (bo->mem.mm_node)
32938 +               bo->offset = (bo->mem.mm_node->start << PAGE_SHIFT) +
32939 +                   bdev->man[bo->mem.mem_type].gpu_offset;
32940 +
32941 +       return 0;
32942 +
32943 +out_err:
32944 +       new_man = &bdev->man[bo->mem.mem_type];
32945 +       if ((new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm) {
32946 +               ttm_tt_unbind(bo->ttm);
32947 +               ttm_tt_destroy(bo->ttm);
32948 +               bo->ttm = NULL;
32949 +       }
32950 +
32951 +       return ret;
32952 +}
32953 +
32954 +static int ttm_bo_expire_sync_obj(struct ttm_buffer_object *bo,
32955 +                                 bool allow_errors)
32956 +{
32957 +       struct ttm_bo_device *bdev = bo->bdev;
32958 +       struct ttm_bo_driver *driver = bdev->driver;
32959 +
32960 +       if (bo->sync_obj) {
32961 +               if (bdev->nice_mode) {
32962 +                       unsigned long _end = jiffies + 3 * HZ;
32963 +                       int ret;
32964 +                       do {
32965 +                               ret = ttm_bo_wait(bo, false, false, false);
32966 +                               if (ret && allow_errors)
32967 +                                       return ret;
32968 +
32969 +                       } while (ret && !time_after_eq(jiffies, _end));
32970 +
32971 +                       if (bo->sync_obj) {
32972 +                               bdev->nice_mode = false;
32973 +                               printk(KERN_ERR "Detected probable GPU lockup. "
32974 +                                      "Evicting buffer.\n");
32975 +                       }
32976 +               }
32977 +               if (bo->sync_obj) {
32978 +                       driver->sync_obj_unref(&bo->sync_obj);
32979 +                       bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
32980 +               }
32981 +       }
32982 +       return 0;
32983 +}
32984 +
32985 +/**
32986 + * If bo idle, remove from delayed- and lru lists, and unref.
32987 + * If not idle, and already on delayed list, do nothing.
32988 + * If not idle, and not on delayed list, put on delayed list,
32989 + *   up the list_kref and schedule a delayed list check.
32990 + */
32991 +
32992 +static void ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
32993 +{
32994 +       struct ttm_bo_device *bdev = bo->bdev;
32995 +       struct ttm_bo_driver *driver = bdev->driver;
32996 +
32997 +       mutex_lock(&bo->mutex);
32998 +
32999 +       if (bo->sync_obj && driver->sync_obj_signaled(bo->sync_obj,
33000 +                                                     bo->sync_obj_arg)) {
33001 +               driver->sync_obj_unref(&bo->sync_obj);
33002 +               bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
33003 +       }
33004 +
33005 +       if (bo->sync_obj && remove_all)
33006 +               (void)ttm_bo_expire_sync_obj(bo, false);
33007 +
33008 +       if (!bo->sync_obj) {
33009 +               int put_count;
33010 +
33011 +               if (bo->ttm)
33012 +                       ttm_tt_unbind(bo->ttm);
33013 +               spin_lock(&bdev->lru_lock);
33014 +               if (!list_empty(&bo->ddestroy)) {
33015 +                       list_del_init(&bo->ddestroy);
33016 +                       kref_put(&bo->list_kref, ttm_bo_ref_bug);
33017 +               }
33018 +               if (bo->mem.mm_node) {
33019 +                       drm_mm_put_block(bo->mem.mm_node);
33020 +                       bo->mem.mm_node = NULL;
33021 +               }
33022 +               put_count = ttm_bo_del_from_lru(bo);
33023 +               spin_unlock(&bdev->lru_lock);
33024 +               mutex_unlock(&bo->mutex);
33025 +               while (put_count--)
33026 +                       kref_put(&bo->list_kref, ttm_bo_release_list);
33027 +
33028 +               return;
33029 +       }
33030 +
33031 +       spin_lock(&bdev->lru_lock);
33032 +       if (list_empty(&bo->ddestroy)) {
33033 +               spin_unlock(&bdev->lru_lock);
33034 +               driver->sync_obj_flush(bo->sync_obj, bo->sync_obj_arg);
33035 +               spin_lock(&bdev->lru_lock);
33036 +               if (list_empty(&bo->ddestroy)) {
33037 +                       kref_get(&bo->list_kref);
33038 +                       list_add_tail(&bo->ddestroy, &bdev->ddestroy);
33039 +               }
33040 +               spin_unlock(&bdev->lru_lock);
33041 +               schedule_delayed_work(&bdev->wq,
33042 +                                     ((HZ / 100) < 1) ? 1 : HZ / 100);
33043 +       } else
33044 +               spin_unlock(&bdev->lru_lock);
33045 +
33046 +       mutex_unlock(&bo->mutex);
33047 +       return;
33048 +}
33049 +
33050 +/**
33051 + * Traverse the delayed list, and call ttm_bo_cleanup_refs on all
33052 + * encountered buffers.
33053 + */
33054 +
33055 +static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
33056 +{
33057 +       struct ttm_buffer_object *entry, *nentry;
33058 +       struct list_head *list, *next;
33059 +       int ret;
33060 +
33061 +       spin_lock(&bdev->lru_lock);
33062 +       list_for_each_safe(list, next, &bdev->ddestroy) {
33063 +               entry = list_entry(list, struct ttm_buffer_object, ddestroy);
33064 +               nentry = NULL;
33065 +
33066 +               /*
33067 +                * Protect the next list entry from destruction while we
33068 +                * unlock the lru_lock.
33069 +                */
33070 +
33071 +               if (next != &bdev->ddestroy) {
33072 +                       nentry = list_entry(next, struct ttm_buffer_object,
33073 +                                           ddestroy);
33074 +                       kref_get(&nentry->list_kref);
33075 +               }
33076 +               kref_get(&entry->list_kref);
33077 +
33078 +               spin_unlock(&bdev->lru_lock);
33079 +               ttm_bo_cleanup_refs(entry, remove_all);
33080 +               kref_put(&entry->list_kref, ttm_bo_release_list);
33081 +               spin_lock(&bdev->lru_lock);
33082 +
33083 +               if (nentry) {
33084 +                       bool next_onlist = !list_empty(next);
33085 +                       kref_put(&nentry->list_kref, ttm_bo_release_list);
33086 +
33087 +                       /*
33088 +                        * Someone might have raced us and removed the
33089 +                        * next entry from the list. We don't bother restarting
33090 +                        * list traversal.
33091 +                        */
33092 +
33093 +                       if (!next_onlist)
33094 +                               break;
33095 +               }
33096 +       }
33097 +       ret = !list_empty(&bdev->ddestroy);
33098 +       spin_unlock(&bdev->lru_lock);
33099 +
33100 +       return ret;
33101 +}
33102 +
33103 +static void ttm_bo_delayed_workqueue(struct work_struct *work)
33104 +{
33105 +       struct ttm_bo_device *bdev =
33106 +           container_of(work, struct ttm_bo_device, wq.work);
33107 +
33108 +       if (ttm_bo_delayed_delete(bdev, false)) {
33109 +               schedule_delayed_work(&bdev->wq,
33110 +                                     ((HZ / 100) < 1) ? 1 : HZ / 100);
33111 +       }
33112 +}
33113 +
33114 +static void ttm_bo_release(struct kref *kref)
33115 +{
33116 +       struct ttm_buffer_object *bo =
33117 +           container_of(kref, struct ttm_buffer_object, kref);
33118 +       struct ttm_bo_device *bdev = bo->bdev;
33119 +
33120 +       if (likely(bo->vm_node != NULL)) {
33121 +               rb_erase(&bo->vm_rb, &bdev->addr_space_rb);
33122 +               drm_mm_put_block(bo->vm_node);
33123 +       }
33124 +       write_unlock(&bdev->vm_lock);
33125 +       ttm_bo_cleanup_refs(bo, false);
33126 +       kref_put(&bo->list_kref, ttm_bo_release_list);
33127 +       write_lock(&bdev->vm_lock);
33128 +}
33129 +
33130 +void ttm_bo_unref(struct ttm_buffer_object **p_bo)
33131 +{
33132 +       struct ttm_buffer_object *bo = *p_bo;
33133 +       struct ttm_bo_device *bdev = bo->bdev;
33134 +
33135 +       *p_bo = NULL;
33136 +       write_lock(&bdev->vm_lock);
33137 +       kref_put(&bo->kref, ttm_bo_release);
33138 +       write_unlock(&bdev->vm_lock);
33139 +}
33140 +
33141 +static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
33142 +                       bool interruptible, bool no_wait)
33143 +{
33144 +       int ret = 0;
33145 +       struct ttm_bo_device *bdev = bo->bdev;
33146 +       struct ttm_mem_reg evict_mem;
33147 +
33148 +       if (bo->mem.mem_type != mem_type)
33149 +               goto out;
33150 +
33151 +       ret = ttm_bo_wait(bo, false, interruptible, no_wait);
33152 +       if (ret && ret != -ERESTART) {
33153 +               printk(KERN_ERR "Failed to expire sync object before "
33154 +                      "buffer eviction.\n");
33155 +               goto out;
33156 +       }
33157 +
33158 +       BUG_ON(!atomic_read(&bo->reserved));
33159 +
33160 +       evict_mem = bo->mem;
33161 +       evict_mem.mm_node = NULL;
33162 +
33163 +       evict_mem.proposed_flags = bdev->driver->evict_flags(bo);
33164 +       BUG_ON(ttm_bo_type_flags(mem_type) & evict_mem.proposed_flags);
33165 +
33166 +       ret = ttm_bo_mem_space(bo, &evict_mem, interruptible, no_wait);
33167 +       if (unlikely(ret != 0 && ret != -ERESTART)) {
33168 +               evict_mem.proposed_flags = TTM_PL_FLAG_SYSTEM;
33169 +               BUG_ON(ttm_bo_type_flags(mem_type) & evict_mem.proposed_flags);
33170 +               ret = ttm_bo_mem_space(bo, &evict_mem, interruptible, no_wait);
33171 +       }
33172 +
33173 +       if (ret) {
33174 +               if (ret != -ERESTART)
33175 +                       printk(KERN_ERR "Failed to find memory space for "
33176 +                              "buffer 0x%p eviction.\n", bo);
33177 +               goto out;
33178 +       }
33179 +
33180 +       ret = ttm_bo_handle_move_mem(bo,
33181 +                                    &evict_mem,
33182 +                                    true,
33183 +                                    interruptible,
33184 +                                    no_wait);
33185 +       if (ret) {
33186 +               if (ret != -ERESTART)
33187 +                       printk(KERN_ERR "Buffer eviction failed\n");
33188 +               goto out;
33189 +       }
33190 +
33191 +       spin_lock(&bdev->lru_lock);
33192 +       if (evict_mem.mm_node) {
33193 +               drm_mm_put_block(evict_mem.mm_node);
33194 +               evict_mem.mm_node = NULL;
33195 +       }
33196 +       spin_unlock(&bdev->lru_lock);
33197 +
33198 +       ttm_flag_masked(&bo->priv_flags, TTM_BO_PRIV_FLAG_EVICTED,
33199 +                       TTM_BO_PRIV_FLAG_EVICTED);
33200 +
33201 +out:
33202 +       return ret;
33203 +}
33204 +
33205 +/**
33206 + * Repeatedly evict memory from the LRU for @mem_type until we create enough
33207 + * space, or we've evicted everything and there isn't enough space.
33208 + */
33209 +static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
33210 +                                 struct ttm_mem_reg *mem,
33211 +                                 uint32_t mem_type,
33212 +                                 bool interruptible, bool no_wait)
33213 +{
33214 +       struct drm_mm_node *node;
33215 +       struct ttm_buffer_object *entry;
33216 +       struct ttm_mem_type_manager *man = &bdev->man[mem_type];
33217 +       struct list_head *lru;
33218 +       unsigned long num_pages = mem->num_pages;
33219 +       int put_count = 0;
33220 +       int ret;
33221 +
33222 +retry_pre_get:
33223 +       ret = drm_mm_pre_get(&man->manager);
33224 +       if (unlikely(ret != 0))
33225 +               return ret;
33226 +
33227 +       spin_lock(&bdev->lru_lock);
33228 +       do {
33229 +               node = drm_mm_search_free(&man->manager, num_pages,
33230 +                                         mem->page_alignment, 1);
33231 +               if (node)
33232 +                       break;
33233 +
33234 +               lru = &man->lru;
33235 +               if (list_empty(lru))
33236 +                       break;
33237 +
33238 +               entry = list_first_entry(lru, struct ttm_buffer_object, lru);
33239 +               kref_get(&entry->list_kref);
33240 +
33241 +               ret = ttm_bo_reserve_locked(entry,
33242 +                                           interruptible,
33243 +                                           no_wait,
33244 +                                           false,
33245 +                                           0);
33246 +
33247 +               if (likely(ret == 0))
33248 +                       put_count = ttm_bo_del_from_lru(entry);
33249 +
33250 +               spin_unlock(&bdev->lru_lock);
33251 +
33252 +               if (unlikely(ret != 0))
33253 +                       return ret;
33254 +
33255 +               while (put_count--)
33256 +                       kref_put(&entry->list_kref, ttm_bo_ref_bug);
33257 +
33258 +               mutex_lock(&entry->mutex);
33259 +               ret = ttm_bo_evict(entry, mem_type, interruptible, no_wait);
33260 +               mutex_unlock(&entry->mutex);
33261 +
33262 +               ttm_bo_unreserve(entry);
33263 +
33264 +               kref_put(&entry->list_kref, ttm_bo_release_list);
33265 +               if (ret)
33266 +                       return ret;
33267 +
33268 +               spin_lock(&bdev->lru_lock);
33269 +       } while (1);
33270 +
33271 +       if (!node) {
33272 +               spin_unlock(&bdev->lru_lock);
33273 +               return -ENOMEM;
33274 +       }
33275 +
33276 +       node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment);
33277 +       if (unlikely(!node)) {
33278 +               spin_unlock(&bdev->lru_lock);
33279 +               goto retry_pre_get;
33280 +       }
33281 +
33282 +       spin_unlock(&bdev->lru_lock);
33283 +       mem->mm_node = node;
33284 +       mem->mem_type = mem_type;
33285 +       return 0;
33286 +}
33287 +
33288 +static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
33289 +                                bool disallow_fixed,
33290 +                                uint32_t mem_type,
33291 +                                uint32_t mask, uint32_t *res_mask)
33292 +{
33293 +       uint32_t cur_flags = ttm_bo_type_flags(mem_type);
33294 +
33295 +       if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && disallow_fixed)
33296 +               return false;
33297 +
33298 +       if ((cur_flags & mask & TTM_PL_MASK_MEM) == 0)
33299 +               return false;
33300 +
33301 +       if ((mask & man->available_caching) == 0)
33302 +               return false;
33303 +       if (mask & man->default_caching)
33304 +               cur_flags |= man->default_caching;
33305 +       else if (mask & TTM_PL_FLAG_CACHED)
33306 +               cur_flags |= TTM_PL_FLAG_CACHED;
33307 +       else if (mask & TTM_PL_FLAG_WC)
33308 +               cur_flags |= TTM_PL_FLAG_WC;
33309 +       else
33310 +               cur_flags |= TTM_PL_FLAG_UNCACHED;
33311 +
33312 +       *res_mask = cur_flags;
33313 +       return true;
33314 +}
33315 +
33316 +/**
33317 + * Creates space for memory region @mem according to its type.
33318 + *
33319 + * This function first searches for free space in compatible memory types in
33320 + * the priority order defined by the driver.  If free space isn't found, then
33321 + * ttm_bo_mem_force_space is attempted in priority order to evict and find
33322 + * space.
33323 + */
33324 +int ttm_bo_mem_space(struct ttm_buffer_object *bo,
33325 +                    struct ttm_mem_reg *mem, bool interruptible, bool no_wait)
33326 +{
33327 +       struct ttm_bo_device *bdev = bo->bdev;
33328 +       struct ttm_mem_type_manager *man;
33329 +
33330 +       uint32_t num_prios = bdev->driver->num_mem_type_prio;
33331 +       const uint32_t *prios = bdev->driver->mem_type_prio;
33332 +       uint32_t i;
33333 +       uint32_t mem_type = TTM_PL_SYSTEM;
33334 +       uint32_t cur_flags = 0;
33335 +       bool type_found = false;
33336 +       bool type_ok = false;
33337 +       bool has_eagain = false;
33338 +       struct drm_mm_node *node = NULL;
33339 +       int ret;
33340 +
33341 +       mem->mm_node = NULL;
33342 +       for (i = 0; i < num_prios; ++i) {
33343 +               mem_type = prios[i];
33344 +               man = &bdev->man[mem_type];
33345 +
33346 +               type_ok = ttm_bo_mt_compatible(man,
33347 +                                              bo->type == ttm_bo_type_user,
33348 +                                              mem_type, mem->proposed_flags,
33349 +                                              &cur_flags);
33350 +
33351 +               if (!type_ok)
33352 +                       continue;
33353 +
33354 +               if (mem_type == TTM_PL_SYSTEM)
33355 +                       break;
33356 +
33357 +               if (man->has_type && man->use_type) {
33358 +                       type_found = true;
33359 +                       do {
33360 +                               ret = drm_mm_pre_get(&man->manager);
33361 +                               if (unlikely(ret))
33362 +                                       return ret;
33363 +
33364 +                               spin_lock(&bdev->lru_lock);
33365 +                               node = drm_mm_search_free(&man->manager,
33366 +                                                         mem->num_pages,
33367 +                                                         mem->page_alignment,
33368 +                                                         1);
33369 +                               if (unlikely(!node)) {
33370 +                                       spin_unlock(&bdev->lru_lock);
33371 +                                       break;
33372 +                               }
33373 +                               node = drm_mm_get_block_atomic(node,
33374 +                                                              mem->num_pages,
33375 +                                                              mem->
33376 +                                                              page_alignment);
33377 +                               spin_unlock(&bdev->lru_lock);
33378 +                       } while (!node);
33379 +               }
33380 +               if (node)
33381 +                       break;
33382 +       }
33383 +
33384 +       if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || node) {
33385 +               mem->mm_node = node;
33386 +               mem->mem_type = mem_type;
33387 +               mem->flags = cur_flags;
33388 +               return 0;
33389 +       }
33390 +
33391 +       if (!type_found)
33392 +               return -EINVAL;
33393 +
33394 +       num_prios = bdev->driver->num_mem_busy_prio;
33395 +       prios = bdev->driver->mem_busy_prio;
33396 +
33397 +       for (i = 0; i < num_prios; ++i) {
33398 +               mem_type = prios[i];
33399 +               man = &bdev->man[mem_type];
33400 +
33401 +               if (!man->has_type)
33402 +                       continue;
33403 +
33404 +               if (!ttm_bo_mt_compatible(man,
33405 +                                         bo->type == ttm_bo_type_user,
33406 +                                         mem_type,
33407 +                                         mem->proposed_flags, &cur_flags))
33408 +                       continue;
33409 +
33410 +               ret = ttm_bo_mem_force_space(bdev, mem, mem_type,
33411 +                                            interruptible, no_wait);
33412 +
33413 +               if (ret == 0 && mem->mm_node) {
33414 +                       mem->flags = cur_flags;
33415 +                       return 0;
33416 +               }
33417 +
33418 +               if (ret == -ERESTART)
33419 +                       has_eagain = true;
33420 +       }
33421 +
33422 +       ret = (has_eagain) ? -ERESTART : -ENOMEM;
33423 +       return ret;
33424 +}
33425 +
33426 +/*
33427 + * Call bo->mutex locked.
33428 + * Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
33429 + */
33430 +
33431 +static int ttm_bo_busy(struct ttm_buffer_object *bo)
33432 +{
33433 +       void *sync_obj = bo->sync_obj;
33434 +       struct ttm_bo_driver *driver = bo->bdev->driver;
33435 +
33436 +       if (sync_obj) {
33437 +               if (driver->sync_obj_signaled(sync_obj, bo->sync_obj_arg)) {
33438 +                       driver->sync_obj_unref(&bo->sync_obj);
33439 +                       bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
33440 +                       return 0;
33441 +               }
33442 +               driver->sync_obj_flush(sync_obj, bo->sync_obj_arg);
33443 +               if (driver->sync_obj_signaled(sync_obj, bo->sync_obj_arg)) {
33444 +                       driver->sync_obj_unref(&bo->sync_obj);
33445 +                       bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
33446 +                       return 0;
33447 +               }
33448 +               return 1;
33449 +       }
33450 +       return 0;
33451 +}
33452 +
33453 +int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait)
33454 +{
33455 +       int ret = 0;
33456 +
33457 +       if ((atomic_read(&bo->cpu_writers) > 0) && no_wait)
33458 +               return -EBUSY;
33459 +
33460 +       ret = wait_event_interruptible(bo->event_queue,
33461 +                                      atomic_read(&bo->cpu_writers) == 0);
33462 +
33463 +       if (ret == -ERESTARTSYS)
33464 +               ret = -ERESTART;
33465 +
33466 +       return ret;
33467 +}
33468 +
33469 +/*
33470 + * bo->mutex locked.
33471 + * Note that new_mem_flags are NOT transferred to the bo->mem.proposed_flags.
33472 + */
33473 +
33474 +int ttm_bo_move_buffer(struct ttm_buffer_object *bo, uint32_t new_mem_flags,
33475 +                      bool interruptible, bool no_wait)
33476 +{
33477 +       struct ttm_bo_device *bdev = bo->bdev;
33478 +       int ret = 0;
33479 +       struct ttm_mem_reg mem;
33480 +
33481 +       BUG_ON(!atomic_read(&bo->reserved));
33482 +
33483 +       /*
33484 +        * FIXME: It's possible to pipeline buffer moves.
33485 +        * Have the driver move function wait for idle when necessary,
33486 +        * instead of doing it here.
33487 +        */
33488 +
33489 +       ttm_bo_busy(bo);
33490 +       ret = ttm_bo_wait(bo, false, interruptible, no_wait);
33491 +       if (ret)
33492 +               return ret;
33493 +
33494 +       mem.num_pages = bo->num_pages;
33495 +       mem.size = mem.num_pages << PAGE_SHIFT;
33496 +       mem.proposed_flags = new_mem_flags;
33497 +       mem.page_alignment = bo->mem.page_alignment;
33498 +
33499 +       /*
33500 +        * Determine where to move the buffer.
33501 +        */
33502 +
33503 +       ret = ttm_bo_mem_space(bo, &mem, interruptible, no_wait);
33504 +       if (ret)
33505 +               goto out_unlock;
33506 +
33507 +       ret = ttm_bo_handle_move_mem(bo, &mem, false, interruptible, no_wait);
33508 +
33509 +out_unlock:
33510 +       if (ret && mem.mm_node) {
33511 +               spin_lock(&bdev->lru_lock);
33512 +               drm_mm_put_block(mem.mm_node);
33513 +               spin_unlock(&bdev->lru_lock);
33514 +       }
33515 +       return ret;
33516 +}
33517 +
33518 +static int ttm_bo_mem_compat(struct ttm_mem_reg *mem)
33519 +{
33520 +       if ((mem->proposed_flags & mem->flags & TTM_PL_MASK_MEM) == 0)
33521 +               return 0;
33522 +       if ((mem->proposed_flags & mem->flags & TTM_PL_MASK_CACHING) == 0)
33523 +               return 0;
33524 +
33525 +       return 1;
33526 +}
33527 +
33528 +int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
33529 +                              bool interruptible, bool no_wait)
33530 +{
33531 +       int ret;
33532 +
33533 +       BUG_ON(!atomic_read(&bo->reserved));
33534 +       bo->mem.proposed_flags = bo->proposed_flags;
33535 +
33536 +       TTM_DEBUG("Proposed flags 0x%08lx, Old flags 0x%08lx\n",
33537 +                 (unsigned long)bo->mem.proposed_flags,
33538 +                 (unsigned long)bo->mem.flags);
33539 +
33540 +       /*
33541 +        * Check whether we need to move buffer.
33542 +        */
33543 +
33544 +       if (!ttm_bo_mem_compat(&bo->mem)) {
33545 +               ret = ttm_bo_move_buffer(bo, bo->mem.proposed_flags,
33546 +                                        interruptible, no_wait);
33547 +               if (ret) {
33548 +                       if (ret != -ERESTART)
33549 +                               printk(KERN_ERR "Failed moving buffer. "
33550 +                                      "Proposed placement 0x%08x\n",
33551 +                                      bo->mem.proposed_flags);
33552 +                       if (ret == -ENOMEM)
33553 +                               printk(KERN_ERR "Out of aperture space or "
33554 +                                      "DRM memory quota.\n");
33555 +                       return ret;
33556 +               }
33557 +       }
33558 +
33559 +       /*
33560 +        * We might need to add a TTM.
33561 +        */
33562 +
33563 +       if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
33564 +               ret = ttm_bo_add_ttm(bo);
33565 +               if (ret)
33566 +                       return ret;
33567 +       }
33568 +       /*
33569 +        * Validation has succeeded, move the access and other
33570 +        * non-mapping-related flag bits from the proposed flags to
33571 +        * the active flags
33572 +        */
33573 +
33574 +       ttm_flag_masked(&bo->mem.flags, bo->proposed_flags,
33575 +                       ~TTM_PL_MASK_MEMTYPE);
33576 +
33577 +       return 0;
33578 +}
33579 +
33580 +int
33581 +ttm_bo_check_placement(struct ttm_buffer_object *bo,
33582 +                      uint32_t set_flags, uint32_t clr_flags)
33583 +{
33584 +       uint32_t new_mask = set_flags | clr_flags;
33585 +
33586 +       if ((bo->type == ttm_bo_type_user) &&
33587 +           (clr_flags & TTM_PL_FLAG_CACHED)) {
33588 +               printk(KERN_ERR
33589 +                      "User buffers require cache-coherent memory.\n");
33590 +               return -EINVAL;
33591 +       }
33592 +
33593 +       if (!capable(CAP_SYS_ADMIN)) {
33594 +               if (new_mask & TTM_PL_FLAG_NO_EVICT) {
33595 +                       printk(KERN_ERR "Need to be root to modify"
33596 +                              " NO_EVICT status.\n");
33597 +                       return -EINVAL;
33598 +               }
33599 +
33600 +               if ((clr_flags & bo->mem.flags & TTM_PL_MASK_MEMTYPE) &&
33601 +                   (bo->mem.flags & TTM_PL_FLAG_NO_EVICT)) {
33602 +                       printk(KERN_ERR "Incompatible memory specification"
33603 +                              " for NO_EVICT buffer.\n");
33604 +                       return -EINVAL;
33605 +               }
33606 +       }
33607 +       return 0;
33608 +}
33609 +
33610 +int ttm_buffer_object_init(struct ttm_bo_device *bdev,
33611 +                          struct ttm_buffer_object *bo,
33612 +                          unsigned long size,
33613 +                          enum ttm_bo_type type,
33614 +                          uint32_t flags,
33615 +                          uint32_t page_alignment,
33616 +                          unsigned long buffer_start,
33617 +                          bool interruptible,
33618 +                          struct file *persistant_swap_storage,
33619 +                          size_t acc_size,
33620 +                          void (*destroy) (struct ttm_buffer_object *))
33621 +{
33622 +       int ret = 0;
33623 +       unsigned long num_pages;
33624 +
33625 +       size += buffer_start & ~PAGE_MASK;
33626 +       num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
33627 +       if (num_pages == 0) {
33628 +               printk(KERN_ERR "Illegal buffer object size.\n");
33629 +               return -EINVAL;
33630 +       }
33631 +       bo->destroy = destroy;
33632 +
33633 +       mutex_init(&bo->mutex);
33634 +       mutex_lock(&bo->mutex);
33635 +       kref_init(&bo->kref);
33636 +       kref_init(&bo->list_kref);
33637 +       atomic_set(&bo->cpu_writers, 0);
33638 +       atomic_set(&bo->reserved, 1);
33639 +       init_waitqueue_head(&bo->event_queue);
33640 +       INIT_LIST_HEAD(&bo->lru);
33641 +       INIT_LIST_HEAD(&bo->ddestroy);
33642 +       INIT_LIST_HEAD(&bo->swap);
33643 +       bo->bdev = bdev;
33644 +       bo->type = type;
33645 +       bo->num_pages = num_pages;
33646 +       bo->mem.mem_type = TTM_PL_SYSTEM;
33647 +       bo->mem.num_pages = bo->num_pages;
33648 +       bo->mem.mm_node = NULL;
33649 +       bo->mem.page_alignment = page_alignment;
33650 +       bo->buffer_start = buffer_start & PAGE_MASK;
33651 +       bo->priv_flags = 0;
33652 +       bo->mem.flags = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED);
33653 +       bo->seq_valid = false;
33654 +       bo->persistant_swap_storage = persistant_swap_storage;
33655 +       bo->acc_size = acc_size;
33656 +
33657 +       ret = ttm_bo_check_placement(bo, flags, 0ULL);
33658 +       if (unlikely(ret != 0))
33659 +               goto out_err;
33660 +
33661 +       /*
33662 +        * If no caching attributes are set, accept any form of caching.
33663 +        */
33664 +
33665 +       if ((flags & TTM_PL_MASK_CACHING) == 0)
33666 +               flags |= TTM_PL_MASK_CACHING;
33667 +
33668 +       bo->proposed_flags = flags;
33669 +       bo->mem.proposed_flags = flags;
33670 +
33671 +       /*
33672 +        * For ttm_bo_type_device buffers, allocate
33673 +        * address space from the device.
33674 +        */
33675 +
33676 +       if (bo->type == ttm_bo_type_device) {
33677 +               ret = ttm_bo_setup_vm(bo);
33678 +               if (ret)
33679 +                       goto out_err;
33680 +       }
33681 +
33682 +       ret = ttm_buffer_object_validate(bo, interruptible, false);
33683 +       if (ret)
33684 +               goto out_err;
33685 +
33686 +       mutex_unlock(&bo->mutex);
33687 +       ttm_bo_unreserve(bo);
33688 +       return 0;
33689 +
33690 +out_err:
33691 +       mutex_unlock(&bo->mutex);
33692 +       ttm_bo_unreserve(bo);
33693 +       ttm_bo_unref(&bo);
33694 +
33695 +       return ret;
33696 +}
33697 +
33698 +static inline size_t ttm_bo_size(struct ttm_bo_device *bdev,
33699 +                                unsigned long num_pages)
33700 +{
33701 +       size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
33702 +           PAGE_MASK;
33703 +
33704 +       return bdev->ttm_bo_size + 2 * page_array_size;
33705 +}
33706 +
33707 +int ttm_buffer_object_create(struct ttm_bo_device *bdev,
33708 +                            unsigned long size,
33709 +                            enum ttm_bo_type type,
33710 +                            uint32_t flags,
33711 +                            uint32_t page_alignment,
33712 +                            unsigned long buffer_start,
33713 +                            bool interruptible,
33714 +                            struct file *persistant_swap_storage,
33715 +                            struct ttm_buffer_object **p_bo)
33716 +{
33717 +       struct ttm_buffer_object *bo;
33718 +       int ret;
33719 +       struct ttm_mem_global *mem_glob = bdev->mem_glob;
33720 +
33721 +       size_t acc_size =
33722 +           ttm_bo_size(bdev, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
33723 +       ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false);
33724 +       if (unlikely(ret != 0))
33725 +               return ret;
33726 +
33727 +       bo = kzalloc(sizeof(*bo), GFP_KERNEL);
33728 +
33729 +       if (unlikely(bo == NULL)) {
33730 +               ttm_mem_global_free(mem_glob, acc_size, false);
33731 +               return -ENOMEM;
33732 +       }
33733 +
33734 +       ret = ttm_buffer_object_init(bdev, bo, size, type, flags,
33735 +                                    page_alignment, buffer_start,
33736 +                                    interruptible,
33737 +                                    persistant_swap_storage, acc_size, NULL);
33738 +       if (likely(ret == 0))
33739 +               *p_bo = bo;
33740 +
33741 +       return ret;
33742 +}
33743 +
33744 +static int ttm_bo_leave_list(struct ttm_buffer_object *bo,
33745 +                            uint32_t mem_type, bool allow_errors)
33746 +{
33747 +       int ret;
33748 +
33749 +       mutex_lock(&bo->mutex);
33750 +
33751 +       ret = ttm_bo_expire_sync_obj(bo, allow_errors);
33752 +       if (ret)
33753 +               goto out;
33754 +
33755 +       if (bo->mem.mem_type == mem_type)
33756 +               ret = ttm_bo_evict(bo, mem_type, false, false);
33757 +
33758 +       if (ret) {
33759 +               if (allow_errors)
33760 +                       goto out;
33761 +               else {
33762 +                       ret = 0;
33763 +                       printk(KERN_ERR "Cleanup eviction failed\n");
33764 +               }
33765 +       }
33766 +
33767 +out:
33768 +       mutex_unlock(&bo->mutex);
33769 +       return ret;
33770 +}
33771 +
33772 +static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
33773 +                                  struct list_head *head,
33774 +                                  unsigned mem_type, bool allow_errors)
33775 +{
33776 +       struct ttm_buffer_object *entry;
33777 +       int ret;
33778 +       int put_count;
33779 +
33780 +       /*
33781 +        * Can't use standard list traversal since we're unlocking.
33782 +        */
33783 +
33784 +       spin_lock(&bdev->lru_lock);
33785 +
33786 +       while (!list_empty(head)) {
33787 +               entry = list_first_entry(head, struct ttm_buffer_object, lru);
33788 +               kref_get(&entry->list_kref);
33789 +               ret = ttm_bo_reserve_locked(entry, false, false, false, 0);
33790 +               put_count = ttm_bo_del_from_lru(entry);
33791 +               spin_unlock(&bdev->lru_lock);
33792 +               while (put_count--)
33793 +                       kref_put(&entry->list_kref, ttm_bo_ref_bug);
33794 +               BUG_ON(ret);
33795 +               ret = ttm_bo_leave_list(entry, mem_type, allow_errors);
33796 +               ttm_bo_unreserve(entry);
33797 +               kref_put(&entry->list_kref, ttm_bo_release_list);
33798 +               spin_lock(&bdev->lru_lock);
33799 +       }
33800 +
33801 +       spin_unlock(&bdev->lru_lock);
33802 +
33803 +       return 0;
33804 +}
33805 +
33806 +int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
33807 +{
33808 +       struct ttm_mem_type_manager *man = &bdev->man[mem_type];
33809 +       int ret = -EINVAL;
33810 +
33811 +       if (mem_type >= TTM_NUM_MEM_TYPES) {
33812 +               printk(KERN_ERR "Illegal memory type %d\n", mem_type);
33813 +               return ret;
33814 +       }
33815 +
33816 +       if (!man->has_type) {
33817 +               printk(KERN_ERR "Trying to take down uninitialized "
33818 +                      "memory manager type %u\n", mem_type);
33819 +               return ret;
33820 +       }
33821 +
33822 +       man->use_type = false;
33823 +       man->has_type = false;
33824 +
33825 +       ret = 0;
33826 +       if (mem_type > 0) {
33827 +               ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false);
33828 +
33829 +               spin_lock(&bdev->lru_lock);
33830 +               if (drm_mm_clean(&man->manager))
33831 +                       drm_mm_takedown(&man->manager);
33832 +               else
33833 +                       ret = -EBUSY;
33834 +               spin_unlock(&bdev->lru_lock);
33835 +       }
33836 +
33837 +       return ret;
33838 +}
33839 +
33840 +int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)
33841 +{
33842 +       struct ttm_mem_type_manager *man = &bdev->man[mem_type];
33843 +
33844 +       if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) {
33845 +               printk(KERN_ERR "Illegal memory manager memory type %u.\n",
33846 +                      mem_type);
33847 +               return -EINVAL;
33848 +       }
33849 +
33850 +       if (!man->has_type) {
33851 +               printk(KERN_ERR "Memory type %u has not been initialized.\n",
33852 +                      mem_type);
33853 +               return 0;
33854 +       }
33855 +
33856 +       return ttm_bo_force_list_clean(bdev, &man->lru, mem_type, true);
33857 +}
33858 +
33859 +int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
33860 +                  unsigned long p_offset, unsigned long p_size)
33861 +{
33862 +       int ret = -EINVAL;
33863 +       struct ttm_mem_type_manager *man;
33864 +
33865 +       if (type >= TTM_NUM_MEM_TYPES) {
33866 +               printk(KERN_ERR "Illegal memory type %d\n", type);
33867 +               return ret;
33868 +       }
33869 +
33870 +       man = &bdev->man[type];
33871 +       if (man->has_type) {
33872 +               printk(KERN_ERR
33873 +                      "Memory manager already initialized for type %d\n",
33874 +                      type);
33875 +               return ret;
33876 +       }
33877 +
33878 +       ret = bdev->driver->init_mem_type(bdev, type, man);
33879 +       if (ret)
33880 +               return ret;
33881 +
33882 +       ret = 0;
33883 +       if (type != TTM_PL_SYSTEM) {
33884 +               if (!p_size) {
33885 +                       printk(KERN_ERR "Zero size memory manager type %d\n",
33886 +                              type);
33887 +                       return ret;
33888 +               }
33889 +               ret = drm_mm_init(&man->manager, p_offset, p_size);
33890 +               if (ret)
33891 +                       return ret;
33892 +       }
33893 +       man->has_type = true;
33894 +       man->use_type = true;
33895 +       man->size = p_size;
33896 +
33897 +       INIT_LIST_HEAD(&man->lru);
33898 +
33899 +       return 0;
33900 +}
33901 +
33902 +int ttm_bo_device_release(struct ttm_bo_device *bdev)
33903 +{
33904 +       int ret = 0;
33905 +       unsigned i = TTM_NUM_MEM_TYPES;
33906 +       struct ttm_mem_type_manager *man;
33907 +
33908 +       while (i--) {
33909 +               man = &bdev->man[i];
33910 +               if (man->has_type) {
33911 +                       man->use_type = false;
33912 +                       if ((i != TTM_PL_SYSTEM) && ttm_bo_clean_mm(bdev, i)) {
33913 +                               ret = -EBUSY;
33914 +                               printk(KERN_ERR "DRM memory manager type %d "
33915 +                                      "is not clean.\n", i);
33916 +                       }
33917 +                       man->has_type = false;
33918 +               }
33919 +       }
33920 +
33921 +       if (!cancel_delayed_work(&bdev->wq))
33922 +               flush_scheduled_work();
33923 +
33924 +       while (ttm_bo_delayed_delete(bdev, true)) {
33925 +               /* Don't you know you have to do */
33926 +               /* something here otherwise checkpatch will */
33927 +               /* give you error */
33928 +       }
33929 +
33930 +
33931 +       spin_lock(&bdev->lru_lock);
33932 +       if (list_empty(&bdev->ddestroy))
33933 +               TTM_DEBUG("Delayed destroy list was clean\n");
33934 +
33935 +       if (list_empty(&bdev->man[0].lru))
33936 +               TTM_DEBUG("Swap list was clean\n");
33937 +       spin_unlock(&bdev->lru_lock);
33938 +
33939 +       ttm_mem_unregister_shrink(bdev->mem_glob, &bdev->shrink);
33940 +       BUG_ON(!drm_mm_clean(&bdev->addr_space_mm));
33941 +       write_lock(&bdev->vm_lock);
33942 +       drm_mm_takedown(&bdev->addr_space_mm);
33943 +       write_unlock(&bdev->vm_lock);
33944 +
33945 +       __free_page(bdev->dummy_read_page);
33946 +       return ret;
33947 +}
33948 +
33949 +/*
33950 + * This function is intended to be called on drm driver load.
33951 + * If you decide to call it from firstopen, you must protect the call
33952 + * from a potentially racing ttm_bo_driver_finish in lastclose.
33953 + * (This may happen on X server restart).
33954 + */
33955 +
33956 +int ttm_bo_device_init(struct ttm_bo_device *bdev,
33957 +                      struct ttm_mem_global *mem_glob,
33958 +                      struct ttm_bo_driver *driver, uint64_t file_page_offset)
33959 +{
33960 +       int ret = -EINVAL;
33961 +
33962 +       bdev->dummy_read_page = NULL;
33963 +       rwlock_init(&bdev->vm_lock);
33964 +       spin_lock_init(&bdev->lru_lock);
33965 +
33966 +       bdev->driver = driver;
33967 +       bdev->mem_glob = mem_glob;
33968 +
33969 +       memset(bdev->man, 0, sizeof(bdev->man));
33970 +
33971 +       bdev->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
33972 +       if (unlikely(bdev->dummy_read_page == NULL)) {
33973 +               ret = -ENOMEM;
33974 +               goto out_err0;
33975 +       }
33976 +
33977 +       /*
33978 +        * Initialize the system memory buffer type.
33979 +        * Other types need to be driver / IOCTL initialized.
33980 +        */
33981 +       ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0);
33982 +       if (unlikely(ret != 0))
33983 +               goto out_err1;
33984 +
33985 +       bdev->addr_space_rb = RB_ROOT;
33986 +       ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
33987 +       if (unlikely(ret != 0))
33988 +               goto out_err2;
33989 +
33990 +       INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
33991 +       bdev->nice_mode = true;
33992 +       INIT_LIST_HEAD(&bdev->ddestroy);
33993 +       INIT_LIST_HEAD(&bdev->swap_lru);
33994 +       bdev->dev_mapping = NULL;
33995 +       ttm_mem_init_shrink(&bdev->shrink, ttm_bo_swapout);
33996 +       ret = ttm_mem_register_shrink(mem_glob, &bdev->shrink);
33997 +       if (unlikely(ret != 0)) {
33998 +               printk(KERN_ERR "Could not register buffer object swapout.\n");
33999 +               goto out_err2;
34000 +       }
34001 +       return 0;
34002 +out_err2:
34003 +       ttm_bo_clean_mm(bdev, 0);
34004 +out_err1:
34005 +       __free_page(bdev->dummy_read_page);
34006 +out_err0:
34007 +       return ret;
34008 +}
34009 +
34010 +/*
34011 + * buffer object vm functions.
34012 + */
34013 +
34014 +bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
34015 +{
34016 +       struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
34017 +
34018 +       if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
34019 +               if (mem->mem_type == TTM_PL_SYSTEM)
34020 +                       return false;
34021 +
34022 +               if (man->flags & TTM_MEMTYPE_FLAG_CMA)
34023 +                       return false;
34024 +
34025 +               if (mem->flags & TTM_PL_FLAG_CACHED)
34026 +                       return false;
34027 +       }
34028 +       return true;
34029 +}
34030 +
34031 +int ttm_bo_pci_offset(struct ttm_bo_device *bdev,
34032 +                     struct ttm_mem_reg *mem,
34033 +                     unsigned long *bus_base,
34034 +                     unsigned long *bus_offset, unsigned long *bus_size)
34035 +{
34036 +       struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
34037 +
34038 +       *bus_size = 0;
34039 +       if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
34040 +               return -EINVAL;
34041 +
34042 +       if (ttm_mem_reg_is_pci(bdev, mem)) {
34043 +               *bus_offset = mem->mm_node->start << PAGE_SHIFT;
34044 +               *bus_size = mem->num_pages << PAGE_SHIFT;
34045 +               *bus_base = man->io_offset;
34046 +       }
34047 +
34048 +       return 0;
34049 +}
34050 +
34051 +/**
34052 + * \c Kill all user-space virtual mappings of this buffer object.
34053 + *
34054 + * \param bo The buffer object.
34055 + *
34056 + * Call bo->mutex locked.
34057 + */
34058 +
34059 +void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)
34060 +{
34061 +       struct ttm_bo_device *bdev = bo->bdev;
34062 +       loff_t offset = (loff_t) bo->addr_space_offset;
34063 +       loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
34064 +
34065 +       if (!bdev->dev_mapping)
34066 +               return;
34067 +
34068 +       unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1);
34069 +}
34070 +
34071 +static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo)
34072 +{
34073 +       struct ttm_bo_device *bdev = bo->bdev;
34074 +       struct rb_node **cur = &bdev->addr_space_rb.rb_node;
34075 +       struct rb_node *parent = NULL;
34076 +       struct ttm_buffer_object *cur_bo;
34077 +       unsigned long offset = bo->vm_node->start;
34078 +       unsigned long cur_offset;
34079 +
34080 +       while (*cur) {
34081 +               parent = *cur;
34082 +               cur_bo = rb_entry(parent, struct ttm_buffer_object, vm_rb);
34083 +               cur_offset = cur_bo->vm_node->start;
34084 +               if (offset < cur_offset)
34085 +                       cur = &parent->rb_left;
34086 +               else if (offset > cur_offset)
34087 +                       cur = &parent->rb_right;
34088 +               else
34089 +                       BUG();
34090 +       }
34091 +
34092 +       rb_link_node(&bo->vm_rb, parent, cur);
34093 +       rb_insert_color(&bo->vm_rb, &bdev->addr_space_rb);
34094 +}
34095 +
34096 +/**
34097 + * ttm_bo_setup_vm:
34098 + *
34099 + * @bo: the buffer to allocate address space for
34100 + *
34101 + * Allocate address space in the drm device so that applications
34102 + * can mmap the buffer and access the contents. This only
34103 + * applies to ttm_bo_type_device objects as others are not
34104 + * placed in the drm device address space.
34105 + */
34106 +
34107 +static int ttm_bo_setup_vm(struct ttm_buffer_object *bo)
34108 +{
34109 +       struct ttm_bo_device *bdev = bo->bdev;
34110 +       int ret;
34111 +
34112 +retry_pre_get:
34113 +       ret = drm_mm_pre_get(&bdev->addr_space_mm);
34114 +       if (unlikely(ret != 0))
34115 +               return ret;
34116 +
34117 +       write_lock(&bdev->vm_lock);
34118 +       bo->vm_node = drm_mm_search_free(&bdev->addr_space_mm,
34119 +                                        bo->mem.num_pages, 0, 0);
34120 +
34121 +       if (unlikely(bo->vm_node == NULL)) {
34122 +               ret = -ENOMEM;
34123 +               goto out_unlock;
34124 +       }
34125 +
34126 +       bo->vm_node = drm_mm_get_block_atomic(bo->vm_node,
34127 +                                             bo->mem.num_pages, 0);
34128 +
34129 +       if (unlikely(bo->vm_node == NULL)) {
34130 +               write_unlock(&bdev->vm_lock);
34131 +               goto retry_pre_get;
34132 +       }
34133 +
34134 +       ttm_bo_vm_insert_rb(bo);
34135 +       write_unlock(&bdev->vm_lock);
34136 +       bo->addr_space_offset = ((uint64_t) bo->vm_node->start) << PAGE_SHIFT;
34137 +
34138 +       return 0;
34139 +out_unlock:
34140 +       write_unlock(&bdev->vm_lock);
34141 +       return ret;
34142 +}
34143 +
34144 +int ttm_bo_wait(struct ttm_buffer_object *bo,
34145 +               bool lazy, bool interruptible, bool no_wait)
34146 +{
34147 +       struct ttm_bo_driver *driver = bo->bdev->driver;
34148 +       void *sync_obj;
34149 +       void *sync_obj_arg;
34150 +       int ret = 0;
34151 +
34152 +       while (bo->sync_obj) {
34153 +               if (driver->sync_obj_signaled(bo->sync_obj, bo->sync_obj_arg)) {
34154 +                       driver->sync_obj_unref(&bo->sync_obj);
34155 +                       bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
34156 +                       goto out;
34157 +               }
34158 +               if (no_wait) {
34159 +                       ret = -EBUSY;
34160 +                       goto out;
34161 +               }
34162 +               sync_obj = driver->sync_obj_ref(bo->sync_obj);
34163 +               sync_obj_arg = bo->sync_obj_arg;
34164 +               mutex_unlock(&bo->mutex);
34165 +               ret = driver->sync_obj_wait(sync_obj, sync_obj_arg,
34166 +                                           lazy, interruptible);
34167 +
34168 +               mutex_lock(&bo->mutex);
34169 +               if (unlikely(ret != 0)) {
34170 +                       driver->sync_obj_unref(&sync_obj);
34171 +                       return ret;
34172 +               }
34173 +
34174 +               if (bo->sync_obj == sync_obj) {
34175 +                       driver->sync_obj_unref(&bo->sync_obj);
34176 +                       bo->priv_flags &= ~TTM_BO_PRIV_FLAG_MOVING;
34177 +               }
34178 +               driver->sync_obj_unref(&sync_obj);
34179 +       }
34180 +out:
34181 +       return 0;
34182 +}
34183 +
34184 +void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
34185 +{
34186 +       atomic_set(&bo->reserved, 0);
34187 +       wake_up_all(&bo->event_queue);
34188 +}
34189 +
34190 +int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible,
34191 +                            bool no_wait)
34192 +{
34193 +       int ret;
34194 +
34195 +       while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
34196 +               if (no_wait)
34197 +                       return -EBUSY;
34198 +               else if (interruptible) {
34199 +                       ret = wait_event_interruptible
34200 +                           (bo->event_queue, atomic_read(&bo->reserved) == 0);
34201 +                       if (unlikely(ret != 0))
34202 +                               return -ERESTART;
34203 +               } else {
34204 +                       wait_event(bo->event_queue,
34205 +                                  atomic_read(&bo->reserved) == 0);
34206 +               }
34207 +       }
34208 +       return 0;
34209 +}
34210 +
34211 +int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
34212 +{
34213 +       int ret = 0;
34214 +
34215 +       /*
34216 +        * Using ttm_bo_reserve instead of ttm_bo_block_reservation
34217 +        * makes sure the lru lists are updated.
34218 +        */
34219 +
34220 +       ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
34221 +       if (unlikely(ret != 0))
34222 +               return ret;
34223 +       mutex_lock(&bo->mutex);
34224 +       ret = ttm_bo_wait(bo, false, true, no_wait);
34225 +       if (unlikely(ret != 0))
34226 +               goto out_err0;
34227 +       atomic_inc(&bo->cpu_writers);
34228 +out_err0:
34229 +       mutex_unlock(&bo->mutex);
34230 +       ttm_bo_unreserve(bo);
34231 +       return ret;
34232 +}
34233 +
34234 +void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
34235 +{
34236 +       if (atomic_dec_and_test(&bo->cpu_writers))
34237 +               wake_up_all(&bo->event_queue);
34238 +}
34239 +
34240 +/**
34241 + * A buffer object shrink method that tries to swap out the first
34242 + * buffer object on the bo_global::swap_lru list.
34243 + */
34244 +
34245 +static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
34246 +{
34247 +       struct ttm_bo_device *bdev =
34248 +           container_of(shrink, struct ttm_bo_device, shrink);
34249 +       struct ttm_buffer_object *bo;
34250 +       int ret = -EBUSY;
34251 +       int put_count;
34252 +       uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
34253 +
34254 +       spin_lock(&bdev->lru_lock);
34255 +       while (ret == -EBUSY) {
34256 +               if (unlikely(list_empty(&bdev->swap_lru))) {
34257 +                       spin_unlock(&bdev->lru_lock);
34258 +                       return -EBUSY;
34259 +               }
34260 +
34261 +               bo = list_first_entry(&bdev->swap_lru,
34262 +                                     struct ttm_buffer_object, swap);
34263 +               kref_get(&bo->list_kref);
34264 +
34265 +               /**
34266 +                * Reserve buffer. Since we unlock while sleeping, we need
34267 +                * to re-check that nobody removed us from the swap-list while
34268 +                * we slept.
34269 +                */
34270 +
34271 +               ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
34272 +               if (unlikely(ret == -EBUSY)) {
34273 +                       spin_unlock(&bdev->lru_lock);
34274 +                       ttm_bo_wait_unreserved(bo, false);
34275 +                       kref_put(&bo->list_kref, ttm_bo_release_list);
34276 +                       spin_lock(&bdev->lru_lock);
34277 +               }
34278 +       }
34279 +
34280 +       BUG_ON(ret != 0);
34281 +       put_count = ttm_bo_del_from_lru(bo);
34282 +       spin_unlock(&bdev->lru_lock);
34283 +
34284 +       while (put_count--)
34285 +               kref_put(&bo->list_kref, ttm_bo_ref_bug);
34286 +
34287 +       /**
34288 +        * Wait for GPU, then move to system cached.
34289 +        */
34290 +
34291 +       mutex_lock(&bo->mutex);
34292 +       ret = ttm_bo_wait(bo, false, false, false);
34293 +       if (unlikely(ret != 0))
34294 +               goto out;
34295 +
34296 +       if ((bo->mem.flags & swap_placement) != swap_placement) {
34297 +               struct ttm_mem_reg evict_mem;
34298 +
34299 +               evict_mem = bo->mem;
34300 +               evict_mem.mm_node = NULL;
34301 +               evict_mem.proposed_flags =
34302 +                   TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
34303 +               evict_mem.flags = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED;
34304 +               evict_mem.mem_type = TTM_PL_SYSTEM;
34305 +
34306 +               ret = ttm_bo_handle_move_mem(bo,
34307 +                                            &evict_mem,
34308 +                                            true,
34309 +                                            false,
34310 +                                            false);
34311 +               if (unlikely(ret != 0))
34312 +                       goto out;
34313 +       }
34314 +
34315 +       ttm_bo_unmap_virtual(bo);
34316 +
34317 +       /**
34318 +        * Swap out. Buffer will be swapped in again as soon as
34319 +        * anyone tries to access a ttm page.
34320 +        */
34321 +
34322 +       ret = ttm_tt_swapout(bo->ttm, bo->persistant_swap_storage);
34323 +out:
34324 +       mutex_unlock(&bo->mutex);
34325 +
34326 +       /**
34327 +        *
34328 +        * Unreserve without putting on LRU to avoid swapping out an
34329 +        * already swapped buffer.
34330 +        */
34331 +
34332 +       atomic_set(&bo->reserved, 0);
34333 +       wake_up_all(&bo->event_queue);
34334 +       kref_put(&bo->list_kref, ttm_bo_release_list);
34335 +       return ret;
34336 +}
34337 +
34338 +void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
34339 +{
34340 +       while (ttm_bo_swapout(&bdev->shrink) == 0) {
34341 +               /* Checkpatch doesn't like it */
34342 +               /* adding something here */
34343 +       }
34344 +}
34345 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_api.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_api.h
34346 new file mode 100644
34347 index 0000000..e336893
34348 --- /dev/null
34349 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_api.h
34350 @@ -0,0 +1,573 @@
34351 +/**************************************************************************
34352 + *
34353 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
34354 + * All Rights Reserved.
34355 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
34356 + * All Rights Reserved.
34357 + *
34358 + * This program is free software; you can redistribute it and/or modify it
34359 + * under the terms and conditions of the GNU General Public License,
34360 + * version 2, as published by the Free Software Foundation.
34361 + *
34362 + * This program is distributed in the hope it will be useful, but WITHOUT
34363 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34364 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
34365 + * more details.
34366 + *
34367 + * You should have received a copy of the GNU General Public License along with
34368 + * this program; if not, write to the Free Software Foundation, Inc., 
34369 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
34370 + *
34371 + **************************************************************************/
34372 +/*
34373 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
34374 + */
34375 +
34376 +#ifndef _TTM_BO_API_H_
34377 +#define _TTM_BO_API_H_
34378 +
34379 +#include <drm/drm_hashtab.h>
34380 +#include <linux/kref.h>
34381 +#include <linux/list.h>
34382 +#include <linux/wait.h>
34383 +#include <linux/mutex.h>
34384 +#include <linux/mm.h>
34385 +#include <linux/rbtree.h>
34386 +
34387 +struct ttm_bo_device;
34388 +
34389 +struct drm_mm_node;
34390 +
34391 +/**
34392 + * struct ttm_mem_reg
34393 + *
34394 + * @mm_node: Memory manager node.
34395 + * @size: Requested size of memory region.
34396 + * @num_pages: Actual size of memory region in pages.
34397 + * @page_alignment: Page alignment.
34398 + * @flags: Placement flags.
34399 + * @proposed_flags: Proposed placement flags.
34400 + *
34401 + * Structure indicating the placement and space resources used by a
34402 + * buffer object.
34403 + */
34404 +
34405 +struct ttm_mem_reg {
34406 +       struct drm_mm_node *mm_node;
34407 +       unsigned long size;
34408 +       unsigned long num_pages;
34409 +       uint32_t page_alignment;
34410 +       uint32_t mem_type;
34411 +       uint32_t flags;
34412 +       uint32_t proposed_flags;
34413 +};
34414 +
34415 +/**
34416 + * enum ttm_bo_type
34417 + *
34418 + * @ttm_bo_type_device:        These are 'normal' buffers that can
34419 + * be mmapped by user space. Each of these bos occupy a slot in the
34420 + * device address space, that can be used for normal vm operations.
34421 + *
34422 + * @ttm_bo_type_user: These are user-space memory areas that are made
34423 + * available to the GPU by mapping the buffer pages into the GPU aperture
34424 + * space. These buffers cannot be mmaped from the device address space.
34425 + *
34426 + * @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers,
34427 + * but they cannot be accessed from user-space. For kernel-only use.
34428 + */
34429 +
34430 +enum ttm_bo_type {
34431 +       ttm_bo_type_device,
34432 +       ttm_bo_type_user,
34433 +       ttm_bo_type_kernel
34434 +};
34435 +
34436 +struct ttm_tt;
34437 +
34438 +/**
34439 + * struct ttm_buffer_object
34440 + *
34441 + * @bdev: Pointer to the buffer object device structure.
34442 + * @kref: Reference count of this buffer object. When this refcount reaches
34443 + * zero, the object is put on the delayed delete list.
34444 + * @list_kref: List reference count of this buffer object. This member is
34445 + * used to avoid destruction while the buffer object is still on a list.
34446 + * Lru lists may keep one refcount, the delayed delete list, and kref != 0
34447 + * keeps one refcount. When this refcount reaches zero,
34448 + * the object is destroyed.
34449 + * @proposed_flags: Proposed placement for the buffer. Changed only by the
34450 + * creator prior to validation as opposed to bo->mem.proposed_flags which is
34451 + * changed by the implementation prior to a buffer move if it wants to outsmart
34452 + * the buffer creator / user. This latter happens, for example, at eviction.
34453 + * @buffer_start: The virtual user-space start address of ttm_bo_type_user
34454 + * buffers.
34455 + * @type: The bo type.
34456 + * @offset: The current GPU offset, which can have different meanings
34457 + * depending on the memory type. For SYSTEM type memory, it should be 0.
34458 + * @mem: structure describing current placement.
34459 + * @val_seq: Sequence of the validation holding the @reserved lock.
34460 + * Used to avoid starvation when many processes compete to validate the
34461 + * buffer. This member is protected by the bo_device::lru_lock.
34462 + * @seq_valid: The value of @val_seq is valid. This value is protected by
34463 + * the bo_device::lru_lock.
34464 + * @lru: List head for the lru list.
34465 + * @ddestroy: List head for the delayed destroy list.
34466 + * @swap: List head for swap LRU list.
34467 + * @persistant_swap_storage: Usually the swap storage is deleted for buffers
34468 + * pinned in physical memory. If this behaviour is not desired, this member
34469 + * holds a pointer to a persistant shmem object.
34470 + * @destroy: Destruction function. If NULL, kfree is used.
34471 + * @sync_obj_arg: Opaque argument to synchronization object function.
34472 + * @sync_obj: Pointer to a synchronization object.
34473 + * @priv_flags: Flags describing buffer object internal state.
34474 + * @event_queue: Queue for processes waiting on buffer object status change.
34475 + * @mutex: Lock protecting all members with the exception of constant members
34476 + * and list heads. We should really use a spinlock here.
34477 + * @num_pages: Actual number of pages.
34478 + * @ttm: TTM structure holding system pages.
34479 + * @vm_hash: Hash item for fast address space lookup. Need to change to a
34480 + * rb-tree node.
34481 + * @vm_node: Address space manager node.
34482 + * @addr_space_offset: Address space offset.
34483 + * @cpu_writes: For synchronization. Number of cpu writers.
34484 + * @reserved: Deadlock-free lock used for synchronization state transitions.
34485 + * @acc_size: Accounted size for this object.
34486 + *
34487 + * Base class for TTM buffer object, that deals with data placement and CPU
34488 + * mappings. GPU mappings are really up to the driver, but for simpler GPUs
34489 + * the driver can usually use the placement offset @offset directly as the
34490 + * GPU virtual address. For drivers implementing multiple
34491 + * GPU memory manager contexts, the driver should manage the address space
34492 + * in these contexts separately and use these objects to get the correct
34493 + * placement and caching for these GPU maps. This makes it possible to use
34494 + * these objects for even quite elaborate memory management schemes.
34495 + * The destroy member, the API visibility of this object makes it possible
34496 + * to derive driver specific types.
34497 + */
34498 +
34499 +struct ttm_buffer_object {
34500 +       struct ttm_bo_device *bdev;
34501 +       struct kref kref;
34502 +       struct kref list_kref;
34503 +
34504 +       /*
34505 +        * If there is a possibility that the usage variable is zero,
34506 +        * then dev->struct_mutex should be locked before incrementing it.
34507 +        */
34508 +
34509 +       uint32_t proposed_flags;
34510 +       unsigned long buffer_start;
34511 +       enum ttm_bo_type type;
34512 +       unsigned long offset;
34513 +       struct ttm_mem_reg mem;
34514 +       uint32_t val_seq;
34515 +       bool seq_valid;
34516 +
34517 +       struct list_head lru;
34518 +       struct list_head ddestroy;
34519 +       struct list_head swap;
34520 +
34521 +       struct file *persistant_swap_storage;
34522 +
34523 +       void (*destroy) (struct ttm_buffer_object *);
34524 +
34525 +       void *sync_obj_arg;
34526 +       void *sync_obj;
34527 +
34528 +       uint32_t priv_flags;
34529 +       wait_queue_head_t event_queue;
34530 +       struct mutex mutex;
34531 +       unsigned long num_pages;
34532 +
34533 +       struct ttm_tt *ttm;
34534 +       struct rb_node vm_rb;
34535 +       struct drm_mm_node *vm_node;
34536 +       uint64_t addr_space_offset;
34537 +
34538 +       atomic_t cpu_writers;
34539 +       atomic_t reserved;
34540 +
34541 +       size_t acc_size;
34542 +};
34543 +
34544 +/**
34545 + * struct ttm_bo_kmap_obj
34546 + *
34547 + * @virtual: The current kernel virtual address.
34548 + * @page: The page when kmap'ing a single page.
34549 + * @bo_kmap_type: Type of bo_kmap.
34550 + *
34551 + * Object describing a kernel mapping. Since a TTM bo may be located
34552 + * in various memory types with various caching policies, the
34553 + * mapping can either be an ioremap, a vmap, a kmap or part of a
34554 + * premapped region.
34555 + */
34556 +
34557 +struct ttm_bo_kmap_obj {
34558 +       void *virtual;
34559 +       struct page *page;
34560 +       enum {
34561 +               ttm_bo_map_iomap,
34562 +               ttm_bo_map_vmap,
34563 +               ttm_bo_map_kmap,
34564 +               ttm_bo_map_premapped,
34565 +       } bo_kmap_type;
34566 +};
34567 +
34568 +/**
34569 + * ttm_bo_reference - reference a struct ttm_buffer_object
34570 + *
34571 + * @bo: The buffer object.
34572 + *
34573 + * Returns a refcounted pointer to a buffer object.
34574 + */
34575 +
34576 +static inline struct ttm_buffer_object *ttm_bo_reference(
34577 +                                       struct ttm_buffer_object *bo)
34578 +{
34579 +       kref_get(&bo->kref);
34580 +       return bo;
34581 +}
34582 +
34583 +/**
34584 + * ttm_bo_wait - wait for buffer idle.
34585 + *
34586 + * @bo:  The buffer object.
34587 + * @interruptible:  Use interruptible wait.
34588 + * @no_wait:  Return immediately if buffer is busy.
34589 + *
34590 + * This function must be called with the bo::mutex held, and makes
34591 + * sure any previous rendering to the buffer is completed.
34592 + * Note: It might be necessary to block validations before the
34593 + * wait by reserving the buffer.
34594 + * Returns -EBUSY if no_wait is true and the buffer is busy.
34595 + * Returns -ERESTART if interrupted by a signal.
34596 + */
34597 +extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
34598 +                      bool interruptible, bool no_wait);
34599 +/**
34600 + * ttm_buffer_object_validate
34601 + *
34602 + * @bo: The buffer object.
34603 + * @interruptible: Sleep interruptible if sleeping.
34604 + * @no_wait: Return immediately if the buffer is busy.
34605 + *
34606 + * Changes placement and caching policy of the buffer object
34607 + * according to bo::proposed_flags.
34608 + * Returns
34609 + * -EINVAL on invalid proposed_flags.
34610 + * -ENOMEM on out-of-memory condition.
34611 + * -EBUSY if no_wait is true and buffer busy.
34612 + * -ERESTART if interrupted by a signal.
34613 + */
34614 +extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
34615 +                                     bool interruptible, bool no_wait);
34616 +/**
34617 + * ttm_bo_unref
34618 + *
34619 + * @bo: The buffer object.
34620 + *
34621 + * Unreference and clear a pointer to a buffer object.
34622 + */
34623 +extern void ttm_bo_unref(struct ttm_buffer_object **bo);
34624 +
34625 +/**
34626 + * ttm_bo_synccpu_write_grab
34627 + *
34628 + * @bo: The buffer object:
34629 + * @no_wait: Return immediately if buffer is busy.
34630 + *
34631 + * Synchronizes a buffer object for CPU RW access. This means
34632 + * blocking command submission that affects the buffer and
34633 + * waiting for buffer idle. This lock is recursive.
34634 + * Returns
34635 + * -EBUSY if the buffer is busy and no_wait is true.
34636 + * -ERESTART if interrupted by a signal.
34637 + */
34638 +
34639 +extern int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo,
34640 +                                    bool no_wait);
34641 +/**
34642 + * ttm_bo_synccpu_write_release:
34643 + *
34644 + * @bo : The buffer object.
34645 + *
34646 + * Releases a synccpu lock.
34647 + */
34648 +extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
34649 +
34650 +/**
34651 + * ttm_buffer_object_init
34652 + *
34653 + * @bdev: Pointer to a ttm_bo_device struct.
34654 + * @bo: Pointer to a ttm_buffer_object to be initialized.
34655 + * @size: Requested size of buffer object.
34656 + * @type: Requested type of buffer object.
34657 + * @flags: Initial placement flags.
34658 + * @page_alignment: Data alignment in pages.
34659 + * @buffer_start: Virtual address of user space data backing a
34660 + * user buffer object.
34661 + * @interruptible: If needing to sleep to wait for GPU resources,
34662 + * sleep interruptible.
34663 + * @persistant_swap_storage: Usually the swap storage is deleted for buffers
34664 + * pinned in physical memory. If this behaviour is not desired, this member
34665 + * holds a pointer to a persistant shmem object. Typically, this would
34666 + * point to the shmem object backing a GEM object if TTM is used to back a
34667 + * GEM user interface.
34668 + * @acc_size: Accounted size for this object.
34669 + * @destroy: Destroy function. Use NULL for kfree().
34670 + *
34671 + * This function initializes a pre-allocated struct ttm_buffer_object.
34672 + * As this object may be part of a larger structure, this function,
34673 + * together with the @destroy function,
34674 + * enables driver-specific objects derived from a ttm_buffer_object.
34675 + * On successful return, the object kref and list_kref are set to 1.
34676 + * Returns
34677 + * -ENOMEM: Out of memory.
34678 + * -EINVAL: Invalid placement flags.
34679 + * -ERESTART: Interrupted by signal while sleeping waiting for resources.
34680 + */
34681 +
34682 +extern int ttm_buffer_object_init(struct ttm_bo_device *bdev,
34683 +                                 struct ttm_buffer_object *bo,
34684 +                                 unsigned long size,
34685 +                                 enum ttm_bo_type type,
34686 +                                 uint32_t flags,
34687 +                                 uint32_t page_alignment,
34688 +                                 unsigned long buffer_start,
34689 +                                 bool interrubtible,
34690 +                                 struct file *persistant_swap_storage,
34691 +                                 size_t acc_size,
34692 +                                 void (*destroy) (struct ttm_buffer_object *));
34693 +/**
34694 + * ttm_bo_synccpu_object_init
34695 + *
34696 + * @bdev: Pointer to a ttm_bo_device struct.
34697 + * @bo: Pointer to a ttm_buffer_object to be initialized.
34698 + * @size: Requested size of buffer object.
34699 + * @type: Requested type of buffer object.
34700 + * @flags: Initial placement flags.
34701 + * @page_alignment: Data alignment in pages.
34702 + * @buffer_start: Virtual address of user space data backing a
34703 + * user buffer object.
34704 + * @interruptible: If needing to sleep while waiting for GPU resources,
34705 + * sleep interruptible.
34706 + * @persistant_swap_storage: Usually the swap storage is deleted for buffers
34707 + * pinned in physical memory. If this behaviour is not desired, this member
34708 + * holds a pointer to a persistant shmem object. Typically, this would
34709 + * point to the shmem object backing a GEM object if TTM is used to back a
34710 + * GEM user interface.
34711 + * @p_bo: On successful completion *p_bo points to the created object.
34712 + *
34713 + * This function allocates a ttm_buffer_object, and then calls
34714 + * ttm_buffer_object_init on that object.
34715 + * The destroy function is set to kfree().
34716 + * Returns
34717 + * -ENOMEM: Out of memory.
34718 + * -EINVAL: Invalid placement flags.
34719 + * -ERESTART: Interrupted by signal while waiting for resources.
34720 + */
34721 +
34722 +extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
34723 +                                   unsigned long size,
34724 +                                   enum ttm_bo_type type,
34725 +                                   uint32_t flags,
34726 +                                   uint32_t page_alignment,
34727 +                                   unsigned long buffer_start,
34728 +                                   bool interruptible,
34729 +                                   struct file *persistant_swap_storage,
34730 +                                   struct ttm_buffer_object **p_bo);
34731 +
34732 +/**
34733 + * ttm_bo_check_placement
34734 + *
34735 + * @bo: the buffer object.
34736 + * @set_flags: placement flags to set.
34737 + * @clr_flags: placement flags to clear.
34738 + *
34739 + * Performs minimal validity checking on an intended change of
34740 + * placement flags.
34741 + * Returns
34742 + * -EINVAL: Intended change is invalid or not allowed.
34743 + */
34744 +
34745 +extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
34746 +                                 uint32_t set_flags, uint32_t clr_flags);
34747 +
34748 +/**
34749 + * ttm_bo_init_mm
34750 + *
34751 + * @bdev: Pointer to a ttm_bo_device struct.
34752 + * @mem_type: The memory type.
34753 + * @p_offset: offset for managed area in pages.
34754 + * @p_size: size managed area in pages.
34755 + *
34756 + * Initialize a manager for a given memory type.
34757 + * Note: if part of driver firstopen, it must be protected from a
34758 + * potentially racing lastclose.
34759 + * Returns:
34760 + * -EINVAL: invalid size or memory type.
34761 + * -ENOMEM: Not enough memory.
34762 + * May also return driver-specified errors.
34763 + */
34764 +
34765 +extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
34766 +                         unsigned long p_offset, unsigned long p_size);
34767 +/**
34768 + * ttm_bo_clean_mm
34769 + *
34770 + * @bdev: Pointer to a ttm_bo_device struct.
34771 + * @mem_type: The memory type.
34772 + *
34773 + * Take down a manager for a given memory type after first walking
34774 + * the LRU list to evict any buffers left alive.
34775 + *
34776 + * Normally, this function is part of lastclose() or unload(), and at that
34777 + * point there shouldn't be any buffers left created by user-space, since
34778 + * there should've been removed by the file descriptor release() method.
34779 + * However, before this function is run, make sure to signal all sync objects,
34780 + * and verify that the delayed delete queue is empty. The driver must also
34781 + * make sure that there are no NO_EVICT buffers present in this memory type
34782 + * when the call is made.
34783 + *
34784 + * If this function is part of a VT switch, the caller must make sure that
34785 + * there are no appications currently validating buffers before this
34786 + * function is called. The caller can do that by first taking the
34787 + * struct ttm_bo_device::ttm_lock in write mode.
34788 + *
34789 + * Returns:
34790 + * -EINVAL: invalid or uninitialized memory type.
34791 + * -EBUSY: There are still buffers left in this memory type.
34792 + */
34793 +
34794 +extern int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type);
34795 +
34796 +/**
34797 + * ttm_bo_evict_mm
34798 + *
34799 + * @bdev: Pointer to a ttm_bo_device struct.
34800 + * @mem_type: The memory type.
34801 + *
34802 + * Evicts all buffers on the lru list of the memory type.
34803 + * This is normally part of a VT switch or an
34804 + * out-of-memory-space-due-to-fragmentation handler.
34805 + * The caller must make sure that there are no other processes
34806 + * currently validating buffers, and can do that by taking the
34807 + * struct ttm_bo_device::ttm_lock in write mode.
34808 + *
34809 + * Returns:
34810 + * -EINVAL: Invalid or uninitialized memory type.
34811 + * -ERESTART: The call was interrupted by a signal while waiting to
34812 + * evict a buffer.
34813 + */
34814 +
34815 +extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type);
34816 +
34817 +/**
34818 + * ttm_kmap_obj_virtual
34819 + *
34820 + * @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap.
34821 + * @is_iomem: Pointer to an integer that on return indicates 1 if the
34822 + * virtual map is io memory, 0 if normal memory.
34823 + *
34824 + * Returns the virtual address of a buffer object area mapped by ttm_bo_kmap.
34825 + * If *is_iomem is 1 on return, the virtual address points to an io memory area,
34826 + * that should strictly be accessed by the iowriteXX() and similar functions.
34827 + */
34828 +
34829 +static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map,
34830 +                                        bool *is_iomem)
34831 +{
34832 +       *is_iomem = (map->bo_kmap_type == ttm_bo_map_iomap ||
34833 +                    map->bo_kmap_type == ttm_bo_map_premapped);
34834 +       return map->virtual;
34835 +}
34836 +
34837 +/**
34838 + * ttm_bo_kmap
34839 + *
34840 + * @bo: The buffer object.
34841 + * @start_page: The first page to map.
34842 + * @num_pages: Number of pages to map.
34843 + * @map: pointer to a struct ttm_bo_kmap_obj representing the map.
34844 + *
34845 + * Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the
34846 + * data in the buffer object. The ttm_kmap_obj_virtual function can then be
34847 + * used to obtain a virtual address to the data.
34848 + *
34849 + * Returns
34850 + * -ENOMEM: Out of memory.
34851 + * -EINVAL: Invalid range.
34852 + */
34853 +
34854 +extern int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page,
34855 +                      unsigned long num_pages, struct ttm_bo_kmap_obj *map);
34856 +
34857 +/**
34858 + * ttm_bo_kunmap
34859 + *
34860 + * @map: Object describing the map to unmap.
34861 + *
34862 + * Unmaps a kernel map set up by ttm_bo_kmap.
34863 + */
34864 +
34865 +extern void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);
34866 +
34867 +#if 0
34868 +#endif
34869 +
34870 +/**
34871 + * ttm_fbdev_mmap - mmap fbdev memory backed by a ttm buffer object.
34872 + *
34873 + * @vma:       vma as input from the fbdev mmap method.
34874 + * @bo:        The bo backing the address space. The address space will
34875 + * have the same size as the bo, and start at offset 0.
34876 + *
34877 + * This function is intended to be called by the fbdev mmap method
34878 + * if the fbdev address space is to be backed by a bo.
34879 + */
34880 +
34881 +extern int ttm_fbdev_mmap(struct vm_area_struct *vma,
34882 +                         struct ttm_buffer_object *bo);
34883 +
34884 +/**
34885 + * ttm_bo_mmap - mmap out of the ttm device address space.
34886 + *
34887 + * @filp:      filp as input from the mmap method.
34888 + * @vma:       vma as input from the mmap method.
34889 + * @bdev:      Pointer to the ttm_bo_device with the address space manager.
34890 + *
34891 + * This function is intended to be called by the device mmap method.
34892 + * if the device address space is to be backed by the bo manager.
34893 + */
34894 +
34895 +extern int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
34896 +                      struct ttm_bo_device *bdev);
34897 +
34898 +/**
34899 + * ttm_bo_io
34900 + *
34901 + * @bdev:      Pointer to the struct ttm_bo_device.
34902 + * @filp:      Pointer to the struct file attempting to read / write.
34903 + * @wbuf:      User-space pointer to address of buffer to write. NULL on read.
34904 + * @rbuf:      User-space pointer to address of buffer to read into.
34905 + *            Null on write.
34906 + * @count:     Number of bytes to read / write.
34907 + * @f_pos:     Pointer to current file position.
34908 + * @write:     1 for read, 0 for write.
34909 + *
34910 + * This function implements read / write into ttm buffer objects, and is
34911 + * intended to be called from the fops::read and fops::write method.
34912 + * Returns:
34913 + * See man (2) write, man(2) read. In particular, the function may
34914 + * return -EINTR if interrupted by a signal.
34915 + */
34916 +
34917 +extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
34918 +                        const char __user *wbuf, char __user *rbuf,
34919 +                        size_t count, loff_t *f_pos, bool write);
34920 +
34921 +extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
34922 +
34923 +#endif
34924 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_driver.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_driver.h
34925 new file mode 100644
34926 index 0000000..4991256
34927 --- /dev/null
34928 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_driver.h
34929 @@ -0,0 +1,862 @@
34930 +/**************************************************************************
34931 + *
34932 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
34933 + * All Rights Reserved.
34934 + * Copyright (c) 2009 Vmware, Inc., Palo Alto, CA., USA
34935 + * All Rights Reserved.
34936 + *
34937 + * This program is free software; you can redistribute it and/or modify it
34938 + * under the terms and conditions of the GNU General Public License,
34939 + * version 2, as published by the Free Software Foundation.
34940 + *
34941 + * This program is distributed in the hope it will be useful, but WITHOUT
34942 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34943 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
34944 + * more details.
34945 + *
34946 + * You should have received a copy of the GNU General Public License along with
34947 + * this program; if not, write to the Free Software Foundation, Inc., 
34948 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
34949 + *
34950 + **************************************************************************/
34951 +/*
34952 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
34953 + */
34954 +#ifndef _TTM_BO_DRIVER_H_
34955 +#define _TTM_BO_DRIVER_H_
34956 +
34957 +#include "ttm_bo_api.h"
34958 +#include "ttm_memory.h"
34959 +#include <drm/drm_mm.h>
34960 +#include "linux/workqueue.h"
34961 +#include "linux/fs.h"
34962 +#include "linux/spinlock.h"
34963 +
34964 +struct ttm_backend;
34965 +
34966 +struct ttm_backend_func {
34967 +       /**
34968 +        * struct ttm_backend_func member populate
34969 +        *
34970 +        * @backend: Pointer to a struct ttm_backend.
34971 +        * @num_pages: Number of pages to populate.
34972 +        * @pages: Array of pointers to ttm pages.
34973 +        * @dummy_read_page: Page to be used instead of NULL pages in the
34974 +        * array @pages.
34975 +        *
34976 +        * Populate the backend with ttm pages. Depending on the backend,
34977 +        * it may or may not copy the @pages array.
34978 +        */
34979 +       int (*populate) (struct ttm_backend *backend,
34980 +                        unsigned long num_pages, struct page **pages,
34981 +                        struct page *dummy_read_page);
34982 +       /**
34983 +        * struct ttm_backend_func member clear
34984 +        *
34985 +        * @backend: Pointer to a struct ttm_backend.
34986 +        *
34987 +        * This is an "unpopulate" function. Release all resources
34988 +        * allocated with populate.
34989 +        */
34990 +       void (*clear) (struct ttm_backend *backend);
34991 +
34992 +       /**
34993 +        * struct ttm_backend_func member bind
34994 +        *
34995 +        * @backend: Pointer to a struct ttm_backend.
34996 +        * @bo_mem: Pointer to a struct ttm_mem_reg describing the
34997 +        * memory type and location for binding.
34998 +        *
34999 +        * Bind the backend pages into the aperture in the location
35000 +        * indicated by @bo_mem. This function should be able to handle
35001 +        * differences between aperture- and system page sizes.
35002 +        */
35003 +       int (*bind) (struct ttm_backend *backend, struct ttm_mem_reg *bo_mem);
35004 +
35005 +       /**
35006 +        * struct ttm_backend_func member unbind
35007 +        *
35008 +        * @backend: Pointer to a struct ttm_backend.
35009 +        *
35010 +        * Unbind previously bound backend pages. This function should be
35011 +        * able to handle differences between aperture- and system page sizes.
35012 +        */
35013 +       int (*unbind) (struct ttm_backend *backend);
35014 +
35015 +       /**
35016 +        * struct ttm_backend_func member destroy
35017 +        *
35018 +        * @backend: Pointer to a struct ttm_backend.
35019 +        *
35020 +        * Destroy the backend.
35021 +        */
35022 +       void (*destroy) (struct ttm_backend *backend);
35023 +};
35024 +
35025 +/**
35026 + * struct ttm_backend
35027 + *
35028 + * @bdev: Pointer to a struct ttm_bo_device.
35029 + * @flags: For driver use.
35030 + * @func: Pointer to a struct ttm_backend_func that describes
35031 + * the backend methods.
35032 + *
35033 + */
35034 +
35035 +struct ttm_backend {
35036 +       struct ttm_bo_device *bdev;
35037 +       uint32_t flags;
35038 +       struct ttm_backend_func *func;
35039 +};
35040 +
35041 +#define TTM_PAGE_FLAG_VMALLOC         (1 << 0)
35042 +#define TTM_PAGE_FLAG_USER            (1 << 1)
35043 +#define TTM_PAGE_FLAG_USER_DIRTY      (1 << 2)
35044 +#define TTM_PAGE_FLAG_WRITE           (1 << 3)
35045 +#define TTM_PAGE_FLAG_SWAPPED         (1 << 4)
35046 +#define TTM_PAGE_FLAG_PERSISTANT_SWAP (1 << 5)
35047 +
35048 +enum ttm_caching_state {
35049 +       tt_uncached,
35050 +       tt_wc,
35051 +       tt_cached
35052 +};
35053 +
35054 +/**
35055 + * struct ttm_tt
35056 + *
35057 + * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL
35058 + * pointer.
35059 + * @pages: Array of pages backing the data.
35060 + * @first_himem_page: Himem pages are put last in the page array, which
35061 + * enables us to run caching attribute changes on only the first part
35062 + * of the page array containing lomem pages. This is the index of the
35063 + * first himem page.
35064 + * @last_lomem_page: Index of the last lomem page in the page array.
35065 + * @num_pages: Number of pages in the page array.
35066 + * @bdev: Pointer to the current struct ttm_bo_device.
35067 + * @be: Pointer to the ttm backend.
35068 + * @tsk: The task for user ttm.
35069 + * @start: virtual address for user ttm.
35070 + * @swap_storage: Pointer to shmem struct file for swap storage.
35071 + * @caching_state: The current caching state of the pages.
35072 + * @state: The current binding state of the pages.
35073 + *
35074 + * This is a structure holding the pages, caching- and aperture binding
35075 + * status for a buffer object that isn't backed by fixed (VRAM / AGP)
35076 + * memory.
35077 + */
35078 +
35079 +struct ttm_tt {
35080 +       struct page *dummy_read_page;
35081 +       struct page **pages;
35082 +       long first_himem_page;
35083 +       long last_lomem_page;
35084 +       uint32_t page_flags;
35085 +       unsigned long num_pages;
35086 +       struct ttm_bo_device *bdev;
35087 +       struct ttm_backend *be;
35088 +       struct task_struct *tsk;
35089 +       unsigned long start;
35090 +       struct file *swap_storage;
35091 +       enum ttm_caching_state caching_state;
35092 +       enum {
35093 +               tt_bound,
35094 +               tt_unbound,
35095 +               tt_unpopulated,
35096 +       } state;
35097 +};
35098 +
35099 +#define TTM_MEMTYPE_FLAG_FIXED         (1 << 0)        /* Fixed (on-card) PCI memory */
35100 +#define TTM_MEMTYPE_FLAG_MAPPABLE      (1 << 1)        /* Memory mappable */
35101 +#define TTM_MEMTYPE_FLAG_NEEDS_IOREMAP (1 << 2)        /* Fixed memory needs ioremap
35102 +                                                  before kernel access. */
35103 +#define TTM_MEMTYPE_FLAG_CMA           (1 << 3)        /* Can't map aperture */
35104 +
35105 +/**
35106 + * struct ttm_mem_type_manager
35107 + *
35108 + * @has_type: The memory type has been initialized.
35109 + * @use_type: The memory type is enabled.
35110 + * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory
35111 + * managed by this memory type.
35112 + * @gpu_offset: If used, the GPU offset of the first managed page of
35113 + * fixed memory or the first managed location in an aperture.
35114 + * @io_offset: The io_offset of the first managed page of IO memory or
35115 + * the first managed location in an aperture. For TTM_MEMTYPE_FLAG_CMA
35116 + * memory, this should be set to NULL.
35117 + * @io_size: The size of a managed IO region (fixed memory or aperture).
35118 + * @io_addr: Virtual kernel address if the io region is pre-mapped. For
35119 + * TTM_MEMTYPE_FLAG_NEEDS_IOREMAP there is no pre-mapped io map and
35120 + * @io_addr should be set to NULL.
35121 + * @size: Size of the managed region.
35122 + * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX,
35123 + * as defined in ttm_placement_common.h
35124 + * @default_caching: The default caching policy used for a buffer object
35125 + * placed in this memory type if the user doesn't provide one.
35126 + * @manager: The range manager used for this memory type. FIXME: If the aperture
35127 + * has a page size different from the underlying system, the granularity
35128 + * of this manager should take care of this. But the range allocating code
35129 + * in ttm_bo.c needs to be modified for this.
35130 + * @lru: The lru list for this memory type.
35131 + *
35132 + * This structure is used to identify and manage memory types for a device.
35133 + * It's set up by the ttm_bo_driver::init_mem_type method.
35134 + */
35135 +
35136 +struct ttm_mem_type_manager {
35137 +
35138 +       /*
35139 +        * No protection. Constant from start.
35140 +        */
35141 +
35142 +       bool has_type;
35143 +       bool use_type;
35144 +       uint32_t flags;
35145 +       unsigned long gpu_offset;
35146 +       unsigned long io_offset;
35147 +       unsigned long io_size;
35148 +       void *io_addr;
35149 +       uint64_t size;
35150 +       uint32_t available_caching;
35151 +       uint32_t default_caching;
35152 +
35153 +       /*
35154 +        * Protected by the bdev->lru_lock.
35155 +        * TODO: Consider one lru_lock per ttm_mem_type_manager.
35156 +        * Plays ill with list removal, though.
35157 +        */
35158 +
35159 +       struct drm_mm manager;
35160 +       struct list_head lru;
35161 +};
35162 +
35163 +/**
35164 + * struct ttm_bo_driver
35165 + *
35166 + * @mem_type_prio: Priority array of memory types to place a buffer object in
35167 + * if it fits without evicting buffers from any of these memory types.
35168 + * @mem_busy_prio: Priority array of memory types to place a buffer object in
35169 + * if it needs to evict buffers to make room.
35170 + * @num_mem_type_prio: Number of elements in the @mem_type_prio array.
35171 + * @num_mem_busy_prio: Number of elements in the @num_mem_busy_prio array.
35172 + * @create_ttm_backend_entry: Callback to create a struct ttm_backend.
35173 + * @invalidate_caches: Callback to invalidate read caches when a buffer object
35174 + * has been evicted.
35175 + * @init_mem_type: Callback to initialize a struct ttm_mem_type_manager
35176 + * structure.
35177 + * @evict_flags: Callback to obtain placement flags when a buffer is evicted.
35178 + * @move: Callback for a driver to hook in accelerated functions to move
35179 + * a buffer.
35180 + * If set to NULL, a potentially slow memcpy() move is used.
35181 + * @sync_obj_signaled: See ttm_fence_api.h
35182 + * @sync_obj_wait: See ttm_fence_api.h
35183 + * @sync_obj_flush: See ttm_fence_api.h
35184 + * @sync_obj_unref: See ttm_fence_api.h
35185 + * @sync_obj_ref: See ttm_fence_api.h
35186 + */
35187 +
35188 +struct ttm_bo_driver {
35189 +       const uint32_t *mem_type_prio;
35190 +       const uint32_t *mem_busy_prio;
35191 +       uint32_t num_mem_type_prio;
35192 +       uint32_t num_mem_busy_prio;
35193 +
35194 +       /**
35195 +        * struct ttm_bo_driver member create_ttm_backend_entry
35196 +        *
35197 +        * @bdev: The buffer object device.
35198 +        *
35199 +        * Create a driver specific struct ttm_backend.
35200 +        */
35201 +
35202 +       struct ttm_backend *(*create_ttm_backend_entry)
35203 +        (struct ttm_bo_device *bdev);
35204 +
35205 +       /**
35206 +        * struct ttm_bo_driver member invalidate_caches
35207 +        *
35208 +        * @bdev: the buffer object device.
35209 +        * @flags: new placement of the rebound buffer object.
35210 +        *
35211 +        * A previosly evicted buffer has been rebound in a
35212 +        * potentially new location. Tell the driver that it might
35213 +        * consider invalidating read (texture) caches on the next command
35214 +        * submission as a consequence.
35215 +        */
35216 +
35217 +       int (*invalidate_caches) (struct ttm_bo_device *bdev, uint32_t flags);
35218 +       int (*init_mem_type) (struct ttm_bo_device *bdev, uint32_t type,
35219 +                             struct ttm_mem_type_manager *man);
35220 +       /**
35221 +        * struct ttm_bo_driver member evict_flags:
35222 +        *
35223 +        * @bo: the buffer object to be evicted
35224 +        *
35225 +        * Return the bo flags for a buffer which is not mapped to the hardware.
35226 +        * These will be placed in proposed_flags so that when the move is
35227 +        * finished, they'll end up in bo->mem.flags
35228 +        */
35229 +
35230 +        uint32_t(*evict_flags) (struct ttm_buffer_object *bo);
35231 +       /**
35232 +        * struct ttm_bo_driver member move:
35233 +        *
35234 +        * @bo: the buffer to move
35235 +        * @evict: whether this motion is evicting the buffer from
35236 +        * the graphics address space
35237 +        * @interruptible: Use interruptible sleeps if possible when sleeping.
35238 +        * @no_wait: whether this should give up and return -EBUSY
35239 +        * if this move would require sleeping
35240 +        * @new_mem: the new memory region receiving the buffer
35241 +        *
35242 +        * Move a buffer between two memory regions.
35243 +        */
35244 +       int (*move) (struct ttm_buffer_object *bo,
35245 +                    bool evict, bool interruptible,
35246 +                    bool no_wait, struct ttm_mem_reg *new_mem);
35247 +
35248 +       /**
35249 +        * struct ttm_bo_driver_member verify_access
35250 +        *
35251 +        * @bo: Pointer to a buffer object.
35252 +        * @filp: Pointer to a struct file trying to access the object.
35253 +        *
35254 +        * Called from the map / write / read methods to verify that the
35255 +        * caller is permitted to access the buffer object.
35256 +        * This member may be set to NULL, which will refuse this kind of
35257 +        * access for all buffer objects.
35258 +        * This function should return 0 if access is granted, -EPERM otherwise.
35259 +        */
35260 +       int (*verify_access) (struct ttm_buffer_object *bo,
35261 +                             struct file *filp);
35262 +
35263 +       /**
35264 +        * In case a driver writer dislikes the TTM fence objects,
35265 +        * the driver writer can replace those with sync objects of
35266 +        * his / her own. If it turns out that no driver writer is
35267 +        * using these. I suggest we remove these hooks and plug in
35268 +        * fences directly. The bo driver needs the following functionality:
35269 +        * See the corresponding functions in the fence object API
35270 +        * documentation.
35271 +        */
35272 +
35273 +       bool (*sync_obj_signaled) (void *sync_obj, void *sync_arg);
35274 +       int (*sync_obj_wait) (void *sync_obj, void *sync_arg,
35275 +                             bool lazy, bool interruptible);
35276 +       int (*sync_obj_flush) (void *sync_obj, void *sync_arg);
35277 +       void (*sync_obj_unref) (void **sync_obj);
35278 +       void *(*sync_obj_ref) (void *sync_obj);
35279 +};
35280 +
35281 +#define TTM_NUM_MEM_TYPES 11
35282 +
35283 +#define TTM_BO_PRIV_FLAG_EVICTED  (1 << 0)     /* Buffer object is evicted. */
35284 +#define TTM_BO_PRIV_FLAG_MOVING   (1 << 1)     /* Buffer object is moving
35285 +                                                  and needs idling before
35286 +                                                  CPU mapping */
35287 +/**
35288 + * struct ttm_bo_device - Buffer object driver device-specific data.
35289 + *
35290 + * @mem_glob: Pointer to a struct ttm_mem_global object for accounting.
35291 + * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver.
35292 + * @count: Current number of buffer object.
35293 + * @pages: Current number of pinned pages.
35294 + * @dummy_read_page: Pointer to a dummy page used for mapping requests
35295 + * of unpopulated pages.
35296 + * @shrink: A shrink callback object used for buffre object swap.
35297 + * @ttm_bo_extra_size: Extra size (sizeof(struct ttm_buffer_object) excluded)
35298 + * used by a buffer object. This is excluding page arrays and backing pages.
35299 + * @ttm_bo_size: This is @ttm_bo_extra_size + sizeof(struct ttm_buffer_object).
35300 + * @man: An array of mem_type_managers.
35301 + * @addr_space_mm: Range manager for the device address space.
35302 + * lru_lock: Spinlock that protects the buffer+device lru lists and
35303 + * ddestroy lists.
35304 + * @nice_mode: Try nicely to wait for buffer idle when cleaning a manager.
35305 + * If a GPU lockup has been detected, this is forced to 0.
35306 + * @dev_mapping: A pointer to the struct address_space representing the
35307 + * device address space.
35308 + * @wq: Work queue structure for the delayed delete workqueue.
35309 + *
35310 + */
35311 +
35312 +struct ttm_bo_device {
35313 +
35314 +       /*
35315 +        * Constant after bo device init / atomic.
35316 +        */
35317 +
35318 +       struct ttm_mem_global *mem_glob;
35319 +       struct ttm_bo_driver *driver;
35320 +       struct page *dummy_read_page;
35321 +       struct ttm_mem_shrink shrink;
35322 +
35323 +       size_t ttm_bo_extra_size;
35324 +       size_t ttm_bo_size;
35325 +
35326 +       rwlock_t vm_lock;
35327 +       /*
35328 +        * Protected by the vm lock.
35329 +        */
35330 +       struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
35331 +       struct rb_root addr_space_rb;
35332 +       struct drm_mm addr_space_mm;
35333 +
35334 +       /*
35335 +        * Might want to change this to one lock per manager.
35336 +        */
35337 +       spinlock_t lru_lock;
35338 +       /*
35339 +        * Protected by the lru lock.
35340 +        */
35341 +       struct list_head ddestroy;
35342 +       struct list_head swap_lru;
35343 +
35344 +       /*
35345 +        * Protected by load / firstopen / lastclose /unload sync.
35346 +        */
35347 +
35348 +       bool nice_mode;
35349 +       struct address_space *dev_mapping;
35350 +
35351 +       /*
35352 +        * Internal protection.
35353 +        */
35354 +
35355 +       struct delayed_work wq;
35356 +};
35357 +
35358 +/**
35359 + * ttm_flag_masked
35360 + *
35361 + * @old: Pointer to the result and original value.
35362 + * @new: New value of bits.
35363 + * @mask: Mask of bits to change.
35364 + *
35365 + * Convenience function to change a number of bits identified by a mask.
35366 + */
35367 +
35368 +static inline uint32_t
35369 +ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask)
35370 +{
35371 +       *old ^= (*old ^ new) & mask;
35372 +       return *old;
35373 +}
35374 +
35375 +/**
35376 + * ttm_tt_create
35377 + *
35378 + * @bdev: pointer to a struct ttm_bo_device:
35379 + * @size: Size of the data needed backing.
35380 + * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags.
35381 + * @dummy_read_page: See struct ttm_bo_device.
35382 + *
35383 + * Create a struct ttm_tt to back data with system memory pages.
35384 + * No pages are actually allocated.
35385 + * Returns:
35386 + * NULL: Out of memory.
35387 + */
35388 +extern struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev,
35389 +                                   unsigned long size,
35390 +                                   uint32_t page_flags,
35391 +                                   struct page *dummy_read_page);
35392 +
35393 +/**
35394 + * ttm_tt_set_user:
35395 + *
35396 + * @ttm: The struct ttm_tt to populate.
35397 + * @tsk: A struct task_struct for which @start is a valid user-space address.
35398 + * @start: A valid user-space address.
35399 + * @num_pages: Size in pages of the user memory area.
35400 + *
35401 + * Populate a struct ttm_tt with a user-space memory area after first pinning
35402 + * the pages backing it.
35403 + * Returns:
35404 + * !0: Error.
35405 + */
35406 +
35407 +extern int ttm_tt_set_user(struct ttm_tt *ttm,
35408 +                          struct task_struct *tsk,
35409 +                          unsigned long start, unsigned long num_pages);
35410 +
35411 +/**
35412 + * ttm_ttm_bind:
35413 + *
35414 + * @ttm: The struct ttm_tt containing backing pages.
35415 + * @bo_mem: The struct ttm_mem_reg identifying the binding location.
35416 + *
35417 + * Bind the pages of @ttm to an aperture location identified by @bo_mem
35418 + */
35419 +extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
35420 +
35421 +/**
35422 + * ttm_ttm_destroy:
35423 + *
35424 + * @ttm: The struct ttm_tt.
35425 + *
35426 + * Unbind, unpopulate and destroy a struct ttm_tt.
35427 + */
35428 +extern void ttm_tt_destroy(struct ttm_tt *ttm);
35429 +
35430 +/**
35431 + * ttm_ttm_unbind:
35432 + *
35433 + * @ttm: The struct ttm_tt.
35434 + *
35435 + * Unbind a struct ttm_tt.
35436 + */
35437 +extern void ttm_tt_unbind(struct ttm_tt *ttm);
35438 +
35439 +/**
35440 + * ttm_ttm_destroy:
35441 + *
35442 + * @ttm: The struct ttm_tt.
35443 + * @index: Index of the desired page.
35444 + *
35445 + * Return a pointer to the struct page backing @ttm at page
35446 + * index @index. If the page is unpopulated, one will be allocated to
35447 + * populate that index.
35448 + *
35449 + * Returns:
35450 + * NULL on OOM.
35451 + */
35452 +extern struct page *ttm_tt_get_page(struct ttm_tt *ttm, int index);
35453 +
35454 +/**
35455 + * ttm_tt_cache_flush:
35456 + *
35457 + * @pages: An array of pointers to struct page:s to flush.
35458 + * @num_pages: Number of pages to flush.
35459 + *
35460 + * Flush the data of the indicated pages from the cpu caches.
35461 + * This is used when changing caching attributes of the pages from
35462 + * cache-coherent.
35463 + */
35464 +extern void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages);
35465 +
35466 +/**
35467 + * ttm_tt_set_placement_caching:
35468 + *
35469 + * @ttm A struct ttm_tt the backing pages of which will change caching policy.
35470 + * @placement: Flag indicating the desired caching policy.
35471 + *
35472 + * This function will change caching policy of any default kernel mappings of
35473 + * the pages backing @ttm. If changing from cached to uncached or
35474 + * write-combined, all CPU caches will first be flushed to make sure the
35475 + * data of the pages hit RAM. This function may be very costly as it involves
35476 + *  global TLB and cache flushes and potential page splitting / combining.
35477 + */
35478 +extern int ttm_tt_set_placement_caching(struct ttm_tt *ttm,
35479 +                                       uint32_t placement);
35480 +extern int ttm_tt_swapout(struct ttm_tt *ttm,
35481 +                         struct file *persistant_swap_storage);
35482 +
35483 +/*
35484 + * ttm_bo.c
35485 + */
35486 +
35487 +/**
35488 + * ttm_mem_reg_is_pci
35489 + *
35490 + * @bdev: Pointer to a struct ttm_bo_device.
35491 + * @mem: A valid struct ttm_mem_reg.
35492 + *
35493 + * Returns true if the memory described by @mem is PCI memory,
35494 + * false otherwise.
35495 + */
35496 +extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev,
35497 +                                  struct ttm_mem_reg *mem);
35498 +
35499 +/**
35500 + * ttm_bo_mem_space
35501 + *
35502 + * @bo: Pointer to a struct ttm_buffer_object. the data of which
35503 + * we want to allocate space for.
35504 + * @mem: A struct ttm_mem_reg with the struct ttm_mem_reg::proposed_flags set
35505 + * up.
35506 + * @interruptible: Sleep interruptible when sliping.
35507 + * @no_wait: Don't sleep waiting for space to become available.
35508 + *
35509 + * Allocate memory space for the buffer object pointed to by @bo, using
35510 + * the placement flags in @mem, potentially evicting other idle buffer objects.
35511 + * This function may sleep while waiting for space to become available.
35512 + * Returns:
35513 + * -EBUSY: No space available (only if no_wait == 1).
35514 + * -ENOMEM: Could not allocate memory for the buffer object, either due to
35515 + * fragmentation or concurrent allocators.
35516 + * -ERESTART: An interruptible sleep was interrupted by a signal.
35517 + */
35518 +extern int ttm_bo_mem_space(struct ttm_buffer_object *bo,
35519 +                           struct ttm_mem_reg *mem,
35520 +                           bool interruptible, bool no_wait);
35521 +/**
35522 + * ttm_bo_wait_for_cpu
35523 + *
35524 + * @bo: Pointer to a struct ttm_buffer_object.
35525 + * @no_wait: Don't sleep while waiting.
35526 + *
35527 + * Wait until a buffer object is no longer sync'ed for CPU access.
35528 + * Returns:
35529 + * -EBUSY: Buffer object was sync'ed for CPU access. (only if no_wait == 1).
35530 + * -ERESTART: An interruptible sleep was interrupted by a signal.
35531 + */
35532 +
35533 +extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait);
35534 +
35535 +/**
35536 + * ttm_bo_pci_offset - Get the PCI offset for the buffer object memory.
35537 + *
35538 + * @bo Pointer to a struct ttm_buffer_object.
35539 + * @bus_base On return the base of the PCI region
35540 + * @bus_offset On return the byte offset into the PCI region
35541 + * @bus_size On return the byte size of the buffer object or zero if
35542 + * the buffer object memory is not accessible through a PCI region.
35543 + *
35544 + * Returns:
35545 + * -EINVAL if the buffer object is currently not mappable.
35546 + * 0 otherwise.
35547 + */
35548 +
35549 +extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev,
35550 +                            struct ttm_mem_reg *mem,
35551 +                            unsigned long *bus_base,
35552 +                            unsigned long *bus_offset,
35553 +                            unsigned long *bus_size);
35554 +
35555 +extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
35556 +
35557 +/**
35558 + * ttm_bo_device_init
35559 + *
35560 + * @bdev: A pointer to a struct ttm_bo_device to initialize.
35561 + * @mem_global: A pointer to an initialized struct ttm_mem_global.
35562 + * @driver: A pointer to a struct ttm_bo_driver set up by the caller.
35563 + * @file_page_offset: Offset into the device address space that is available
35564 + * for buffer data. This ensures compatibility with other users of the
35565 + * address space.
35566 + *
35567 + * Initializes a struct ttm_bo_device:
35568 + * Returns:
35569 + * !0: Failure.
35570 + */
35571 +extern int ttm_bo_device_init(struct ttm_bo_device *bdev,
35572 +                             struct ttm_mem_global *mem_glob,
35573 +                             struct ttm_bo_driver *driver,
35574 +                             uint64_t file_page_offset);
35575 +
35576 +/**
35577 + * ttm_bo_reserve:
35578 + *
35579 + * @bo: A pointer to a struct ttm_buffer_object.
35580 + * @interruptible: Sleep interruptible if waiting.
35581 + * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
35582 + * @use_sequence: If @bo is already reserved, Only sleep waiting for
35583 + * it to become unreserved if @sequence < (@bo)->sequence.
35584 + *
35585 + * Locks a buffer object for validation. (Or prevents other processes from
35586 + * locking it for validation) and removes it from lru lists, while taking
35587 + * a number of measures to prevent deadlocks.
35588 + *
35589 + * Deadlocks may occur when two processes try to reserve multiple buffers in
35590 + * different order, either by will or as a result of a buffer being evicted
35591 + * to make room for a buffer already reserved. (Buffers are reserved before
35592 + * they are evicted). The following algorithm prevents such deadlocks from
35593 + * occuring:
35594 + * 1) Buffers are reserved with the lru spinlock held. Upon successful
35595 + * reservation they are removed from the lru list. This stops a reserved buffer
35596 + * from being evicted. However the lru spinlock is released between the time
35597 + * a buffer is selected for eviction and the time it is reserved.
35598 + * Therefore a check is made when a buffer is reserved for eviction, that it
35599 + * is still the first buffer in the lru list, before it is removed from the
35600 + * list. @check_lru == 1 forces this check. If it fails, the function returns
35601 + * -EINVAL, and the caller should then choose a new buffer to evict and repeat
35602 + * the procedure.
35603 + * 2) Processes attempting to reserve multiple buffers other than for eviction,
35604 + * (typically execbuf), should first obtain a unique 32-bit
35605 + * validation sequence number,
35606 + * and call this function with @use_sequence == 1 and @sequence == the unique
35607 + * sequence number. If upon call of this function, the buffer object is already
35608 + * reserved, the validation sequence is checked against the validation
35609 + * sequence of the process currently reserving the buffer,
35610 + * and if the current validation sequence is greater than that of the process
35611 + * holding the reservation, the function returns -EAGAIN. Otherwise it sleeps
35612 + * waiting for the buffer to become unreserved, after which it retries
35613 + * reserving. The caller should, when receiving an -EAGAIN error
35614 + * release all its buffer reservations, wait for @bo to become unreserved, and
35615 + * then rerun the validation with the same validation sequence. This procedure
35616 + * will always guarantee that the process with the lowest validation sequence
35617 + * will eventually succeed, preventing both deadlocks and starvation.
35618 + *
35619 + * Returns:
35620 + * -EAGAIN: The reservation may cause a deadlock. Release all buffer
35621 + *  reservations, wait for @bo to become unreserved and try again.
35622 + *  (only if use_sequence == 1).
35623 + *  -ERESTART: A wait for the buffer to become unreserved was interrupted by
35624 + * a signal. Release all buffer reservations and return to user-space.
35625 + */
35626 +extern int ttm_bo_reserve(struct ttm_buffer_object *bo,
35627 +                         bool interruptible,
35628 +                         bool no_wait, bool use_sequence, uint32_t sequence);
35629 +
35630 +/**
35631 + * ttm_bo_unreserve
35632 + *
35633 + * @bo: A pointer to a struct ttm_buffer_object.
35634 + *
35635 + * Unreserve a previous reservation of @bo.
35636 + */
35637 +extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
35638 +
35639 +/**
35640 + * ttm_bo_wait_unreserved
35641 + *
35642 + * @bo: A pointer to a struct ttm_buffer_object.
35643 + *
35644 + * Wait for a struct ttm_buffer_object to become unreserved.
35645 + * This is typically used in the execbuf code to relax cpu-usage when
35646 + * a potential deadlock condition backoff.
35647 + */
35648 +extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo,
35649 +                                 bool interruptible);
35650 +
35651 +/**
35652 + * ttm_bo_block_reservation
35653 + *
35654 + * @bo: A pointer to a struct ttm_buffer_object.
35655 + * @interruptible: Use interruptible sleep when waiting.
35656 + * @no_wait: Don't sleep, but rather return -EBUSY.
35657 + *
35658 + * Block reservation for validation by simply reserving the buffer.
35659 + * This is intended for single buffer use only without eviction,
35660 + * and thus needs no deadlock protection.
35661 + *
35662 + * Returns:
35663 + * -EBUSY: If no_wait == 1 and the buffer is already reserved.
35664 + * -ERESTART: If interruptible == 1 and the process received a
35665 + *           signal while sleeping.
35666 + */
35667 +extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo,
35668 +                                   bool interruptible, bool no_wait);
35669 +
35670 +/**
35671 + * ttm_bo_unblock_reservation
35672 + *
35673 + * @bo: A pointer to a struct ttm_buffer_object.
35674 + *
35675 + * Unblocks reservation leaving lru lists untouched.
35676 + */
35677 +extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo);
35678 +
35679 +/*
35680 + * ttm_bo_util.c
35681 + */
35682 +
35683 +/**
35684 + * ttm_bo_move_ttm
35685 + *
35686 + * @bo: A pointer to a struct ttm_buffer_object.
35687 + * @evict: 1: This is an eviction. Don't try to pipeline.
35688 + * @no_wait: Never sleep, but rather return with -EBUSY.
35689 + * @new_mem: struct ttm_mem_reg indicating where to move.
35690 + *
35691 + * Optimized move function for a buffer object with both old and
35692 + * new placement backed by a TTM. The function will, if successful,
35693 + * free any old aperture space, and set (@new_mem)->mm_node to NULL,
35694 + * and update the (@bo)->mem placement flags. If unsuccessful, the old
35695 + * data remains untouched, and it's up to the caller to free the
35696 + * memory space indicated by @new_mem.
35697 + * Returns:
35698 + * !0: Failure.
35699 + */
35700 +
35701 +extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
35702 +                          bool evict,
35703 +                          bool no_wait,
35704 +                          struct ttm_mem_reg *new_mem);
35705 +
35706 +/**
35707 + * ttm_bo_move_memcpy
35708 + *
35709 + * @bo: A pointer to a struct ttm_buffer_object.
35710 + * @evict: 1: This is an eviction. Don't try to pipeline.
35711 + * @no_wait: Never sleep, but rather return with -EBUSY.
35712 + * @new_mem: struct ttm_mem_reg indicating where to move.
35713 + *
35714 + * Fallback move function for a mappable buffer object in mappable memory.
35715 + * The function will, if successful,
35716 + * free any old aperture space, and set (@new_mem)->mm_node to NULL,
35717 + * and update the (@bo)->mem placement flags. If unsuccessful, the old
35718 + * data remains untouched, and it's up to the caller to free the
35719 + * memory space indicated by @new_mem.
35720 + * Returns:
35721 + * !0: Failure.
35722 + */
35723 +
35724 +extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
35725 +                             bool evict,
35726 +                             bool no_wait,
35727 +                             struct ttm_mem_reg *new_mem);
35728 +
35729 +/**
35730 + * ttm_bo_free_old_node
35731 + *
35732 + * @bo: A pointer to a struct ttm_buffer_object.
35733 + *
35734 + * Utility function to free an old placement after a successful move.
35735 + */
35736 +extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo);
35737 +
35738 +/**
35739 + * ttm_bo_move_accel_cleanup.
35740 + *
35741 + * @bo: A pointer to a struct ttm_buffer_object.
35742 + * @sync_obj: A sync object that signals when moving is complete.
35743 + * @sync_obj_arg: An argument to pass to the sync object idle / wait
35744 + * functions.
35745 + * @evict: This is an evict move. Don't return until the buffer is idle.
35746 + * @no_wait: Never sleep, but rather return with -EBUSY.
35747 + * @new_mem: struct ttm_mem_reg indicating where to move.
35748 + *
35749 + * Accelerated move function to be called when an accelerated move
35750 + * has been scheduled. The function will create a new temporary buffer object
35751 + * representing the old placement, and put the sync object on both buffer
35752 + * objects. After that the newly created buffer object is unref'd to be
35753 + * destroyed when the move is complete. This will help pipeline
35754 + * buffer moves.
35755 + */
35756 +
35757 +extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
35758 +                                    void *sync_obj,
35759 +                                    void *sync_obj_arg,
35760 +                                    bool evict, bool no_wait,
35761 +                                    struct ttm_mem_reg *new_mem);
35762 +/**
35763 + * ttm_io_prot
35764 + *
35765 + * @c_state: Caching state.
35766 + * @tmp: Page protection flag for a normal, cached mapping.
35767 + *
35768 + * Utility function that returns the pgprot_t that should be used for
35769 + * setting up a PTE with the caching model indicated by @c_state.
35770 + */
35771 +extern pgprot_t ttm_io_prot(enum ttm_caching_state c_state, pgprot_t tmp);
35772 +
35773 +#if (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
35774 +#define TTM_HAS_AGP
35775 +#include <linux/agp_backend.h>
35776 +
35777 +/**
35778 + * ttm_agp_backend_init
35779 + *
35780 + * @bdev: Pointer to a struct ttm_bo_device.
35781 + * @bridge: The agp bridge this device is sitting on.
35782 + *
35783 + * Create a TTM backend that uses the indicated AGP bridge as an aperture
35784 + * for TT memory. This function uses the linux agpgart interface to
35785 + * bind and unbind memory backing a ttm_tt.
35786 + */
35787 +extern struct ttm_backend *ttm_agp_backend_init(struct ttm_bo_device *bdev,
35788 +                                               struct agp_bridge_data *bridge);
35789 +#endif
35790 +
35791 +#endif
35792 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_util.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_util.c
35793 new file mode 100644
35794 index 0000000..ce8eaed
35795 --- /dev/null
35796 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_util.c
35797 @@ -0,0 +1,546 @@
35798 +/**************************************************************************
35799 + *
35800 + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
35801 + * All Rights Reserved.
35802 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
35803 + * All Rights Reserved.
35804 + *
35805 + * This program is free software; you can redistribute it and/or modify it
35806 + * under the terms and conditions of the GNU General Public License,
35807 + * version 2, as published by the Free Software Foundation.
35808 + *
35809 + * This program is distributed in the hope it will be useful, but WITHOUT
35810 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35811 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
35812 + * more details.
35813 + *
35814 + * You should have received a copy of the GNU General Public License along with
35815 + * this program; if not, write to the Free Software Foundation, Inc., 
35816 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
35817 + *
35818 + **************************************************************************/
35819 +/*
35820 + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
35821 + */
35822 +
35823 +#include "ttm_bo_driver.h"
35824 +#include "ttm_placement_common.h"
35825 +#include "ttm_pat_compat.h"
35826 +#include <linux/io.h>
35827 +#include <linux/highmem.h>
35828 +#include <linux/wait.h>
35829 +#include <linux/version.h>
35830 +
35831 +void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
35832 +{
35833 +       struct ttm_mem_reg *old_mem = &bo->mem;
35834 +
35835 +       if (old_mem->mm_node) {
35836 +               spin_lock(&bo->bdev->lru_lock);
35837 +               drm_mm_put_block(old_mem->mm_node);
35838 +               spin_unlock(&bo->bdev->lru_lock);
35839 +       }
35840 +       old_mem->mm_node = NULL;
35841 +}
35842 +
35843 +int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
35844 +                   bool evict, bool no_wait, struct ttm_mem_reg *new_mem)
35845 +{
35846 +       struct ttm_tt *ttm = bo->ttm;
35847 +       struct ttm_mem_reg *old_mem = &bo->mem;
35848 +       uint32_t save_flags = old_mem->flags;
35849 +       uint32_t save_proposed_flags = old_mem->proposed_flags;
35850 +       int ret;
35851 +
35852 +       if (old_mem->mem_type != TTM_PL_SYSTEM) {
35853 +               ttm_tt_unbind(ttm);
35854 +               ttm_bo_free_old_node(bo);
35855 +               ttm_flag_masked(&old_mem->flags, TTM_PL_FLAG_SYSTEM,
35856 +                               TTM_PL_MASK_MEM);
35857 +               old_mem->mem_type = TTM_PL_SYSTEM;
35858 +               save_flags = old_mem->flags;
35859 +       }
35860 +
35861 +       ret = ttm_tt_set_placement_caching(ttm, new_mem->flags);
35862 +       if (unlikely(ret != 0))
35863 +               return ret;
35864 +
35865 +       if (new_mem->mem_type != TTM_PL_SYSTEM) {
35866 +               ret = ttm_tt_bind(ttm, new_mem);
35867 +               if (unlikely(ret != 0))
35868 +                       return ret;
35869 +       }
35870 +
35871 +       *old_mem = *new_mem;
35872 +       new_mem->mm_node = NULL;
35873 +       old_mem->proposed_flags = save_proposed_flags;
35874 +       ttm_flag_masked(&save_flags, new_mem->flags, TTM_PL_MASK_MEMTYPE);
35875 +       return 0;
35876 +}
35877 +
35878 +int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
35879 +                       void **virtual)
35880 +{
35881 +       struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
35882 +       unsigned long bus_offset;
35883 +       unsigned long bus_size;
35884 +       unsigned long bus_base;
35885 +       int ret;
35886 +       void *addr;
35887 +
35888 +       *virtual = NULL;
35889 +       ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, &bus_size);
35890 +       if (ret || bus_size == 0)
35891 +               return ret;
35892 +
35893 +       if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP))
35894 +               addr = (void *)(((u8 *) man->io_addr) + bus_offset);
35895 +       else {
35896 +               if (mem->flags & TTM_PL_FLAG_WC)
35897 +                       addr = ioremap_wc(bus_base + bus_offset, bus_size);
35898 +               else
35899 +                       addr = ioremap_nocache(bus_base + bus_offset, bus_size);
35900 +               if (!addr)
35901 +                       return -ENOMEM;
35902 +       }
35903 +       *virtual = addr;
35904 +       return 0;
35905 +}
35906 +
35907 +void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
35908 +                        void *virtual)
35909 +{
35910 +       struct ttm_mem_type_manager *man;
35911 +
35912 +       man = &bdev->man[mem->mem_type];
35913 +
35914 +       if (virtual && (man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP))
35915 +               iounmap(virtual);
35916 +}
35917 +
35918 +static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
35919 +{
35920 +       uint32_t *dstP =
35921 +           (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
35922 +       uint32_t *srcP =
35923 +           (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
35924 +
35925 +       int i;
35926 +       for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
35927 +               iowrite32(ioread32(srcP++), dstP++);
35928 +       return 0;
35929 +}
35930 +
35931 +static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
35932 +                               unsigned long page)
35933 +{
35934 +       struct page *d = ttm_tt_get_page(ttm, page);
35935 +       void *dst;
35936 +
35937 +       if (!d)
35938 +               return -ENOMEM;
35939 +
35940 +       src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
35941 +       dst = kmap(d);
35942 +       if (!dst)
35943 +               return -ENOMEM;
35944 +
35945 +       memcpy_fromio(dst, src, PAGE_SIZE);
35946 +       kunmap(d);
35947 +       return 0;
35948 +}
35949 +
35950 +static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
35951 +                               unsigned long page)
35952 +{
35953 +       struct page *s = ttm_tt_get_page(ttm, page);
35954 +       void *src;
35955 +
35956 +       if (!s)
35957 +               return -ENOMEM;
35958 +
35959 +       dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
35960 +       src = kmap(s);
35961 +       if (!src)
35962 +               return -ENOMEM;
35963 +
35964 +       memcpy_toio(dst, src, PAGE_SIZE);
35965 +       kunmap(s);
35966 +       return 0;
35967 +}
35968 +
35969 +int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
35970 +                      bool evict, bool no_wait, struct ttm_mem_reg *new_mem)
35971 +{
35972 +       struct ttm_bo_device *bdev = bo->bdev;
35973 +       struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
35974 +       struct ttm_tt *ttm = bo->ttm;
35975 +       struct ttm_mem_reg *old_mem = &bo->mem;
35976 +       struct ttm_mem_reg old_copy = *old_mem;
35977 +       void *old_iomap;
35978 +       void *new_iomap;
35979 +       int ret;
35980 +       uint32_t save_flags = old_mem->flags;
35981 +       uint32_t save_proposed_flags = old_mem->proposed_flags;
35982 +       unsigned long i;
35983 +       unsigned long page;
35984 +       unsigned long add = 0;
35985 +       int dir;
35986 +
35987 +       ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);
35988 +       if (ret)
35989 +               return ret;
35990 +       ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);
35991 +       if (ret)
35992 +               goto out;
35993 +
35994 +       if (old_iomap == NULL && new_iomap == NULL)
35995 +               goto out2;
35996 +       if (old_iomap == NULL && ttm == NULL)
35997 +               goto out2;
35998 +
35999 +       add = 0;
36000 +       dir = 1;
36001 +
36002 +       if ((old_mem->mem_type == new_mem->mem_type) &&
36003 +           (new_mem->mm_node->start <
36004 +            old_mem->mm_node->start + old_mem->mm_node->size)) {
36005 +               dir = -1;
36006 +               add = new_mem->num_pages - 1;
36007 +       }
36008 +
36009 +       for (i = 0; i < new_mem->num_pages; ++i) {
36010 +               page = i * dir + add;
36011 +               if (old_iomap == NULL)
36012 +                       ret = ttm_copy_ttm_io_page(ttm, new_iomap, page);
36013 +               else if (new_iomap == NULL)
36014 +                       ret = ttm_copy_io_ttm_page(ttm, old_iomap, page);
36015 +               else
36016 +                       ret = ttm_copy_io_page(new_iomap, old_iomap, page);
36017 +               if (ret)
36018 +                       goto out1;
36019 +       }
36020 +       mb();
36021 +out2:
36022 +       ttm_bo_free_old_node(bo);
36023 +
36024 +       *old_mem = *new_mem;
36025 +       new_mem->mm_node = NULL;
36026 +       old_mem->proposed_flags = save_proposed_flags;
36027 +       ttm_flag_masked(&save_flags, new_mem->flags, TTM_PL_MASK_MEMTYPE);
36028 +
36029 +       if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
36030 +               ttm_tt_unbind(ttm);
36031 +               ttm_tt_destroy(ttm);
36032 +               bo->ttm = NULL;
36033 +       }
36034 +
36035 +out1:
36036 +       ttm_mem_reg_iounmap(bdev, new_mem, new_iomap);
36037 +out:
36038 +       ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
36039 +       return ret;
36040 +}
36041 +
36042 +/**
36043 + * ttm_buffer_object_transfer
36044 + *
36045 + * @bo: A pointer to a struct ttm_buffer_object.
36046 + * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
36047 + * holding the data of @bo with the old placement.
36048 + *
36049 + * This is a utility function that may be called after an accelerated move
36050 + * has been scheduled. A new buffer object is created as a placeholder for
36051 + * the old data while it's being copied. When that buffer object is idle,
36052 + * it can be destroyed, releasing the space of the old placement.
36053 + * Returns:
36054 + * !0: Failure.
36055 + */
36056 +
36057 +static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
36058 +                                     struct ttm_buffer_object **new_obj)
36059 +{
36060 +       struct ttm_buffer_object *fbo;
36061 +       struct ttm_bo_device *bdev = bo->bdev;
36062 +       struct ttm_bo_driver *driver = bdev->driver;
36063 +
36064 +       fbo = kzalloc(sizeof(*fbo), GFP_KERNEL);
36065 +       if (!fbo)
36066 +               return -ENOMEM;
36067 +
36068 +       *fbo = *bo;
36069 +       mutex_init(&fbo->mutex);
36070 +       mutex_lock(&fbo->mutex);
36071 +
36072 +       init_waitqueue_head(&fbo->event_queue);
36073 +       INIT_LIST_HEAD(&fbo->ddestroy);
36074 +       INIT_LIST_HEAD(&fbo->lru);
36075 +
36076 +       fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
36077 +       if (fbo->mem.mm_node)
36078 +               fbo->mem.mm_node->private = (void *)fbo;
36079 +       kref_init(&fbo->list_kref);
36080 +       kref_init(&fbo->kref);
36081 +
36082 +       mutex_unlock(&fbo->mutex);
36083 +
36084 +       *new_obj = fbo;
36085 +       return 0;
36086 +}
36087 +
36088 +pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
36089 +{
36090 +#if defined(__i386__) || defined(__x86_64__)
36091 +       if (caching_flags & TTM_PL_FLAG_WC) {
36092 +               tmp = pgprot_ttm_x86_wc(tmp);
36093 +       } else if (boot_cpu_data.x86 > 3 &&
36094 +               (caching_flags & TTM_PL_FLAG_UNCACHED)) {
36095 +               tmp = pgprot_noncached(tmp);
36096 +       }
36097 +#elif defined(__powerpc__)
36098 +       if (!(caching_flags & TTM_PL_FLAG_CACHED)) {
36099 +               pgprot_val(tmp) |= _PAGE_NO_CACHE;
36100 +               if (caching_flags & TTM_PL_FLAG_UNCACHED)
36101 +                       pgprot_val(tmp) |= _PAGE_GUARDED;
36102 +       }
36103 +#endif
36104 +#if defined(__ia64__)
36105 +       if (caching_flags & TTM_PL_FLAG_WC)
36106 +               tmp = pgprot_writecombine(tmp);
36107 +       else
36108 +               tmp = pgprot_noncached(tmp);
36109 +#endif
36110 +#if defined(__sparc__)
36111 +       if (!(caching_flags & TTM_PL_FLAG_CACHED))
36112 +               tmp = pgprot_noncached(tmp);
36113 +#endif
36114 +       return tmp;
36115 +}
36116 +
36117 +static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
36118 +                         unsigned long bus_base,
36119 +                         unsigned long bus_offset,
36120 +                         unsigned long bus_size,
36121 +                         struct ttm_bo_kmap_obj *map)
36122 +{
36123 +       struct ttm_bo_device *bdev = bo->bdev;
36124 +       struct ttm_mem_reg *mem = &bo->mem;
36125 +       struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
36126 +
36127 +       if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) {
36128 +               map->bo_kmap_type = ttm_bo_map_premapped;
36129 +               map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset);
36130 +       } else {
36131 +                       map->bo_kmap_type = ttm_bo_map_iomap;
36132 +                       if (mem->flags & TTM_PL_FLAG_WC)
36133 +                               map->virtual =
36134 +                                       ioremap_wc(bus_base + bus_offset,
36135 +                                                  bus_size);
36136 +                       else
36137 +                               map->virtual =
36138 +                                       ioremap_nocache(bus_base + bus_offset,
36139 +                                                       bus_size);
36140 +               }
36141 +               return (!map->virtual) ? -ENOMEM : 0;
36142 +}
36143 +
36144 +static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
36145 +                          unsigned long start_page,
36146 +                          unsigned long num_pages,
36147 +                          struct ttm_bo_kmap_obj *map)
36148 +{
36149 +       struct ttm_mem_reg *mem = &bo->mem; pgprot_t prot;
36150 +       struct ttm_tt *ttm = bo->ttm;
36151 +       struct page *d;
36152 +       bool do_kmap = false;
36153 +       int i;
36154 +       BUG_ON(!ttm);
36155 +       if (num_pages == 1) {
36156 +               map->page = ttm_tt_get_page(ttm, start_page);
36157 +               do_kmap = (!PageHighMem(map->page) ||
36158 +                       (mem->flags & TTM_PL_FLAG_CACHED));
36159 +       }
36160 +
36161 +       if (do_kmap) {
36162 +               /*
36163 +               * We're mapping a single page, and the desired
36164 +               * page protection is consistent with the bo.
36165 +               */
36166 +               map->bo_kmap_type = ttm_bo_map_kmap;
36167 +               map->virtual = kmap(map->page);
36168 +       } else {
36169 +               /* Populate the part we're mapping; */
36170 +               for (i = start_page; i < start_page + num_pages; ++i) {
36171 +                       d = ttm_tt_get_page(ttm, i);
36172 +
36173 +                       if (!d)
36174 +                               return -ENOMEM;
36175 +               }
36176 +
36177 +               /*
36178 +                * We need to use vmap to get the desired page protection
36179 +                * or to make the buffer object look contigous.
36180 +                */
36181 +               prot = (mem->flags & TTM_PL_FLAG_CACHED) ?
36182 +                       PAGE_KERNEL :
36183 +                       ttm_io_prot(mem->flags, PAGE_KERNEL);
36184 +               map->bo_kmap_type = ttm_bo_map_vmap;
36185 +               map->virtual = vmap(ttm->pages + start_page,
36186 +                                       num_pages,
36187 +                                       0,
36188 +                                       prot);
36189 +       }
36190 +       return (!map->virtual) ? -ENOMEM : 0;
36191 +}
36192 +
36193 +int ttm_bo_kmap(struct ttm_buffer_object *bo,
36194 +               unsigned long start_page, unsigned long num_pages,
36195 +               struct ttm_bo_kmap_obj *map)
36196 +{
36197 +       int ret;
36198 +       unsigned long bus_base;
36199 +       unsigned long bus_offset;
36200 +       unsigned long bus_size;
36201 +       BUG_ON(!list_empty(&bo->swap));
36202 +       map->virtual = NULL;
36203 +
36204 +       if (num_pages > bo->num_pages)
36205 +               return -EINVAL;
36206 +
36207 +       if (start_page > bo->num_pages)
36208 +               return -EINVAL;
36209 +#if 0
36210 +       if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC))
36211 +               return -EPERM;
36212 +#endif
36213 +       ret = ttm_bo_pci_offset(bo->bdev,
36214 +                               &bo->mem,
36215 +                               &bus_base,
36216 +                               &bus_offset,
36217 +                               &bus_size);
36218 +       if (ret)
36219 +               return ret;
36220 +
36221 +       if (bus_size == 0) {
36222 +               return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
36223 +       } else {
36224 +               bus_offset += start_page << PAGE_SHIFT;
36225 +               bus_size = num_pages << PAGE_SHIFT;
36226 +
36227 +               return ttm_bo_ioremap(bo,
36228 +                                     bus_base,
36229 +                                     bus_offset,
36230 +                                     bus_size, map);
36231 +       }
36232 +}
36233 +
36234 +void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
36235 +{
36236 +       if (!map->virtual)
36237 +               return;
36238 +       switch (map->bo_kmap_type) {
36239 +       case ttm_bo_map_iomap:
36240 +               iounmap(map->virtual);
36241 +               break;
36242 +       case ttm_bo_map_vmap:
36243 +               vunmap(map->virtual);
36244 +               break;
36245 +       case ttm_bo_map_kmap:
36246 +               kunmap(map->page);
36247 +               break;
36248 +       case ttm_bo_map_premapped:
36249 +               break;
36250 +       default:
36251 +               BUG();
36252 +       }
36253 +       map->virtual = NULL;
36254 +       map->page = NULL;
36255 +}
36256 +
36257 +int ttm_bo_pfn_prot(struct ttm_buffer_object *bo,
36258 +                   unsigned long dst_offset,
36259 +                   unsigned long *pfn, pgprot_t *prot)
36260 +{
36261 +       struct ttm_mem_reg *mem = &bo->mem;
36262 +       struct ttm_bo_device *bdev = bo->bdev;
36263 +       unsigned long bus_offset;
36264 +       unsigned long bus_size;
36265 +       unsigned long bus_base;
36266 +       int ret;
36267 +       ret = ttm_bo_pci_offset(bdev,
36268 +                               mem,
36269 +                               &bus_base,
36270 +                               &bus_offset,
36271 +                               &bus_size);
36272 +       if (ret)
36273 +               return -EINVAL;
36274 +       if (bus_size != 0)
36275 +               *pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT;
36276 +       else
36277 +               if (!bo->ttm)
36278 +                       return -EINVAL;
36279 +               else
36280 +                       *pfn = page_to_pfn(ttm_tt_get_page(
36281 +                                               bo->ttm,
36282 +                                               dst_offset >> PAGE_SHIFT));
36283 +
36284 +       *prot = (mem->flags & TTM_PL_FLAG_CACHED) ?
36285 +                       PAGE_KERNEL :
36286 +                       ttm_io_prot(mem->flags, PAGE_KERNEL);
36287 +       return 0;
36288 +}
36289 +
36290 +int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
36291 +                             void *sync_obj,
36292 +                             void *sync_obj_arg,
36293 +                             bool evict, bool no_wait,
36294 +                             struct ttm_mem_reg *new_mem)
36295 +{
36296 +       struct ttm_bo_device *bdev = bo->bdev;
36297 +       struct ttm_bo_driver *driver = bdev->driver;
36298 +       struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
36299 +       struct ttm_mem_reg *old_mem = &bo->mem;
36300 +       int ret;
36301 +       uint32_t save_flags = old_mem->flags;
36302 +       uint32_t save_proposed_flags = old_mem->proposed_flags;
36303 +       struct ttm_buffer_object *old_obj;
36304 +       if (bo->sync_obj)
36305 +               driver->sync_obj_unref(&bo->sync_obj);
36306 +       bo->sync_obj = driver->sync_obj_ref(sync_obj);
36307 +       bo->sync_obj_arg = sync_obj_arg;
36308 +       if (evict) {
36309 +               ret = ttm_bo_wait(bo, false, false, false);
36310 +               if (ret)
36311 +                       return ret;
36312 +               ttm_bo_free_old_node(bo);
36313 +               if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
36314 +                   (bo->ttm != NULL)) {
36315 +                       ttm_tt_unbind(bo->ttm);
36316 +                       ttm_tt_destroy(bo->ttm);
36317 +                       bo->ttm = NULL;
36318 +               }
36319 +       } else {
36320 +
36321 +               /* This should help pipeline ordinary buffer moves.
36322 +                *
36323 +                * Hang old buffer memory on a new buffer object,
36324 +                * and leave it to be released when the GPU
36325 +                * operation has completed.
36326 +                */
36327 +               ret = ttm_buffer_object_transfer(bo, &old_obj);
36328 +               if (ret)
36329 +                       return ret;
36330 +               if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
36331 +                       old_obj->ttm = NULL;
36332 +               else
36333 +                       bo->ttm = NULL;
36334 +               bo->priv_flags |= TTM_BO_PRIV_FLAG_MOVING;
36335 +               ttm_bo_unreserve(old_obj);
36336 +       }
36337 +
36338 +       *old_mem = *new_mem;
36339 +       new_mem->mm_node = NULL;
36340 +       old_mem->proposed_flags = save_proposed_flags;
36341 +       ttm_flag_masked(&save_flags, new_mem->flags, TTM_PL_MASK_MEMTYPE);
36342 +       return 0;
36343 +}
36344 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_vm.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_vm.c
36345 new file mode 100644
36346 index 0000000..a8aae7e
36347 --- /dev/null
36348 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_bo_vm.c
36349 @@ -0,0 +1,429 @@
36350 +/**************************************************************************
36351 + *
36352 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
36353 + * All Rights Reserved.
36354 + * Copyright (c) 2009 Vmware, Inc., Palo Alto, CA., USA
36355 + * All Rights Reserved.
36356 + *
36357 + * This program is free software; you can redistribute it and/or modify it
36358 + * under the terms and conditions of the GNU General Public License,
36359 + * version 2, as published by the Free Software Foundation.
36360 + *
36361 + * This program is distributed in the hope it will be useful, but WITHOUT
36362 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36363 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36364 + * more details.
36365 + *
36366 + * You should have received a copy of the GNU General Public License along with
36367 + * this program; if not, write to the Free Software Foundation, Inc., 
36368 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
36369 + *
36370 + **************************************************************************/
36371 +/*
36372 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
36373 + */
36374 +
36375 +
36376 +#include "ttm_bo_driver.h"
36377 +#include "ttm_placement_common.h"
36378 +#include <linux/mm.h>
36379 +#include <linux/version.h>
36380 +#include <linux/rbtree.h>
36381 +#include <linux/uaccess.h>
36382 +
36383 +#define TTM_BO_VM_NUM_PREFAULT 16
36384 +
36385 +static struct ttm_buffer_object *ttm_bo_vm_lookup_rb(struct ttm_bo_device *bdev,
36386 +                                                    unsigned long page_start,
36387 +                                                    unsigned long num_pages)
36388 +{
36389 +       struct rb_node *cur = bdev->addr_space_rb.rb_node;
36390 +       unsigned long cur_offset;
36391 +       struct ttm_buffer_object *bo;
36392 +       struct ttm_buffer_object *best_bo = NULL;
36393 +
36394 +       while (likely(cur != NULL)) {
36395 +               bo = rb_entry(cur, struct ttm_buffer_object, vm_rb);
36396 +               cur_offset = bo->vm_node->start;
36397 +               if (page_start >= cur_offset) {
36398 +                       cur = cur->rb_right;
36399 +                       best_bo = bo;
36400 +                       if (page_start == cur_offset)
36401 +                               break;
36402 +               } else
36403 +                       cur = cur->rb_left;
36404 +       }
36405 +
36406 +       if (unlikely(best_bo == NULL))
36407 +               return NULL;
36408 +
36409 +       if (unlikely((best_bo->vm_node->start + best_bo->num_pages) <
36410 +                    (page_start + num_pages)))
36411 +               return NULL;
36412 +
36413 +       return best_bo;
36414 +}
36415 +
36416 +static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
36417 +{
36418 +       struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
36419 +           vma->vm_private_data;
36420 +       struct ttm_bo_device *bdev = bo->bdev;
36421 +       unsigned long bus_base;
36422 +       unsigned long bus_offset;
36423 +       unsigned long bus_size;
36424 +       unsigned long page_offset;
36425 +       unsigned long page_last;
36426 +       unsigned long pfn;
36427 +       struct ttm_tt *ttm = NULL;
36428 +       struct page *page;
36429 +       int ret;
36430 +       int i;
36431 +       bool is_iomem;
36432 +       unsigned long address = (unsigned long)vmf->virtual_address;
36433 +       int retval = VM_FAULT_NOPAGE;
36434 +
36435 +       ret = ttm_bo_reserve(bo, true, false, false, 0);
36436 +       if (unlikely(ret != 0))
36437 +               return VM_FAULT_NOPAGE;
36438 +
36439 +       mutex_lock(&bo->mutex);
36440 +
36441 +       /*
36442 +        * Wait for buffer data in transit, due to a pipelined
36443 +        * move.
36444 +        */
36445 +
36446 +       if (bo->priv_flags & TTM_BO_PRIV_FLAG_MOVING) {
36447 +               ret = ttm_bo_wait(bo, false, true, false);
36448 +               if (unlikely(ret != 0)) {
36449 +                       retval = (ret != -ERESTART) ?
36450 +                           VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
36451 +                       goto out_unlock;
36452 +               }
36453 +       }
36454 +
36455 +       ret = ttm_bo_pci_offset(bdev, &bo->mem, &bus_base, &bus_offset,
36456 +                               &bus_size);
36457 +       if (unlikely(ret != 0)) {
36458 +               retval = VM_FAULT_SIGBUS;
36459 +               goto out_unlock;
36460 +       }
36461 +
36462 +       is_iomem = (bus_size != 0);
36463 +
36464 +       page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) +
36465 +           bo->vm_node->start - vma->vm_pgoff;
36466 +       page_last = ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) +
36467 +           bo->vm_node->start - vma->vm_pgoff;
36468 +
36469 +       if (unlikely(page_offset >= bo->num_pages)) {
36470 +               retval = VM_FAULT_SIGBUS;
36471 +               goto out_unlock;
36472 +       }
36473 +
36474 +       /*
36475 +        * Strictly, we're not allowed to modify vma->vm_page_prot here,
36476 +        * since the mmap_sem is only held in read mode. However, we
36477 +        * modify only the caching bits of vma->vm_page_prot and
36478 +        * consider those bits protected by
36479 +        * the bo->mutex, as we should be the only writers.
36480 +        * There shouldn't really be any readers of these bits except
36481 +        * within vm_insert_mixed()? fork?
36482 +        *
36483 +        * TODO: Add a list of vmas to the bo, and change the
36484 +        * vma->vm_page_prot when the object changes caching policy, with
36485 +        * the correct locks held.
36486 +        */
36487 +
36488 +       if (is_iomem) {
36489 +               vma->vm_page_prot = ttm_io_prot(bo->mem.flags,
36490 +                                               vma->vm_page_prot);
36491 +       } else {
36492 +               ttm = bo->ttm;
36493 +               vma->vm_page_prot = (bo->mem.flags & TTM_PL_FLAG_CACHED) ?
36494 +                   vm_get_page_prot(vma->vm_flags) :
36495 +                   ttm_io_prot(bo->mem.flags, vma->vm_page_prot);
36496 +       }
36497 +
36498 +       /*
36499 +        * Speculatively prefault a number of pages. Only error on
36500 +        * first page.
36501 +        */
36502 +
36503 +       for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; ++i) {
36504 +
36505 +               if (is_iomem)
36506 +                       pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) +
36507 +                           page_offset;
36508 +               else {
36509 +                       page = ttm_tt_get_page(ttm, page_offset);
36510 +                       if (unlikely(!page && i == 0)) {
36511 +                               retval = VM_FAULT_OOM;
36512 +                               goto out_unlock;
36513 +                       } else if (unlikely(!page)) {
36514 +                               break;
36515 +                       }
36516 +                       pfn = page_to_pfn(page);
36517 +               }
36518 +
36519 +               ret = vm_insert_mixed(vma, address, pfn);
36520 +               /*
36521 +                * Somebody beat us to this PTE or prefaulting to
36522 +                * an already populated PTE, or prefaulting error.
36523 +                */
36524 +
36525 +               if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
36526 +                       break;
36527 +               else if (unlikely(ret != 0)) {
36528 +                       retval =
36529 +                           (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
36530 +                       goto out_unlock;
36531 +
36532 +               }
36533 +
36534 +               address += PAGE_SIZE;
36535 +               if (unlikely(++page_offset >= page_last))
36536 +                       break;
36537 +       }
36538 +
36539 +out_unlock:
36540 +       mutex_unlock(&bo->mutex);
36541 +       ttm_bo_unreserve(bo);
36542 +       return retval;
36543 +}
36544 +
36545 +static void ttm_bo_vm_open(struct vm_area_struct *vma)
36546 +{
36547 +       struct ttm_buffer_object *bo =
36548 +           (struct ttm_buffer_object *)vma->vm_private_data;
36549 +
36550 +       (void)ttm_bo_reference(bo);
36551 +}
36552 +
36553 +static void ttm_bo_vm_close(struct vm_area_struct *vma)
36554 +{
36555 +       struct ttm_buffer_object *bo =
36556 +           (struct ttm_buffer_object *)vma->vm_private_data;
36557 +
36558 +       ttm_bo_unref(&bo);
36559 +       vma->vm_private_data = NULL;
36560 +}
36561 +
36562 +static struct vm_operations_struct ttm_bo_vm_ops = {
36563 +       .fault = ttm_bo_vm_fault,
36564 +       .open = ttm_bo_vm_open,
36565 +       .close = ttm_bo_vm_close
36566 +};
36567 +
36568 +int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
36569 +               struct ttm_bo_device *bdev)
36570 +{
36571 +       struct ttm_bo_driver *driver;
36572 +       struct ttm_buffer_object *bo;
36573 +       int ret;
36574 +
36575 +       read_lock(&bdev->vm_lock);
36576 +       bo = ttm_bo_vm_lookup_rb(bdev, vma->vm_pgoff,
36577 +                                (vma->vm_end - vma->vm_start) >> PAGE_SHIFT);
36578 +       if (likely(bo != NULL))
36579 +               ttm_bo_reference(bo);
36580 +       read_unlock(&bdev->vm_lock);
36581 +
36582 +       if (unlikely(bo == NULL)) {
36583 +               printk(KERN_ERR "Could not find buffer object to map.\n");
36584 +               ret = -EINVAL;
36585 +               goto out_unref;
36586 +       }
36587 +
36588 +       driver = bo->bdev->driver;
36589 +       if (unlikely(!driver->verify_access)) {
36590 +               ret = -EPERM;
36591 +               goto out_unref;
36592 +       }
36593 +       ret = driver->verify_access(bo, filp);
36594 +       if (unlikely(ret != 0))
36595 +               goto out_unref;
36596 +
36597 +       vma->vm_ops = &ttm_bo_vm_ops;
36598 +
36599 +       /*
36600 +        * Note: We're transferring the bo reference to
36601 +        * vma->vm_private_data here.
36602 +        */
36603 +
36604 +       vma->vm_private_data = bo;
36605 +       vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
36606 +       return 0;
36607 +out_unref:
36608 +       ttm_bo_unref(&bo);
36609 +       return ret;
36610 +}
36611 +
36612 +int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
36613 +{
36614 +       if (vma->vm_pgoff != 0)
36615 +               return -EACCES;
36616 +
36617 +       vma->vm_ops = &ttm_bo_vm_ops;
36618 +       vma->vm_private_data = ttm_bo_reference(bo);
36619 +       vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
36620 +       return 0;
36621 +}
36622 +
36623 +ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
36624 +                 const char __user *wbuf, char __user *rbuf, size_t count,
36625 +                 loff_t *f_pos, bool write)
36626 +{
36627 +       struct ttm_buffer_object *bo;
36628 +       struct ttm_bo_driver *driver;
36629 +       struct ttm_bo_kmap_obj map;
36630 +       unsigned long dev_offset = (*f_pos >> PAGE_SHIFT);
36631 +       unsigned long kmap_offset;
36632 +       unsigned long kmap_end;
36633 +       unsigned long kmap_num;
36634 +       size_t io_size;
36635 +       unsigned int page_offset;
36636 +       char *virtual;
36637 +       int ret;
36638 +       bool no_wait = false;
36639 +       bool dummy;
36640 +
36641 +       read_lock(&bdev->vm_lock);
36642 +       bo = ttm_bo_vm_lookup_rb(bdev, dev_offset, 1);
36643 +       if (likely(bo != NULL))
36644 +               ttm_bo_reference(bo);
36645 +       read_unlock(&bdev->vm_lock);
36646 +
36647 +       if (unlikely(bo == NULL))
36648 +               return -EFAULT;
36649 +
36650 +       driver = bo->bdev->driver;
36651 +       if (unlikely(driver->verify_access))
36652 +               return -EPERM;
36653 +
36654 +       ret = driver->verify_access(bo, filp);
36655 +       if (unlikely(ret != 0))
36656 +               goto out_unref;
36657 +
36658 +       kmap_offset = dev_offset - bo->vm_node->start;
36659 +       if (unlikely(kmap_offset) >= bo->num_pages) {
36660 +               ret = -EFBIG;
36661 +               goto out_unref;
36662 +       }
36663 +
36664 +       page_offset = *f_pos & ~PAGE_MASK;
36665 +       io_size = bo->num_pages - kmap_offset;
36666 +       io_size = (io_size << PAGE_SHIFT) - page_offset;
36667 +       if (count < io_size)
36668 +               io_size = count;
36669 +
36670 +       kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
36671 +       kmap_num = kmap_end - kmap_offset + 1;
36672 +
36673 +       ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
36674 +
36675 +       switch (ret) {
36676 +       case 0:
36677 +               break;
36678 +       case -ERESTART:
36679 +               ret = -EINTR;
36680 +               goto out_unref;
36681 +       case -EBUSY:
36682 +               ret = -EAGAIN;
36683 +               goto out_unref;
36684 +       default:
36685 +               goto out_unref;
36686 +       }
36687 +
36688 +       ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
36689 +       if (unlikely(ret != 0))
36690 +               goto out_unref;
36691 +
36692 +       virtual = ttm_kmap_obj_virtual(&map, &dummy);
36693 +       virtual += page_offset;
36694 +
36695 +       if (write)
36696 +               ret = copy_from_user(virtual, wbuf, io_size);
36697 +       else
36698 +               ret = copy_to_user(rbuf, virtual, io_size);
36699 +
36700 +       ttm_bo_kunmap(&map);
36701 +       ttm_bo_unreserve(bo);
36702 +       ttm_bo_unref(&bo);
36703 +
36704 +       if (unlikely(ret != 0))
36705 +               return -EFBIG;
36706 +
36707 +       *f_pos += io_size;
36708 +
36709 +       return io_size;
36710 +out_unref:
36711 +       ttm_bo_unref(&bo);
36712 +       return ret;
36713 +}
36714 +
36715 +ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf,
36716 +                       char __user *rbuf, size_t count, loff_t *f_pos,
36717 +                       bool write)
36718 +{
36719 +       struct ttm_bo_kmap_obj map;
36720 +       unsigned long kmap_offset;
36721 +       unsigned long kmap_end;
36722 +       unsigned long kmap_num;
36723 +       size_t io_size;
36724 +       unsigned int page_offset;
36725 +       char *virtual;
36726 +       int ret;
36727 +       bool no_wait = false;
36728 +       bool dummy;
36729 +
36730 +       kmap_offset = (*f_pos >> PAGE_SHIFT);
36731 +       if (unlikely(kmap_offset) >= bo->num_pages)
36732 +               return -EFBIG;
36733 +
36734 +       page_offset = *f_pos & ~PAGE_MASK;
36735 +       io_size = bo->num_pages - kmap_offset;
36736 +       io_size = (io_size << PAGE_SHIFT) - page_offset;
36737 +       if (count < io_size)
36738 +               io_size = count;
36739 +
36740 +       kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
36741 +       kmap_num = kmap_end - kmap_offset + 1;
36742 +
36743 +       ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
36744 +
36745 +       switch (ret) {
36746 +       case 0:
36747 +               break;
36748 +       case -ERESTART:
36749 +               return -EINTR;
36750 +       case -EBUSY:
36751 +               return -EAGAIN;
36752 +       default:
36753 +               return ret;
36754 +       }
36755 +
36756 +       ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
36757 +       if (unlikely(ret != 0))
36758 +               return ret;
36759 +
36760 +       virtual = ttm_kmap_obj_virtual(&map, &dummy);
36761 +       virtual += page_offset;
36762 +
36763 +       if (write)
36764 +               ret = copy_from_user(virtual, wbuf, io_size);
36765 +       else
36766 +               ret = copy_to_user(rbuf, virtual, io_size);
36767 +
36768 +       ttm_bo_kunmap(&map);
36769 +       ttm_bo_unreserve(bo);
36770 +       ttm_bo_unref(&bo);
36771 +
36772 +       if (unlikely(ret != 0))
36773 +               return ret;
36774 +
36775 +       *f_pos += io_size;
36776 +
36777 +       return io_size;
36778 +}
36779 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.c
36780 new file mode 100644
36781 index 0000000..610e0e0
36782 --- /dev/null
36783 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.c
36784 @@ -0,0 +1,108 @@
36785 +/**************************************************************************
36786 + *
36787 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
36788 + * All Rights Reserved.
36789 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
36790 + * All Rights Reserved.
36791 + *
36792 + * This program is free software; you can redistribute it and/or modify it
36793 + * under the terms and conditions of the GNU General Public License,
36794 + * version 2, as published by the Free Software Foundation.
36795 + *
36796 + * This program is distributed in the hope it will be useful, but WITHOUT
36797 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36798 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36799 + * more details.
36800 + *
36801 + * You should have received a copy of the GNU General Public License along with
36802 + * this program; if not, write to the Free Software Foundation, Inc., 
36803 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
36804 + *
36805 + **************************************************************************/
36806 +
36807 +#include "ttm_execbuf_util.h"
36808 +#include "ttm_bo_driver.h"
36809 +#include "ttm_placement_common.h"
36810 +#include <linux/wait.h>
36811 +#include <linux/sched.h>
36812 +
36813 +void ttm_eu_backoff_reservation(struct list_head *list)
36814 +{
36815 +       struct ttm_validate_buffer *entry;
36816 +
36817 +       list_for_each_entry(entry, list, head) {
36818 +               struct ttm_buffer_object *bo = entry->bo;
36819 +               if (!entry->reserved)
36820 +                       continue;
36821 +
36822 +               entry->reserved = false;
36823 +               ttm_bo_unreserve(bo);
36824 +       }
36825 +}
36826 +
36827 +/*
36828 + * Reserve buffers for validation.
36829 + *
36830 + * If a buffer in the list is marked for CPU access, we back off and
36831 + * wait for that buffer to become free for GPU access.
36832 + *
36833 + * If a buffer is reserved for another validation, the validator with
36834 + * the highest validation sequence backs off and waits for that buffer
36835 + * to become unreserved. This prevents deadlocks when validating multiple
36836 + * buffers in different orders.
36837 + */
36838 +
36839 +int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq)
36840 +{
36841 +       struct ttm_validate_buffer *entry;
36842 +       int ret;
36843 +
36844 +retry:
36845 +       list_for_each_entry(entry, list, head) {
36846 +               struct ttm_buffer_object *bo = entry->bo;
36847 +
36848 +               entry->reserved = false;
36849 +               ret = ttm_bo_reserve(bo, true, false, true, val_seq);
36850 +               if (ret != 0) {
36851 +                       ttm_eu_backoff_reservation(list);
36852 +                       if (ret == -EAGAIN) {
36853 +                               ret = ttm_bo_wait_unreserved(bo, true);
36854 +                               if (unlikely(ret != 0))
36855 +                                       return ret;
36856 +                               goto retry;
36857 +                       } else
36858 +                               return ret;
36859 +               }
36860 +
36861 +               entry->reserved = true;
36862 +               if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
36863 +                       ttm_eu_backoff_reservation(list);
36864 +                       ret = ttm_bo_wait_cpu(bo, false);
36865 +                       if (ret)
36866 +                               return ret;
36867 +                       goto retry;
36868 +               }
36869 +       }
36870 +       return 0;
36871 +}
36872 +
36873 +void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
36874 +{
36875 +       struct ttm_validate_buffer *entry;
36876 +
36877 +       list_for_each_entry(entry, list, head) {
36878 +               struct ttm_buffer_object *bo = entry->bo;
36879 +               struct ttm_bo_driver *driver = bo->bdev->driver;
36880 +               void *old_sync_obj;
36881 +
36882 +               mutex_lock(&bo->mutex);
36883 +               old_sync_obj = bo->sync_obj;
36884 +               bo->sync_obj = driver->sync_obj_ref(sync_obj);
36885 +               bo->sync_obj_arg = entry->new_sync_obj_arg;
36886 +               mutex_unlock(&bo->mutex);
36887 +               ttm_bo_unreserve(bo);
36888 +               entry->reserved = false;
36889 +               if (old_sync_obj)
36890 +                       driver->sync_obj_unref(&old_sync_obj);
36891 +       }
36892 +}
36893 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.h
36894 new file mode 100644
36895 index 0000000..0b88d08
36896 --- /dev/null
36897 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_execbuf_util.h
36898 @@ -0,0 +1,103 @@
36899 +/**************************************************************************
36900 + *
36901 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
36902 + * All Rights Reserved.
36903 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
36904 + * All Rights Reserved.
36905 + *
36906 + * This program is free software; you can redistribute it and/or modify it
36907 + * under the terms and conditions of the GNU General Public License,
36908 + * version 2, as published by the Free Software Foundation.
36909 + *
36910 + * This program is distributed in the hope it will be useful, but WITHOUT
36911 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36912 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36913 + * more details.
36914 + *
36915 + * You should have received a copy of the GNU General Public License along with
36916 + * this program; if not, write to the Free Software Foundation, Inc., 
36917 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
36918 + *
36919 + **************************************************************************/
36920 +/*
36921 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
36922 + */
36923 +
36924 +#ifndef _TTM_EXECBUF_UTIL_H_
36925 +#define _TTM_EXECBUF_UTIL_H_
36926 +
36927 +#include "ttm_bo_api.h"
36928 +#include "ttm_fence_api.h"
36929 +#include <linux/list.h>
36930 +
36931 +/**
36932 + * struct ttm_validate_buffer
36933 + *
36934 + * @head:           list head for thread-private list.
36935 + * @bo:             refcounted buffer object pointer.
36936 + * @new_sync_obj_arg: New sync_obj_arg for @bo, to be used once
36937 + * adding a new sync object.
36938 + * @reservied:      Indicates whether @bo has been reserved for validation.
36939 + */
36940 +
36941 +struct ttm_validate_buffer {
36942 +       struct list_head head;
36943 +       struct ttm_buffer_object *bo;
36944 +       void *new_sync_obj_arg;
36945 +       bool reserved;
36946 +};
36947 +
36948 +/**
36949 + * function ttm_eu_backoff_reservation
36950 + *
36951 + * @list:     thread private list of ttm_validate_buffer structs.
36952 + *
36953 + * Undoes all buffer validation reservations for bos pointed to by
36954 + * the list entries.
36955 + */
36956 +
36957 +extern void ttm_eu_backoff_reservation(struct list_head *list);
36958 +
36959 +/**
36960 + * function ttm_eu_reserve_buffers
36961 + *
36962 + * @list:    thread private list of ttm_validate_buffer structs.
36963 + * @val_seq: A unique sequence number.
36964 + *
36965 + * Tries to reserve bos pointed to by the list entries for validation.
36966 + * If the function returns 0, all buffers are marked as "unfenced",
36967 + * taken off the lru lists and are not synced for write CPU usage.
36968 + *
36969 + * If the function detects a deadlock due to multiple threads trying to
36970 + * reserve the same buffers in reverse order, all threads except one will
36971 + * back off and retry. This function may sleep while waiting for
36972 + * CPU write reservations to be cleared, and for other threads to
36973 + * unreserve their buffers.
36974 + *
36975 + * This function may return -ERESTART or -EAGAIN if the calling process
36976 + * receives a signal while waiting. In that case, no buffers on the list
36977 + * will be reserved upon return.
36978 + *
36979 + * Buffers reserved by this function should be unreserved by
36980 + * a call to either ttm_eu_backoff_reservation() or
36981 + * ttm_eu_fence_buffer_objects() when command submission is complete or
36982 + * has failed.
36983 + */
36984 +
36985 +extern int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq);
36986 +
36987 +/**
36988 + * function ttm_eu_fence_buffer_objects.
36989 + *
36990 + * @list:        thread private list of ttm_validate_buffer structs.
36991 + * @sync_obj:    The new sync object for the buffers.
36992 + *
36993 + * This function should be called when command submission is complete, and
36994 + * it will add a new sync object to bos pointed to by entries on @list.
36995 + * It also unreserves all buffers, putting them on lru lists.
36996 + *
36997 + */
36998 +
36999 +extern void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj);
37000 +
37001 +#endif
37002 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_fence.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence.c
37003 new file mode 100644
37004 index 0000000..3f36ecc
37005 --- /dev/null
37006 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence.c
37007 @@ -0,0 +1,607 @@
37008 +/**************************************************************************
37009 + *
37010 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
37011 + * All Rights Reserved.
37012 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
37013 + * All Rights Reserved.
37014 + *
37015 + * This program is free software; you can redistribute it and/or modify it
37016 + * under the terms and conditions of the GNU General Public License,
37017 + * version 2, as published by the Free Software Foundation.
37018 + *
37019 + * This program is distributed in the hope it will be useful, but WITHOUT
37020 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37021 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
37022 + * more details.
37023 + *
37024 + * You should have received a copy of the GNU General Public License along with
37025 + * this program; if not, write to the Free Software Foundation, Inc., 
37026 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
37027 + *
37028 + **************************************************************************/
37029 +/*
37030 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
37031 + */
37032 +
37033 +#include "ttm_fence_api.h"
37034 +#include "ttm_fence_driver.h"
37035 +#include <linux/wait.h>
37036 +#include <linux/sched.h>
37037 +
37038 +#include <drm/drmP.h>
37039 +
37040 +/*
37041 + * Simple implementation for now.
37042 + */
37043 +
37044 +static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask)
37045 +{
37046 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37047 +
37048 +       printk(KERN_ERR "GPU lockup dectected on engine %u "
37049 +              "fence type 0x%08x\n",
37050 +              (unsigned int)fence->fence_class, (unsigned int)mask);
37051 +       /*
37052 +        * Give engines some time to idle?
37053 +        */
37054 +
37055 +       write_lock(&fc->lock);
37056 +       ttm_fence_handler(fence->fdev, fence->fence_class,
37057 +                         fence->sequence, mask, -EBUSY);
37058 +       write_unlock(&fc->lock);
37059 +}
37060 +
37061 +/*
37062 + * Convenience function to be called by fence::wait methods that
37063 + * need polling.
37064 + */
37065 +
37066 +int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy,
37067 +                          bool interruptible, uint32_t mask)
37068 +{
37069 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37070 +       const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
37071 +       uint32_t count = 0;
37072 +       int ret;
37073 +       unsigned long end_jiffies = fence->timeout_jiffies;
37074 +
37075 +       DECLARE_WAITQUEUE(entry, current);
37076 +       add_wait_queue(&fc->fence_queue, &entry);
37077 +
37078 +       ret = 0;
37079 +
37080 +       for (;;) {
37081 +               __set_current_state((interruptible) ?
37082 +                                   TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
37083 +               if (ttm_fence_object_signaled(fence, mask))
37084 +                       break;
37085 +               if (time_after_eq(jiffies, end_jiffies)) {
37086 +                       if (driver->lockup)
37087 +                               driver->lockup(fence, mask);
37088 +                       else
37089 +                               ttm_fence_lockup(fence, mask);
37090 +                       continue;
37091 +               }
37092 +               if (lazy)
37093 +                       schedule_timeout(1);
37094 +               else if ((++count & 0x0F) == 0) {
37095 +                       __set_current_state(TASK_RUNNING);
37096 +                       schedule();
37097 +                       __set_current_state((interruptible) ?
37098 +                                           TASK_INTERRUPTIBLE :
37099 +                                           TASK_UNINTERRUPTIBLE);
37100 +               }
37101 +               if (interruptible && signal_pending(current)) {
37102 +                       ret = -ERESTART;
37103 +                       break;
37104 +               }
37105 +       }
37106 +       __set_current_state(TASK_RUNNING);
37107 +       remove_wait_queue(&fc->fence_queue, &entry);
37108 +       return ret;
37109 +}
37110 +
37111 +/*
37112 + * Typically called by the IRQ handler.
37113 + */
37114 +
37115 +void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class,
37116 +                      uint32_t sequence, uint32_t type, uint32_t error)
37117 +{
37118 +       int wake = 0;
37119 +       uint32_t diff;
37120 +       uint32_t relevant_type;
37121 +       uint32_t new_type;
37122 +       struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
37123 +       const struct ttm_fence_driver *driver = ttm_fence_driver_from_dev(fdev);
37124 +       struct list_head *head;
37125 +       struct ttm_fence_object *fence, *next;
37126 +       bool found = false;
37127 +
37128 +       if (list_empty(&fc->ring))
37129 +               return;
37130 +
37131 +       list_for_each_entry(fence, &fc->ring, ring) {
37132 +               diff = (sequence - fence->sequence) & fc->sequence_mask;
37133 +               if (diff > fc->wrap_diff) {
37134 +                       found = true;
37135 +                       break;
37136 +               }
37137 +       }
37138 +
37139 +       fc->waiting_types &= ~type;
37140 +       head = (found) ? &fence->ring : &fc->ring;
37141 +
37142 +       list_for_each_entry_safe_reverse(fence, next, head, ring) {
37143 +               if (&fence->ring == &fc->ring)
37144 +                       break;
37145 +
37146 +               DRM_DEBUG("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n",
37147 +                         (unsigned long)fence, fence->sequence,
37148 +                         fence->fence_type);
37149 +
37150 +               if (error) {
37151 +                       fence->info.error = error;
37152 +                       fence->info.signaled_types = fence->fence_type;
37153 +                       list_del_init(&fence->ring);
37154 +                       wake = 1;
37155 +                       break;
37156 +               }
37157 +
37158 +               relevant_type = type & fence->fence_type;
37159 +               new_type = (fence->info.signaled_types | relevant_type) ^
37160 +                   fence->info.signaled_types;
37161 +
37162 +               if (new_type) {
37163 +                       fence->info.signaled_types |= new_type;
37164 +                       DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
37165 +                                 (unsigned long)fence,
37166 +                                 fence->info.signaled_types);
37167 +
37168 +                       if (unlikely(driver->signaled))
37169 +                               driver->signaled(fence);
37170 +
37171 +                       if (driver->needed_flush)
37172 +                               fc->pending_flush |=
37173 +                                   driver->needed_flush(fence);
37174 +
37175 +                       if (new_type & fence->waiting_types)
37176 +                               wake = 1;
37177 +               }
37178 +
37179 +               fc->waiting_types |=
37180 +                   fence->waiting_types & ~fence->info.signaled_types;
37181 +
37182 +               if (!(fence->fence_type & ~fence->info.signaled_types)) {
37183 +                       DRM_DEBUG("Fence completely signaled 0x%08lx\n",
37184 +                                 (unsigned long)fence);
37185 +                       list_del_init(&fence->ring);
37186 +               }
37187 +       }
37188 +
37189 +       /*
37190 +        * Reinstate lost waiting types.
37191 +        */
37192 +
37193 +       if ((fc->waiting_types & type) != type) {
37194 +               head = head->prev;
37195 +               list_for_each_entry(fence, head, ring) {
37196 +                       if (&fence->ring == &fc->ring)
37197 +                               break;
37198 +                       diff =
37199 +                           (fc->highest_waiting_sequence -
37200 +                            fence->sequence) & fc->sequence_mask;
37201 +                       if (diff > fc->wrap_diff)
37202 +                               break;
37203 +
37204 +                       fc->waiting_types |=
37205 +                           fence->waiting_types & ~fence->info.signaled_types;
37206 +               }
37207 +       }
37208 +
37209 +       if (wake)
37210 +               wake_up_all(&fc->fence_queue);
37211 +}
37212 +
37213 +static void ttm_fence_unring(struct ttm_fence_object *fence)
37214 +{
37215 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37216 +       unsigned long irq_flags;
37217 +
37218 +       write_lock_irqsave(&fc->lock, irq_flags);
37219 +       list_del_init(&fence->ring);
37220 +       write_unlock_irqrestore(&fc->lock, irq_flags);
37221 +}
37222 +
37223 +bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask)
37224 +{
37225 +       unsigned long flags;
37226 +       bool signaled;
37227 +       const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
37228 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37229 +
37230 +       mask &= fence->fence_type;
37231 +       read_lock_irqsave(&fc->lock, flags);
37232 +       signaled = (mask & fence->info.signaled_types) == mask;
37233 +       read_unlock_irqrestore(&fc->lock, flags);
37234 +       if (!signaled && driver->poll) {
37235 +               write_lock_irqsave(&fc->lock, flags);
37236 +               driver->poll(fence->fdev, fence->fence_class, mask);
37237 +               signaled = (mask & fence->info.signaled_types) == mask;
37238 +               write_unlock_irqrestore(&fc->lock, flags);
37239 +       }
37240 +       return signaled;
37241 +}
37242 +
37243 +int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type)
37244 +{
37245 +       const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
37246 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37247 +       unsigned long irq_flags;
37248 +       uint32_t saved_pending_flush;
37249 +       uint32_t diff;
37250 +       bool call_flush;
37251 +
37252 +       if (type & ~fence->fence_type) {
37253 +               DRM_ERROR("Flush trying to extend fence type, "
37254 +                         "0x%x, 0x%x\n", type, fence->fence_type);
37255 +               return -EINVAL;
37256 +       }
37257 +
37258 +       write_lock_irqsave(&fc->lock, irq_flags);
37259 +       fence->waiting_types |= type;
37260 +       fc->waiting_types |= fence->waiting_types;
37261 +       diff = (fence->sequence - fc->highest_waiting_sequence) &
37262 +           fc->sequence_mask;
37263 +
37264 +       if (diff < fc->wrap_diff)
37265 +               fc->highest_waiting_sequence = fence->sequence;
37266 +
37267 +       /*
37268 +        * fence->waiting_types has changed. Determine whether
37269 +        * we need to initiate some kind of flush as a result of this.
37270 +        */
37271 +
37272 +       saved_pending_flush = fc->pending_flush;
37273 +       if (driver->needed_flush)
37274 +               fc->pending_flush |= driver->needed_flush(fence);
37275 +
37276 +       if (driver->poll)
37277 +               driver->poll(fence->fdev, fence->fence_class,
37278 +                            fence->waiting_types);
37279 +
37280 +       call_flush = (fc->pending_flush != 0);
37281 +       write_unlock_irqrestore(&fc->lock, irq_flags);
37282 +
37283 +       if (call_flush && driver->flush)
37284 +               driver->flush(fence->fdev, fence->fence_class);
37285 +
37286 +       return 0;
37287 +}
37288 +
37289 +/*
37290 + * Make sure old fence objects are signaled before their fence sequences are
37291 + * wrapped around and reused.
37292 + */
37293 +
37294 +void ttm_fence_flush_old(struct ttm_fence_device *fdev,
37295 +                        uint32_t fence_class, uint32_t sequence)
37296 +{
37297 +       struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
37298 +       struct ttm_fence_object *fence;
37299 +       unsigned long irq_flags;
37300 +       const struct ttm_fence_driver *driver = fdev->driver;
37301 +       bool call_flush;
37302 +
37303 +       uint32_t diff;
37304 +
37305 +       write_lock_irqsave(&fc->lock, irq_flags);
37306 +
37307 +       list_for_each_entry_reverse(fence, &fc->ring, ring) {
37308 +               diff = (sequence - fence->sequence) & fc->sequence_mask;
37309 +               if (diff <= fc->flush_diff)
37310 +                       break;
37311 +
37312 +               fence->waiting_types = fence->fence_type;
37313 +               fc->waiting_types |= fence->fence_type;
37314 +
37315 +               if (driver->needed_flush)
37316 +                       fc->pending_flush |= driver->needed_flush(fence);
37317 +       }
37318 +
37319 +       if (driver->poll)
37320 +               driver->poll(fdev, fence_class, fc->waiting_types);
37321 +
37322 +       call_flush = (fc->pending_flush != 0);
37323 +       write_unlock_irqrestore(&fc->lock, irq_flags);
37324 +
37325 +       if (call_flush && driver->flush)
37326 +               driver->flush(fdev, fence->fence_class);
37327 +
37328 +       /*
37329 +        * FIXME: Shold we implement a wait here for really old fences?
37330 +        */
37331 +
37332 +}
37333 +
37334 +int ttm_fence_object_wait(struct ttm_fence_object *fence,
37335 +                         bool lazy, bool interruptible, uint32_t mask)
37336 +{
37337 +       const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
37338 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37339 +       int ret = 0;
37340 +       unsigned long timeout;
37341 +       unsigned long cur_jiffies;
37342 +       unsigned long to_jiffies;
37343 +
37344 +       if (mask & ~fence->fence_type) {
37345 +               DRM_ERROR("Wait trying to extend fence type"
37346 +                         " 0x%08x 0x%08x\n", mask, fence->fence_type);
37347 +               BUG();
37348 +               return -EINVAL;
37349 +       }
37350 +
37351 +       if (driver->wait)
37352 +               return driver->wait(fence, lazy, interruptible, mask);
37353 +
37354 +       ttm_fence_object_flush(fence, mask);
37355 +retry:
37356 +       if (!driver->has_irq ||
37357 +           driver->has_irq(fence->fdev, fence->fence_class, mask)) {
37358 +
37359 +               cur_jiffies = jiffies;
37360 +               to_jiffies = fence->timeout_jiffies;
37361 +
37362 +               timeout = (time_after(to_jiffies, cur_jiffies)) ?
37363 +                   to_jiffies - cur_jiffies : 1;
37364 +
37365 +               if (interruptible)
37366 +                       ret = wait_event_interruptible_timeout
37367 +                           (fc->fence_queue,
37368 +                            ttm_fence_object_signaled(fence, mask), timeout);
37369 +               else
37370 +                       ret = wait_event_timeout
37371 +                           (fc->fence_queue,
37372 +                            ttm_fence_object_signaled(fence, mask), timeout);
37373 +
37374 +               if (unlikely(ret == -ERESTARTSYS))
37375 +                       return -ERESTART;
37376 +
37377 +               if (unlikely(ret == 0)) {
37378 +                       if (driver->lockup)
37379 +                               driver->lockup(fence, mask);
37380 +                       else
37381 +                               ttm_fence_lockup(fence, mask);
37382 +                       goto retry;
37383 +               }
37384 +
37385 +               return 0;
37386 +       }
37387 +
37388 +       return ttm_fence_wait_polling(fence, lazy, interruptible, mask);
37389 +}
37390 +
37391 +int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags,
37392 +                         uint32_t fence_class, uint32_t type)
37393 +{
37394 +       const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
37395 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37396 +       unsigned long flags;
37397 +       uint32_t sequence;
37398 +       unsigned long timeout;
37399 +       int ret;
37400 +
37401 +       ttm_fence_unring(fence);
37402 +       ret = driver->emit(fence->fdev,
37403 +                          fence_class, fence_flags, &sequence, &timeout);
37404 +       if (ret)
37405 +               return ret;
37406 +
37407 +       write_lock_irqsave(&fc->lock, flags);
37408 +       fence->fence_class = fence_class;
37409 +       fence->fence_type = type;
37410 +       fence->waiting_types = 0;
37411 +       fence->info.signaled_types = 0;
37412 +       fence->info.error = 0;
37413 +       fence->sequence = sequence;
37414 +       fence->timeout_jiffies = timeout;
37415 +       if (list_empty(&fc->ring))
37416 +               fc->highest_waiting_sequence = sequence - 1;
37417 +       list_add_tail(&fence->ring, &fc->ring);
37418 +       fc->latest_queued_sequence = sequence;
37419 +       write_unlock_irqrestore(&fc->lock, flags);
37420 +       return 0;
37421 +}
37422 +
37423 +int ttm_fence_object_init(struct ttm_fence_device *fdev,
37424 +                         uint32_t fence_class,
37425 +                         uint32_t type,
37426 +                         uint32_t create_flags,
37427 +                         void (*destroy) (struct ttm_fence_object *),
37428 +                         struct ttm_fence_object *fence)
37429 +{
37430 +       int ret = 0;
37431 +
37432 +       kref_init(&fence->kref);
37433 +       fence->fence_class = fence_class;
37434 +       fence->fence_type = type;
37435 +       fence->info.signaled_types = 0;
37436 +       fence->waiting_types = 0;
37437 +       fence->sequence = 0;
37438 +       fence->info.error = 0;
37439 +       fence->fdev = fdev;
37440 +       fence->destroy = destroy;
37441 +       INIT_LIST_HEAD(&fence->ring);
37442 +       atomic_inc(&fdev->count);
37443 +
37444 +       if (create_flags & TTM_FENCE_FLAG_EMIT) {
37445 +               ret = ttm_fence_object_emit(fence, create_flags,
37446 +                                           fence->fence_class, type);
37447 +       }
37448 +
37449 +       return ret;
37450 +}
37451 +
37452 +int ttm_fence_object_create(struct ttm_fence_device *fdev,
37453 +                           uint32_t fence_class,
37454 +                           uint32_t type,
37455 +                           uint32_t create_flags,
37456 +                           struct ttm_fence_object **c_fence)
37457 +{
37458 +       struct ttm_fence_object *fence;
37459 +       int ret;
37460 +
37461 +       ret = ttm_mem_global_alloc(fdev->mem_glob,
37462 +                                  sizeof(*fence),
37463 +                                  false,
37464 +                                  false,
37465 +                                  false);
37466 +       if (unlikely(ret != 0)) {
37467 +               printk(KERN_ERR "Out of memory creating fence object\n");
37468 +               return ret;
37469 +       }
37470 +
37471 +       fence = kmalloc(sizeof(*fence), GFP_KERNEL);
37472 +       if (!fence) {
37473 +               printk(KERN_ERR "Out of memory creating fence object\n");
37474 +               ttm_mem_global_free(fdev->mem_glob, sizeof(*fence), false);
37475 +               return -ENOMEM;
37476 +       }
37477 +
37478 +       ret = ttm_fence_object_init(fdev, fence_class, type,
37479 +                                   create_flags, NULL, fence);
37480 +       if (ret) {
37481 +               ttm_fence_object_unref(&fence);
37482 +               return ret;
37483 +       }
37484 +       *c_fence = fence;
37485 +
37486 +       return 0;
37487 +}
37488 +
37489 +static void ttm_fence_object_destroy(struct kref *kref)
37490 +{
37491 +       struct ttm_fence_object *fence =
37492 +           container_of(kref, struct ttm_fence_object, kref);
37493 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37494 +       unsigned long irq_flags;
37495 +
37496 +       write_lock_irqsave(&fc->lock, irq_flags);
37497 +       list_del_init(&fence->ring);
37498 +       write_unlock_irqrestore(&fc->lock, irq_flags);
37499 +
37500 +       atomic_dec(&fence->fdev->count);
37501 +       if (fence->destroy)
37502 +               fence->destroy(fence);
37503 +       else {
37504 +               ttm_mem_global_free(fence->fdev->mem_glob,
37505 +                                   sizeof(*fence),
37506 +                                   false);
37507 +               kfree(fence);
37508 +       }
37509 +}
37510 +
37511 +void ttm_fence_device_release(struct ttm_fence_device *fdev)
37512 +{
37513 +       kfree(fdev->fence_class);
37514 +}
37515 +
37516 +int
37517 +ttm_fence_device_init(int num_classes,
37518 +                     struct ttm_mem_global *mem_glob,
37519 +                     struct ttm_fence_device *fdev,
37520 +                     const struct ttm_fence_class_init *init,
37521 +                     bool replicate_init,
37522 +                     const struct ttm_fence_driver *driver)
37523 +{
37524 +       struct ttm_fence_class_manager *fc;
37525 +       const struct ttm_fence_class_init *fci;
37526 +       int i;
37527 +
37528 +       fdev->mem_glob = mem_glob;
37529 +       fdev->fence_class = kzalloc(num_classes *
37530 +                                   sizeof(*fdev->fence_class), GFP_KERNEL);
37531 +
37532 +       if (unlikely(!fdev->fence_class))
37533 +               return -ENOMEM;
37534 +
37535 +       fdev->num_classes = num_classes;
37536 +       atomic_set(&fdev->count, 0);
37537 +       fdev->driver = driver;
37538 +
37539 +       for (i = 0; i < fdev->num_classes; ++i) {
37540 +               fc = &fdev->fence_class[i];
37541 +               fci = &init[(replicate_init) ? 0 : i];
37542 +
37543 +               fc->wrap_diff = fci->wrap_diff;
37544 +               fc->flush_diff = fci->flush_diff;
37545 +               fc->sequence_mask = fci->sequence_mask;
37546 +
37547 +               rwlock_init(&fc->lock);
37548 +               INIT_LIST_HEAD(&fc->ring);
37549 +               init_waitqueue_head(&fc->fence_queue);
37550 +       }
37551 +
37552 +       return 0;
37553 +}
37554 +
37555 +struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence)
37556 +{
37557 +       struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
37558 +       struct ttm_fence_info tmp;
37559 +       unsigned long irq_flags;
37560 +
37561 +       read_lock_irqsave(&fc->lock, irq_flags);
37562 +       tmp = fence->info;
37563 +       read_unlock_irqrestore(&fc->lock, irq_flags);
37564 +
37565 +       return tmp;
37566 +}
37567 +
37568 +void ttm_fence_object_unref(struct ttm_fence_object **p_fence)
37569 +{
37570 +       struct ttm_fence_object *fence = *p_fence;
37571 +
37572 +       *p_fence = NULL;
37573 +       (void)kref_put(&fence->kref, &ttm_fence_object_destroy);
37574 +}
37575 +
37576 +/*
37577 + * Placement / BO sync object glue.
37578 + */
37579 +
37580 +bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg)
37581 +{
37582 +       struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
37583 +       uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
37584 +
37585 +       return ttm_fence_object_signaled(fence, fence_types);
37586 +}
37587 +
37588 +int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
37589 +                           bool lazy, bool interruptible)
37590 +{
37591 +       struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
37592 +       uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
37593 +
37594 +       return ttm_fence_object_wait(fence, lazy, interruptible, fence_types);
37595 +}
37596 +
37597 +int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg)
37598 +{
37599 +       struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
37600 +       uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
37601 +
37602 +       return ttm_fence_object_flush(fence, fence_types);
37603 +}
37604 +
37605 +void ttm_fence_sync_obj_unref(void **sync_obj)
37606 +{
37607 +       ttm_fence_object_unref((struct ttm_fence_object **)sync_obj);
37608 +}
37609 +
37610 +void *ttm_fence_sync_obj_ref(void *sync_obj)
37611 +{
37612 +       return (void *)
37613 +           ttm_fence_object_ref((struct ttm_fence_object *)sync_obj);
37614 +}
37615 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_api.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_api.h
37616 new file mode 100644
37617 index 0000000..d42904c
37618 --- /dev/null
37619 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_api.h
37620 @@ -0,0 +1,272 @@
37621 +/**************************************************************************
37622 + *
37623 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
37624 + * All Rights Reserved.
37625 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
37626 + * All Rights Reserved.
37627 + *
37628 + * This program is free software; you can redistribute it and/or modify it
37629 + * under the terms and conditions of the GNU General Public License,
37630 + * version 2, as published by the Free Software Foundation.
37631 + *
37632 + * This program is distributed in the hope it will be useful, but WITHOUT
37633 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37634 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
37635 + * more details.
37636 + *
37637 + * You should have received a copy of the GNU General Public License along with
37638 + * this program; if not, write to the Free Software Foundation, Inc., 
37639 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
37640 + *
37641 + **************************************************************************/
37642 +/*
37643 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
37644 + */
37645 +#ifndef _TTM_FENCE_API_H_
37646 +#define _TTM_FENCE_API_H_
37647 +
37648 +#include <linux/list.h>
37649 +#include <linux/kref.h>
37650 +
37651 +#define TTM_FENCE_FLAG_EMIT (1 << 0)
37652 +#define TTM_FENCE_TYPE_EXE  (1 << 0)
37653 +
37654 +struct ttm_fence_device;
37655 +
37656 +/**
37657 + * struct ttm_fence_info
37658 + *
37659 + * @fence_class:    The fence class.
37660 + * @fence_type:     Bitfield indicating types for this fence.
37661 + * @signaled_types: Bitfield indicating which types are signaled.
37662 + * @error:          Last error reported from the device.
37663 + *
37664 + * Used as output from the ttm_fence_get_info
37665 + */
37666 +
37667 +struct ttm_fence_info {
37668 +       uint32_t signaled_types;
37669 +       uint32_t error;
37670 +};
37671 +
37672 +/**
37673 + * struct ttm_fence_object
37674 + *
37675 + * @fdev:            Pointer to the fence device struct.
37676 + * @kref:            Holds the reference count of this fence object.
37677 + * @ring:            List head used for the circular list of not-completely
37678 + *                   signaled fences.
37679 + * @info:            Data for fast retrieval using the ttm_fence_get_info()
37680 + * function.
37681 + * @timeout_jiffies: Absolute jiffies value indicating when this fence
37682 + *                   object times out and, if waited on, calls ttm_fence_lockup
37683 + *                   to check for and resolve a GPU lockup.
37684 + * @sequence:        Fence sequence number.
37685 + * @waiting_types:   Types currently waited on.
37686 + * @destroy:         Called to free the fence object, when its refcount has
37687 + *                   reached zero. If NULL, kfree is used.
37688 + *
37689 + * This struct is provided in the driver interface so that drivers can
37690 + * derive from it and create their own fence implementation. All members
37691 + * are private to the fence implementation and the fence driver callbacks.
37692 + * Otherwise a driver may access the derived object using container_of().
37693 + */
37694 +
37695 +struct ttm_fence_object {
37696 +       struct ttm_fence_device *fdev;
37697 +       struct kref kref;
37698 +       uint32_t fence_class;
37699 +       uint32_t fence_type;
37700 +
37701 +       /*
37702 +        * The below fields are protected by the fence class
37703 +        * manager spinlock.
37704 +        */
37705 +
37706 +       struct list_head ring;
37707 +       struct ttm_fence_info info;
37708 +       unsigned long timeout_jiffies;
37709 +       uint32_t sequence;
37710 +       uint32_t waiting_types;
37711 +       void (*destroy) (struct ttm_fence_object *);
37712 +};
37713 +
37714 +/**
37715 + * ttm_fence_object_init
37716 + *
37717 + * @fdev: Pointer to a struct ttm_fence_device.
37718 + * @fence_class: Fence class for this fence.
37719 + * @type: Fence type for this fence.
37720 + * @create_flags: Flags indicating varios actions at init time. At this point
37721 + * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
37722 + * the command stream.
37723 + * @destroy: Destroy function. If NULL, kfree() is used.
37724 + * @fence: The struct ttm_fence_object to initialize.
37725 + *
37726 + * Initialize a pre-allocated fence object. This function, together with the
37727 + * destroy function makes it possible to derive driver-specific fence objects.
37728 + */
37729 +
37730 +extern int
37731 +ttm_fence_object_init(struct ttm_fence_device *fdev,
37732 +                     uint32_t fence_class,
37733 +                     uint32_t type,
37734 +                     uint32_t create_flags,
37735 +                     void (*destroy) (struct ttm_fence_object *fence),
37736 +                     struct ttm_fence_object *fence);
37737 +
37738 +/**
37739 + * ttm_fence_object_create
37740 + *
37741 + * @fdev: Pointer to a struct ttm_fence_device.
37742 + * @fence_class: Fence class for this fence.
37743 + * @type: Fence type for this fence.
37744 + * @create_flags: Flags indicating varios actions at init time. At this point
37745 + * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
37746 + * the command stream.
37747 + * @c_fence: On successful termination, *(@c_fence) will point to the created
37748 + * fence object.
37749 + *
37750 + * Create and initialize a struct ttm_fence_object. The destroy function will
37751 + * be set to kfree().
37752 + */
37753 +
37754 +extern int
37755 +ttm_fence_object_create(struct ttm_fence_device *fdev,
37756 +                       uint32_t fence_class,
37757 +                       uint32_t type,
37758 +                       uint32_t create_flags,
37759 +                       struct ttm_fence_object **c_fence);
37760 +
37761 +/**
37762 + * ttm_fence_object_wait
37763 + *
37764 + * @fence: The fence object to wait on.
37765 + * @lazy: Allow sleeps to reduce the cpu-usage if polling.
37766 + * @interruptible: Sleep interruptible when waiting.
37767 + * @type_mask: Wait for the given type_mask to signal.
37768 + *
37769 + * Wait for a fence to signal the given type_mask. The function will
37770 + * perform a fence_flush using type_mask. (See ttm_fence_object_flush).
37771 + *
37772 + * Returns
37773 + * -ERESTART if interrupted by a signal.
37774 + * May return driver-specific error codes if timed-out.
37775 + */
37776 +
37777 +extern int
37778 +ttm_fence_object_wait(struct ttm_fence_object *fence,
37779 +                     bool lazy, bool interruptible, uint32_t type_mask);
37780 +
37781 +/**
37782 + * ttm_fence_object_flush
37783 + *
37784 + * @fence: The fence object to flush.
37785 + * @flush_mask: Fence types to flush.
37786 + *
37787 + * Make sure that the given fence eventually signals the
37788 + * types indicated by @flush_mask. Note that this may or may not
37789 + * map to a CPU or GPU flush.
37790 + */
37791 +
37792 +extern int
37793 +ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask);
37794 +
37795 +/**
37796 + * ttm_fence_get_info
37797 + *
37798 + * @fence: The fence object.
37799 + *
37800 + * Copy the info block from the fence while holding relevant locks.
37801 + */
37802 +
37803 +struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence);
37804 +
37805 +/**
37806 + * ttm_fence_object_ref
37807 + *
37808 + * @fence: The fence object.
37809 + *
37810 + * Return a ref-counted pointer to the fence object indicated by @fence.
37811 + */
37812 +
37813 +static inline struct ttm_fence_object *ttm_fence_object_ref(struct
37814 +                                                           ttm_fence_object
37815 +                                                           *fence)
37816 +{
37817 +       kref_get(&fence->kref);
37818 +       return fence;
37819 +}
37820 +
37821 +/**
37822 + * ttm_fence_object_unref
37823 + *
37824 + * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object.
37825 + *
37826 + * Unreference the fence object pointed to by *(@p_fence), clearing
37827 + * *(p_fence).
37828 + */
37829 +
37830 +extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence);
37831 +
37832 +/**
37833 + * ttm_fence_object_signaled
37834 + *
37835 + * @fence: Pointer to the struct ttm_fence_object.
37836 + * @mask: Type mask to check whether signaled.
37837 + *
37838 + * This function checks (without waiting) whether the fence object
37839 + * pointed to by @fence has signaled the types indicated by @mask,
37840 + * and returns 1 if true, 0 if false. This function does NOT perform
37841 + * an implicit fence flush.
37842 + */
37843 +
37844 +extern bool
37845 +ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask);
37846 +
37847 +/**
37848 + * ttm_fence_class
37849 + *
37850 + * @fence: Pointer to the struct ttm_fence_object.
37851 + *
37852 + * Convenience function that returns the fence class of a
37853 + * struct ttm_fence_object.
37854 + */
37855 +
37856 +static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence)
37857 +{
37858 +       return fence->fence_class;
37859 +}
37860 +
37861 +/**
37862 + * ttm_fence_types
37863 + *
37864 + * @fence: Pointer to the struct ttm_fence_object.
37865 + *
37866 + * Convenience function that returns the fence types of a
37867 + * struct ttm_fence_object.
37868 + */
37869 +
37870 +static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence)
37871 +{
37872 +       return fence->fence_type;
37873 +}
37874 +
37875 +/*
37876 + * The functions below are wrappers to the above functions, with
37877 + * similar names but with sync_obj omitted. These wrappers are intended
37878 + * to be plugged directly into the buffer object driver's sync object
37879 + * API, if the driver chooses to use ttm_fence_objects as buffer object
37880 + * sync objects. In the prototypes below, a sync_obj is cast to a
37881 + * struct ttm_fence_object, whereas a sync_arg is cast to an
37882 + * uint32_t representing a fence_type argument.
37883 + */
37884 +
37885 +extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg);
37886 +extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
37887 +                                  bool lazy, bool interruptible);
37888 +extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg);
37889 +extern void ttm_fence_sync_obj_unref(void **sync_obj);
37890 +extern void *ttm_fence_sync_obj_ref(void *sync_obj);
37891 +
37892 +#endif
37893 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_driver.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_driver.h
37894 new file mode 100644
37895 index 0000000..1dbd817
37896 --- /dev/null
37897 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_driver.h
37898 @@ -0,0 +1,302 @@
37899 +/**************************************************************************
37900 + *
37901 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
37902 + * All Rights Reserved.
37903 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
37904 + * All Rights Reserved.
37905 + *
37906 + * This program is free software; you can redistribute it and/or modify it
37907 + * under the terms and conditions of the GNU General Public License,
37908 + * version 2, as published by the Free Software Foundation.
37909 + *
37910 + * This program is distributed in the hope it will be useful, but WITHOUT
37911 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37912 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
37913 + * more details.
37914 + *
37915 + * You should have received a copy of the GNU General Public License along with
37916 + * this program; if not, write to the Free Software Foundation, Inc., 
37917 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
37918 + *
37919 + **************************************************************************/
37920 +/*
37921 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
37922 + */
37923 +#ifndef _TTM_FENCE_DRIVER_H_
37924 +#define _TTM_FENCE_DRIVER_H_
37925 +
37926 +#include <linux/kref.h>
37927 +#include <linux/spinlock.h>
37928 +#include <linux/wait.h>
37929 +#include "ttm_fence_api.h"
37930 +#include "ttm_memory.h"
37931 +
37932 +/** @file ttm_fence_driver.h
37933 + *
37934 + * Definitions needed for a driver implementing the
37935 + * ttm_fence subsystem.
37936 + */
37937 +
37938 +/**
37939 + * struct ttm_fence_class_manager:
37940 + *
37941 + * @wrap_diff: Sequence difference to catch 32-bit wrapping.
37942 + * if (seqa - seqb) > @wrap_diff, then seqa < seqb.
37943 + * @flush_diff: Sequence difference to trigger fence flush.
37944 + * if (cur_seq - seqa) > @flush_diff, then consider fence object with
37945 + * seqa as old an needing a flush.
37946 + * @sequence_mask: Mask of valid bits in a fence sequence.
37947 + * @lock: Lock protecting this struct as well as fence objects
37948 + * associated with this struct.
37949 + * @ring: Circular sequence-ordered list of fence objects.
37950 + * @pending_flush: Fence types currently needing a flush.
37951 + * @waiting_types: Fence types that are currently waited for.
37952 + * @fence_queue: Queue of waiters on fences belonging to this fence class.
37953 + * @highest_waiting_sequence: Sequence number of the fence with highest
37954 + * sequence number and that is waited for.
37955 + * @latest_queued_sequence: Sequence number of the fence latest queued
37956 + * on the ring.
37957 + */
37958 +
37959 +struct ttm_fence_class_manager {
37960 +
37961 +       /*
37962 +        * Unprotected constant members.
37963 +        */
37964 +
37965 +       uint32_t wrap_diff;
37966 +       uint32_t flush_diff;
37967 +       uint32_t sequence_mask;
37968 +
37969 +       /*
37970 +        * The rwlock protects this structure as well as
37971 +        * the data in all fence objects belonging to this
37972 +        * class. This should be OK as most fence objects are
37973 +        * only read from once they're created.
37974 +        */
37975 +
37976 +       rwlock_t lock;
37977 +       struct list_head ring;
37978 +       uint32_t pending_flush;
37979 +       uint32_t waiting_types;
37980 +       wait_queue_head_t fence_queue;
37981 +       uint32_t highest_waiting_sequence;
37982 +       uint32_t latest_queued_sequence;
37983 +};
37984 +
37985 +/**
37986 + * struct ttm_fence_device
37987 + *
37988 + * @fence_class:  Array of fence class managers.
37989 + * @num_classes:  Array dimension of @fence_class.
37990 + * @count:        Current number of fence objects for statistics.
37991 + * @driver:       Driver struct.
37992 + *
37993 + * Provided in the driver interface so that the driver can derive
37994 + * from this struct for its driver_private, and accordingly
37995 + * access the driver_private from the fence driver callbacks.
37996 + *
37997 + * All members except "count" are initialized at creation and
37998 + * never touched after that. No protection needed.
37999 + *
38000 + * This struct is private to the fence implementation and to the fence
38001 + * driver callbacks, and may otherwise be used by drivers only to
38002 + * obtain the derived device_private object using container_of().
38003 + */
38004 +
38005 +struct ttm_fence_device {
38006 +       struct ttm_mem_global *mem_glob;
38007 +       struct ttm_fence_class_manager *fence_class;
38008 +       uint32_t num_classes;
38009 +       atomic_t count;
38010 +       const struct ttm_fence_driver *driver;
38011 +};
38012 +
38013 +/**
38014 + * struct ttm_fence_class_init
38015 + *
38016 + * @wrap_diff:    Fence sequence number wrap indicator. If
38017 + * (sequence1 - sequence2) > @wrap_diff, then sequence1 is
38018 + * considered to be older than sequence2.
38019 + * @flush_diff:   Fence sequence number flush indicator.
38020 + * If a non-completely-signaled fence has a fence sequence number
38021 + * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff,
38022 + * the fence is considered too old and it will be flushed upon the
38023 + * next call of ttm_fence_flush_old(), to make sure no fences with
38024 + * stale sequence numbers remains unsignaled. @flush_diff should
38025 + * be sufficiently less than @wrap_diff.
38026 + * @sequence_mask: Mask with valid bits of the fence sequence
38027 + * number set to 1.
38028 + *
38029 + * This struct is used as input to ttm_fence_device_init.
38030 + */
38031 +
38032 +struct ttm_fence_class_init {
38033 +       uint32_t wrap_diff;
38034 +       uint32_t flush_diff;
38035 +       uint32_t sequence_mask;
38036 +};
38037 +
38038 +/**
38039 + * struct ttm_fence_driver
38040 + *
38041 + * @has_irq: Called by a potential waiter. Should return 1 if a
38042 + * fence object with indicated parameters is expected to signal
38043 + * automatically, and 0 if the fence implementation needs to
38044 + * repeatedly call @poll to make it signal.
38045 + * @emit:    Make sure a fence with the given parameters is
38046 + * present in the indicated command stream. Return its sequence number
38047 + * in "breadcrumb".
38048 + * @poll:    Check and report sequences of the given "fence_class"
38049 + *           that have signaled "types"
38050 + * @flush:   Make sure that the types indicated by the bitfield
38051 + *           ttm_fence_class_manager::pending_flush will eventually
38052 + *           signal. These bits have been put together using the
38053 + *           result from the needed_flush function described below.
38054 + * @needed_flush: Given the fence_class and fence_types indicated by
38055 + *           "fence", and the last received fence sequence of this
38056 + *           fence class, indicate what types need a fence flush to
38057 + *           signal. Return as a bitfield.
38058 + * @wait:    Set to non-NULL if the driver wants to override the fence
38059 + *           wait implementation. Return 0 on success, -EBUSY on failure,
38060 + *           and -ERESTART if interruptible and a signal is pending.
38061 + * @signaled:  Driver callback that is called whenever a
38062 + *           ttm_fence_object::signaled_types has changed status.
38063 + *           This function is called from atomic context,
38064 + *           with the ttm_fence_class_manager::lock held in write mode.
38065 + * @lockup:  Driver callback that is called whenever a wait has exceeded
38066 + *           the lifetime of a fence object.
38067 + *           If there is a GPU lockup,
38068 + *           this function should, if possible, reset the GPU,
38069 + *           call the ttm_fence_handler with an error status, and
38070 + *           return. If no lockup was detected, simply extend the
38071 + *           fence timeout_jiffies and return. The driver might
38072 + *           want to protect the lockup check with a mutex and cache a
38073 + *           non-locked-up status for a while to avoid an excessive
38074 + *           amount of lockup checks from every waiting thread.
38075 + */
38076 +
38077 +struct ttm_fence_driver {
38078 +       bool (*has_irq) (struct ttm_fence_device *fdev,
38079 +                       uint32_t fence_class, uint32_t flags);
38080 +       int (*emit) (struct ttm_fence_device *fdev,
38081 +                    uint32_t fence_class,
38082 +                    uint32_t flags,
38083 +                    uint32_t *breadcrumb, unsigned long *timeout_jiffies);
38084 +       void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class);
38085 +       void (*poll) (struct ttm_fence_device *fdev,
38086 +                     uint32_t fence_class, uint32_t types);
38087 +        uint32_t(*needed_flush)
38088 +        (struct ttm_fence_object *fence);
38089 +       int (*wait) (struct ttm_fence_object *fence, bool lazy,
38090 +                    bool interruptible, uint32_t mask);
38091 +       void (*signaled) (struct ttm_fence_object *fence);
38092 +       void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types);
38093 +};
38094 +
38095 +/**
38096 + * function ttm_fence_device_init
38097 + *
38098 + * @num_classes:      Number of fence classes for this fence implementation.
38099 + * @mem_global:       Pointer to the global memory accounting info.
38100 + * @fdev:             Pointer to an uninitialised struct ttm_fence_device.
38101 + * @init:             Array of initialization info for each fence class.
38102 + * @replicate_init:   Use the first @init initialization info for all classes.
38103 + * @driver:           Driver callbacks.
38104 + *
38105 + * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if
38106 + * out-of-memory. Otherwise returns 0.
38107 + */
38108 +extern int
38109 +ttm_fence_device_init(int num_classes,
38110 +                     struct ttm_mem_global *mem_glob,
38111 +                     struct ttm_fence_device *fdev,
38112 +                     const struct ttm_fence_class_init *init,
38113 +                     bool replicate_init,
38114 +                     const struct ttm_fence_driver *driver);
38115 +
38116 +/**
38117 + * function ttm_fence_device_release
38118 + *
38119 + * @fdev:             Pointer to the fence device.
38120 + *
38121 + * Release all resources held by a fence device. Note that before
38122 + * this function is called, the caller must have made sure all fence
38123 + * objects belonging to this fence device are completely signaled.
38124 + */
38125 +
38126 +extern void ttm_fence_device_release(struct ttm_fence_device *fdev);
38127 +
38128 +/**
38129 + * ttm_fence_handler - the fence handler.
38130 + *
38131 + * @fdev:        Pointer to the fence device.
38132 + * @fence_class: Fence class that signals.
38133 + * @sequence:    Signaled sequence.
38134 + * @type:        Types that signal.
38135 + * @error:       Error from the engine.
38136 + *
38137 + * This function signals all fences with a sequence previous to the
38138 + * @sequence argument, and belonging to @fence_class. The signaled fence
38139 + * types are provided in @type. If error is non-zero, the error member
38140 + * of the fence with sequence = @sequence is set to @error. This value
38141 + * may be reported back to user-space, indicating, for example an illegal
38142 + * 3D command or illegal mpeg data.
38143 + *
38144 + * This function is typically called from the driver::poll method when the
38145 + * command sequence preceding the fence marker has executed. It should be
38146 + * called with the ttm_fence_class_manager::lock held in write mode and
38147 + * may be called from interrupt context.
38148 + */
38149 +
38150 +extern void
38151 +ttm_fence_handler(struct ttm_fence_device *fdev,
38152 +                 uint32_t fence_class,
38153 +                 uint32_t sequence, uint32_t type, uint32_t error);
38154 +
38155 +/**
38156 + * ttm_fence_driver_from_dev
38157 + *
38158 + * @fdev:        The ttm fence device.
38159 + *
38160 + * Returns a pointer to the fence driver struct.
38161 + */
38162 +
38163 +static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev(
38164 +                                               struct ttm_fence_device *fdev)
38165 +{
38166 +       return fdev->driver;
38167 +}
38168 +
38169 +/**
38170 + * ttm_fence_driver
38171 + *
38172 + * @fence:        Pointer to a ttm fence object.
38173 + *
38174 + * Returns a pointer to the fence driver struct.
38175 + */
38176 +
38177 +static inline const struct ttm_fence_driver *ttm_fence_driver(struct
38178 +                                                             ttm_fence_object
38179 +                                                             *fence)
38180 +{
38181 +       return ttm_fence_driver_from_dev(fence->fdev);
38182 +}
38183 +
38184 +/**
38185 + * ttm_fence_fc
38186 + *
38187 + * @fence:        Pointer to a ttm fence object.
38188 + *
38189 + * Returns a pointer to the struct ttm_fence_class_manager for the
38190 + * fence class of @fence.
38191 + */
38192 +
38193 +static inline struct ttm_fence_class_manager *ttm_fence_fc(struct
38194 +                                                          ttm_fence_object
38195 +                                                          *fence)
38196 +{
38197 +       return &fence->fdev->fence_class[fence->fence_class];
38198 +}
38199 +
38200 +#endif
38201 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.c
38202 new file mode 100644
38203 index 0000000..878c9bd
38204 --- /dev/null
38205 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.c
38206 @@ -0,0 +1,238 @@
38207 +/**************************************************************************
38208 + *
38209 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
38210 + * All Rights Reserved.
38211 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
38212 + * All Rights Reserved.
38213 + *
38214 + * This program is free software; you can redistribute it and/or modify it
38215 + * under the terms and conditions of the GNU General Public License,
38216 + * version 2, as published by the Free Software Foundation.
38217 + *
38218 + * This program is distributed in the hope it will be useful, but WITHOUT
38219 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38220 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
38221 + * more details.
38222 + *
38223 + * You should have received a copy of the GNU General Public License along with
38224 + * this program; if not, write to the Free Software Foundation, Inc., 
38225 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
38226 + *
38227 + **************************************************************************/
38228 +/*
38229 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
38230 + */
38231 +
38232 +#include <drm/drmP.h>
38233 +#include "ttm_fence_user.h"
38234 +#include "ttm_object.h"
38235 +#include "ttm_fence_driver.h"
38236 +#include "ttm_userobj_api.h"
38237 +
38238 +/**
38239 + * struct ttm_fence_user_object
38240 + *
38241 + * @base:    The base object used for user-space visibility and refcounting.
38242 + *
38243 + * @fence:   The fence object itself.
38244 + *
38245 + */
38246 +
38247 +struct ttm_fence_user_object {
38248 +       struct ttm_base_object base;
38249 +       struct ttm_fence_object fence;
38250 +};
38251 +
38252 +static struct ttm_fence_user_object *ttm_fence_user_object_lookup(
38253 +                                       struct ttm_object_file *tfile,
38254 +                                       uint32_t handle)
38255 +{
38256 +       struct ttm_base_object *base;
38257 +
38258 +       base = ttm_base_object_lookup(tfile, handle);
38259 +       if (unlikely(base == NULL)) {
38260 +               printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
38261 +                      (unsigned long)handle);
38262 +               return NULL;
38263 +       }
38264 +
38265 +       if (unlikely(base->object_type != ttm_fence_type)) {
38266 +               ttm_base_object_unref(&base);
38267 +               printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
38268 +                      (unsigned long)handle);
38269 +               return NULL;
38270 +       }
38271 +
38272 +       return container_of(base, struct ttm_fence_user_object, base);
38273 +}
38274 +
38275 +/*
38276 + * The fence object destructor.
38277 + */
38278 +
38279 +static void ttm_fence_user_destroy(struct ttm_fence_object *fence)
38280 +{
38281 +       struct ttm_fence_user_object *ufence =
38282 +           container_of(fence, struct ttm_fence_user_object, fence);
38283 +
38284 +       ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence), false);
38285 +       kfree(ufence);
38286 +}
38287 +
38288 +/*
38289 + * The base object destructor. We basically unly unreference the
38290 + * attached fence object.
38291 + */
38292 +
38293 +static void ttm_fence_user_release(struct ttm_base_object **p_base)
38294 +{
38295 +       struct ttm_fence_user_object *ufence;
38296 +       struct ttm_base_object *base = *p_base;
38297 +       struct ttm_fence_object *fence;
38298 +
38299 +       *p_base = NULL;
38300 +
38301 +       if (unlikely(base == NULL))
38302 +               return;
38303 +
38304 +       ufence = container_of(base, struct ttm_fence_user_object, base);
38305 +       fence = &ufence->fence;
38306 +       ttm_fence_object_unref(&fence);
38307 +}
38308 +
38309 +int
38310 +ttm_fence_user_create(struct ttm_fence_device *fdev,
38311 +                     struct ttm_object_file *tfile,
38312 +                     uint32_t fence_class,
38313 +                     uint32_t fence_types,
38314 +                     uint32_t create_flags,
38315 +                     struct ttm_fence_object **fence,
38316 +                     uint32_t *user_handle)
38317 +{
38318 +       int ret;
38319 +       struct ttm_fence_object *tmp;
38320 +       struct ttm_fence_user_object *ufence;
38321 +
38322 +       ret = ttm_mem_global_alloc(fdev->mem_glob,
38323 +                                  sizeof(*ufence),
38324 +                                  false,
38325 +                                  false,
38326 +                                  false);
38327 +       if (unlikely(ret != 0))
38328 +               return -ENOMEM;
38329 +
38330 +       ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
38331 +       if (unlikely(ufence == NULL)) {
38332 +               ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence), false);
38333 +               return -ENOMEM;
38334 +       }
38335 +
38336 +       ret = ttm_fence_object_init(fdev,
38337 +                                   fence_class,
38338 +                                   fence_types, create_flags,
38339 +                                   &ttm_fence_user_destroy, &ufence->fence);
38340 +
38341 +       if (unlikely(ret != 0))
38342 +               goto out_err0;
38343 +
38344 +       /*
38345 +        * One fence ref is held by the fence ptr we return.
38346 +        * The other one by the base object. Need to up the
38347 +        * fence refcount before we publish this object to
38348 +        * user-space.
38349 +        */
38350 +
38351 +       tmp = ttm_fence_object_ref(&ufence->fence);
38352 +       ret = ttm_base_object_init(tfile, &ufence->base,
38353 +                                  false, ttm_fence_type,
38354 +                                  &ttm_fence_user_release, NULL);
38355 +
38356 +       if (unlikely(ret != 0))
38357 +               goto out_err1;
38358 +
38359 +       *fence = &ufence->fence;
38360 +       *user_handle = ufence->base.hash.key;
38361 +
38362 +       return 0;
38363 +out_err1:
38364 +       ttm_fence_object_unref(&tmp);
38365 +       tmp = &ufence->fence;
38366 +       ttm_fence_object_unref(&tmp);
38367 +       return ret;
38368 +out_err0:
38369 +       ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence), false);
38370 +       kfree(ufence);
38371 +       return ret;
38372 +}
38373 +
38374 +int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data)
38375 +{
38376 +       int ret;
38377 +       union ttm_fence_signaled_arg *arg = data;
38378 +       struct ttm_fence_object *fence;
38379 +       struct ttm_fence_info info;
38380 +       struct ttm_fence_user_object *ufence;
38381 +       struct ttm_base_object *base;
38382 +       ret = 0;
38383 +
38384 +       ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
38385 +       if (unlikely(ufence == NULL))
38386 +               return -EINVAL;
38387 +
38388 +       fence = &ufence->fence;
38389 +
38390 +       if (arg->req.flush) {
38391 +               ret = ttm_fence_object_flush(fence, arg->req.fence_type);
38392 +               if (unlikely(ret != 0))
38393 +                       goto out;
38394 +       }
38395 +
38396 +       info = ttm_fence_get_info(fence);
38397 +       arg->rep.signaled_types = info.signaled_types;
38398 +       arg->rep.fence_error = info.error;
38399 +
38400 +out:
38401 +       base = &ufence->base;
38402 +       ttm_base_object_unref(&base);
38403 +       return ret;
38404 +}
38405 +
38406 +int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data)
38407 +{
38408 +       int ret;
38409 +       union ttm_fence_finish_arg *arg = data;
38410 +       struct ttm_fence_user_object *ufence;
38411 +       struct ttm_base_object *base;
38412 +       struct ttm_fence_object *fence;
38413 +       ret = 0;
38414 +
38415 +       ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
38416 +       if (unlikely(ufence == NULL))
38417 +               return -EINVAL;
38418 +
38419 +       fence = &ufence->fence;
38420 +
38421 +       ret = ttm_fence_object_wait(fence,
38422 +                                   arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY,
38423 +                                   true, arg->req.fence_type);
38424 +       if (likely(ret == 0)) {
38425 +               struct ttm_fence_info info = ttm_fence_get_info(fence);
38426 +
38427 +               arg->rep.signaled_types = info.signaled_types;
38428 +               arg->rep.fence_error = info.error;
38429 +       }
38430 +
38431 +       base = &ufence->base;
38432 +       ttm_base_object_unref(&base);
38433 +
38434 +       return ret;
38435 +}
38436 +
38437 +int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data)
38438 +{
38439 +       struct ttm_fence_unref_arg *arg = data;
38440 +       int ret = 0;
38441 +
38442 +       ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type);
38443 +       return ret;
38444 +}
38445 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.h
38446 new file mode 100644
38447 index 0000000..ee95e6a
38448 --- /dev/null
38449 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_fence_user.h
38450 @@ -0,0 +1,140 @@
38451 +/**************************************************************************
38452 + *
38453 + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
38454 + * All Rights Reserved.
38455 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
38456 + * All Rights Reserved.
38457 + *
38458 + * This program is free software; you can redistribute it and/or modify it
38459 + * under the terms and conditions of the GNU General Public License,
38460 + * version 2, as published by the Free Software Foundation.
38461 + *
38462 + * This program is distributed in the hope it will be useful, but WITHOUT
38463 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38464 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
38465 + * more details.
38466 + *
38467 + * You should have received a copy of the GNU General Public License along with
38468 + * this program; if not, write to the Free Software Foundation, Inc., 
38469 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
38470 + *
38471 + **************************************************************************/
38472 +/*
38473 + * Authors
38474 + * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
38475 + */
38476 +
38477 +#ifndef TTM_FENCE_USER_H
38478 +#define TTM_FENCE_USER_H
38479 +
38480 +#if !defined(__KERNEL__) && !defined(_KERNEL)
38481 +#include <stdint.h>
38482 +#endif
38483 +
38484 +#define TTM_FENCE_MAJOR 0
38485 +#define TTM_FENCE_MINOR 1
38486 +#define TTM_FENCE_PL    0
38487 +#define TTM_FENCE_DATE  "080819"
38488 +
38489 +/**
38490 + * struct ttm_fence_signaled_req
38491 + *
38492 + * @handle: Handle to the fence object. Input.
38493 + *
38494 + * @fence_type: Fence types we want to flush. Input.
38495 + *
38496 + * @flush: Boolean. Flush the indicated fence_types. Input.
38497 + *
38498 + * Argument to the TTM_FENCE_SIGNALED ioctl.
38499 + */
38500 +
38501 +struct ttm_fence_signaled_req {
38502 +       uint32_t handle;
38503 +       uint32_t fence_type;
38504 +       int32_t flush;
38505 +       uint32_t pad64;
38506 +};
38507 +
38508 +/**
38509 + * struct ttm_fence_rep
38510 + *
38511 + * @signaled_types: Fence type that has signaled.
38512 + *
38513 + * @fence_error: Command execution error.
38514 + * Hardware errors that are consequences of the execution
38515 + * of the command stream preceding the fence are reported
38516 + * here.
38517 + *
38518 + * Output argument to the TTM_FENCE_SIGNALED and
38519 + * TTM_FENCE_FINISH ioctls.
38520 + */
38521 +
38522 +struct ttm_fence_rep {
38523 +       uint32_t signaled_types;
38524 +       uint32_t fence_error;
38525 +};
38526 +
38527 +union ttm_fence_signaled_arg {
38528 +       struct ttm_fence_signaled_req req;
38529 +       struct ttm_fence_rep rep;
38530 +};
38531 +
38532 +/*
38533 + * Waiting mode flags for the TTM_FENCE_FINISH ioctl.
38534 + *
38535 + * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling
38536 + * wait.
38537 + *
38538 + * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU,
38539 + * but return -EBUSY if the buffer is busy.
38540 + */
38541 +
38542 +#define TTM_FENCE_FINISH_MODE_LAZY     (1 << 0)
38543 +#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1)
38544 +
38545 +/**
38546 + * struct ttm_fence_finish_req
38547 + *
38548 + * @handle: Handle to the fence object. Input.
38549 + *
38550 + * @fence_type: Fence types we want to finish.
38551 + *
38552 + * @mode: Wait mode.
38553 + *
38554 + * Input to the TTM_FENCE_FINISH ioctl.
38555 + */
38556 +
38557 +struct ttm_fence_finish_req {
38558 +       uint32_t handle;
38559 +       uint32_t fence_type;
38560 +       uint32_t mode;
38561 +       uint32_t pad64;
38562 +};
38563 +
38564 +union ttm_fence_finish_arg {
38565 +       struct ttm_fence_finish_req req;
38566 +       struct ttm_fence_rep rep;
38567 +};
38568 +
38569 +/**
38570 + * struct ttm_fence_unref_arg
38571 + *
38572 + * @handle: Handle to the fence object.
38573 + *
38574 + * Argument to the TTM_FENCE_UNREF ioctl.
38575 + */
38576 +
38577 +struct ttm_fence_unref_arg {
38578 +       uint32_t handle;
38579 +       uint32_t pad64;
38580 +};
38581 +
38582 +/*
38583 + * Ioctl offsets frome extenstion start.
38584 + */
38585 +
38586 +#define TTM_FENCE_SIGNALED 0x01
38587 +#define TTM_FENCE_FINISH   0x02
38588 +#define TTM_FENCE_UNREF    0x03
38589 +
38590 +#endif
38591 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.c
38592 new file mode 100644
38593 index 0000000..be7464c
38594 --- /dev/null
38595 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.c
38596 @@ -0,0 +1,155 @@
38597 +/**************************************************************************
38598 + *
38599 + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
38600 + * All Rights Reserved.
38601 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
38602 + * All Rights Reserved.
38603 + *
38604 + * This program is free software; you can redistribute it and/or modify it
38605 + * under the terms and conditions of the GNU General Public License,
38606 + * version 2, as published by the Free Software Foundation.
38607 + *
38608 + * This program is distributed in the hope it will be useful, but WITHOUT
38609 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38610 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
38611 + * more details.
38612 + *
38613 + * You should have received a copy of the GNU General Public License along with
38614 + * this program; if not, write to the Free Software Foundation, Inc., 
38615 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
38616 + *
38617 + **************************************************************************/
38618 +/*
38619 + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
38620 + */
38621 +
38622 +#include "ttm_lock.h"
38623 +#include <asm/atomic.h>
38624 +#include <linux/errno.h>
38625 +#include <linux/wait.h>
38626 +#include <linux/sched.h>
38627 +
38628 +void ttm_lock_init(struct ttm_lock *lock)
38629 +{
38630 +       init_waitqueue_head(&lock->queue);
38631 +       atomic_set(&lock->write_lock_pending, 0);
38632 +       atomic_set(&lock->readers, 0);
38633 +       lock->kill_takers = false;
38634 +       lock->signal = SIGKILL;
38635 +}
38636 +
38637 +void ttm_read_unlock(struct ttm_lock *lock)
38638 +{
38639 +       if (atomic_dec_and_test(&lock->readers))
38640 +               wake_up_all(&lock->queue);
38641 +}
38642 +
38643 +int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
38644 +{
38645 +       while (unlikely(atomic_read(&lock->write_lock_pending) != 0)) {
38646 +               int ret;
38647 +
38648 +               if (!interruptible) {
38649 +                       wait_event(lock->queue,
38650 +                                  atomic_read(&lock->write_lock_pending) == 0);
38651 +                       continue;
38652 +               }
38653 +               ret = wait_event_interruptible
38654 +                   (lock->queue, atomic_read(&lock->write_lock_pending) == 0);
38655 +               if (ret)
38656 +                       return -ERESTART;
38657 +       }
38658 +
38659 +       while (unlikely(!atomic_add_unless(&lock->readers, 1, -1))) {
38660 +               int ret;
38661 +               if (!interruptible) {
38662 +                       wait_event(lock->queue,
38663 +                                  atomic_read(&lock->readers) != -1);
38664 +                       continue;
38665 +               }
38666 +               ret = wait_event_interruptible
38667 +                   (lock->queue, atomic_read(&lock->readers) != -1);
38668 +               if (ret)
38669 +                       return -ERESTART;
38670 +       }
38671 +
38672 +       if (unlikely(lock->kill_takers)) {
38673 +               send_sig(lock->signal, current, 0);
38674 +               ttm_read_unlock(lock);
38675 +               return -ERESTART;
38676 +       }
38677 +
38678 +       return 0;
38679 +}
38680 +
38681 +static int __ttm_write_unlock(struct ttm_lock *lock)
38682 +{
38683 +       if (unlikely(atomic_cmpxchg(&lock->readers, -1, 0) != -1))
38684 +               return -EINVAL;
38685 +       wake_up_all(&lock->queue);
38686 +       return 0;
38687 +}
38688 +
38689 +static void ttm_write_lock_remove(struct ttm_base_object **p_base)
38690 +{
38691 +       struct ttm_base_object *base = *p_base;
38692 +       struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
38693 +       int ret;
38694 +
38695 +       *p_base = NULL;
38696 +       ret = __ttm_write_unlock(lock);
38697 +       BUG_ON(ret != 0);
38698 +}
38699 +
38700 +int ttm_write_lock(struct ttm_lock *lock,
38701 +                  bool interruptible,
38702 +                  struct ttm_object_file *tfile)
38703 +{
38704 +       int ret = 0;
38705 +
38706 +       atomic_inc(&lock->write_lock_pending);
38707 +
38708 +       while (unlikely(atomic_cmpxchg(&lock->readers, 0, -1) != 0)) {
38709 +               if (!interruptible) {
38710 +                       wait_event(lock->queue,
38711 +                                  atomic_read(&lock->readers) == 0);
38712 +                       continue;
38713 +               }
38714 +               ret = wait_event_interruptible
38715 +                   (lock->queue, atomic_read(&lock->readers) == 0);
38716 +
38717 +               if (ret) {
38718 +                       if (atomic_dec_and_test(&lock->write_lock_pending))
38719 +                               wake_up_all(&lock->queue);
38720 +                       return -ERESTART;
38721 +               }
38722 +       }
38723 +
38724 +       if (atomic_dec_and_test(&lock->write_lock_pending))
38725 +               wake_up_all(&lock->queue);
38726 +
38727 +       if (unlikely(lock->kill_takers)) {
38728 +               send_sig(lock->signal, current, 0);
38729 +               __ttm_write_unlock(lock);
38730 +               return -ERESTART;
38731 +       }
38732 +
38733 +       /*
38734 +        * Add a base-object, the destructor of which will
38735 +        * make sure the lock is released if the client dies
38736 +        * while holding it.
38737 +        */
38738 +
38739 +       ret = ttm_base_object_init(tfile, &lock->base, false,
38740 +                                  ttm_lock_type, &ttm_write_lock_remove, NULL);
38741 +       if (ret)
38742 +               (void)__ttm_write_unlock(lock);
38743 +
38744 +       return ret;
38745 +}
38746 +
38747 +int ttm_write_unlock(struct ttm_lock *lock, struct ttm_object_file *tfile)
38748 +{
38749 +       return ttm_ref_object_base_unref(tfile,
38750 +                                        lock->base.hash.key, TTM_REF_USAGE);
38751 +}
38752 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.h
38753 new file mode 100644
38754 index 0000000..500b2c1
38755 --- /dev/null
38756 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_lock.h
38757 @@ -0,0 +1,176 @@
38758 +/**************************************************************************
38759 + *
38760 + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
38761 + * All Rights Reserved.
38762 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
38763 + * All Rights Reserved.
38764 + *
38765 + * This program is free software; you can redistribute it and/or modify it
38766 + * under the terms and conditions of the GNU General Public License,
38767 + * version 2, as published by the Free Software Foundation.
38768 + *
38769 + * This program is distributed in the hope it will be useful, but WITHOUT
38770 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38771 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
38772 + * more details.
38773 + *
38774 + * You should have received a copy of the GNU General Public License along with
38775 + * this program; if not, write to the Free Software Foundation, Inc., 
38776 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
38777 + *
38778 + **************************************************************************/
38779 +/*
38780 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
38781 + */
38782 +
38783 +/** @file ttm_lock.h
38784 + * This file implements a simple replacement for the buffer manager use
38785 + * of the DRM heavyweight hardware lock.
38786 + * The lock is a read-write lock. Taking it in read mode is fast, and
38787 + * intended for in-kernel use only.
38788 + * Taking it in write mode is slow.
38789 + *
38790 + * The write mode is used only when there is a need to block all
38791 + * user-space processes from validating buffers.
38792 + * It's allowed to leave kernel space with the write lock held.
38793 + * If a user-space process dies while having the write-lock,
38794 + * it will be released during the file descriptor release.
38795 + *
38796 + * The read lock is typically placed at the start of an IOCTL- or
38797 + * user-space callable function that may end up allocating a memory area.
38798 + * This includes setstatus, super-ioctls and faults; the latter may move
38799 + * unmappable regions to mappable. It's a bug to leave kernel space with the
38800 + * read lock held.
38801 + *
38802 + * Both read- and write lock taking is interruptible for low signal-delivery
38803 + * latency. The locking functions will return -ERESTART if interrupted by a
38804 + * signal.
38805 + *
38806 + * Locking order: The lock should be taken BEFORE any TTM mutexes
38807 + * or spinlocks.
38808 + *
38809 + * Typical usages:
38810 + * a) VT-switching, when we want to clean VRAM and perhaps AGP. The lock
38811 + * stops it from being repopulated.
38812 + * b) out-of-VRAM or out-of-aperture space, in which case the process
38813 + * receiving the out-of-space notification may take the lock in write mode
38814 + * and evict all buffers prior to start validating its own buffers.
38815 + */
38816 +
38817 +#ifndef _TTM_LOCK_H_
38818 +#define _TTM_LOCK_H_
38819 +
38820 +#include "ttm_object.h"
38821 +#include <linux/wait.h>
38822 +#include <asm/atomic.h>
38823 +
38824 +/**
38825 + * struct ttm_lock
38826 + *
38827 + * @base: ttm base object used solely to release the lock if the client
38828 + * holding the lock dies.
38829 + * @queue: Queue for processes waiting for lock change-of-status.
38830 + * @write_lock_pending: Flag indicating that a write-lock is pending. Avoids
38831 + * write lock starvation.
38832 + * @readers: The lock status: A negative number indicates that a write lock is
38833 + * held. Positive values indicate number of concurrent readers.
38834 + */
38835 +
38836 +struct ttm_lock {
38837 +       struct ttm_base_object base;
38838 +       wait_queue_head_t queue;
38839 +       atomic_t write_lock_pending;
38840 +       atomic_t readers;
38841 +       bool kill_takers;
38842 +       int signal;
38843 +};
38844 +
38845 +/**
38846 + * ttm_lock_init
38847 + *
38848 + * @lock: Pointer to a struct ttm_lock
38849 + * Initializes the lock.
38850 + */
38851 +extern void ttm_lock_init(struct ttm_lock *lock);
38852 +
38853 +/**
38854 + * ttm_read_unlock
38855 + *
38856 + * @lock: Pointer to a struct ttm_lock
38857 + *
38858 + * Releases a read lock.
38859 + */
38860 +
38861 +extern void ttm_read_unlock(struct ttm_lock *lock);
38862 +
38863 +/**
38864 + * ttm_read_unlock
38865 + *
38866 + * @lock: Pointer to a struct ttm_lock
38867 + * @interruptible: Interruptible sleeping while waiting for a lock.
38868 + *
38869 + * Takes the lock in read mode.
38870 + * Returns:
38871 + * -ERESTART If interrupted by a signal and interruptible is true.
38872 + */
38873 +
38874 +extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
38875 +
38876 +/**
38877 + * ttm_write_lock
38878 + *
38879 + * @lock: Pointer to a struct ttm_lock
38880 + * @interruptible: Interruptible sleeping while waiting for a lock.
38881 + * @tfile: Pointer to a struct ttm_object_file used to identify the user-space
38882 + * application taking the lock.
38883 + *
38884 + * Takes the lock in write mode.
38885 + * Returns:
38886 + * -ERESTART If interrupted by a signal and interruptible is true.
38887 + * -ENOMEM: Out of memory when locking.
38888 + */
38889 +extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible,
38890 +                         struct ttm_object_file *tfile);
38891 +
38892 +/**
38893 + * ttm_write_unlock
38894 + *
38895 + * @lock: Pointer to a struct ttm_lock
38896 + * @tfile: Pointer to a struct ttm_object_file used to identify the user-space
38897 + * application taking the lock.
38898 + *
38899 + * Releases a write lock.
38900 + * Returns:
38901 + * -EINVAL If the lock was not held.
38902 + */
38903 +extern int ttm_write_unlock(struct ttm_lock *lock,
38904 +                           struct ttm_object_file *tfile);
38905 +
38906 +/**
38907 + * ttm_lock_set_kill
38908 + *
38909 + * @lock: Pointer to a struct ttm_lock
38910 + * @val: Boolean whether to kill processes taking the lock.
38911 + * @signal: Signal to send to the process taking the lock.
38912 + *
38913 + * The kill-when-taking-lock functionality is used to kill processes that keep
38914 + * on using the TTM functionality when its resources has been taken down, for
38915 + * example when the X server exits. A typical sequence would look like this:
38916 + * - X server takes lock in write mode.
38917 + * - ttm_lock_set_kill() is called with @val set to true.
38918 + * - As part of X server exit, TTM resources are taken down.
38919 + * - X server releases the lock on file release.
38920 + * - Another dri client wants to render, takes the lock and is killed.
38921 + *
38922 + */
38923 +
38924 +static inline void ttm_lock_set_kill(struct ttm_lock *lock,
38925 +                                    bool val,
38926 +                                    int signal)
38927 +{
38928 +       lock->kill_takers = val;
38929 +       if (val)
38930 +               lock->signal = signal;
38931 +}
38932 +
38933 +#endif
38934 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.c
38935 new file mode 100644
38936 index 0000000..363c1c3
38937 --- /dev/null
38938 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.c
38939 @@ -0,0 +1,228 @@
38940 +/**************************************************************************
38941 + *
38942 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
38943 + * All Rights Reserved.
38944 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
38945 + * All Rights Reserved.
38946 + *
38947 + * This program is free software; you can redistribute it and/or modify it
38948 + * under the terms and conditions of the GNU General Public License,
38949 + * version 2, as published by the Free Software Foundation.
38950 + *
38951 + * This program is distributed in the hope it will be useful, but WITHOUT
38952 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38953 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
38954 + * more details.
38955 + *
38956 + * You should have received a copy of the GNU General Public License along with
38957 + * this program; if not, write to the Free Software Foundation, Inc., 
38958 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
38959 + *
38960 + **************************************************************************/
38961 +
38962 +#include "ttm_memory.h"
38963 +#include <linux/spinlock.h>
38964 +#include <linux/sched.h>
38965 +#include <linux/wait.h>
38966 +#include <linux/mm.h>
38967 +
38968 +#define TTM_MEMORY_ALLOC_RETRIES 4
38969 +
38970 +/**
38971 + * At this point we only support a single shrink callback.
38972 + * Extend this if needed, perhaps using a linked list of callbacks.
38973 + * Note that this function is reentrant:
38974 + * many threads may try to swap out at any given time.
38975 + */
38976 +
38977 +static void ttm_shrink(struct ttm_mem_global *glob, bool from_workqueue,
38978 +                      uint64_t extra)
38979 +{
38980 +       int ret;
38981 +       struct ttm_mem_shrink *shrink;
38982 +       uint64_t target;
38983 +       uint64_t total_target;
38984 +
38985 +       spin_lock(&glob->lock);
38986 +       if (glob->shrink == NULL)
38987 +               goto out;
38988 +
38989 +       if (from_workqueue) {
38990 +               target = glob->swap_limit;
38991 +               total_target = glob->total_memory_swap_limit;
38992 +       } else if (capable(CAP_SYS_ADMIN)) {
38993 +               total_target = glob->emer_total_memory;
38994 +               target = glob->emer_memory;
38995 +       } else {
38996 +               total_target = glob->max_total_memory;
38997 +               target = glob->max_memory;
38998 +       }
38999 +
39000 +       total_target = (extra >= total_target) ? 0 : total_target - extra;
39001 +       target = (extra >= target) ? 0 : target - extra;
39002 +
39003 +       while (glob->used_memory > target ||
39004 +              glob->used_total_memory > total_target) {
39005 +               shrink = glob->shrink;
39006 +               spin_unlock(&glob->lock);
39007 +               ret = shrink->do_shrink(shrink);
39008 +               spin_lock(&glob->lock);
39009 +               if (unlikely(ret != 0))
39010 +                       goto out;
39011 +       }
39012 +out:
39013 +       spin_unlock(&glob->lock);
39014 +}
39015 +
39016 +static void ttm_shrink_work(struct work_struct *work)
39017 +{
39018 +       struct ttm_mem_global *glob =
39019 +           container_of(work, struct ttm_mem_global, work);
39020 +
39021 +       ttm_shrink(glob, true, 0ULL);
39022 +}
39023 +
39024 +int ttm_mem_global_init(struct ttm_mem_global *glob)
39025 +{
39026 +       struct sysinfo si;
39027 +       uint64_t mem;
39028 +
39029 +       spin_lock_init(&glob->lock);
39030 +       glob->swap_queue = create_singlethread_workqueue("ttm_swap");
39031 +       INIT_WORK(&glob->work, ttm_shrink_work);
39032 +       init_waitqueue_head(&glob->queue);
39033 +
39034 +       si_meminfo(&si);
39035 +
39036 +       mem = si.totalram - si.totalhigh;
39037 +       mem *= si.mem_unit;
39038 +
39039 +       glob->max_memory = mem >> 1;
39040 +       glob->emer_memory = glob->max_memory + (mem >> 2);
39041 +       glob->swap_limit = glob->max_memory - (mem >> 5);
39042 +       glob->used_memory = 0;
39043 +       glob->used_total_memory = 0;
39044 +       glob->shrink = NULL;
39045 +
39046 +       mem = si.totalram;
39047 +       mem *= si.mem_unit;
39048 +
39049 +       glob->max_total_memory = mem >> 1;
39050 +       glob->emer_total_memory = glob->max_total_memory + (mem >> 2);
39051 +       glob->total_memory_swap_limit = glob->max_total_memory - (mem >> 5);
39052 +
39053 +       printk(KERN_INFO "TTM available graphics memory: %llu MiB\n",
39054 +              glob->max_total_memory >> 20);
39055 +       printk(KERN_INFO "TTM available object memory: %llu MiB\n",
39056 +              glob->max_memory >> 20);
39057 +       printk(KERN_INFO "TTM available swap breakpoint: %llu MiB\n",
39058 +              glob->swap_limit >> 20);
39059 +
39060 +       return 0;
39061 +}
39062 +
39063 +void ttm_mem_global_release(struct ttm_mem_global *glob)
39064 +{
39065 +       printk(KERN_INFO "Used total memory is %llu bytes.\n",
39066 +              (unsigned long long)glob->used_total_memory);
39067 +       flush_workqueue(glob->swap_queue);
39068 +       destroy_workqueue(glob->swap_queue);
39069 +       glob->swap_queue = NULL;
39070 +}
39071 +
39072 +static inline void ttm_check_swapping(struct ttm_mem_global *glob)
39073 +{
39074 +       bool needs_swapping;
39075 +
39076 +       spin_lock(&glob->lock);
39077 +       needs_swapping = (glob->used_memory > glob->swap_limit ||
39078 +                         glob->used_total_memory >
39079 +                         glob->total_memory_swap_limit);
39080 +       spin_unlock(&glob->lock);
39081 +
39082 +       if (unlikely(needs_swapping))
39083 +               (void)queue_work(glob->swap_queue, &glob->work);
39084 +
39085 +}
39086 +
39087 +void ttm_mem_global_free(struct ttm_mem_global *glob,
39088 +                        uint64_t amount, bool himem)
39089 +{
39090 +       spin_lock(&glob->lock);
39091 +       glob->used_total_memory -= amount;
39092 +       if (!himem)
39093 +               glob->used_memory -= amount;
39094 +       wake_up_all(&glob->queue);
39095 +       spin_unlock(&glob->lock);
39096 +}
39097 +
39098 +static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
39099 +                                 uint64_t amount, bool himem, bool reserve)
39100 +{
39101 +       uint64_t limit;
39102 +       uint64_t lomem_limit;
39103 +       int ret = -ENOMEM;
39104 +
39105 +       spin_lock(&glob->lock);
39106 +
39107 +       if (capable(CAP_SYS_ADMIN)) {
39108 +               limit = glob->emer_total_memory;
39109 +               lomem_limit = glob->emer_memory;
39110 +       } else {
39111 +               limit = glob->max_total_memory;
39112 +               lomem_limit = glob->max_memory;
39113 +       }
39114 +
39115 +       if (unlikely(glob->used_total_memory + amount > limit))
39116 +               goto out_unlock;
39117 +       if (unlikely(!himem && glob->used_memory + amount > lomem_limit))
39118 +               goto out_unlock;
39119 +
39120 +       if (reserve) {
39121 +               glob->used_total_memory += amount;
39122 +               if (!himem)
39123 +                       glob->used_memory += amount;
39124 +       }
39125 +       ret = 0;
39126 +out_unlock:
39127 +       spin_unlock(&glob->lock);
39128 +       ttm_check_swapping(glob);
39129 +
39130 +       return ret;
39131 +}
39132 +
39133 +int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
39134 +                        bool no_wait, bool interruptible, bool himem)
39135 +{
39136 +       int count = TTM_MEMORY_ALLOC_RETRIES;
39137 +
39138 +       while (unlikely(ttm_mem_global_reserve(glob,
39139 +                                              memory,
39140 +                                              himem,
39141 +                                              true) != 0)) {
39142 +               if (no_wait)
39143 +                       return -ENOMEM;
39144 +               if (unlikely(count-- == 0))
39145 +                       return -ENOMEM;
39146 +               ttm_shrink(glob, false, memory + (memory >> 2) + 16);
39147 +       }
39148 +
39149 +       return 0;
39150 +}
39151 +
39152 +size_t ttm_round_pot(size_t size)
39153 +{
39154 +       if ((size & (size - 1)) == 0)
39155 +               return size;
39156 +       else if (size > PAGE_SIZE)
39157 +               return PAGE_ALIGN(size);
39158 +       else {
39159 +               size_t tmp_size = 4;
39160 +
39161 +               while (tmp_size < size)
39162 +                       tmp_size <<= 1;
39163 +
39164 +               return tmp_size;
39165 +       }
39166 +       return 0;
39167 +}
39168 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.h
39169 new file mode 100644
39170 index 0000000..2ceeb32
39171 --- /dev/null
39172 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_memory.h
39173 @@ -0,0 +1,147 @@
39174 +/**************************************************************************
39175 + *
39176 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
39177 + * All Rights Reserved.
39178 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
39179 + * All Rights Reserved.
39180 + *
39181 + * This program is free software; you can redistribute it and/or modify it
39182 + * under the terms and conditions of the GNU General Public License,
39183 + * version 2, as published by the Free Software Foundation.
39184 + *
39185 + * This program is distributed in the hope it will be useful, but WITHOUT
39186 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39187 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
39188 + * more details.
39189 + *
39190 + * You should have received a copy of the GNU General Public License along with
39191 + * this program; if not, write to the Free Software Foundation, Inc., 
39192 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
39193 + *
39194 + **************************************************************************/
39195 +
39196 +#ifndef TTM_MEMORY_H
39197 +#define TTM_MEMORY_H
39198 +
39199 +#include <linux/workqueue.h>
39200 +#include <linux/spinlock.h>
39201 +#include <linux/wait.h>
39202 +
39203 +/**
39204 + * struct ttm_mem_shrink - callback to shrink TTM memory usage.
39205 + *
39206 + * @do_shrink: The callback function.
39207 + *
39208 + * Arguments to the do_shrink functions are intended to be passed using
39209 + * inheritance. That is, the argument class derives from struct ttm_mem_srink,
39210 + * and can be accessed using container_of().
39211 + */
39212 +
39213 +struct ttm_mem_shrink {
39214 +       int (*do_shrink) (struct ttm_mem_shrink *);
39215 +};
39216 +
39217 +/**
39218 + * struct ttm_mem_global - Global memory accounting structure.
39219 + *
39220 + * @shrink: A single callback to shrink TTM memory usage. Extend this
39221 + * to a linked list to be able to handle multiple callbacks when needed.
39222 + * @swap_queue: A workqueue to handle shrinking in low memory situations. We
39223 + * need a separate workqueue since it will spend a lot of time waiting
39224 + * for the GPU, and this will otherwise block other workqueue tasks(?)
39225 + * At this point we use only a single-threaded workqueue.
39226 + * @work: The workqueue callback for the shrink queue.
39227 + * @queue: Wait queue for processes suspended waiting for memory.
39228 + * @lock: Lock to protect the @shrink - and the memory accounting members,
39229 + * that is, essentially the whole structure with some exceptions.
39230 + * @emer_memory: Lowmem memory limit available for root.
39231 + * @max_memory: Lowmem memory limit available for non-root.
39232 + * @swap_limit: Lowmem memory limit where the shrink workqueue kicks in.
39233 + * @used_memory: Currently used lowmem memory.
39234 + * @used_total_memory: Currently used total (lowmem + highmem) memory.
39235 + * @total_memory_swap_limit: Total memory limit where the shrink workqueue
39236 + * kicks in.
39237 + * @max_total_memory: Total memory available to non-root processes.
39238 + * @emer_total_memory: Total memory available to root processes.
39239 + *
39240 + * Note that this structure is not per device. It should be global for all
39241 + * graphics devices.
39242 + */
39243 +
39244 +struct ttm_mem_global {
39245 +       struct ttm_mem_shrink *shrink;
39246 +       struct workqueue_struct *swap_queue;
39247 +       struct work_struct work;
39248 +       wait_queue_head_t queue;
39249 +       spinlock_t lock;
39250 +       uint64_t emer_memory;
39251 +       uint64_t max_memory;
39252 +       uint64_t swap_limit;
39253 +       uint64_t used_memory;
39254 +       uint64_t used_total_memory;
39255 +       uint64_t total_memory_swap_limit;
39256 +       uint64_t max_total_memory;
39257 +       uint64_t emer_total_memory;
39258 +};
39259 +
39260 +/**
39261 + * ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object
39262 + *
39263 + * @shrink: The object to initialize.
39264 + * @func: The callback function.
39265 + */
39266 +
39267 +static inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink,
39268 +                                      int (*func) (struct ttm_mem_shrink *))
39269 +{
39270 +       shrink->do_shrink = func;
39271 +}
39272 +
39273 +/**
39274 + * ttm_mem_register_shrink - register a struct ttm_mem_shrink object.
39275 + *
39276 + * @glob: The struct ttm_mem_global object to register with.
39277 + * @shrink: An initialized struct ttm_mem_shrink object to register.
39278 + *
39279 + * Returns:
39280 + * -EBUSY: There's already a callback registered. (May change).
39281 + */
39282 +
39283 +static inline int ttm_mem_register_shrink(struct ttm_mem_global *glob,
39284 +                                         struct ttm_mem_shrink *shrink)
39285 +{
39286 +       spin_lock(&glob->lock);
39287 +       if (glob->shrink != NULL) {
39288 +               spin_unlock(&glob->lock);
39289 +               return -EBUSY;
39290 +       }
39291 +       glob->shrink = shrink;
39292 +       spin_unlock(&glob->lock);
39293 +       return 0;
39294 +}
39295 +
39296 +/**
39297 + * ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object.
39298 + *
39299 + * @glob: The struct ttm_mem_global object to unregister from.
39300 + * @shrink: A previously registert struct ttm_mem_shrink object.
39301 + *
39302 + */
39303 +
39304 +static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,
39305 +                                            struct ttm_mem_shrink *shrink)
39306 +{
39307 +       spin_lock(&glob->lock);
39308 +       BUG_ON(glob->shrink != shrink);
39309 +       glob->shrink = NULL;
39310 +       spin_unlock(&glob->lock);
39311 +}
39312 +
39313 +extern int ttm_mem_global_init(struct ttm_mem_global *glob);
39314 +extern void ttm_mem_global_release(struct ttm_mem_global *glob);
39315 +extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
39316 +                               bool no_wait, bool interruptible, bool himem);
39317 +extern void ttm_mem_global_free(struct ttm_mem_global *glob,
39318 +                               uint64_t amount, bool himem);
39319 +extern size_t ttm_round_pot(size_t size);
39320 +#endif
39321 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_object.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_object.c
39322 new file mode 100644
39323 index 0000000..53ee1c9
39324 --- /dev/null
39325 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_object.c
39326 @@ -0,0 +1,440 @@
39327 +/**************************************************************************
39328 + *
39329 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
39330 + * All Rights Reserved.
39331 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
39332 + * All Rights Reserved.
39333 + *
39334 + * This program is free software; you can redistribute it and/or modify it
39335 + * under the terms and conditions of the GNU General Public License,
39336 + * version 2, as published by the Free Software Foundation.
39337 + *
39338 + * This program is distributed in the hope it will be useful, but WITHOUT
39339 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39340 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
39341 + * more details.
39342 + *
39343 + * You should have received a copy of the GNU General Public License along with
39344 + * this program; if not, write to the Free Software Foundation, Inc., 
39345 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
39346 + *
39347 + **************************************************************************/
39348 +/*
39349 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
39350 + */
39351 +/** @file ttm_ref_object.c
39352 + *
39353 + * Base- and reference object implementation for the various
39354 + * ttm objects. Implements reference counting, minimal security checks
39355 + * and release on file close.
39356 + */
39357 +
39358 +/**
39359 + * struct ttm_object_file
39360 + *
39361 + * @tdev: Pointer to the ttm_object_device.
39362 + *
39363 + * @lock: Lock that protects the ref_list list and the
39364 + * ref_hash hash tables.
39365 + *
39366 + * @ref_list: List of ttm_ref_objects to be destroyed at
39367 + * file release.
39368 + *
39369 + * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
39370 + * for fast lookup of ref objects given a base object.
39371 + */
39372 +
39373 +#include "ttm_object.h"
39374 +#include <linux/list.h>
39375 +#include <linux/spinlock.h>
39376 +#include <linux/slab.h>
39377 +#include <asm/atomic.h>
39378 +
39379 +struct ttm_object_file {
39380 +       struct ttm_object_device *tdev;
39381 +       rwlock_t lock;
39382 +       struct list_head ref_list;
39383 +       struct drm_open_hash ref_hash[TTM_REF_NUM];
39384 +       struct kref refcount;
39385 +};
39386 +
39387 +/**
39388 + * struct ttm_object_device
39389 + *
39390 + * @object_lock: lock that protects the object_hash hash table.
39391 + *
39392 + * @object_hash: hash table for fast lookup of object global names.
39393 + *
39394 + * @object_count: Per device object count.
39395 + *
39396 + * This is the per-device data structure needed for ttm object management.
39397 + */
39398 +
39399 +struct ttm_object_device {
39400 +       rwlock_t object_lock;
39401 +       struct drm_open_hash object_hash;
39402 +       atomic_t object_count;
39403 +       struct ttm_mem_global *mem_glob;
39404 +};
39405 +
39406 +/**
39407 + * struct ttm_ref_object
39408 + *
39409 + * @hash: Hash entry for the per-file object reference hash.
39410 + *
39411 + * @head: List entry for the per-file list of ref-objects.
39412 + *
39413 + * @kref: Ref count.
39414 + *
39415 + * @obj: Base object this ref object is referencing.
39416 + *
39417 + * @ref_type: Type of ref object.
39418 + *
39419 + * This is similar to an idr object, but it also has a hash table entry
39420 + * that allows lookup with a pointer to the referenced object as a key. In
39421 + * that way, one can easily detect whether a base object is referenced by
39422 + * a particular ttm_object_file. It also carries a ref count to avoid creating
39423 + * multiple ref objects if a ttm_object_file references the same base object
39424 + * more than once.
39425 + */
39426 +
39427 +struct ttm_ref_object {
39428 +       struct drm_hash_item hash;
39429 +       struct list_head head;
39430 +       struct kref kref;
39431 +       struct ttm_base_object *obj;
39432 +       enum ttm_ref_type ref_type;
39433 +       struct ttm_object_file *tfile;
39434 +};
39435 +
39436 +static inline struct ttm_object_file *
39437 +ttm_object_file_ref(struct ttm_object_file *tfile)
39438 +{
39439 +       kref_get(&tfile->refcount);
39440 +       return tfile;
39441 +}
39442 +
39443 +static void ttm_object_file_destroy(struct kref *kref)
39444 +{
39445 +       struct ttm_object_file *tfile =
39446 +               container_of(kref, struct ttm_object_file, refcount);
39447 +
39448 +       /* printk(KERN_INFO "Freeing 0x%08lx\n", (unsigned long) tfile); */
39449 +       kfree(tfile);
39450 +}
39451 +
39452 +
39453 +static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
39454 +{
39455 +       struct ttm_object_file *tfile = *p_tfile;
39456 +
39457 +       *p_tfile = NULL;
39458 +       kref_put(&tfile->refcount, ttm_object_file_destroy);
39459 +}
39460 +
39461 +
39462 +int ttm_base_object_init(struct ttm_object_file *tfile,
39463 +                        struct ttm_base_object *base,
39464 +                        bool shareable,
39465 +                        enum ttm_object_type object_type,
39466 +                        void (*refcount_release) (struct ttm_base_object **),
39467 +                        void (*ref_obj_release) (struct ttm_base_object *,
39468 +                                                 enum ttm_ref_type ref_type))
39469 +{
39470 +       struct ttm_object_device *tdev = tfile->tdev;
39471 +       int ret;
39472 +
39473 +       base->shareable = shareable;
39474 +       base->tfile = ttm_object_file_ref(tfile);
39475 +       base->refcount_release = refcount_release;
39476 +       base->ref_obj_release = ref_obj_release;
39477 +       base->object_type = object_type;
39478 +       write_lock(&tdev->object_lock);
39479 +       kref_init(&base->refcount);
39480 +       ret = drm_ht_just_insert_please(&tdev->object_hash,
39481 +                                       &base->hash,
39482 +                                       (unsigned long)base, 31, 0, 0);
39483 +       write_unlock(&tdev->object_lock);
39484 +       if (unlikely(ret != 0))
39485 +               goto out_err0;
39486 +
39487 +       ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
39488 +       if (unlikely(ret != 0))
39489 +               goto out_err1;
39490 +
39491 +       ttm_base_object_unref(&base);
39492 +
39493 +       return 0;
39494 +out_err1:
39495 +       (void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
39496 +out_err0:
39497 +       return ret;
39498 +}
39499 +
39500 +static void ttm_release_base(struct kref *kref)
39501 +{
39502 +       struct ttm_base_object *base =
39503 +           container_of(kref, struct ttm_base_object, refcount);
39504 +       struct ttm_object_device *tdev = base->tfile->tdev;
39505 +
39506 +       (void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
39507 +       write_unlock(&tdev->object_lock);
39508 +       if (base->refcount_release) {
39509 +               ttm_object_file_unref(&base->tfile);
39510 +               base->refcount_release(&base);
39511 +       }
39512 +       write_lock(&tdev->object_lock);
39513 +}
39514 +
39515 +void ttm_base_object_unref(struct ttm_base_object **p_base)
39516 +{
39517 +       struct ttm_base_object *base = *p_base;
39518 +       struct ttm_object_device *tdev = base->tfile->tdev;
39519 +
39520 +       /* printk(KERN_INFO "TTM base object unref.\n"); */
39521 +       *p_base = NULL;
39522 +
39523 +       /*
39524 +        * Need to take the lock here to avoid racing with
39525 +        * users trying to look up the object.
39526 +        */
39527 +
39528 +       write_lock(&tdev->object_lock);
39529 +       (void)kref_put(&base->refcount, &ttm_release_base);
39530 +       write_unlock(&tdev->object_lock);
39531 +}
39532 +
39533 +struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
39534 +                                              uint32_t key)
39535 +{
39536 +       struct ttm_object_device *tdev = tfile->tdev;
39537 +       struct ttm_base_object *base;
39538 +       struct drm_hash_item *hash;
39539 +       int ret;
39540 +
39541 +       read_lock(&tdev->object_lock);
39542 +       ret = drm_ht_find_item(&tdev->object_hash, key, &hash);
39543 +
39544 +       if (likely(ret == 0)) {
39545 +               base = drm_hash_entry(hash, struct ttm_base_object, hash);
39546 +               kref_get(&base->refcount);
39547 +       }
39548 +       read_unlock(&tdev->object_lock);
39549 +
39550 +       if (unlikely(ret != 0))
39551 +               return NULL;
39552 +
39553 +       if (tfile != base->tfile && !base->shareable) {
39554 +               printk(KERN_ERR "Attempted access of non-shareable object.\n");
39555 +               ttm_base_object_unref(&base);
39556 +               return NULL;
39557 +       }
39558 +
39559 +       return base;
39560 +}
39561 +
39562 +int ttm_ref_object_add(struct ttm_object_file *tfile,
39563 +                      struct ttm_base_object *base,
39564 +                      enum ttm_ref_type ref_type, bool *existed)
39565 +{
39566 +       struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
39567 +       struct ttm_ref_object *ref;
39568 +       struct drm_hash_item *hash;
39569 +       struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
39570 +       int ret = -EINVAL;
39571 +
39572 +       if (existed != NULL)
39573 +               *existed = true;
39574 +
39575 +       while (ret == -EINVAL) {
39576 +               read_lock(&tfile->lock);
39577 +               ret = drm_ht_find_item(ht, base->hash.key, &hash);
39578 +
39579 +               if (ret == 0) {
39580 +                       ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
39581 +                       kref_get(&ref->kref);
39582 +                       read_unlock(&tfile->lock);
39583 +                       break;
39584 +               }
39585 +
39586 +               read_unlock(&tfile->lock);
39587 +               ret = ttm_mem_global_alloc(mem_glob,
39588 +                                          sizeof(*ref),
39589 +                                          false,
39590 +                                          false,
39591 +                                          false);
39592 +               if (unlikely(ret != 0))
39593 +                       return ret;
39594 +               ref = kmalloc(sizeof(*ref), GFP_KERNEL);
39595 +               if (unlikely(ref == NULL)) {
39596 +                       ttm_mem_global_free(mem_glob, sizeof(*ref), false);
39597 +                       return -ENOMEM;
39598 +               }
39599 +
39600 +               ref->hash.key = base->hash.key;
39601 +               ref->obj = base;
39602 +               ref->tfile = tfile;
39603 +               ref->ref_type = ref_type;
39604 +               kref_init(&ref->kref);
39605 +
39606 +               write_lock(&tfile->lock);
39607 +               ret = drm_ht_insert_item(ht, &ref->hash);
39608 +
39609 +               if (likely(ret == 0)) {
39610 +                       list_add_tail(&ref->head, &tfile->ref_list);
39611 +                       kref_get(&base->refcount);
39612 +                       write_unlock(&tfile->lock);
39613 +                       if (existed != NULL)
39614 +                               *existed = false;
39615 +                       break;
39616 +               }
39617 +
39618 +               write_unlock(&tfile->lock);
39619 +               BUG_ON(ret != -EINVAL);
39620 +
39621 +               ttm_mem_global_free(mem_glob, sizeof(*ref), false);
39622 +               kfree(ref);
39623 +       }
39624 +
39625 +       return ret;
39626 +}
39627 +
39628 +static void ttm_ref_object_release(struct kref *kref)
39629 +{
39630 +       struct ttm_ref_object *ref =
39631 +           container_of(kref, struct ttm_ref_object, kref);
39632 +       struct ttm_base_object *base = ref->obj;
39633 +       struct ttm_object_file *tfile = ref->tfile;
39634 +       struct drm_open_hash *ht;
39635 +       struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
39636 +
39637 +       ht = &tfile->ref_hash[ref->ref_type];
39638 +       (void)drm_ht_remove_item(ht, &ref->hash);
39639 +       list_del(&ref->head);
39640 +       write_unlock(&tfile->lock);
39641 +
39642 +       if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
39643 +               base->ref_obj_release(base, ref->ref_type);
39644 +
39645 +       ttm_base_object_unref(&ref->obj);
39646 +       ttm_mem_global_free(mem_glob, sizeof(*ref), false);
39647 +       kfree(ref);
39648 +       write_lock(&tfile->lock);
39649 +}
39650 +
39651 +int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
39652 +                             unsigned long key, enum ttm_ref_type ref_type)
39653 +{
39654 +       struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
39655 +       struct ttm_ref_object *ref;
39656 +       struct drm_hash_item *hash;
39657 +       int ret;
39658 +
39659 +       write_lock(&tfile->lock);
39660 +       ret = drm_ht_find_item(ht, key, &hash);
39661 +       if (unlikely(ret != 0)) {
39662 +               write_unlock(&tfile->lock);
39663 +               return -EINVAL;
39664 +       }
39665 +       ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
39666 +       kref_put(&ref->kref, ttm_ref_object_release);
39667 +       write_unlock(&tfile->lock);
39668 +       return 0;
39669 +}
39670 +
39671 +void ttm_object_file_release(struct ttm_object_file **p_tfile)
39672 +{
39673 +       struct ttm_ref_object *ref;
39674 +       struct list_head *list;
39675 +       unsigned int i;
39676 +       struct ttm_object_file *tfile = *p_tfile;
39677 +
39678 +       *p_tfile = NULL;
39679 +       write_lock(&tfile->lock);
39680 +
39681 +       /*
39682 +        * Since we release the lock within the loop, we have to
39683 +        * restart it from the beginning each time.
39684 +        */
39685 +
39686 +       while (!list_empty(&tfile->ref_list)) {
39687 +               list = tfile->ref_list.next;
39688 +               ref = list_entry(list, struct ttm_ref_object, head);
39689 +               ttm_ref_object_release(&ref->kref);
39690 +       }
39691 +
39692 +       for (i = 0; i < TTM_REF_NUM; ++i)
39693 +               drm_ht_remove(&tfile->ref_hash[i]);
39694 +
39695 +       write_unlock(&tfile->lock);
39696 +       ttm_object_file_unref(&tfile);
39697 +}
39698 +
39699 +struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
39700 +                                            unsigned int hash_order)
39701 +{
39702 +       struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
39703 +       unsigned int i;
39704 +       unsigned int j = 0;
39705 +       int ret;
39706 +
39707 +       if (unlikely(tfile == NULL))
39708 +               return NULL;
39709 +
39710 +       rwlock_init(&tfile->lock);
39711 +       tfile->tdev = tdev;
39712 +       kref_init(&tfile->refcount);
39713 +       INIT_LIST_HEAD(&tfile->ref_list);
39714 +
39715 +       for (i = 0; i < TTM_REF_NUM; ++i) {
39716 +               ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
39717 +               if (ret) {
39718 +                       j = i;
39719 +                       goto out_err;
39720 +               }
39721 +       }
39722 +
39723 +       return tfile;
39724 +out_err:
39725 +       for (i = 0; i < j; ++i)
39726 +               drm_ht_remove(&tfile->ref_hash[i]);
39727 +
39728 +       kfree(tfile);
39729 +
39730 +       return NULL;
39731 +}
39732 +
39733 +struct ttm_object_device *ttm_object_device_init(struct ttm_mem_global
39734 +                                                *mem_glob,
39735 +                                                unsigned int hash_order)
39736 +{
39737 +       struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
39738 +       int ret;
39739 +
39740 +       if (unlikely(tdev == NULL))
39741 +               return NULL;
39742 +
39743 +       tdev->mem_glob = mem_glob;
39744 +       rwlock_init(&tdev->object_lock);
39745 +       atomic_set(&tdev->object_count, 0);
39746 +       ret = drm_ht_create(&tdev->object_hash, hash_order);
39747 +
39748 +       if (likely(ret == 0))
39749 +               return tdev;
39750 +
39751 +       kfree(tdev);
39752 +       return NULL;
39753 +}
39754 +
39755 +void ttm_object_device_release(struct ttm_object_device **p_tdev)
39756 +{
39757 +       struct ttm_object_device *tdev = *p_tdev;
39758 +
39759 +       *p_tdev = NULL;
39760 +
39761 +       write_lock(&tdev->object_lock);
39762 +       drm_ht_remove(&tdev->object_hash);
39763 +       write_unlock(&tdev->object_lock);
39764 +
39765 +       kfree(tdev);
39766 +}
39767 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_object.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_object.h
39768 new file mode 100644
39769 index 0000000..b04c714
39770 --- /dev/null
39771 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_object.h
39772 @@ -0,0 +1,262 @@
39773 +/**************************************************************************
39774 + *
39775 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
39776 + * All Rights Reserved.
39777 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
39778 + * All Rights Reserved.
39779 + *
39780 + * This program is free software; you can redistribute it and/or modify it
39781 + * under the terms and conditions of the GNU General Public License,
39782 + * version 2, as published by the Free Software Foundation.
39783 + *
39784 + * This program is distributed in the hope it will be useful, but WITHOUT
39785 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39786 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
39787 + * more details.
39788 + *
39789 + * You should have received a copy of the GNU General Public License along with
39790 + * this program; if not, write to the Free Software Foundation, Inc., 
39791 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
39792 + *
39793 + **************************************************************************/
39794 +/*
39795 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
39796 + */
39797 +/** @file ttm_ref_object.h
39798 + *
39799 + * Base- and reference object implementation for the various
39800 + * ttm objects. Implements reference counting, minimal security checks
39801 + * and release on file close.
39802 + */
39803 +
39804 +#ifndef _TTM_OBJECT_H_
39805 +#define _TTM_OBJECT_H_
39806 +
39807 +#include <linux/list.h>
39808 +#include <drm/drm_hashtab.h>
39809 +#include <linux/kref.h>
39810 +#include "ttm_memory.h"
39811 +
39812 +/**
39813 + * enum ttm_ref_type
39814 + *
39815 + * Describes what type of reference a ref object holds.
39816 + *
39817 + * TTM_REF_USAGE is a simple refcount on a base object.
39818 + *
39819 + * TTM_REF_SYNCCPU_READ is a SYNCCPU_READ reference on a
39820 + * buffer object.
39821 + *
39822 + * TTM_REF_SYNCCPU_WRITE is a SYNCCPU_WRITE reference on a
39823 + * buffer object.
39824 + *
39825 + */
39826 +
39827 +enum ttm_ref_type {
39828 +       TTM_REF_USAGE,
39829 +       TTM_REF_SYNCCPU_READ,
39830 +       TTM_REF_SYNCCPU_WRITE,
39831 +       TTM_REF_NUM
39832 +};
39833 +
39834 +/**
39835 + * enum ttm_object_type
39836 + *
39837 + * One entry per ttm object type.
39838 + * Device-specific types should use the
39839 + * ttm_driver_typex types.
39840 + */
39841 +
39842 +enum ttm_object_type {
39843 +       ttm_fence_type,
39844 +       ttm_buffer_type,
39845 +       ttm_lock_type,
39846 +       ttm_driver_type0 = 256,
39847 +       ttm_driver_type1
39848 +};
39849 +
39850 +struct ttm_object_file;
39851 +struct ttm_object_device;
39852 +
39853 +/**
39854 + * struct ttm_base_object
39855 + *
39856 + * @hash: hash entry for the per-device object hash.
39857 + * @type: derived type this object is base class for.
39858 + * @shareable: Other ttm_object_files can access this object.
39859 + *
39860 + * @tfile: Pointer to ttm_object_file of the creator.
39861 + * NULL if the object was not created by a user request.
39862 + * (kernel object).
39863 + *
39864 + * @refcount: Number of references to this object, not
39865 + * including the hash entry. A reference to a base object can
39866 + * only be held by a ref object.
39867 + *
39868 + * @refcount_release: A function to be called when there are
39869 + * no more references to this object. This function should
39870 + * destroy the object (or make sure destruction eventually happens),
39871 + * and when it is called, the object has
39872 + * already been taken out of the per-device hash. The parameter
39873 + * "base" should be set to NULL by the function.
39874 + *
39875 + * @ref_obj_release: A function to be called when a reference object
39876 + * with another ttm_ref_type than TTM_REF_USAGE is deleted.
39877 + * this function may, for example, release a lock held by a user-space
39878 + * process.
39879 + *
39880 + * This struct is intended to be used as a base struct for objects that
39881 + * are visible to user-space. It provides a global name, race-safe
39882 + * access and refcounting, minimal access contol and hooks for unref actions.
39883 + */
39884 +
39885 +struct ttm_base_object {
39886 +       struct drm_hash_item hash;
39887 +       enum ttm_object_type object_type;
39888 +       bool shareable;
39889 +       struct ttm_object_file *tfile;
39890 +       struct kref refcount;
39891 +       void (*refcount_release) (struct ttm_base_object **base);
39892 +       void (*ref_obj_release) (struct ttm_base_object *base,
39893 +                                enum ttm_ref_type ref_type);
39894 +};
39895 +
39896 +/**
39897 + * ttm_base_object_init
39898 + *
39899 + * @tfile: Pointer to a struct ttm_object_file.
39900 + * @base: The struct ttm_base_object to initialize.
39901 + * @shareable: This object is shareable with other applcations.
39902 + * (different @tfile pointers.)
39903 + * @type: The object type.
39904 + * @refcount_release: See the struct ttm_base_object description.
39905 + * @ref_obj_release: See the struct ttm_base_object description.
39906 + *
39907 + * Initializes a struct ttm_base_object.
39908 + */
39909 +
39910 +extern int ttm_base_object_init(struct ttm_object_file *tfile,
39911 +                               struct ttm_base_object *base,
39912 +                               bool shareable,
39913 +                               enum ttm_object_type type,
39914 +                               void (*refcount_release) (struct ttm_base_object
39915 +                                                         **),
39916 +                               void (*ref_obj_release) (struct ttm_base_object
39917 +                                                        *,
39918 +                                                        enum ttm_ref_type
39919 +                                                        ref_type));
39920 +
39921 +/**
39922 + * ttm_base_object_lookup
39923 + *
39924 + * @tfile: Pointer to a struct ttm_object_file.
39925 + * @key: Hash key
39926 + *
39927 + * Looks up a struct ttm_base_object with the key @key.
39928 + * Also verifies that the object is visible to the application, by
39929 + * comparing the @tfile argument and checking the object shareable flag.
39930 + */
39931 +
39932 +extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file
39933 +                                                     *tfile, uint32_t key);
39934 +
39935 +/**
39936 + * ttm_base_object_unref
39937 + *
39938 + * @p_base: Pointer to a pointer referncing a struct ttm_base_object.
39939 + *
39940 + * Decrements the base object refcount and clears the pointer pointed to by
39941 + * p_base.
39942 + */
39943 +
39944 +extern void ttm_base_object_unref(struct ttm_base_object **p_base);
39945 +
39946 +/**
39947 + * ttm_ref_object_add.
39948 + *
39949 + * @tfile: A struct ttm_object_file representing the application owning the
39950 + * ref_object.
39951 + * @base: The base object to reference.
39952 + * @ref_type: The type of reference.
39953 + * @existed: Upon completion, indicates that an identical reference object
39954 + * already existed, and the refcount was upped on that object instead.
39955 + *
39956 + * Adding a ref object to a base object is basically like referencing the
39957 + * base object, but a user-space application holds the reference. When the
39958 + * file corresponding to @tfile is closed, all its reference objects are
39959 + * deleted. A reference object can have different types depending on what
39960 + * it's intended for. It can be refcounting to prevent object destruction,
39961 + * When user-space takes a lock, it can add a ref object to that lock to
39962 + * make sure the lock is released if the application dies. A ref object
39963 + * will hold a single reference on a base object.
39964 + */
39965 +extern int ttm_ref_object_add(struct ttm_object_file *tfile,
39966 +                             struct ttm_base_object *base,
39967 +                             enum ttm_ref_type ref_type, bool *existed);
39968 +/**
39969 + * ttm_ref_object_base_unref
39970 + *
39971 + * @key: Key representing the base object.
39972 + * @ref_type: Ref type of the ref object to be dereferenced.
39973 + *
39974 + * Unreference a ref object with type @ref_type
39975 + * on the base object identified by @key. If there are no duplicate
39976 + * references, the ref object will be destroyed and the base object
39977 + * will be unreferenced.
39978 + */
39979 +extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
39980 +                                    unsigned long key,
39981 +                                    enum ttm_ref_type ref_type);
39982 +
39983 +/**
39984 + * ttm_object_file_init - initialize a struct ttm_object file
39985 + *
39986 + * @tdev: A struct ttm_object device this file is initialized on.
39987 + * @hash_order: Order of the hash table used to hold the reference objects.
39988 + *
39989 + * This is typically called by the file_ops::open function.
39990 + */
39991 +
39992 +extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device
39993 +                                                   *tdev,
39994 +                                                   unsigned int hash_order);
39995 +
39996 +/**
39997 + * ttm_object_file_release - release data held by a ttm_object_file
39998 + *
39999 + * @p_tfile: Pointer to pointer to the ttm_object_file object to release.
40000 + * *p_tfile will be set to NULL by this function.
40001 + *
40002 + * Releases all data associated by a ttm_object_file.
40003 + * Typically called from file_ops::release. The caller must
40004 + * ensure that there are no concurrent users of tfile.
40005 + */
40006 +
40007 +extern void ttm_object_file_release(struct ttm_object_file **p_tfile);
40008 +
40009 +/**
40010 + * ttm_object device init - initialize a struct ttm_object_device
40011 + *
40012 + * @hash_order: Order of hash table used to hash the base objects.
40013 + *
40014 + * This function is typically called on device initialization to prepare
40015 + * data structures needed for ttm base and ref objects.
40016 + */
40017 +
40018 +extern struct ttm_object_device *ttm_object_device_init
40019 +    (struct ttm_mem_global *mem_glob, unsigned int hash_order);
40020 +
40021 +/**
40022 + * ttm_object_device_release - release data held by a ttm_object_device
40023 + *
40024 + * @p_tdev: Pointer to pointer to the ttm_object_device object to release.
40025 + * *p_tdev will be set to NULL by this function.
40026 + *
40027 + * Releases all data associated by a ttm_object_device.
40028 + * Typically called from driver::unload before the destruction of the
40029 + * device private data structure.
40030 + */
40031 +
40032 +extern void ttm_object_device_release(struct ttm_object_device **p_tdev);
40033 +
40034 +#endif
40035 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.c
40036 new file mode 100644
40037 index 0000000..83f34c6
40038 --- /dev/null
40039 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.c
40040 @@ -0,0 +1,164 @@
40041 +/**************************************************************************
40042 + *
40043 + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
40044 + * All Rights Reserved.
40045 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
40046 + * All Rights Reserved.
40047 + *
40048 + * This program is free software; you can redistribute it and/or modify it
40049 + * under the terms and conditions of the GNU General Public License,
40050 + * version 2, as published by the Free Software Foundation.
40051 + *
40052 + * This program is distributed in the hope it will be useful, but WITHOUT
40053 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40054 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
40055 + * more details.
40056 + *
40057 + * You should have received a copy of the GNU General Public License along with
40058 + * this program; if not, write to the Free Software Foundation, Inc., 
40059 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
40060 + *
40061 + **************************************************************************/
40062 +/*
40063 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
40064 + */
40065 +
40066 +#include "ttm_pat_compat.h"
40067 +#include <linux/version.h>
40068 +#include <asm/page.h>
40069 +#include <linux/spinlock.h>
40070 +#include <asm/pgtable.h>
40071 +
40072 +#if (defined(CONFIG_X86) && !defined(CONFIG_X86_PAT))
40073 +#include <asm/tlbflush.h>
40074 +#include <asm/msr.h>
40075 +#include <asm/system.h>
40076 +#include <linux/notifier.h>
40077 +#include <linux/cpu.h>
40078 +
40079 +#ifndef MSR_IA32_CR_PAT
40080 +#define MSR_IA32_CR_PAT 0x0277
40081 +#endif
40082 +
40083 +#ifndef _PAGE_PAT
40084 +#define _PAGE_PAT 0x080
40085 +#endif
40086 +
40087 +static int ttm_has_pat;
40088 +
40089 +/*
40090 + * Used at resume-time when CPU-s are fired up.
40091 + */
40092 +
40093 +static void ttm_pat_ipi_handler(void *notused)
40094 +{
40095 +       u32 v1, v2;
40096 +
40097 +       rdmsr(MSR_IA32_CR_PAT, v1, v2);
40098 +       v2 &= 0xFFFFFFF8;
40099 +       v2 |= 0x00000001;
40100 +       wbinvd();
40101 +       wrmsr(MSR_IA32_CR_PAT, v1, v2);
40102 +       wbinvd();
40103 +       __flush_tlb_all();
40104 +}
40105 +
40106 +static void ttm_pat_enable(void)
40107 +{
40108 +       if (on_each_cpu(ttm_pat_ipi_handler, NULL, 1) != 0)
40109 +               printk(KERN_ERR "Timed out setting up CPU PAT.\n");
40110 +}
40111 +
40112 +void ttm_pat_resume(void)
40113 +{
40114 +       if (unlikely(!ttm_has_pat))
40115 +               return;
40116 +
40117 +       ttm_pat_enable();
40118 +}
40119 +
40120 +static int psb_cpu_callback(struct notifier_block *nfb,
40121 +                           unsigned long action, void *hcpu)
40122 +{
40123 +       if (action == CPU_ONLINE)
40124 +               ttm_pat_resume();
40125 +
40126 +       return 0;
40127 +}
40128 +
40129 +static struct notifier_block psb_nb = {
40130 +       .notifier_call = psb_cpu_callback,
40131 +       .priority = 1
40132 +};
40133 +
40134 +/*
40135 + * Set i386 PAT entry PAT4 to Write-combining memory type on all processors.
40136 + */
40137 +
40138 +void ttm_pat_init(void)
40139 +{
40140 +       if (likely(ttm_has_pat))
40141 +               return;
40142 +
40143 +       if (!boot_cpu_has(X86_FEATURE_PAT))
40144 +               return;
40145 +
40146 +       ttm_pat_enable();
40147 +
40148 +       if (num_present_cpus() > 1)
40149 +               register_cpu_notifier(&psb_nb);
40150 +
40151 +       ttm_has_pat = 1;
40152 +}
40153 +
40154 +void ttm_pat_takedown(void)
40155 +{
40156 +       if (unlikely(!ttm_has_pat))
40157 +               return;
40158 +
40159 +       if (num_present_cpus() > 1)
40160 +               unregister_cpu_notifier(&psb_nb);
40161 +
40162 +       ttm_has_pat = 0;
40163 +}
40164 +
40165 +pgprot_t pgprot_ttm_x86_wc(pgprot_t prot)
40166 +{
40167 +       if (likely(ttm_has_pat)) {
40168 +               pgprot_val(prot) |= _PAGE_PAT;
40169 +               return prot;
40170 +       } else {
40171 +               return pgprot_noncached(prot);
40172 +       }
40173 +}
40174 +
40175 +#else
40176 +
40177 +void ttm_pat_init(void)
40178 +{
40179 +}
40180 +
40181 +void ttm_pat_takedown(void)
40182 +{
40183 +}
40184 +
40185 +void ttm_pat_resume(void)
40186 +{
40187 +}
40188 +
40189 +#ifdef CONFIG_X86
40190 +#include <asm/pat.h>
40191 +
40192 +pgprot_t pgprot_ttm_x86_wc(pgprot_t prot)
40193 +{
40194 +       uint32_t cache_bits = ((1) ? _PAGE_CACHE_WC : _PAGE_CACHE_UC_MINUS);
40195 +
40196 +       return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | cache_bits);
40197 +}
40198 +#else
40199 +pgprot_t pgprot_ttm_x86_wc(pgprot_t prot)
40200 +{
40201 +       BUG();
40202 +}
40203 +#endif
40204 +#endif
40205 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.h
40206 new file mode 100644
40207 index 0000000..4702f1c
40208 --- /dev/null
40209 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_pat_compat.h
40210 @@ -0,0 +1,34 @@
40211 +/**************************************************************************
40212 + *
40213 + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
40214 + * All Rights Reserved.
40215 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
40216 + * All Rights Reserved.
40217 + *
40218 + * This program is free software; you can redistribute it and/or modify it
40219 + * under the terms and conditions of the GNU General Public License,
40220 + * version 2, as published by the Free Software Foundation.
40221 + *
40222 + * This program is distributed in the hope it will be useful, but WITHOUT
40223 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40224 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
40225 + * more details.
40226 + *
40227 + * You should have received a copy of the GNU General Public License along with
40228 + * this program; if not, write to the Free Software Foundation, Inc., 
40229 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
40230 + *
40231 + **************************************************************************/
40232 +/*
40233 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
40234 + */
40235 +
40236 +#ifndef _TTM_PAT_COMPAT_
40237 +#define _TTM_PAT_COMPAT_
40238 +#include <asm/page.h>
40239 +#include <asm/pgtable_types.h>
40240 +extern void ttm_pat_init(void);
40241 +extern void ttm_pat_takedown(void);
40242 +extern void ttm_pat_resume(void);
40243 +extern pgprot_t pgprot_ttm_x86_wc(pgprot_t prot);
40244 +#endif
40245 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_common.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_common.h
40246 new file mode 100644
40247 index 0000000..067ce27
40248 --- /dev/null
40249 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_common.h
40250 @@ -0,0 +1,91 @@
40251 +/**************************************************************************
40252 + *
40253 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
40254 + * All Rights Reserved.
40255 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
40256 + * All Rights Reserved.
40257 + *
40258 + * This program is free software; you can redistribute it and/or modify it
40259 + * under the terms and conditions of the GNU General Public License,
40260 + * version 2, as published by the Free Software Foundation.
40261 + *
40262 + * This program is distributed in the hope it will be useful, but WITHOUT
40263 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40264 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
40265 + * more details.
40266 + *
40267 + * You should have received a copy of the GNU General Public License along with
40268 + * this program; if not, write to the Free Software Foundation, Inc., 
40269 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
40270 + *
40271 + **************************************************************************/
40272 +/*
40273 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
40274 + */
40275 +
40276 +#ifndef _TTM_PL_COMMON_H_
40277 +#define _TTM_PL_COMMON_H_
40278 +/*
40279 + * Memory regions for data placement.
40280 + */
40281 +
40282 +#define TTM_PL_SYSTEM          0
40283 +#define TTM_PL_TT              1
40284 +#define TTM_PL_VRAM            2
40285 +#define TTM_PL_PRIV0           3
40286 +#define TTM_PL_PRIV1           4
40287 +#define TTM_PL_PRIV2           5
40288 +#define TTM_PL_PRIV3           6
40289 +#define TTM_PL_PRIV4           7
40290 +#define TTM_PL_PRIV5           8
40291 +#define TTM_PL_CI              9
40292 +#define TTM_PL_RAR             10
40293 +#define TTM_PL_SWAPPED         15
40294 +
40295 +#define TTM_PL_FLAG_SYSTEM     (1 << TTM_PL_SYSTEM)
40296 +#define TTM_PL_FLAG_TT         (1 << TTM_PL_TT)
40297 +#define TTM_PL_FLAG_VRAM       (1 << TTM_PL_VRAM)
40298 +#define TTM_PL_FLAG_PRIV0      (1 << TTM_PL_PRIV0)
40299 +#define TTM_PL_FLAG_PRIV1      (1 << TTM_PL_PRIV1)
40300 +#define TTM_PL_FLAG_PRIV2      (1 << TTM_PL_PRIV2)
40301 +#define TTM_PL_FLAG_PRIV3      (1 << TTM_PL_PRIV3)
40302 +#define TTM_PL_FLAG_PRIV4      (1 << TTM_PL_PRIV4)
40303 +#define TTM_PL_FLAG_PRIV5      (1 << TTM_PL_PRIV5)
40304 +#define TTM_PL_FLAG_CI         (1 << TTM_PL_CI)
40305 +#define TTM_PL_FLAG_RAR                (1 << TTM_PL_RAR)
40306 +#define TTM_PL_FLAG_SWAPPED    (1 << TTM_PL_SWAPPED)
40307 +#define TTM_PL_MASK_MEM                0x0000FFFF
40308 +
40309 +/*
40310 + * Other flags that affects data placement.
40311 + * TTM_PL_FLAG_CACHED indicates cache-coherent mappings
40312 + * if available.
40313 + * TTM_PL_FLAG_SHARED means that another application may
40314 + * reference the buffer.
40315 + * TTM_PL_FLAG_NO_EVICT means that the buffer may never
40316 + * be evicted to make room for other buffers.
40317 + */
40318 +
40319 +#define TTM_PL_FLAG_CACHED     (1 << 16)
40320 +#define TTM_PL_FLAG_UNCACHED   (1 << 17)
40321 +#define TTM_PL_FLAG_WC         (1 << 18)
40322 +#define TTM_PL_FLAG_SHARED     (1 << 20)
40323 +#define TTM_PL_FLAG_NO_EVICT   (1 << 21)
40324 +
40325 +#define TTM_PL_MASK_CACHING    (TTM_PL_FLAG_CACHED | \
40326 +                                TTM_PL_FLAG_UNCACHED | \
40327 +                                TTM_PL_FLAG_WC)
40328 +
40329 +#define TTM_PL_MASK_MEMTYPE    (TTM_PL_MASK_MEM | TTM_PL_MASK_CACHING)
40330 +
40331 +/*
40332 + * Access flags to be used for CPU- and GPU- mappings.
40333 + * The idea is that the TTM synchronization mechanism will
40334 + * allow concurrent READ access and exclusive write access.
40335 + * Currently GPU- and CPU accesses are exclusive.
40336 + */
40337 +
40338 +#define TTM_ACCESS_READ                (1 << 0)
40339 +#define TTM_ACCESS_WRITE       (1 << 1)
40340 +
40341 +#endif
40342 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.c
40343 new file mode 100644
40344 index 0000000..e4d6964
40345 --- /dev/null
40346 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.c
40347 @@ -0,0 +1,468 @@
40348 +/**************************************************************************
40349 + *
40350 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
40351 + * All Rights Reserved.
40352 + *
40353 + * This program is free software; you can redistribute it and/or modify it
40354 + * under the terms and conditions of the GNU General Public License,
40355 + * version 2, as published by the Free Software Foundation.
40356 + *
40357 + * This program is distributed in the hope it will be useful, but WITHOUT
40358 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40359 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
40360 + * more details.
40361 + *
40362 + * You should have received a copy of the GNU General Public License along with
40363 + * this program; if not, write to the Free Software Foundation, Inc., 
40364 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
40365 + *
40366 + **************************************************************************/
40367 +/*
40368 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
40369 + */
40370 +
40371 +#include "ttm_placement_user.h"
40372 +#include "ttm_bo_driver.h"
40373 +#include "ttm_object.h"
40374 +#include "ttm_userobj_api.h"
40375 +#include "ttm_lock.h"
40376 +
40377 +struct ttm_bo_user_object {
40378 +       struct ttm_base_object base;
40379 +       struct ttm_buffer_object bo;
40380 +};
40381 +
40382 +static size_t pl_bo_size;
40383 +
40384 +static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages)
40385 +{
40386 +       size_t page_array_size =
40387 +           (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK;
40388 +
40389 +       if (unlikely(pl_bo_size == 0)) {
40390 +               pl_bo_size = bdev->ttm_bo_extra_size +
40391 +                   ttm_round_pot(sizeof(struct ttm_bo_user_object));
40392 +       }
40393 +
40394 +       return bdev->ttm_bo_size + 2 * page_array_size;
40395 +}
40396 +
40397 +static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file
40398 +                                                    *tfile, uint32_t handle)
40399 +{
40400 +       struct ttm_base_object *base;
40401 +
40402 +       base = ttm_base_object_lookup(tfile, handle);
40403 +       if (unlikely(base == NULL)) {
40404 +               printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
40405 +                      (unsigned long)handle);
40406 +               return NULL;
40407 +       }
40408 +
40409 +       if (unlikely(base->object_type != ttm_buffer_type)) {
40410 +               ttm_base_object_unref(&base);
40411 +               printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
40412 +                      (unsigned long)handle);
40413 +               return NULL;
40414 +       }
40415 +
40416 +       return container_of(base, struct ttm_bo_user_object, base);
40417 +}
40418 +
40419 +struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
40420 +                                                  *tfile, uint32_t handle)
40421 +{
40422 +       struct ttm_bo_user_object *user_bo;
40423 +       struct ttm_base_object *base;
40424 +
40425 +       user_bo = ttm_bo_user_lookup(tfile, handle);
40426 +       if (unlikely(user_bo == NULL))
40427 +               return NULL;
40428 +
40429 +       (void)ttm_bo_reference(&user_bo->bo);
40430 +       base = &user_bo->base;
40431 +       ttm_base_object_unref(&base);
40432 +       return &user_bo->bo;
40433 +}
40434 +
40435 +static void ttm_bo_user_destroy(struct ttm_buffer_object *bo)
40436 +{
40437 +       struct ttm_bo_user_object *user_bo =
40438 +           container_of(bo, struct ttm_bo_user_object, bo);
40439 +
40440 +       ttm_mem_global_free(bo->bdev->mem_glob, bo->acc_size, false);
40441 +       kfree(user_bo);
40442 +}
40443 +
40444 +static void ttm_bo_user_release(struct ttm_base_object **p_base)
40445 +{
40446 +       struct ttm_bo_user_object *user_bo;
40447 +       struct ttm_base_object *base = *p_base;
40448 +       struct ttm_buffer_object *bo;
40449 +
40450 +       *p_base = NULL;
40451 +
40452 +       if (unlikely(base == NULL))
40453 +               return;
40454 +
40455 +       user_bo = container_of(base, struct ttm_bo_user_object, base);
40456 +       bo = &user_bo->bo;
40457 +       ttm_bo_unref(&bo);
40458 +}
40459 +
40460 +static void ttm_bo_user_ref_release(struct ttm_base_object *base,
40461 +                                   enum ttm_ref_type ref_type)
40462 +{
40463 +       struct ttm_bo_user_object *user_bo =
40464 +           container_of(base, struct ttm_bo_user_object, base);
40465 +       struct ttm_buffer_object *bo = &user_bo->bo;
40466 +
40467 +       switch (ref_type) {
40468 +       case TTM_REF_SYNCCPU_WRITE:
40469 +               ttm_bo_synccpu_write_release(bo);
40470 +               break;
40471 +       default:
40472 +               BUG();
40473 +       }
40474 +}
40475 +
40476 +static void ttm_pl_fill_rep(struct ttm_buffer_object *bo,
40477 +                           struct ttm_pl_rep *rep)
40478 +{
40479 +       struct ttm_bo_user_object *user_bo =
40480 +           container_of(bo, struct ttm_bo_user_object, bo);
40481 +
40482 +       rep->gpu_offset = bo->offset;
40483 +       rep->bo_size = bo->num_pages << PAGE_SHIFT;
40484 +       rep->map_handle = bo->addr_space_offset;
40485 +       rep->placement = bo->mem.flags;
40486 +       rep->handle = user_bo->base.hash.key;
40487 +       rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg;
40488 +}
40489 +
40490 +int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
40491 +                       struct ttm_bo_device *bdev,
40492 +                       struct ttm_lock *lock, void *data)
40493 +{
40494 +       union ttm_pl_create_arg *arg = data;
40495 +       struct ttm_pl_create_req *req = &arg->req;
40496 +       struct ttm_pl_rep *rep = &arg->rep;
40497 +       struct ttm_buffer_object *bo;
40498 +       struct ttm_buffer_object *tmp;
40499 +       struct ttm_bo_user_object *user_bo;
40500 +       uint32_t flags;
40501 +       int ret = 0;
40502 +       struct ttm_mem_global *mem_glob = bdev->mem_glob;
40503 +       size_t acc_size =
40504 +           ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
40505 +       ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false);
40506 +       if (unlikely(ret != 0))
40507 +               return ret;
40508 +
40509 +       flags = req->placement;
40510 +       user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
40511 +       if (unlikely(user_bo == NULL)) {
40512 +               ttm_mem_global_free(mem_glob, acc_size, false);
40513 +               return -ENOMEM;
40514 +       }
40515 +
40516 +       bo = &user_bo->bo;
40517 +       ret = ttm_read_lock(lock, true);
40518 +       if (unlikely(ret != 0)) {
40519 +               ttm_mem_global_free(mem_glob, acc_size, false);
40520 +               kfree(user_bo);
40521 +               return ret;
40522 +       }
40523 +
40524 +       ret = ttm_buffer_object_init(bdev, bo, req->size,
40525 +                                    ttm_bo_type_device, flags,
40526 +                                    req->page_alignment, 0, true,
40527 +                                    NULL, acc_size, &ttm_bo_user_destroy);
40528 +       ttm_read_unlock(lock);
40529 +
40530 +       /*
40531 +        * Note that the ttm_buffer_object_init function
40532 +        * would've called the destroy function on failure!!
40533 +        */
40534 +
40535 +       if (unlikely(ret != 0))
40536 +               goto out;
40537 +
40538 +       tmp = ttm_bo_reference(bo);
40539 +       ret = ttm_base_object_init(tfile, &user_bo->base,
40540 +                                  flags & TTM_PL_FLAG_SHARED,
40541 +                                  ttm_buffer_type,
40542 +                                  &ttm_bo_user_release,
40543 +                                  &ttm_bo_user_ref_release);
40544 +       if (unlikely(ret != 0))
40545 +               goto out_err;
40546 +
40547 +       mutex_lock(&bo->mutex);
40548 +       ttm_pl_fill_rep(bo, rep);
40549 +       mutex_unlock(&bo->mutex);
40550 +       ttm_bo_unref(&bo);
40551 +out:
40552 +       return 0;
40553 +out_err:
40554 +       ttm_bo_unref(&tmp);
40555 +       ttm_bo_unref(&bo);
40556 +       return ret;
40557 +}
40558 +
40559 +int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
40560 +                          struct ttm_bo_device *bdev,
40561 +                          struct ttm_lock *lock, void *data)
40562 +{
40563 +       union ttm_pl_create_ub_arg *arg = data;
40564 +       struct ttm_pl_create_ub_req *req = &arg->req;
40565 +       struct ttm_pl_rep *rep = &arg->rep;
40566 +       struct ttm_buffer_object *bo;
40567 +       struct ttm_buffer_object *tmp;
40568 +       struct ttm_bo_user_object *user_bo;
40569 +       uint32_t flags;
40570 +       int ret = 0;
40571 +       struct ttm_mem_global *mem_glob = bdev->mem_glob;
40572 +       size_t acc_size =
40573 +           ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
40574 +       ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false);
40575 +       if (unlikely(ret != 0))
40576 +               return ret;
40577 +
40578 +       flags = req->placement;
40579 +       user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
40580 +       if (unlikely(user_bo == NULL)) {
40581 +               ttm_mem_global_free(mem_glob, acc_size, false);
40582 +               return -ENOMEM;
40583 +       }
40584 +       ret = ttm_read_lock(lock, true);
40585 +       if (unlikely(ret != 0)) {
40586 +               ttm_mem_global_free(mem_glob, acc_size, false);
40587 +               kfree(user_bo);
40588 +               return ret;
40589 +       }
40590 +       bo = &user_bo->bo;
40591 +       ret = ttm_buffer_object_init(bdev,
40592 +                                       bo,
40593 +                                       req->size,
40594 +                                       ttm_bo_type_user,
40595 +                                       flags,
40596 +                                       req->page_alignment,
40597 +                                       req->user_address,
40598 +                                       true,
40599 +                                       NULL,
40600 +                                       acc_size,
40601 +                                       &ttm_bo_user_destroy);
40602 +
40603 +       /*
40604 +        * Note that the ttm_buffer_object_init function
40605 +        * would've called the destroy function on failure!!
40606 +        */
40607 +       ttm_read_unlock(lock);
40608 +       if (unlikely(ret != 0))
40609 +               goto out;
40610 +
40611 +       tmp = ttm_bo_reference(bo);
40612 +       ret = ttm_base_object_init(tfile, &user_bo->base,
40613 +                                  flags & TTM_PL_FLAG_SHARED,
40614 +                                  ttm_buffer_type,
40615 +                                  &ttm_bo_user_release,
40616 +                                  &ttm_bo_user_ref_release);
40617 +       if (unlikely(ret != 0))
40618 +               goto out_err;
40619 +
40620 +       mutex_lock(&bo->mutex);
40621 +       ttm_pl_fill_rep(bo, rep);
40622 +       mutex_unlock(&bo->mutex);
40623 +       ttm_bo_unref(&bo);
40624 +out:
40625 +       return 0;
40626 +out_err:
40627 +       ttm_bo_unref(&tmp);
40628 +       ttm_bo_unref(&bo);
40629 +       return ret;
40630 +}
40631 +
40632 +int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data)
40633 +{
40634 +       union ttm_pl_reference_arg *arg = data;
40635 +       struct ttm_pl_rep *rep = &arg->rep;
40636 +       struct ttm_bo_user_object *user_bo;
40637 +       struct ttm_buffer_object *bo;
40638 +       struct ttm_base_object *base;
40639 +       int ret;
40640 +
40641 +       user_bo = ttm_bo_user_lookup(tfile, arg->req.handle);
40642 +       if (unlikely(user_bo == NULL)) {
40643 +               printk(KERN_ERR "Could not reference buffer object.\n");
40644 +               return -EINVAL;
40645 +       }
40646 +
40647 +       bo = &user_bo->bo;
40648 +       ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL);
40649 +       if (unlikely(ret != 0)) {
40650 +               printk(KERN_ERR
40651 +                      "Could not add a reference to buffer object.\n");
40652 +               goto out;
40653 +       }
40654 +
40655 +       mutex_lock(&bo->mutex);
40656 +       ttm_pl_fill_rep(bo, rep);
40657 +       mutex_unlock(&bo->mutex);
40658 +
40659 +out:
40660 +       base = &user_bo->base;
40661 +       ttm_base_object_unref(&base);
40662 +       return ret;
40663 +}
40664 +
40665 +int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data)
40666 +{
40667 +       struct ttm_pl_reference_req *arg = data;
40668 +
40669 +       return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE);
40670 +}
40671 +
40672 +int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data)
40673 +{
40674 +       struct ttm_pl_synccpu_arg *arg = data;
40675 +       struct ttm_bo_user_object *user_bo;
40676 +       struct ttm_buffer_object *bo;
40677 +       struct ttm_base_object *base;
40678 +       bool existed;
40679 +       int ret;
40680 +
40681 +       switch (arg->op) {
40682 +       case TTM_PL_SYNCCPU_OP_GRAB:
40683 +               user_bo = ttm_bo_user_lookup(tfile, arg->handle);
40684 +               if (unlikely(user_bo == NULL)) {
40685 +                       printk(KERN_ERR
40686 +                              "Could not find buffer object for synccpu.\n");
40687 +                       return -EINVAL;
40688 +               }
40689 +               bo = &user_bo->bo;
40690 +               base = &user_bo->base;
40691 +               ret = ttm_bo_synccpu_write_grab(bo,
40692 +                                               arg->access_mode &
40693 +                                               TTM_PL_SYNCCPU_MODE_NO_BLOCK);
40694 +               if (unlikely(ret != 0)) {
40695 +                       ttm_base_object_unref(&base);
40696 +                       goto out;
40697 +               }
40698 +               ret = ttm_ref_object_add(tfile, &user_bo->base,
40699 +                                        TTM_REF_SYNCCPU_WRITE, &existed);
40700 +               if (existed || ret != 0)
40701 +                       ttm_bo_synccpu_write_release(bo);
40702 +               ttm_base_object_unref(&base);
40703 +               break;
40704 +       case TTM_PL_SYNCCPU_OP_RELEASE:
40705 +               ret = ttm_ref_object_base_unref(tfile, arg->handle,
40706 +                                               TTM_REF_SYNCCPU_WRITE);
40707 +               break;
40708 +       default:
40709 +               ret = -EINVAL;
40710 +               break;
40711 +       }
40712 +out:
40713 +       return ret;
40714 +}
40715 +
40716 +int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
40717 +                          struct ttm_lock *lock, void *data)
40718 +{
40719 +       union ttm_pl_setstatus_arg *arg = data;
40720 +       struct ttm_pl_setstatus_req *req = &arg->req;
40721 +       struct ttm_pl_rep *rep = &arg->rep;
40722 +       struct ttm_buffer_object *bo;
40723 +       struct ttm_bo_device *bdev;
40724 +       int ret;
40725 +
40726 +       bo = ttm_buffer_object_lookup(tfile, req->handle);
40727 +       if (unlikely(bo == NULL)) {
40728 +               printk(KERN_ERR
40729 +                      "Could not find buffer object for setstatus.\n");
40730 +               return -EINVAL;
40731 +       }
40732 +
40733 +       bdev = bo->bdev;
40734 +
40735 +       ret = ttm_read_lock(lock, true);
40736 +       if (unlikely(ret != 0))
40737 +               goto out_err0;
40738 +
40739 +       ret = ttm_bo_reserve(bo, true, false, false, 0);
40740 +       if (unlikely(ret != 0))
40741 +               goto out_err1;
40742 +
40743 +       ret = ttm_bo_wait_cpu(bo, false);
40744 +       if (unlikely(ret != 0))
40745 +               goto out_err2;
40746 +
40747 +       mutex_lock(&bo->mutex);
40748 +       ret = ttm_bo_check_placement(bo, req->set_placement,
40749 +                                    req->clr_placement);
40750 +       if (unlikely(ret != 0))
40751 +               goto out_err2;
40752 +
40753 +       bo->proposed_flags = (bo->proposed_flags | req->set_placement)
40754 +           & ~req->clr_placement;
40755 +       ret = ttm_buffer_object_validate(bo, true, false);
40756 +       if (unlikely(ret != 0))
40757 +               goto out_err2;
40758 +
40759 +       ttm_pl_fill_rep(bo, rep);
40760 +out_err2:
40761 +       mutex_unlock(&bo->mutex);
40762 +       ttm_bo_unreserve(bo);
40763 +out_err1:
40764 +       ttm_read_unlock(lock);
40765 +out_err0:
40766 +       ttm_bo_unref(&bo);
40767 +       return ret;
40768 +}
40769 +
40770 +int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data)
40771 +{
40772 +       struct ttm_pl_waitidle_arg *arg = data;
40773 +       struct ttm_buffer_object *bo;
40774 +       int ret;
40775 +
40776 +       bo = ttm_buffer_object_lookup(tfile, arg->handle);
40777 +       if (unlikely(bo == NULL)) {
40778 +               printk(KERN_ERR "Could not find buffer object for waitidle.\n");
40779 +               return -EINVAL;
40780 +       }
40781 +
40782 +       ret =
40783 +           ttm_bo_block_reservation(bo, true,
40784 +                                    arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
40785 +       if (unlikely(ret != 0))
40786 +               goto out;
40787 +       mutex_lock(&bo->mutex);
40788 +       ret = ttm_bo_wait(bo,
40789 +                         arg->mode & TTM_PL_WAITIDLE_MODE_LAZY,
40790 +                         true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
40791 +       mutex_unlock(&bo->mutex);
40792 +       ttm_bo_unblock_reservation(bo);
40793 +out:
40794 +       ttm_bo_unref(&bo);
40795 +       return ret;
40796 +}
40797 +
40798 +int ttm_pl_verify_access(struct ttm_buffer_object *bo,
40799 +                        struct ttm_object_file *tfile)
40800 +{
40801 +       struct ttm_bo_user_object *ubo;
40802 +
40803 +       /*
40804 +        * Check bo subclass.
40805 +        */
40806 +
40807 +       if (unlikely(bo->destroy != &ttm_bo_user_destroy))
40808 +               return -EPERM;
40809 +
40810 +       ubo = container_of(bo, struct ttm_bo_user_object, bo);
40811 +       if (likely(ubo->base.shareable || ubo->base.tfile == tfile))
40812 +               return 0;
40813 +
40814 +       return -EPERM;
40815 +}
40816 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.h
40817 new file mode 100644
40818 index 0000000..5d8100f
40819 --- /dev/null
40820 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_placement_user.h
40821 @@ -0,0 +1,252 @@
40822 +/**************************************************************************
40823 + *
40824 + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
40825 + * All Rights Reserved.
40826 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
40827 + * All Rights Reserved.
40828 + *
40829 + * This program is free software; you can redistribute it and/or modify it
40830 + * under the terms and conditions of the GNU General Public License,
40831 + * version 2, as published by the Free Software Foundation.
40832 + *
40833 + * This program is distributed in the hope it will be useful, but WITHOUT
40834 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40835 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
40836 + * more details.
40837 + *
40838 + * You should have received a copy of the GNU General Public License along with
40839 + * this program; if not, write to the Free Software Foundation, Inc., 
40840 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
40841 + *
40842 + **************************************************************************/
40843 +/*
40844 + * Authors
40845 + * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
40846 + */
40847 +
40848 +#ifndef _TTM_PLACEMENT_USER_H_
40849 +#define _TTM_PLACEMENT_USER_H_
40850 +
40851 +#if !defined(__KERNEL__) && !defined(_KERNEL)
40852 +#include <stdint.h>
40853 +#else
40854 +#include <linux/kernel.h>
40855 +#endif
40856 +
40857 +#include "ttm_placement_common.h"
40858 +
40859 +#define TTM_PLACEMENT_MAJOR 0
40860 +#define TTM_PLACEMENT_MINOR 1
40861 +#define TTM_PLACEMENT_PL    0
40862 +#define TTM_PLACEMENT_DATE  "080819"
40863 +
40864 +/**
40865 + * struct ttm_pl_create_req
40866 + *
40867 + * @size: The buffer object size.
40868 + * @placement: Flags that indicate initial acceptable
40869 + *  placement.
40870 + * @page_alignment: Required alignment in pages.
40871 + *
40872 + * Input to the TTM_BO_CREATE ioctl.
40873 + */
40874 +
40875 +struct ttm_pl_create_req {
40876 +       uint64_t size;
40877 +       uint32_t placement;
40878 +       uint32_t page_alignment;
40879 +};
40880 +
40881 +/**
40882 + * struct ttm_pl_create_ub_req
40883 + *
40884 + * @size: The buffer object size.
40885 + * @user_address: User-space address of the memory area that
40886 + * should be used to back the buffer object cast to 64-bit.
40887 + * @placement: Flags that indicate initial acceptable
40888 + *  placement.
40889 + * @page_alignment: Required alignment in pages.
40890 + *
40891 + * Input to the TTM_BO_CREATE_UB ioctl.
40892 + */
40893 +
40894 +struct ttm_pl_create_ub_req {
40895 +       uint64_t size;
40896 +       uint64_t user_address;
40897 +       uint32_t placement;
40898 +       uint32_t page_alignment;
40899 +};
40900 +
40901 +/**
40902 + * struct ttm_pl_rep
40903 + *
40904 + * @gpu_offset: The current offset into the memory region used.
40905 + * This can be used directly by the GPU if there are no
40906 + * additional GPU mapping procedures used by the driver.
40907 + *
40908 + * @bo_size: Actual buffer object size.
40909 + *
40910 + * @map_handle: Offset into the device address space.
40911 + * Used for map, seek, read, write. This will never change
40912 + * during the lifetime of an object.
40913 + *
40914 + * @placement: Flag indicating the placement status of
40915 + * the buffer object using the TTM_PL flags above.
40916 + *
40917 + * @sync_object_arg: Used for user-space synchronization and
40918 + * depends on the synchronization model used. If fences are
40919 + * used, this is the buffer_object::fence_type_mask
40920 + *
40921 + * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and
40922 + * TTM_PL_SETSTATUS ioctls.
40923 + */
40924 +
40925 +struct ttm_pl_rep {
40926 +       uint64_t gpu_offset;
40927 +       uint64_t bo_size;
40928 +       uint64_t map_handle;
40929 +       uint32_t placement;
40930 +       uint32_t handle;
40931 +       uint32_t sync_object_arg;
40932 +       uint32_t pad64;
40933 +};
40934 +
40935 +/**
40936 + * struct ttm_pl_setstatus_req
40937 + *
40938 + * @set_placement: Placement flags to set.
40939 + *
40940 + * @clr_placement: Placement flags to clear.
40941 + *
40942 + * @handle: The object handle
40943 + *
40944 + * Input to the TTM_PL_SETSTATUS ioctl.
40945 + */
40946 +
40947 +struct ttm_pl_setstatus_req {
40948 +       uint32_t set_placement;
40949 +       uint32_t clr_placement;
40950 +       uint32_t handle;
40951 +       uint32_t pad64;
40952 +};
40953 +
40954 +/**
40955 + * struct ttm_pl_reference_req
40956 + *
40957 + * @handle: The object to put a reference on.
40958 + *
40959 + * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls.
40960 + */
40961 +
40962 +struct ttm_pl_reference_req {
40963 +       uint32_t handle;
40964 +       uint32_t pad64;
40965 +};
40966 +
40967 +/*
40968 + * ACCESS mode flags for SYNCCPU.
40969 + *
40970 + * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not
40971 + * writing to the buffer.
40972 + *
40973 + * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not
40974 + * accessing the buffer.
40975 + *
40976 + * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait
40977 + * for GPU accesses to finish but return -EBUSY.
40978 + *
40979 + * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable
40980 + * memory while synchronized for CPU.
40981 + */
40982 +
40983 +#define TTM_PL_SYNCCPU_MODE_READ      TTM_ACCESS_READ
40984 +#define TTM_PL_SYNCCPU_MODE_WRITE     TTM_ACCESS_WRITE
40985 +#define TTM_PL_SYNCCPU_MODE_NO_BLOCK  (1 << 2)
40986 +#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3)
40987 +
40988 +/**
40989 + * struct ttm_pl_synccpu_arg
40990 + *
40991 + * @handle: The object to synchronize.
40992 + *
40993 + * @access_mode: access mode indicated by the
40994 + * TTM_SYNCCPU_MODE flags.
40995 + *
40996 + * @op: indicates whether to grab or release the
40997 + * buffer for cpu usage.
40998 + *
40999 + * Input to the TTM_PL_SYNCCPU ioctl.
41000 + */
41001 +
41002 +struct ttm_pl_synccpu_arg {
41003 +       uint32_t handle;
41004 +       uint32_t access_mode;
41005 +       enum {
41006 +               TTM_PL_SYNCCPU_OP_GRAB,
41007 +               TTM_PL_SYNCCPU_OP_RELEASE
41008 +       } op;
41009 +       uint32_t pad64;
41010 +};
41011 +
41012 +/*
41013 + * Waiting mode flags for the TTM_BO_WAITIDLE ioctl.
41014 + *
41015 + * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling
41016 + * wait.
41017 + *
41018 + * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU,
41019 + * but return -EBUSY if the buffer is busy.
41020 + */
41021 +
41022 +#define TTM_PL_WAITIDLE_MODE_LAZY     (1 << 0)
41023 +#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1)
41024 +
41025 +/**
41026 + * struct ttm_waitidle_arg
41027 + *
41028 + * @handle: The object to synchronize.
41029 + *
41030 + * @mode: wait mode indicated by the
41031 + * TTM_SYNCCPU_MODE flags.
41032 + *
41033 + * Argument to the TTM_BO_WAITIDLE ioctl.
41034 + */
41035 +
41036 +struct ttm_pl_waitidle_arg {
41037 +       uint32_t handle;
41038 +       uint32_t mode;
41039 +};
41040 +
41041 +union ttm_pl_create_arg {
41042 +       struct ttm_pl_create_req req;
41043 +       struct ttm_pl_rep rep;
41044 +};
41045 +
41046 +union ttm_pl_reference_arg {
41047 +       struct ttm_pl_reference_req req;
41048 +       struct ttm_pl_rep rep;
41049 +};
41050 +
41051 +union ttm_pl_setstatus_arg {
41052 +       struct ttm_pl_setstatus_req req;
41053 +       struct ttm_pl_rep rep;
41054 +};
41055 +
41056 +union ttm_pl_create_ub_arg {
41057 +       struct ttm_pl_create_ub_req req;
41058 +       struct ttm_pl_rep rep;
41059 +};
41060 +
41061 +/*
41062 + * Ioctl offsets.
41063 + */
41064 +
41065 +#define TTM_PL_CREATE      0x00
41066 +#define TTM_PL_REFERENCE   0x01
41067 +#define TTM_PL_UNREF       0x02
41068 +#define TTM_PL_SYNCCPU     0x03
41069 +#define TTM_PL_WAITIDLE    0x04
41070 +#define TTM_PL_SETSTATUS   0x05
41071 +#define TTM_PL_CREATE_UB   0x06
41072 +
41073 +#endif
41074 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_regman.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_regman.h
41075 new file mode 100644
41076 index 0000000..ed73652
41077 --- /dev/null
41078 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_regman.h
41079 @@ -0,0 +1,67 @@
41080 +/**************************************************************************
41081 + *
41082 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
41083 + * All Rights Reserved.
41084 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
41085 + * All Rights Reserved.
41086 + *
41087 + * This program is free software; you can redistribute it and/or modify it
41088 + * under the terms and conditions of the GNU General Public License,
41089 + * version 2, as published by the Free Software Foundation.
41090 + *
41091 + * This program is distributed in the hope it will be useful, but WITHOUT
41092 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41093 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
41094 + * more details.
41095 + *
41096 + * You should have received a copy of the GNU General Public License along with
41097 + * this program; if not, write to the Free Software Foundation, Inc., 
41098 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
41099 + *
41100 + **************************************************************************/
41101 +/*
41102 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
41103 + */
41104 +
41105 +#ifndef _TTM_REGMAN_H_
41106 +#define _TTM_REGMAN_H_
41107 +
41108 +#include <linux/list.h>
41109 +
41110 +struct ttm_fence_object;
41111 +
41112 +struct ttm_reg {
41113 +       struct list_head head;
41114 +       struct ttm_fence_object *fence;
41115 +       uint32_t fence_type;
41116 +       uint32_t new_fence_type;
41117 +};
41118 +
41119 +struct ttm_reg_manager {
41120 +       struct list_head free;
41121 +       struct list_head lru;
41122 +       struct list_head unfenced;
41123 +
41124 +       int (*reg_reusable)(const struct ttm_reg *reg, const void *data);
41125 +       void (*reg_destroy)(struct ttm_reg *reg);
41126 +};
41127 +
41128 +extern int ttm_regs_alloc(struct ttm_reg_manager *manager,
41129 +                         const void *data,
41130 +                         uint32_t fence_class,
41131 +                         uint32_t fence_type,
41132 +                         int interruptible,
41133 +                         int no_wait,
41134 +                         struct ttm_reg **reg);
41135 +
41136 +extern void ttm_regs_fence(struct ttm_reg_manager *regs,
41137 +                          struct ttm_fence_object *fence);
41138 +
41139 +extern void ttm_regs_free(struct ttm_reg_manager *manager);
41140 +extern void ttm_regs_add(struct ttm_reg_manager *manager, struct ttm_reg *reg);
41141 +extern void ttm_regs_init(struct ttm_reg_manager *manager,
41142 +                         int (*reg_reusable)(const struct ttm_reg *,
41143 +                                             const void *),
41144 +                         void (*reg_destroy)(struct ttm_reg *));
41145 +
41146 +#endif
41147 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_tt.c b/drivers/gpu/drm/mrst/drv/ttm/ttm_tt.c
41148 new file mode 100644
41149 index 0000000..4c0e318
41150 --- /dev/null
41151 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_tt.c
41152 @@ -0,0 +1,653 @@
41153 +/**************************************************************************
41154 + *
41155 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
41156 + * All Rights Reserved.
41157 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
41158 + * All Rights Reserved.
41159 + *
41160 + * This program is free software; you can redistribute it and/or modify it
41161 + * under the terms and conditions of the GNU General Public License,
41162 + * version 2, as published by the Free Software Foundation.
41163 + *
41164 + * This program is distributed in the hope it will be useful, but WITHOUT
41165 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41166 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
41167 + * more details.
41168 + *
41169 + * You should have received a copy of the GNU General Public License along with
41170 + * this program; if not, write to the Free Software Foundation, Inc., 
41171 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
41172 + *
41173 + **************************************************************************/
41174 +/*
41175 + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
41176 + */
41177 +
41178 +#include <linux/version.h>
41179 +#include <linux/vmalloc.h>
41180 +#include <linux/sched.h>
41181 +#include <linux/highmem.h>
41182 +#include <linux/pagemap.h>
41183 +#include <linux/file.h>
41184 +#include <linux/swap.h>
41185 +#include "ttm_bo_driver.h"
41186 +#include "ttm_placement_common.h"
41187 +
41188 +static int ttm_tt_swapin(struct ttm_tt *ttm);
41189 +
41190 +#if defined(CONFIG_X86)
41191 +static void ttm_tt_clflush_page(struct page *page)
41192 +{
41193 +       uint8_t *page_virtual;
41194 +       unsigned int i;
41195 +
41196 +       if (unlikely(page == NULL))
41197 +               return;
41198 +
41199 +       page_virtual = kmap_atomic(page, KM_USER0);
41200 +
41201 +       for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
41202 +               clflush(page_virtual + i);
41203 +
41204 +       kunmap_atomic(page_virtual, KM_USER0);
41205 +}
41206 +
41207 +static void ttm_tt_cache_flush_clflush(struct page *pages[],
41208 +                                      unsigned long num_pages)
41209 +{
41210 +       unsigned long i;
41211 +
41212 +       mb();
41213 +       for (i = 0; i < num_pages; ++i)
41214 +               ttm_tt_clflush_page(*pages++);
41215 +       mb();
41216 +}
41217 +#else
41218 +static void ttm_tt_ipi_handler(void *null)
41219 +{
41220 +       ;
41221 +}
41222 +#endif
41223 +
41224 +void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages)
41225 +{
41226 +
41227 +#if defined(CONFIG_X86)
41228 +       if (cpu_has_clflush) {
41229 +               ttm_tt_cache_flush_clflush(pages, num_pages);
41230 +               return;
41231 +       }
41232 +#else
41233 +       if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1, 1) != 0)
41234 +               printk(KERN_ERR "Timed out waiting for drm cache flush.\n");
41235 +#endif
41236 +}
41237 +
41238 +/**
41239 + * Allocates storage for pointers to the pages that back the ttm.
41240 + *
41241 + * Uses kmalloc if possible. Otherwise falls back to vmalloc.
41242 + */
41243 +static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
41244 +{
41245 +       unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
41246 +       ttm->pages = NULL;
41247 +
41248 +       if (size <= PAGE_SIZE)
41249 +               ttm->pages = kzalloc(size, GFP_KERNEL);
41250 +
41251 +       if (!ttm->pages) {
41252 +               ttm->pages = vmalloc_user(size);
41253 +               if (ttm->pages)
41254 +                       ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC;
41255 +       }
41256 +}
41257 +
41258 +static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
41259 +{
41260 +       if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) {
41261 +               vfree(ttm->pages);
41262 +               ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC;
41263 +       } else {
41264 +               kfree(ttm->pages);
41265 +       }
41266 +       ttm->pages = NULL;
41267 +}
41268 +
41269 +static struct page *ttm_tt_alloc_page(void)
41270 +{
41271 +       return alloc_page(GFP_KERNEL | __GFP_ZERO);
41272 +}
41273 +
41274 +static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
41275 +{
41276 +       int write;
41277 +       int dirty;
41278 +       struct page *page;
41279 +       int i;
41280 +       struct ttm_backend *be = ttm->be;
41281 +
41282 +       BUG_ON(!(ttm->page_flags & TTM_PAGE_FLAG_USER));
41283 +       write = ((ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0);
41284 +       dirty = ((ttm->page_flags & TTM_PAGE_FLAG_USER_DIRTY) != 0);
41285 +
41286 +       if (be)
41287 +               be->func->clear(be);
41288 +
41289 +       for (i = 0; i < ttm->num_pages; ++i) {
41290 +               page = ttm->pages[i];
41291 +               if (page == NULL)
41292 +                       continue;
41293 +
41294 +               if (page == ttm->dummy_read_page) {
41295 +                       BUG_ON(write);
41296 +                       continue;
41297 +               }
41298 +
41299 +               if (write && dirty && !PageReserved(page))
41300 +                       set_page_dirty_lock(page);
41301 +
41302 +               ttm->pages[i] = NULL;
41303 +               ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, false);
41304 +               put_page(page);
41305 +       }
41306 +       ttm->state = tt_unpopulated;
41307 +       ttm->first_himem_page = ttm->num_pages;
41308 +       ttm->last_lomem_page = -1;
41309 +}
41310 +
41311 +static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
41312 +{
41313 +       struct page *p;
41314 +       struct ttm_bo_device *bdev = ttm->bdev;
41315 +       struct ttm_mem_global *mem_glob = bdev->mem_glob;
41316 +       int ret;
41317 +
41318 +       while (NULL == (p = ttm->pages[index])) {
41319 +               p = ttm_tt_alloc_page();
41320 +
41321 +               if (!p)
41322 +                       return NULL;
41323 +
41324 +               if (PageHighMem(p)) {
41325 +                       ret = ttm_mem_global_alloc(mem_glob,
41326 +                                                  PAGE_SIZE,
41327 +                                                  false,
41328 +                                                  false,
41329 +                                                  true);
41330 +                       if (unlikely(ret != 0))
41331 +                               goto out_err;
41332 +                       ttm->pages[--ttm->first_himem_page] = p;
41333 +               } else {
41334 +                       ret =
41335 +                           ttm_mem_global_alloc(mem_glob,
41336 +                                                PAGE_SIZE,
41337 +                                                false,
41338 +                                                false,
41339 +                                                false);
41340 +                       if (unlikely(ret != 0))
41341 +                               goto out_err;
41342 +                       ttm->pages[++ttm->last_lomem_page] = p;
41343 +               }
41344 +       }
41345 +       return p;
41346 +out_err:
41347 +       put_page(p);
41348 +       return NULL;
41349 +}
41350 +
41351 +struct page *ttm_tt_get_page(struct ttm_tt *ttm, int index)
41352 +{
41353 +       int ret;
41354 +
41355 +       if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
41356 +               ret = ttm_tt_swapin(ttm);
41357 +               if (unlikely(ret != 0))
41358 +                       return NULL;
41359 +       }
41360 +       return __ttm_tt_get_page(ttm, index);
41361 +}
41362 +
41363 +int ttm_tt_populate(struct ttm_tt *ttm)
41364 +{
41365 +       struct page *page;
41366 +       unsigned long i;
41367 +       struct ttm_backend *be;
41368 +       int ret;
41369 +
41370 +       if (ttm->state != tt_unpopulated)
41371 +               return 0;
41372 +
41373 +       if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
41374 +               ret = ttm_tt_swapin(ttm);
41375 +               if (unlikely(ret != 0))
41376 +                       return ret;
41377 +       }
41378 +
41379 +       be = ttm->be;
41380 +
41381 +       for (i = 0; i < ttm->num_pages; ++i) {
41382 +               page = __ttm_tt_get_page(ttm, i);
41383 +               if (!page)
41384 +                       return -ENOMEM;
41385 +       }
41386 +
41387 +       be->func->populate(be, ttm->num_pages, ttm->pages,
41388 +                          ttm->dummy_read_page);
41389 +       ttm->state = tt_unbound;
41390 +       return 0;
41391 +}
41392 +
41393 +#ifdef CONFIG_X86
41394 +static inline int ttm_tt_set_page_caching(struct page *p,
41395 +                                         enum ttm_caching_state c_state)
41396 +{
41397 +       if (PageHighMem(p))
41398 +               return 0;
41399 +
41400 +       switch (c_state) {
41401 +       case tt_cached:
41402 +               return set_pages_wb(p, 1);
41403 +       case tt_wc:
41404 +           return set_memory_wc((unsigned long) page_address(p), 1);
41405 +       default:
41406 +               return set_pages_uc(p, 1);
41407 +       }
41408 +}
41409 +#else /* CONFIG_X86 */
41410 +static inline int ttm_tt_set_page_caching(struct page *p,
41411 +                                         enum ttm_caching_state c_state)
41412 +{
41413 +       return 0;
41414 +}
41415 +#endif /* CONFIG_X86 */
41416 +
41417 +/*
41418 + * Change caching policy for the linear kernel map
41419 + * for range of pages in a ttm.
41420 + */
41421 +
41422 +static int ttm_tt_set_caching(struct ttm_tt *ttm,
41423 +                             enum ttm_caching_state c_state)
41424 +{
41425 +       int i, j;
41426 +       struct page *cur_page;
41427 +       int ret;
41428 +
41429 +       if (ttm->caching_state == c_state)
41430 +               return 0;
41431 +
41432 +       if (c_state != tt_cached) {
41433 +               ret = ttm_tt_populate(ttm);
41434 +               if (unlikely(ret != 0))
41435 +                       return ret;
41436 +       }
41437 +
41438 +       if (ttm->caching_state == tt_cached)
41439 +               ttm_tt_cache_flush(ttm->pages, ttm->num_pages);
41440 +
41441 +       for (i = 0; i < ttm->num_pages; ++i) {
41442 +               cur_page = ttm->pages[i];
41443 +               if (likely(cur_page != NULL)) {
41444 +                       ret = ttm_tt_set_page_caching(cur_page, c_state);
41445 +                       if (unlikely(ret != 0))
41446 +                               goto out_err;
41447 +               }
41448 +       }
41449 +
41450 +       ttm->caching_state = c_state;
41451 +
41452 +       return 0;
41453 +
41454 +out_err:
41455 +       for (j = 0; j < i; ++j) {
41456 +               cur_page = ttm->pages[j];
41457 +               if (likely(cur_page != NULL)) {
41458 +                       (void)ttm_tt_set_page_caching(cur_page,
41459 +                                                     ttm->caching_state);
41460 +               }
41461 +       }
41462 +
41463 +       return ret;
41464 +}
41465 +
41466 +int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement)
41467 +{
41468 +       enum ttm_caching_state state;
41469 +
41470 +       if (placement & TTM_PL_FLAG_WC)
41471 +               state = tt_wc;
41472 +       else if (placement & TTM_PL_FLAG_UNCACHED)
41473 +               state = tt_uncached;
41474 +       else
41475 +               state = tt_cached;
41476 +
41477 +       return ttm_tt_set_caching(ttm, state);
41478 +}
41479 +
41480 +static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
41481 +{
41482 +       int i;
41483 +       struct page *cur_page;
41484 +       struct ttm_backend *be = ttm->be;
41485 +
41486 +       if (be)
41487 +               be->func->clear(be);
41488 +       (void)ttm_tt_set_caching(ttm, tt_cached);
41489 +       for (i = 0; i < ttm->num_pages; ++i) {
41490 +               cur_page = ttm->pages[i];
41491 +               ttm->pages[i] = NULL;
41492 +               if (cur_page) {
41493 +                       if (page_count(cur_page) != 1)
41494 +                               printk(KERN_ERR
41495 +                                   "Erroneous page count. Leaking pages.\n");
41496 +                       ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE,
41497 +                                           PageHighMem(cur_page));
41498 +                       __free_page(cur_page);
41499 +               }
41500 +       }
41501 +       ttm->state = tt_unpopulated;
41502 +       ttm->first_himem_page = ttm->num_pages;
41503 +       ttm->last_lomem_page = -1;
41504 +}
41505 +
41506 +void ttm_tt_destroy(struct ttm_tt *ttm)
41507 +{
41508 +       struct ttm_backend *be;
41509 +
41510 +       if (unlikely(ttm == NULL))
41511 +               return;
41512 +
41513 +       be = ttm->be;
41514 +       if (likely(be != NULL)) {
41515 +               be->func->destroy(be);
41516 +               ttm->be = NULL;
41517 +       }
41518 +
41519 +       if (likely(ttm->pages != NULL)) {
41520 +               if (ttm->page_flags & TTM_PAGE_FLAG_USER)
41521 +                       ttm_tt_free_user_pages(ttm);
41522 +               else
41523 +                       ttm_tt_free_alloced_pages(ttm);
41524 +
41525 +               ttm_tt_free_page_directory(ttm);
41526 +       }
41527 +
41528 +       if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTANT_SWAP) &&
41529 +           ttm->swap_storage)
41530 +               fput(ttm->swap_storage);
41531 +
41532 +       kfree(ttm);
41533 +}
41534 +
41535 +int ttm_tt_set_user(struct ttm_tt *ttm,
41536 +                   struct task_struct *tsk,
41537 +                   unsigned long start, unsigned long num_pages)
41538 +{
41539 +       struct mm_struct *mm = tsk->mm;
41540 +       int ret;
41541 +       int write = (ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0;
41542 +       struct ttm_mem_global *mem_glob = ttm->bdev->mem_glob;
41543 +
41544 +       BUG_ON(num_pages != ttm->num_pages);
41545 +       BUG_ON((ttm->page_flags & TTM_PAGE_FLAG_USER) == 0);
41546 +
41547 +       /**
41548 +        * Account user pages as lowmem pages for now.
41549 +        */
41550 +
41551 +       ret = ttm_mem_global_alloc(mem_glob,
41552 +                                  num_pages * PAGE_SIZE,
41553 +                                  false,
41554 +                                  false,
41555 +                                  false);
41556 +       if (unlikely(ret != 0))
41557 +               return ret;
41558 +
41559 +       down_read(&mm->mmap_sem);
41560 +       ret = get_user_pages(tsk, mm, start, num_pages,
41561 +                            write, 0, ttm->pages, NULL);
41562 +       up_read(&mm->mmap_sem);
41563 +
41564 +       if (ret != num_pages && write) {
41565 +               ttm_tt_free_user_pages(ttm);
41566 +               ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE, false);
41567 +               return -ENOMEM;
41568 +       }
41569 +
41570 +       ttm->tsk = tsk;
41571 +       ttm->start = start;
41572 +       ttm->state = tt_unbound;
41573 +
41574 +       return 0;
41575 +}
41576 +
41577 +struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
41578 +                            uint32_t page_flags, struct page *dummy_read_page)
41579 +{
41580 +       struct ttm_bo_driver *bo_driver = bdev->driver;
41581 +       struct ttm_tt *ttm;
41582 +
41583 +       if (!bo_driver)
41584 +               return NULL;
41585 +
41586 +       ttm = kzalloc(sizeof(*ttm), GFP_KERNEL);
41587 +       if (!ttm)
41588 +               return NULL;
41589 +
41590 +       ttm->bdev = bdev;
41591 +
41592 +       ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
41593 +       ttm->first_himem_page = ttm->num_pages;
41594 +       ttm->last_lomem_page = -1;
41595 +       ttm->caching_state = tt_cached;
41596 +       ttm->page_flags = page_flags;
41597 +
41598 +       ttm->dummy_read_page = dummy_read_page;
41599 +
41600 +       ttm_tt_alloc_page_directory(ttm);
41601 +       if (!ttm->pages) {
41602 +               ttm_tt_destroy(ttm);
41603 +               printk(KERN_ERR "Failed allocating page table\n");
41604 +               return NULL;
41605 +       }
41606 +       ttm->be = bo_driver->create_ttm_backend_entry(bdev);
41607 +       if (!ttm->be) {
41608 +               ttm_tt_destroy(ttm);
41609 +               printk(KERN_ERR "Failed creating ttm backend entry\n");
41610 +               return NULL;
41611 +       }
41612 +       ttm->state = tt_unpopulated;
41613 +       return ttm;
41614 +}
41615 +
41616 +/**
41617 + * ttm_tt_unbind:
41618 + *
41619 + * @ttm: the object to unbind from the graphics device
41620 + *
41621 + * Unbind an object from the aperture. This removes the mappings
41622 + * from the graphics device and flushes caches if necessary.
41623 + */
41624 +void ttm_tt_unbind(struct ttm_tt *ttm)
41625 +{
41626 +       int ret;
41627 +       struct ttm_backend *be = ttm->be;
41628 +
41629 +       if (ttm->state == tt_bound) {
41630 +               ret = be->func->unbind(be);
41631 +               BUG_ON(ret);
41632 +       }
41633 +       ttm->state = tt_unbound;
41634 +}
41635 +
41636 +/**
41637 + * ttm_tt_bind:
41638 + *
41639 + * @ttm: the ttm object to bind to the graphics device
41640 + *
41641 + * @bo_mem: the aperture memory region which will hold the object
41642 + *
41643 + * Bind a ttm object to the aperture. This ensures that the necessary
41644 + * pages are allocated, flushes CPU caches as needed and marks the
41645 + * ttm as DRM_TTM_PAGE_USER_DIRTY to indicate that it may have been
41646 + * modified by the GPU
41647 + */
41648 +
41649 +int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
41650 +{
41651 +       int ret = 0;
41652 +       struct ttm_backend *be;
41653 +
41654 +       if (!ttm)
41655 +               return -EINVAL;
41656 +
41657 +       if (ttm->state == tt_bound)
41658 +               return 0;
41659 +
41660 +       be = ttm->be;
41661 +
41662 +       ret = ttm_tt_populate(ttm);
41663 +       if (ret)
41664 +               return ret;
41665 +
41666 +       ret = be->func->bind(be, bo_mem);
41667 +       if (ret) {
41668 +               printk(KERN_ERR "Couldn't bind backend.\n");
41669 +               return ret;
41670 +       }
41671 +
41672 +       ttm->state = tt_bound;
41673 +
41674 +       if (ttm->page_flags & TTM_PAGE_FLAG_USER)
41675 +               ttm->page_flags |= TTM_PAGE_FLAG_USER_DIRTY;
41676 +       return 0;
41677 +}
41678 +
41679 +static int ttm_tt_swapin(struct ttm_tt *ttm)
41680 +{
41681 +       struct address_space *swap_space;
41682 +       struct file *swap_storage;
41683 +       struct page *from_page;
41684 +       struct page *to_page;
41685 +       void *from_virtual;
41686 +       void *to_virtual;
41687 +       int i;
41688 +       int ret;
41689 +
41690 +       if (ttm->page_flags & TTM_PAGE_FLAG_USER) {
41691 +               ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start,
41692 +                                     ttm->num_pages);
41693 +               if (unlikely(ret != 0))
41694 +                       return ret;
41695 +
41696 +               ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED;
41697 +               return 0;
41698 +       }
41699 +
41700 +       swap_storage = ttm->swap_storage;
41701 +       BUG_ON(swap_storage == NULL);
41702 +
41703 +       swap_space = swap_storage->f_path.dentry->d_inode->i_mapping;
41704 +
41705 +       for (i = 0; i < ttm->num_pages; ++i) {
41706 +               from_page = read_mapping_page(swap_space, i, NULL);
41707 +               if (IS_ERR(from_page))
41708 +                       goto out_err;
41709 +               to_page = __ttm_tt_get_page(ttm, i);
41710 +               if (unlikely(to_page == NULL))
41711 +                       goto out_err;
41712 +
41713 +               preempt_disable();
41714 +               from_virtual = kmap_atomic(from_page, KM_USER0);
41715 +               to_virtual = kmap_atomic(to_page, KM_USER1);
41716 +               memcpy(to_virtual, from_virtual, PAGE_SIZE);
41717 +               kunmap_atomic(to_virtual, KM_USER1);
41718 +               kunmap_atomic(from_virtual, KM_USER0);
41719 +               preempt_enable();
41720 +               page_cache_release(from_page);
41721 +       }
41722 +
41723 +       if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTANT_SWAP))
41724 +               fput(swap_storage);
41725 +       ttm->swap_storage = NULL;
41726 +       ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED;
41727 +
41728 +       return 0;
41729 +out_err:
41730 +       ttm_tt_free_alloced_pages(ttm);
41731 +       return -ENOMEM;
41732 +}
41733 +
41734 +int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage)
41735 +{
41736 +       struct address_space *swap_space;
41737 +       struct file *swap_storage;
41738 +       struct page *from_page;
41739 +       struct page *to_page;
41740 +       void *from_virtual;
41741 +       void *to_virtual;
41742 +       int i;
41743 +
41744 +       BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated);
41745 +       BUG_ON(ttm->caching_state != tt_cached);
41746 +
41747 +       /*
41748 +        * For user buffers, just unpin the pages, as there should be
41749 +        * vma references.
41750 +        */
41751 +
41752 +       if (ttm->page_flags & TTM_PAGE_FLAG_USER) {
41753 +               ttm_tt_free_user_pages(ttm);
41754 +               ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED;
41755 +               ttm->swap_storage = NULL;
41756 +               return 0;
41757 +       }
41758 +
41759 +       if (!persistant_swap_storage) {
41760 +               swap_storage = shmem_file_setup("ttm swap",
41761 +                                               ttm->num_pages << PAGE_SHIFT,
41762 +                                               0);
41763 +               if (unlikely(IS_ERR(swap_storage))) {
41764 +                       printk(KERN_ERR "Failed allocating swap storage.\n");
41765 +                       return -ENOMEM;
41766 +               }
41767 +       } else
41768 +               swap_storage = persistant_swap_storage;
41769 +
41770 +       swap_space = swap_storage->f_path.dentry->d_inode->i_mapping;
41771 +
41772 +       for (i = 0; i < ttm->num_pages; ++i) {
41773 +               from_page = ttm->pages[i];
41774 +               if (unlikely(from_page == NULL))
41775 +                       continue;
41776 +               to_page = read_mapping_page(swap_space, i, NULL);
41777 +               if (unlikely(to_page == NULL))
41778 +                       goto out_err;
41779 +
41780 +               preempt_disable();
41781 +               from_virtual = kmap_atomic(from_page, KM_USER0);
41782 +               to_virtual = kmap_atomic(to_page, KM_USER1);
41783 +               memcpy(to_virtual, from_virtual, PAGE_SIZE);
41784 +               kunmap_atomic(to_virtual, KM_USER1);
41785 +               kunmap_atomic(from_virtual, KM_USER0);
41786 +               preempt_enable();
41787 +               set_page_dirty(to_page);
41788 +               mark_page_accessed(to_page);
41789 +               /* unlock_page(to_page); */
41790 +               page_cache_release(to_page);
41791 +       }
41792 +
41793 +       ttm_tt_free_alloced_pages(ttm);
41794 +       ttm->swap_storage = swap_storage;
41795 +       ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED;
41796 +       if (persistant_swap_storage)
41797 +               ttm->page_flags |= TTM_PAGE_FLAG_PERSISTANT_SWAP;
41798 +
41799 +       return 0;
41800 +out_err:
41801 +       if (!persistant_swap_storage)
41802 +               fput(swap_storage);
41803 +
41804 +       return -ENOMEM;
41805 +}
41806 diff --git a/drivers/gpu/drm/mrst/drv/ttm/ttm_userobj_api.h b/drivers/gpu/drm/mrst/drv/ttm/ttm_userobj_api.h
41807 new file mode 100644
41808 index 0000000..36df724
41809 --- /dev/null
41810 +++ b/drivers/gpu/drm/mrst/drv/ttm/ttm_userobj_api.h
41811 @@ -0,0 +1,72 @@
41812 +/**************************************************************************
41813 + *
41814 + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
41815 + * All Rights Reserved.
41816 + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
41817 + * All Rights Reserved.
41818 + *
41819 + * This program is free software; you can redistribute it and/or modify it
41820 + * under the terms and conditions of the GNU General Public License,
41821 + * version 2, as published by the Free Software Foundation.
41822 + *
41823 + * This program is distributed in the hope it will be useful, but WITHOUT
41824 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41825 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
41826 + * more details.
41827 + *
41828 + * You should have received a copy of the GNU General Public License along with
41829 + * this program; if not, write to the Free Software Foundation, Inc., 
41830 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
41831 + *
41832 + **************************************************************************/
41833 +/*
41834 + * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
41835 + */
41836 +
41837 +#ifndef _TTM_USEROBJ_API_H_
41838 +#define _TTM_USEROBJ_API_H_
41839 +
41840 +#include "ttm_placement_user.h"
41841 +#include "ttm_fence_user.h"
41842 +#include "ttm_object.h"
41843 +#include "ttm_fence_api.h"
41844 +#include "ttm_bo_api.h"
41845 +
41846 +struct ttm_lock;
41847 +
41848 +/*
41849 + * User ioctls.
41850 + */
41851 +
41852 +extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
41853 +                              struct ttm_bo_device *bdev,
41854 +                              struct ttm_lock *lock, void *data);
41855 +extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
41856 +                                 struct ttm_bo_device *bdev,
41857 +                                 struct ttm_lock *lock, void *data);
41858 +extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data);
41859 +extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data);
41860 +extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data);
41861 +extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
41862 +                                 struct ttm_lock *lock, void *data);
41863 +extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data);
41864 +extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data);
41865 +extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data);
41866 +extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data);
41867 +
41868 +extern int
41869 +ttm_fence_user_create(struct ttm_fence_device *fdev,
41870 +                     struct ttm_object_file *tfile,
41871 +                     uint32_t fence_class,
41872 +                     uint32_t fence_types,
41873 +                     uint32_t create_flags,
41874 +                     struct ttm_fence_object **fence, uint32_t * user_handle);
41875 +
41876 +extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
41877 +                                                         *tfile,
41878 +                                                         uint32_t handle);
41879 +
41880 +extern int
41881 +ttm_pl_verify_access(struct ttm_buffer_object *bo,
41882 +                    struct ttm_object_file *tfile);
41883 +#endif
41884 diff --git a/drivers/gpu/drm/mrst/pvr/COPYING b/drivers/gpu/drm/mrst/pvr/COPYING
41885 new file mode 100644
41886 index 0000000..80dd76b
41887 --- /dev/null
41888 +++ b/drivers/gpu/drm/mrst/pvr/COPYING
41889 @@ -0,0 +1,351 @@
41890 +
41891 +This software is Copyright (C) 2008 Imagination Technologies Ltd.
41892 +                       All rights reserved.
41893 +
41894 +You may use, distribute and copy this software under the terms of
41895 +GNU General Public License version 2, which is displayed below.
41896 +
41897 +-------------------------------------------------------------------------
41898 +
41899 +                   GNU GENERAL PUBLIC LICENSE
41900 +                      Version 2, June 1991
41901 +
41902 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
41903 +    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
41904 + Everyone is permitted to copy and distribute verbatim copies
41905 + of this license document, but changing it is not allowed.
41906 +
41907 +                           Preamble
41908 +
41909 +  The licenses for most software are designed to take away your
41910 +freedom to share and change it.  By contrast, the GNU General Public
41911 +License is intended to guarantee your freedom to share and change free
41912 +software--to make sure the software is free for all its users.  This
41913 +General Public License applies to most of the Free Software
41914 +Foundation's software and to any other program whose authors commit to
41915 +using it.  (Some other Free Software Foundation software is covered by
41916 +the GNU Library General Public License instead.)  You can apply it to
41917 +your programs, too.
41918 +
41919 +  When we speak of free software, we are referring to freedom, not
41920 +price.  Our General Public Licenses are designed to make sure that you
41921 +have the freedom to distribute copies of free software (and charge for
41922 +this service if you wish), that you receive source code or can get it
41923 +if you want it, that you can change the software or use pieces of it
41924 +in new free programs; and that you know you can do these things.
41925 +
41926 +  To protect your rights, we need to make restrictions that forbid
41927 +anyone to deny you these rights or to ask you to surrender the rights.
41928 +These restrictions translate to certain responsibilities for you if you
41929 +distribute copies of the software, or if you modify it.
41930 +
41931 +  For example, if you distribute copies of such a program, whether
41932 +gratis or for a fee, you must give the recipients all the rights that
41933 +you have.  You must make sure that they, too, receive or can get the
41934 +source code.  And you must show them these terms so they know their
41935 +rights.
41936 +
41937 +  We protect your rights with two steps: (1) copyright the software, and
41938 +(2) offer you this license which gives you legal permission to copy,
41939 +distribute and/or modify the software.
41940 +
41941 +  Also, for each author's protection and ours, we want to make certain
41942 +that everyone understands that there is no warranty for this free
41943 +software.  If the software is modified by someone else and passed on, we
41944 +want its recipients to know that what they have is not the original, so
41945 +that any problems introduced by others will not reflect on the original
41946 +authors' reputations.
41947 +
41948 +  Finally, any free program is threatened constantly by software
41949 +patents.  We wish to avoid the danger that redistributors of a free
41950 +program will individually obtain patent licenses, in effect making the
41951 +program proprietary.  To prevent this, we have made it clear that any
41952 +patent must be licensed for everyone's free use or not licensed at all.
41953 +
41954 +  The precise terms and conditions for copying, distribution and
41955 +modification follow.
41956 +
41957 +                   GNU GENERAL PUBLIC LICENSE
41958 +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
41959 +
41960 +  0. This License applies to any program or other work which contains
41961 +a notice placed by the copyright holder saying it may be distributed
41962 +under the terms of this General Public License.  The "Program", below,
41963 +refers to any such program or work, and a "work based on the Program"
41964 +means either the Program or any derivative work under copyright law:
41965 +that is to say, a work containing the Program or a portion of it,
41966 +either verbatim or with modifications and/or translated into another
41967 +language.  (Hereinafter, translation is included without limitation in
41968 +the term "modification".)  Each licensee is addressed as "you".
41969 +
41970 +Activities other than copying, distribution and modification are not
41971 +covered by this License; they are outside its scope.  The act of
41972 +running the Program is not restricted, and the output from the Program
41973 +is covered only if its contents constitute a work based on the
41974 +Program (independent of having been made by running the Program).
41975 +Whether that is true depends on what the Program does.
41976 +
41977 +  1. You may copy and distribute verbatim copies of the Program's
41978 +source code as you receive it, in any medium, provided that you
41979 +conspicuously and appropriately publish on each copy an appropriate
41980 +copyright notice and disclaimer of warranty; keep intact all the
41981 +notices that refer to this License and to the absence of any warranty;
41982 +and give any other recipients of the Program a copy of this License
41983 +along with the Program.
41984 +
41985 +You may charge a fee for the physical act of transferring a copy, and
41986 +you may at your option offer warranty protection in exchange for a fee.
41987 +
41988 +  2. You may modify your copy or copies of the Program or any portion
41989 +of it, thus forming a work based on the Program, and copy and
41990 +distribute such modifications or work under the terms of Section 1
41991 +above, provided that you also meet all of these conditions:
41992 +
41993 +    a) You must cause the modified files to carry prominent notices
41994 +    stating that you changed the files and the date of any change.
41995 +
41996 +    b) You must cause any work that you distribute or publish, that in
41997 +    whole or in part contains or is derived from the Program or any
41998 +    part thereof, to be licensed as a whole at no charge to all third
41999 +    parties under the terms of this License.
42000 +
42001 +    c) If the modified program normally reads commands interactively
42002 +    when run, you must cause it, when started running for such
42003 +    interactive use in the most ordinary way, to print or display an
42004 +    announcement including an appropriate copyright notice and a
42005 +    notice that there is no warranty (or else, saying that you provide
42006 +    a warranty) and that users may redistribute the program under
42007 +    these conditions, and telling the user how to view a copy of this
42008 +    License.  (Exception: if the Program itself is interactive but
42009 +    does not normally print such an announcement, your work based on
42010 +    the Program is not required to print an announcement.)
42011 +
42012 +These requirements apply to the modified work as a whole.  If
42013 +identifiable sections of that work are not derived from the Program,
42014 +and can be reasonably considered independent and separate works in
42015 +themselves, then this License, and its terms, do not apply to those
42016 +sections when you distribute them as separate works.  But when you
42017 +distribute the same sections as part of a whole which is a work based
42018 +on the Program, the distribution of the whole must be on the terms of
42019 +this License, whose permissions for other licensees extend to the
42020 +entire whole, and thus to each and every part regardless of who wrote it.
42021 +
42022 +Thus, it is not the intent of this section to claim rights or contest
42023 +your rights to work written entirely by you; rather, the intent is to
42024 +exercise the right to control the distribution of derivative or
42025 +collective works based on the Program.
42026 +
42027 +In addition, mere aggregation of another work not based on the Program
42028 +with the Program (or with a work based on the Program) on a volume of
42029 +a storage or distribution medium does not bring the other work under
42030 +the scope of this License.
42031 +
42032 +  3. You may copy and distribute the Program (or a work based on it,
42033 +under Section 2) in object code or executable form under the terms of
42034 +Sections 1 and 2 above provided that you also do one of the following:
42035 +
42036 +    a) Accompany it with the complete corresponding machine-readable
42037 +    source code, which must be distributed under the terms of Sections
42038 +    1 and 2 above on a medium customarily used for software interchange; or,
42039 +
42040 +    b) Accompany it with a written offer, valid for at least three
42041 +    years, to give any third party, for a charge no more than your
42042 +    cost of physically performing source distribution, a complete
42043 +    machine-readable copy of the corresponding source code, to be
42044 +    distributed under the terms of Sections 1 and 2 above on a medium
42045 +    customarily used for software interchange; or,
42046 +
42047 +    c) Accompany it with the information you received as to the offer
42048 +    to distribute corresponding source code.  (This alternative is
42049 +    allowed only for noncommercial distribution and only if you
42050 +    received the program in object code or executable form with such
42051 +    an offer, in accord with Subsection b above.)
42052 +
42053 +The source code for a work means the preferred form of the work for
42054 +making modifications to it.  For an executable work, complete source
42055 +code means all the source code for all modules it contains, plus any
42056 +associated interface definition files, plus the scripts used to
42057 +control compilation and installation of the executable.  However, as a
42058 +special exception, the source code distributed need not include
42059 +anything that is normally distributed (in either source or binary
42060 +form) with the major components (compiler, kernel, and so on) of the
42061 +operating system on which the executable runs, unless that component
42062 +itself accompanies the executable.
42063 +
42064 +If distribution of executable or object code is made by offering
42065 +access to copy from a designated place, then offering equivalent
42066 +access to copy the source code from the same place counts as
42067 +distribution of the source code, even though third parties are not
42068 +compelled to copy the source along with the object code.
42069 +
42070 +  4. You may not copy, modify, sublicense, or distribute the Program
42071 +except as expressly provided under this License.  Any attempt
42072 +otherwise to copy, modify, sublicense or distribute the Program is
42073 +void, and will automatically terminate your rights under this License.
42074 +However, parties who have received copies, or rights, from you under
42075 +this License will not have their licenses terminated so long as such
42076 +parties remain in full compliance.
42077 +
42078 +  5. You are not required to accept this License, since you have not
42079 +signed it.  However, nothing else grants you permission to modify or
42080 +distribute the Program or its derivative works.  These actions are
42081 +prohibited by law if you do not accept this License.  Therefore, by
42082 +modifying or distributing the Program (or any work based on the
42083 +Program), you indicate your acceptance of this License to do so, and
42084 +all its terms and conditions for copying, distributing or modifying
42085 +the Program or works based on it.
42086 +
42087 +  6. Each time you redistribute the Program (or any work based on the
42088 +Program), the recipient automatically receives a license from the
42089 +original licensor to copy, distribute or modify the Program subject to
42090 +these terms and conditions.  You may not impose any further
42091 +restrictions on the recipients' exercise of the rights granted herein.
42092 +You are not responsible for enforcing compliance by third parties to
42093 +this License.
42094 +
42095 +  7. If, as a consequence of a court judgment or allegation of patent
42096 +infringement or for any other reason (not limited to patent issues),
42097 +conditions are imposed on you (whether by court order, agreement or
42098 +otherwise) that contradict the conditions of this License, they do not
42099 +excuse you from the conditions of this License.  If you cannot
42100 +distribute so as to satisfy simultaneously your obligations under this
42101 +License and any other pertinent obligations, then as a consequence you
42102 +may not distribute the Program at all.  For example, if a patent
42103 +license would not permit royalty-free redistribution of the Program by
42104 +all those who receive copies directly or indirectly through you, then
42105 +the only way you could satisfy both it and this License would be to
42106 +refrain entirely from distribution of the Program.
42107 +
42108 +If any portion of this section is held invalid or unenforceable under
42109 +any particular circumstance, the balance of the section is intended to
42110 +apply and the section as a whole is intended to apply in other
42111 +circumstances.
42112 +
42113 +It is not the purpose of this section to induce you to infringe any
42114 +patents or other property right claims or to contest validity of any
42115 +such claims; this section has the sole purpose of protecting the
42116 +integrity of the free software distribution system, which is
42117 +implemented by public license practices.  Many people have made
42118 +generous contributions to the wide range of software distributed
42119 +through that system in reliance on consistent application of that
42120 +system; it is up to the author/donor to decide if he or she is willing
42121 +to distribute software through any other system and a licensee cannot
42122 +impose that choice.
42123 +
42124 +This section is intended to make thoroughly clear what is believed to
42125 +be a consequence of the rest of this License.
42126 +
42127 +  8. If the distribution and/or use of the Program is restricted in
42128 +certain countries either by patents or by copyrighted interfaces, the
42129 +original copyright holder who places the Program under this License
42130 +may add an explicit geographical distribution limitation excluding
42131 +those countries, so that distribution is permitted only in or among
42132 +countries not thus excluded.  In such case, this License incorporates
42133 +the limitation as if written in the body of this License.
42134 +
42135 +  9. The Free Software Foundation may publish revised and/or new versions
42136 +of the General Public License from time to time.  Such new versions will
42137 +be similar in spirit to the present version, but may differ in detail to
42138 +address new problems or concerns.
42139 +
42140 +Each version is given a distinguishing version number.  If the Program
42141 +specifies a version number of this License which applies to it and "any
42142 +later version", you have the option of following the terms and conditions
42143 +either of that version or of any later version published by the Free
42144 +Software Foundation.  If the Program does not specify a version number of
42145 +this License, you may choose any version ever published by the Free Software
42146 +Foundation.
42147 +
42148 +  10. If you wish to incorporate parts of the Program into other free
42149 +programs whose distribution conditions are different, write to the author
42150 +to ask for permission.  For software which is copyrighted by the Free
42151 +Software Foundation, write to the Free Software Foundation; we sometimes
42152 +make exceptions for this.  Our decision will be guided by the two goals
42153 +of preserving the free status of all derivatives of our free software and
42154 +of promoting the sharing and reuse of software generally.
42155 +
42156 +                           NO WARRANTY
42157 +
42158 +  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
42159 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
42160 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
42161 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
42162 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42163 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
42164 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
42165 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
42166 +REPAIR OR CORRECTION.
42167 +
42168 +  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
42169 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
42170 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
42171 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
42172 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
42173 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
42174 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
42175 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
42176 +POSSIBILITY OF SUCH DAMAGES.
42177 +
42178 +                    END OF TERMS AND CONDITIONS
42179 +
42180 +       Appendix: How to Apply These Terms to Your New Programs
42181 +
42182 +  If you develop a new program, and you want it to be of the greatest
42183 +possible use to the public, the best way to achieve this is to make it
42184 +free software which everyone can redistribute and change under these terms.
42185 +
42186 +  To do so, attach the following notices to the program.  It is safest
42187 +to attach them to the start of each source file to most effectively
42188 +convey the exclusion of warranty; and each file should have at least
42189 +the "copyright" line and a pointer to where the full notice is found.
42190 +
42191 +    <one line to give the program's name and a brief idea of what it does.>
42192 +    Copyright (C) 19yy  <name of author>
42193 +
42194 +    This program is free software; you can redistribute it and/or modify
42195 +    it under the terms of the GNU General Public License as published by
42196 +    the Free Software Foundation; either version 2 of the License, or
42197 +    (at your option) any later version.
42198 +
42199 +    This program is distributed in the hope that it will be useful,
42200 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
42201 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42202 +    GNU General Public License for more details.
42203 +
42204 +    You should have received a copy of the GNU General Public License
42205 +    along with this program; if not, write to the Free Software
42206 +    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42207 +
42208 +Also add information on how to contact you by electronic and paper mail.
42209 +
42210 +If the program is interactive, make it output a short notice like this
42211 +when it starts in an interactive mode:
42212 +
42213 +    Gnomovision version 69, Copyright (C) 19yy name of author
42214 +    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
42215 +    This is free software, and you are welcome to redistribute it
42216 +    under certain conditions; type `show c' for details.
42217 +
42218 +The hypothetical commands `show w' and `show c' should show the appropriate
42219 +parts of the General Public License.  Of course, the commands you use may
42220 +be called something other than `show w' and `show c'; they could even be
42221 +mouse-clicks or menu items--whatever suits your program.
42222 +
42223 +You should also get your employer (if you work as a programmer) or your
42224 +school, if any, to sign a "copyright disclaimer" for the program, if
42225 +necessary.  Here is a sample; alter the names:
42226 +
42227 +  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
42228 +  `Gnomovision' (which makes passes at compilers) written by James Hacker.
42229 +
42230 +  <signature of Ty Coon>, 1 April 1989
42231 +  Ty Coon, President of Vice
42232 +
42233 +This General Public License does not permit incorporating your program into
42234 +proprietary programs.  If your program is a subroutine library, you may
42235 +consider it more useful to permit linking proprietary applications with the
42236 +library.  If this is what you want to do, use the GNU Library General
42237 +Public License instead of this License.
42238 +
42239 +-------------------------------------------------------------------------
42240 +
42241 diff --git a/drivers/gpu/drm/mrst/pvr/INSTALL b/drivers/gpu/drm/mrst/pvr/INSTALL
42242 new file mode 100644
42243 index 0000000..e4c1069
42244 --- /dev/null
42245 +++ b/drivers/gpu/drm/mrst/pvr/INSTALL
42246 @@ -0,0 +1,76 @@
42247 +
42248 +SGX Embedded Systems DDK for the Linux kernel.
42249 +Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved.
42250 +======================================================================
42251 +
42252 +This file covers how to build and install the Imagination Technologies
42253 +SGX DDK for the Linux kernel.
42254 +
42255 +
42256 +Build System Environment Variables
42257 +-------------------------------------------
42258 +
42259 +The SGX DDK Build scripts depend on a number of environment variables
42260 +being setup before compilation or installation of DDK software can
42261 +commence:
42262 +
42263 +$DISCIMAGE
42264 +The DDK Build scripts install files to the location specified by the
42265 +DISCIMAGE environment variable, when the make install target is used.
42266 +This should point to the target filesystem.
42267 +$ export DISCIMAGE=/path/to/filesystem
42268 +
42269 +$KERNELDIR
42270 +When building the SGX DDK kernel module, the build needs access
42271 +to the headers of the Linux kernel
42272 +$ export KERNELDIR=/path/to/kernel
42273 +
42274 +$PATH
42275 +If a cross compiler is being used make sure the PATH environment variable
42276 +includes the path to the toolchain
42277 +$ export PATH=$PATH:/path/to/toolchain
42278 +
42279 +$CROSS_COMPILE
42280 +Since the SGX DDK Build scripts are geared toward a cross-compilation
42281 +workflow, the CROSS_COMPILE environment variable needs to be set
42282 +$ export CROSS_COMPILE=toolchain-prefix-
42283 +
42284 +
42285 +Build and Install Instructions
42286 +-------------------------------------------
42287 +
42288 +The SGX DDK configures different target builds within directories under
42289 +eurasiacon/build/linux/.
42290 +
42291 +The supported build targets are:
42292 +
42293 +       all             Makes everything
42294 +       clean   Removes all intermediate files created by a build.
42295 +       clobber Removes all binaries for all builds as well.
42296 +       install Runs the install script generated by the build.
42297 +
42298 +The following variables may be set on the command line to influence a build.
42299 +
42300 +       BUILD   The type of build being performed.
42301 +                       Alternatives are release, timing or debug.
42302 +       CFLAGS  Build dependent optimisations and debug information flags.
42303 +       SILENT  Determines whether text of commands is produced during build.
42304 +
42305 +To build for, change to the appropriate target directory, e.g.:
42306 +$ cd eurasiacon/build/linux/platform/kbuild
42307 +
42308 +Issue the make command:
42309 +$ make BUILD=debug all
42310 +
42311 +The DDK software must be installed by the root user.  Become the root user:
42312 +$ su
42313 +
42314 +Install the DDK software:
42315 +$ make install
42316 +
42317 +Become an ordinary user again:
42318 +$ exit
42319 +
42320 +
42321 +
42322 +
42323 diff --git a/drivers/gpu/drm/mrst/pvr/README b/drivers/gpu/drm/mrst/pvr/README
42324 new file mode 100644
42325 index 0000000..8039c39
42326 --- /dev/null
42327 +++ b/drivers/gpu/drm/mrst/pvr/README
42328 @@ -0,0 +1,48 @@
42329 +
42330 +SGX Embedded Systems DDK for Linux kernel.
42331 +Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved.
42332 +======================================================================
42333 +
42334 +
42335 +About
42336 +-------------------------------------------
42337 +
42338 +This is the Imagination Technologies SGX DDK for the Linux kernel.
42339 +
42340 +
42341 +License
42342 +-------------------------------------------
42343 +
42344 +You may use, distribute and copy this software under the terms of
42345 +GNU General Public License version 2.
42346 +
42347 +The full GNU General Public License version 2 is included in this
42348 +distribution in the file called "COPYING".
42349 +
42350 +
42351 +Build and Install Instructions
42352 +-------------------------------------------
42353 +
42354 +For details see the "INSTALL" file.
42355 +
42356 +To build for, change to the appropriate target directory, e.g.:
42357 +$ cd eurasiacon/build/linux/platform/kbuild
42358 +
42359 +Issue the make command:
42360 +$ make BUILD=debug all
42361 +
42362 +The DDK software must be installed by the root user.  Become the root user:
42363 +$ su
42364 +
42365 +Install the DDK software:
42366 +$ make install
42367 +
42368 +Become an ordinary user again:
42369 +$ exit
42370 +
42371 +
42372 +Contact information:
42373 +-------------------------------------------
42374 +
42375 +Imagination Technologies Ltd. <gpl-support@imgtec.com>
42376 +Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
42377 diff --git a/drivers/gpu/drm/mrst/pvr/eurasiacon/.gitignore b/drivers/gpu/drm/mrst/pvr/eurasiacon/.gitignore
42378 new file mode 100644
42379 index 0000000..f558f8b
42380 --- /dev/null
42381 +++ b/drivers/gpu/drm/mrst/pvr/eurasiacon/.gitignore
42382 @@ -0,0 +1,6 @@
42383 +bin_pc_i686*
42384 +tmp_pc_i686*
42385 +host_pc_i686*
42386 +binary_pc_i686*
42387 +*.o
42388 +*.o.cmd
42389 diff --git a/drivers/gpu/drm/mrst/pvr/include4/dbgdrvif.h b/drivers/gpu/drm/mrst/pvr/include4/dbgdrvif.h
42390 new file mode 100644
42391 index 0000000..e65e551
42392 --- /dev/null
42393 +++ b/drivers/gpu/drm/mrst/pvr/include4/dbgdrvif.h
42394 @@ -0,0 +1,298 @@
42395 +/**********************************************************************
42396 + *
42397 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
42398 + *
42399 + * This program is free software; you can redistribute it and/or modify it
42400 + * under the terms and conditions of the GNU General Public License,
42401 + * version 2, as published by the Free Software Foundation.
42402 + *
42403 + * This program is distributed in the hope it will be useful but, except
42404 + * as otherwise stated in writing, without any warranty; without even the
42405 + * implied warranty of merchantability or fitness for a particular purpose.
42406 + * See the GNU General Public License for more details.
42407 + *
42408 + * You should have received a copy of the GNU General Public License along with
42409 + * this program; if not, write to the Free Software Foundation, Inc.,
42410 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
42411 + *
42412 + * The full GNU General Public License is included in this distribution in
42413 + * the file called "COPYING".
42414 + *
42415 + * Contact Information:
42416 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
42417 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
42418 + *
42419 + ******************************************************************************/
42420 +
42421 +#ifndef _DBGDRVIF_
42422 +#define _DBGDRVIF_
42423 +
42424 +
42425 +#include "ioctldef.h"
42426 +
42427 +#define DEBUG_CAPMODE_FRAMED                   0x00000001UL
42428 +#define DEBUG_CAPMODE_CONTINUOUS               0x00000002UL
42429 +#define DEBUG_CAPMODE_HOTKEY                   0x00000004UL
42430 +
42431 +#define DEBUG_OUTMODE_STANDARDDBG              0x00000001UL
42432 +#define DEBUG_OUTMODE_MONO                             0x00000002UL
42433 +#define DEBUG_OUTMODE_STREAMENABLE             0x00000004UL
42434 +#define DEBUG_OUTMODE_ASYNC                            0x00000008UL
42435 +#define DEBUG_OUTMODE_SGXVGA            0x00000010UL
42436 +
42437 +#define DEBUG_FLAGS_USE_NONPAGED_MEM   0x00000001UL
42438 +#define DEBUG_FLAGS_NO_BUF_EXPANDSION  0x00000002UL
42439 +#define DEBUG_FLAGS_ENABLESAMPLE               0x00000004UL
42440 +
42441 +#define DEBUG_FLAGS_TEXTSTREAM                 0x80000000UL
42442 +
42443 +#define DEBUG_LEVEL_0                                  0x00000001UL
42444 +#define DEBUG_LEVEL_1                                  0x00000003UL
42445 +#define DEBUG_LEVEL_2                                  0x00000007UL
42446 +#define DEBUG_LEVEL_3                                  0x0000000FUL
42447 +#define DEBUG_LEVEL_4                                  0x0000001FUL
42448 +#define DEBUG_LEVEL_5                                  0x0000003FUL
42449 +#define DEBUG_LEVEL_6                                  0x0000007FUL
42450 +#define DEBUG_LEVEL_7                                  0x000000FFUL
42451 +#define DEBUG_LEVEL_8                                  0x000001FFUL
42452 +#define DEBUG_LEVEL_9                                  0x000003FFUL
42453 +#define DEBUG_LEVEL_10                                 0x000007FFUL
42454 +#define DEBUG_LEVEL_11                                 0x00000FFFUL
42455 +
42456 +#define DEBUG_LEVEL_SEL0                               0x00000001UL
42457 +#define DEBUG_LEVEL_SEL1                               0x00000002UL
42458 +#define DEBUG_LEVEL_SEL2                               0x00000004UL
42459 +#define DEBUG_LEVEL_SEL3                               0x00000008UL
42460 +#define DEBUG_LEVEL_SEL4                               0x00000010UL
42461 +#define DEBUG_LEVEL_SEL5                               0x00000020UL
42462 +#define DEBUG_LEVEL_SEL6                               0x00000040UL
42463 +#define DEBUG_LEVEL_SEL7                               0x00000080UL
42464 +#define DEBUG_LEVEL_SEL8                               0x00000100UL
42465 +#define DEBUG_LEVEL_SEL9                               0x00000200UL
42466 +#define DEBUG_LEVEL_SEL10                              0x00000400UL
42467 +#define DEBUG_LEVEL_SEL11                              0x00000800UL
42468 +
42469 +#define DEBUG_SERVICE_IOCTL_BASE       0x800UL
42470 +#define DEBUG_SERVICE_CREATESTREAM \
42471 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, \
42472 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42473 +#define DEBUG_SERVICE_DESTROYSTREAM \
42474 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, \
42475 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42476 +#define DEBUG_SERVICE_GETSTREAM \
42477 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, \
42478 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42479 +#define DEBUG_SERVICE_WRITESTRING \
42480 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, \
42481 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42482 +#define DEBUG_SERVICE_READSTRING \
42483 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, \
42484 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42485 +#define DEBUG_SERVICE_WRITE \
42486 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, \
42487 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42488 +#define DEBUG_SERVICE_READ \
42489 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, \
42490 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42491 +#define DEBUG_SERVICE_SETDEBUGMODE \
42492 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, \
42493 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42494 +#define DEBUG_SERVICE_SETDEBUGOUTMODE \
42495 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x09, \
42496 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42497 +#define DEBUG_SERVICE_SETDEBUGLEVEL \
42498 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0A, \
42499 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42500 +#define DEBUG_SERVICE_SETFRAME \
42501 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0B, \
42502 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42503 +#define DEBUG_SERVICE_GETFRAME \
42504 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0C, \
42505 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42506 +#define DEBUG_SERVICE_OVERRIDEMODE \
42507 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0D, \
42508 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42509 +#define DEBUG_SERVICE_DEFAULTMODE \
42510 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0E, \
42511 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42512 +#define DEBUG_SERVICE_GETSERVICETABLE \
42513 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0F, \
42514 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42515 +#define DEBUG_SERVICE_WRITE2 \
42516 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x10, \
42517 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42518 +#define DEBUG_SERVICE_WRITESTRINGCM \
42519 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x11, \
42520 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42521 +#define DEBUG_SERVICE_WRITECM \
42522 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x12, \
42523 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42524 +#define DEBUG_SERVICE_SETMARKER \
42525 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x13, \
42526 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42527 +#define DEBUG_SERVICE_GETMARKER \
42528 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x14, \
42529 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42530 +#define DEBUG_SERVICE_ISCAPTUREFRAME \
42531 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x15, \
42532 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42533 +#define DEBUG_SERVICE_WRITELF \
42534 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x16, \
42535 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42536 +#define DEBUG_SERVICE_READLF \
42537 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, \
42538 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42539 +#define DEBUG_SERVICE_WAITFOREVENT \
42540 +       CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, \
42541 +       METHOD_BUFFERED, FILE_ANY_ACCESS)
42542 +
42543 +
42544 +typedef enum _DBG_EVENT_ {
42545 +       DBG_EVENT_STREAM_DATA = 1
42546 +} DBG_EVENT;
42547 +
42548 +typedef struct _DBG_IN_CREATESTREAM_ {
42549 +       IMG_UINT32 ui32Pages;
42550 +       IMG_UINT32 ui32CapMode;
42551 +       IMG_UINT32 ui32OutMode;
42552 +       IMG_CHAR *pszName;
42553 +}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM;
42554 +
42555 +typedef struct _DBG_IN_FINDSTREAM_ {
42556 +       IMG_BOOL bResetStream;
42557 +       IMG_CHAR *pszName;
42558 +}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
42559 +
42560 +typedef struct _DBG_IN_WRITESTRING_ {
42561 +       IMG_VOID *pvStream;
42562 +       IMG_UINT32 ui32Level;
42563 +       IMG_CHAR *pszString;
42564 +}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING;
42565 +
42566 +typedef struct _DBG_IN_READSTRING_ {
42567 +       IMG_VOID *pvStream;
42568 +       IMG_UINT32 ui32StringLen;
42569 +       IMG_CHAR *pszString;
42570 +} DBG_IN_READSTRING, *PDBG_IN_READSTRING;
42571 +
42572 +typedef struct _DBG_IN_SETDEBUGMODE_ {
42573 +       IMG_VOID *pvStream;
42574 +       IMG_UINT32 ui32Mode;
42575 +       IMG_UINT32 ui32Start;
42576 +       IMG_UINT32 ui32End;
42577 +       IMG_UINT32 ui32SampleRate;
42578 +} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE;
42579 +
42580 +typedef struct _DBG_IN_SETDEBUGOUTMODE_ {
42581 +       IMG_VOID *pvStream;
42582 +       IMG_UINT32 ui32Mode;
42583 +} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE;
42584 +
42585 +typedef struct _DBG_IN_SETDEBUGLEVEL_ {
42586 +       IMG_VOID *pvStream;
42587 +       IMG_UINT32 ui32Level;
42588 +} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL;
42589 +
42590 +typedef struct _DBG_IN_SETFRAME_ {
42591 +       IMG_VOID *pvStream;
42592 +       IMG_UINT32 ui32Frame;
42593 +} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME;
42594 +
42595 +typedef struct _DBG_IN_WRITE_ {
42596 +       IMG_VOID *pvStream;
42597 +       IMG_UINT32 ui32Level;
42598 +       IMG_UINT32 ui32TransferSize;
42599 +       IMG_UINT8 *pui8InBuffer;
42600 +} DBG_IN_WRITE, *PDBG_IN_WRITE;
42601 +
42602 +typedef struct _DBG_IN_READ_ {
42603 +       IMG_VOID *pvStream;
42604 +       IMG_BOOL bReadInitBuffer;
42605 +       IMG_UINT32 ui32OutBufferSize;
42606 +       IMG_UINT8 *pui8OutBuffer;
42607 +} DBG_IN_READ, *PDBG_IN_READ;
42608 +
42609 +typedef struct _DBG_IN_OVERRIDEMODE_ {
42610 +       IMG_VOID *pvStream;
42611 +       IMG_UINT32 ui32Mode;
42612 +} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE;
42613 +
42614 +typedef struct _DBG_IN_ISCAPTUREFRAME_ {
42615 +       IMG_VOID *pvStream;
42616 +       IMG_BOOL bCheckPreviousFrame;
42617 +} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME;
42618 +
42619 +typedef struct _DBG_IN_SETMARKER_ {
42620 +       IMG_VOID *pvStream;
42621 +       IMG_UINT32 ui32Marker;
42622 +} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER;
42623 +
42624 +typedef struct _DBG_IN_WRITE_LF_ {
42625 +       IMG_UINT32 ui32Flags;
42626 +       IMG_VOID *pvStream;
42627 +       IMG_UINT32 ui32Level;
42628 +       IMG_UINT32 ui32BufferSize;
42629 +       IMG_UINT8 *pui8InBuffer;
42630 +} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF;
42631 +
42632 +#define WRITELF_FLAGS_RESETBUF         0x00000001UL
42633 +
42634 +typedef struct _DBG_STREAM_ {
42635 +       struct _DBG_STREAM_ *psNext;
42636 +       struct _DBG_STREAM_ *psInitStream;
42637 +       IMG_BOOL   bInitPhaseComplete;
42638 +       IMG_UINT32 ui32Flags;
42639 +       IMG_UINT32 ui32Base;
42640 +       IMG_UINT32 ui32Size;
42641 +       IMG_UINT32 ui32RPtr;
42642 +       IMG_UINT32 ui32WPtr;
42643 +       IMG_UINT32 ui32DataWritten;
42644 +       IMG_UINT32 ui32CapMode;
42645 +       IMG_UINT32 ui32OutMode;
42646 +       IMG_UINT32 ui32DebugLevel;
42647 +       IMG_UINT32 ui32DefaultMode;
42648 +       IMG_UINT32 ui32Start;
42649 +       IMG_UINT32 ui32End;
42650 +       IMG_UINT32 ui32Current;
42651 +       IMG_UINT32 ui32Access;
42652 +       IMG_UINT32 ui32SampleRate;
42653 +       IMG_UINT32 ui32Reserved;
42654 +       IMG_UINT32 ui32Timeout;
42655 +       IMG_UINT32 ui32Marker;
42656 +       IMG_CHAR szName[30];
42657 +} DBG_STREAM,*PDBG_STREAM;
42658 +
42659 +typedef struct _DBGKM_SERVICE_TABLE_ {
42660 +       IMG_UINT32 ui32Size;
42661 +       IMG_VOID *      (IMG_CALLCONV *pfnCreateStream)                 (IMG_CHAR * pszName,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32OutMode,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages);
42662 +       IMG_VOID        (IMG_CALLCONV *pfnDestroyStream)                (PDBG_STREAM psStream);
42663 +       IMG_VOID *      (IMG_CALLCONV *pfnFindStream)                   (IMG_CHAR * pszName, IMG_BOOL bResetInitBuffer);
42664 +       IMG_UINT32      (IMG_CALLCONV *pfnWriteString)                  (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
42665 +       IMG_UINT32      (IMG_CALLCONV *pfnReadString)                   (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit);
42666 +       IMG_UINT32      (IMG_CALLCONV *pfnWriteBIN)                             (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
42667 +       IMG_UINT32      (IMG_CALLCONV *pfnReadBIN)                              (PDBG_STREAM psStream,IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf);
42668 +       IMG_VOID        (IMG_CALLCONV *pfnSetCaptureMode)               (PDBG_STREAM psStream,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate);
42669 +       IMG_VOID        (IMG_CALLCONV *pfnSetOutputMode)                (PDBG_STREAM psStream,IMG_UINT32 ui32OutMode);
42670 +       IMG_VOID        (IMG_CALLCONV *pfnSetDebugLevel)                (PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel);
42671 +       IMG_VOID        (IMG_CALLCONV *pfnSetFrame)                             (PDBG_STREAM psStream,IMG_UINT32 ui32Frame);
42672 +       IMG_UINT32      (IMG_CALLCONV *pfnGetFrame)                             (PDBG_STREAM psStream);
42673 +       IMG_VOID        (IMG_CALLCONV *pfnOverrideMode)                 (PDBG_STREAM psStream,IMG_UINT32 ui32Mode);
42674 +       IMG_VOID        (IMG_CALLCONV *pfnDefaultMode)                  (PDBG_STREAM psStream);
42675 +       IMG_UINT32      (IMG_CALLCONV *pfnDBGDrivWrite2)                (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
42676 +       IMG_UINT32      (IMG_CALLCONV *pfnWriteStringCM)                (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
42677 +       IMG_UINT32      (IMG_CALLCONV *pfnWriteBINCM)                   (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
42678 +       IMG_VOID        (IMG_CALLCONV *pfnSetMarker)                    (PDBG_STREAM psStream,IMG_UINT32 ui32Marker);
42679 +       IMG_UINT32      (IMG_CALLCONV *pfnGetMarker)                    (PDBG_STREAM psStream);
42680 +       IMG_VOID        (IMG_CALLCONV *pfnStartInitPhase)               (PDBG_STREAM psStream);
42681 +       IMG_VOID        (IMG_CALLCONV *pfnStopInitPhase)                (PDBG_STREAM psStream);
42682 +       IMG_BOOL        (IMG_CALLCONV *pfnIsCaptureFrame)               (PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
42683 +       IMG_UINT32      (IMG_CALLCONV *pfnWriteLF)                              (PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
42684 +       IMG_UINT32      (IMG_CALLCONV *pfnReadLF)                               (PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
42685 +       IMG_UINT32      (IMG_CALLCONV *pfnGetStreamOffset)              (PDBG_STREAM psStream);
42686 +       IMG_VOID        (IMG_CALLCONV *pfnSetStreamOffset)              (PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
42687 +       IMG_BOOL        (IMG_CALLCONV *pfnIsLastCaptureFrame)   (PDBG_STREAM psStream);
42688 +       IMG_VOID        (IMG_CALLCONV *pfnWaitForEvent) (DBG_EVENT eEvent);
42689 +} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE;
42690 +
42691 +
42692 +#endif
42693 diff --git a/drivers/gpu/drm/mrst/pvr/include4/img_defs.h b/drivers/gpu/drm/mrst/pvr/include4/img_defs.h
42694 new file mode 100644
42695 index 0000000..370300a
42696 --- /dev/null
42697 +++ b/drivers/gpu/drm/mrst/pvr/include4/img_defs.h
42698 @@ -0,0 +1,108 @@
42699 +/**********************************************************************
42700 + *
42701 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
42702 + *
42703 + * This program is free software; you can redistribute it and/or modify it
42704 + * under the terms and conditions of the GNU General Public License,
42705 + * version 2, as published by the Free Software Foundation.
42706 + *
42707 + * This program is distributed in the hope it will be useful but, except
42708 + * as otherwise stated in writing, without any warranty; without even the
42709 + * implied warranty of merchantability or fitness for a particular purpose.
42710 + * See the GNU General Public License for more details.
42711 + *
42712 + * You should have received a copy of the GNU General Public License along with
42713 + * this program; if not, write to the Free Software Foundation, Inc.,
42714 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
42715 + *
42716 + * The full GNU General Public License is included in this distribution in
42717 + * the file called "COPYING".
42718 + *
42719 + * Contact Information:
42720 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
42721 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
42722 + *
42723 + ******************************************************************************/
42724 +
42725 +#if !defined (__IMG_DEFS_H__)
42726 +#define __IMG_DEFS_H__
42727 +
42728 +#include "img_types.h"
42729 +
42730 +typedef                enum    img_tag_TriStateSwitch
42731 +{
42732 +       IMG_ON          =       0x00,
42733 +       IMG_OFF,
42734 +       IMG_IGNORE
42735 +
42736 +} img_TriStateSwitch, * img_pTriStateSwitch;
42737 +
42738 +#define                IMG_SUCCESS                             0
42739 +
42740 +#define                IMG_NO_REG                              1
42741 +
42742 +#if defined (NO_INLINE_FUNCS)
42743 +       #define INLINE
42744 +       #define FORCE_INLINE
42745 +#else
42746 +#if defined (__cplusplus)
42747 +       #define INLINE                                  inline
42748 +       #define FORCE_INLINE                    inline
42749 +#else
42750 +#if    !defined(INLINE)
42751 +       #define INLINE                                  __inline
42752 +#endif
42753 +       #define FORCE_INLINE                    static __inline
42754 +#endif
42755 +#endif
42756 +
42757 +
42758 +#ifndef PVR_UNREFERENCED_PARAMETER
42759 +#define        PVR_UNREFERENCED_PARAMETER(param) (param) = (param)
42760 +#endif
42761 +
42762 +#ifdef __GNUC__
42763 +#define unref__ __attribute__ ((unused))
42764 +#else
42765 +#define unref__
42766 +#endif
42767 +
42768 +#ifndef _TCHAR_DEFINED
42769 +#if defined(UNICODE)
42770 +typedef unsigned short         TCHAR, *PTCHAR, *PTSTR;
42771 +#else
42772 +typedef char                           TCHAR, *PTCHAR, *PTSTR;
42773 +#endif
42774 +#define _TCHAR_DEFINED
42775 +#endif
42776 +
42777 +
42778 +                       #if defined(__linux__) || defined(__METAG)
42779 +
42780 +                               #define IMG_CALLCONV
42781 +                               #define IMG_INTERNAL    __attribute__ ((visibility ("hidden")))
42782 +                               #define IMG_EXPORT
42783 +                               #define IMG_IMPORT
42784 +                               #define IMG_RESTRICT    __restrict__
42785 +
42786 +                       #else
42787 +                                       #error("define an OS")
42788 +                       #endif
42789 +
42790 +#ifndef IMG_ABORT
42791 +       #define IMG_ABORT()     abort()
42792 +#endif
42793 +
42794 +#ifndef IMG_MALLOC
42795 +       #define IMG_MALLOC(A)           malloc  (A)
42796 +#endif
42797 +
42798 +#ifndef IMG_FREE
42799 +       #define IMG_FREE(A)                     free    (A)
42800 +#endif
42801 +
42802 +#define IMG_CONST const
42803 +
42804 +#define IMG_FORMAT_PRINTF(x,y)
42805 +
42806 +#endif 
42807 diff --git a/drivers/gpu/drm/mrst/pvr/include4/img_types.h b/drivers/gpu/drm/mrst/pvr/include4/img_types.h
42808 new file mode 100644
42809 index 0000000..1b55521
42810 --- /dev/null
42811 +++ b/drivers/gpu/drm/mrst/pvr/include4/img_types.h
42812 @@ -0,0 +1,128 @@
42813 +/**********************************************************************
42814 + *
42815 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
42816 + *
42817 + * This program is free software; you can redistribute it and/or modify it
42818 + * under the terms and conditions of the GNU General Public License,
42819 + * version 2, as published by the Free Software Foundation.
42820 + *
42821 + * This program is distributed in the hope it will be useful but, except
42822 + * as otherwise stated in writing, without any warranty; without even the
42823 + * implied warranty of merchantability or fitness for a particular purpose.
42824 + * See the GNU General Public License for more details.
42825 + *
42826 + * You should have received a copy of the GNU General Public License along with
42827 + * this program; if not, write to the Free Software Foundation, Inc.,
42828 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
42829 + *
42830 + * The full GNU General Public License is included in this distribution in
42831 + * the file called "COPYING".
42832 + *
42833 + * Contact Information:
42834 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
42835 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
42836 + *
42837 + ******************************************************************************/
42838 +
42839 +#ifndef __IMG_TYPES_H__
42840 +#define __IMG_TYPES_H__
42841 +
42842 +#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS)
42843 +#define IMG_ADDRSPACE_CPUVADDR_BITS            32
42844 +#endif
42845 +
42846 +#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS)
42847 +#define IMG_ADDRSPACE_PHYSADDR_BITS            32
42848 +#endif
42849 +
42850 +typedef unsigned int   IMG_UINT,       *IMG_PUINT;
42851 +typedef signed int             IMG_INT,        *IMG_PINT;
42852 +
42853 +typedef unsigned char  IMG_UINT8,      *IMG_PUINT8;
42854 +typedef unsigned char  IMG_BYTE,       *IMG_PBYTE;
42855 +typedef signed char            IMG_INT8,       *IMG_PINT8;
42856 +typedef char                   IMG_CHAR,       *IMG_PCHAR;
42857 +
42858 +typedef unsigned short IMG_UINT16,     *IMG_PUINT16;
42859 +typedef signed short   IMG_INT16,      *IMG_PINT16;
42860 +typedef unsigned long  IMG_UINT32,     *IMG_PUINT32;
42861 +typedef signed long            IMG_INT32,      *IMG_PINT32;
42862 +
42863 +#if !defined(IMG_UINT32_MAX)
42864 +       #define IMG_UINT32_MAX 0xFFFFFFFFUL
42865 +#endif
42866 +
42867 +       #if (defined(LINUX) || defined(__METAG))
42868 +#if !defined(USE_CODE)
42869 +               typedef unsigned long long              IMG_UINT64,     *IMG_PUINT64;
42870 +               typedef long long                               IMG_INT64,      *IMG_PINT64;
42871 +#endif
42872 +       #else
42873 +
42874 +               #error("define an OS")
42875 +
42876 +       #endif
42877 +
42878 +#if !(defined(LINUX) && defined (__KERNEL__))
42879 +typedef float                  IMG_FLOAT,      *IMG_PFLOAT;
42880 +typedef double                 IMG_DOUBLE, *IMG_PDOUBLE;
42881 +#endif
42882 +
42883 +typedef        enum tag_img_bool
42884 +{
42885 +       IMG_FALSE               = 0,
42886 +       IMG_TRUE                = 1,
42887 +       IMG_FORCE_ALIGN = 0x7FFFFFFF
42888 +} IMG_BOOL, *IMG_PBOOL;
42889 +
42890 +typedef void            IMG_VOID,      *IMG_PVOID;
42891 +
42892 +typedef IMG_INT32       IMG_RESULT;
42893 +
42894 +typedef IMG_UINT32      IMG_UINTPTR_T;
42895 +
42896 +typedef IMG_PVOID       IMG_HANDLE;
42897 +
42898 +typedef void**          IMG_HVOID,     * IMG_PHVOID;
42899 +
42900 +typedef IMG_UINT32             IMG_SIZE_T;
42901 +
42902 +#define IMG_NULL        0
42903 +
42904 +
42905 +typedef IMG_PVOID IMG_CPU_VIRTADDR;
42906 +
42907 +typedef struct
42908 +{
42909 +
42910 +       IMG_UINT32 uiAddr;
42911 +#define IMG_CAST_TO_DEVVADDR_UINT(var)         (IMG_UINT32)(var)
42912 +
42913 +} IMG_DEV_VIRTADDR;
42914 +
42915 +typedef struct _IMG_CPU_PHYADDR
42916 +{
42917 +
42918 +       IMG_UINTPTR_T uiAddr;
42919 +} IMG_CPU_PHYADDR;
42920 +
42921 +typedef struct _IMG_DEV_PHYADDR
42922 +{
42923 +#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
42924 +
42925 +       IMG_UINTPTR_T uiAddr;
42926 +#else
42927 +       IMG_UINT32 uiAddr;
42928 +       IMG_UINT32 uiHighAddr;
42929 +#endif
42930 +} IMG_DEV_PHYADDR;
42931 +
42932 +typedef struct _IMG_SYS_PHYADDR
42933 +{
42934 +
42935 +       IMG_UINTPTR_T uiAddr;
42936 +} IMG_SYS_PHYADDR;
42937 +
42938 +#include "img_defs.h"
42939 +
42940 +#endif
42941 diff --git a/drivers/gpu/drm/mrst/pvr/include4/ioctldef.h b/drivers/gpu/drm/mrst/pvr/include4/ioctldef.h
42942 new file mode 100644
42943 index 0000000..cc69629
42944 --- /dev/null
42945 +++ b/drivers/gpu/drm/mrst/pvr/include4/ioctldef.h
42946 @@ -0,0 +1,98 @@
42947 +/**********************************************************************
42948 + *
42949 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
42950 + *
42951 + * This program is free software; you can redistribute it and/or modify it
42952 + * under the terms and conditions of the GNU General Public License,
42953 + * version 2, as published by the Free Software Foundation.
42954 + *
42955 + * This program is distributed in the hope it will be useful but, except
42956 + * as otherwise stated in writing, without any warranty; without even the
42957 + * implied warranty of merchantability or fitness for a particular purpose.
42958 + * See the GNU General Public License for more details.
42959 + *
42960 + * You should have received a copy of the GNU General Public License along with
42961 + * this program; if not, write to the Free Software Foundation, Inc.,
42962 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
42963 + *
42964 + * The full GNU General Public License is included in this distribution in
42965 + * the file called "COPYING".
42966 + *
42967 + * Contact Information:
42968 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
42969 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
42970 + *
42971 + ******************************************************************************/
42972 +
42973 +#ifndef __IOCTLDEF_H__
42974 +#define __IOCTLDEF_H__
42975 +
42976 +#define MAKEIOCTLINDEX(i)      (((i) >> 2) & 0xFFF)
42977 +
42978 +#ifndef CTL_CODE
42979 +
42980 +#define DEVICE_TYPE ULONG
42981 +
42982 +#define FILE_DEVICE_BEEP                0x00000001
42983 +#define FILE_DEVICE_CD_ROM              0x00000002
42984 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM  0x00000003
42985 +#define FILE_DEVICE_CONTROLLER          0x00000004
42986 +#define FILE_DEVICE_DATALINK            0x00000005
42987 +#define FILE_DEVICE_DFS                 0x00000006
42988 +#define FILE_DEVICE_DISK                0x00000007
42989 +#define FILE_DEVICE_DISK_FILE_SYSTEM    0x00000008
42990 +#define FILE_DEVICE_FILE_SYSTEM         0x00000009
42991 +#define FILE_DEVICE_INPORT_PORT         0x0000000a
42992 +#define FILE_DEVICE_KEYBOARD            0x0000000b
42993 +#define FILE_DEVICE_MAILSLOT            0x0000000c
42994 +#define FILE_DEVICE_MIDI_IN             0x0000000d
42995 +#define FILE_DEVICE_MIDI_OUT            0x0000000e
42996 +#define FILE_DEVICE_MOUSE               0x0000000f
42997 +#define FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
42998 +#define FILE_DEVICE_NAMED_PIPE          0x00000011
42999 +#define FILE_DEVICE_NETWORK             0x00000012
43000 +#define FILE_DEVICE_NETWORK_BROWSER     0x00000013
43001 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
43002 +#define FILE_DEVICE_NULL                0x00000015
43003 +#define FILE_DEVICE_PARALLEL_PORT       0x00000016
43004 +#define FILE_DEVICE_PHYSICAL_NETCARD    0x00000017
43005 +#define FILE_DEVICE_PRINTER             0x00000018
43006 +#define FILE_DEVICE_SCANNER             0x00000019
43007 +#define FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001a
43008 +#define FILE_DEVICE_SERIAL_PORT         0x0000001b
43009 +#define FILE_DEVICE_SCREEN              0x0000001c
43010 +#define FILE_DEVICE_SOUND               0x0000001d
43011 +#define FILE_DEVICE_STREAMS             0x0000001e
43012 +#define FILE_DEVICE_TAPE                0x0000001f
43013 +#define FILE_DEVICE_TAPE_FILE_SYSTEM    0x00000020
43014 +#define FILE_DEVICE_TRANSPORT           0x00000021
43015 +#define FILE_DEVICE_UNKNOWN             0x00000022
43016 +#define FILE_DEVICE_VIDEO               0x00000023
43017 +#define FILE_DEVICE_VIRTUAL_DISK        0x00000024
43018 +#define FILE_DEVICE_WAVE_IN             0x00000025
43019 +#define FILE_DEVICE_WAVE_OUT            0x00000026
43020 +#define FILE_DEVICE_8042_PORT           0x00000027
43021 +#define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
43022 +#define FILE_DEVICE_BATTERY             0x00000029
43023 +#define FILE_DEVICE_BUS_EXTENDER        0x0000002a
43024 +#define FILE_DEVICE_MODEM               0x0000002b
43025 +#define FILE_DEVICE_VDM                 0x0000002c
43026 +#define FILE_DEVICE_MASS_STORAGE        0x0000002d
43027 +
43028 +#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
43029 +    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
43030 +)
43031 +
43032 +#define METHOD_BUFFERED                 0
43033 +#define METHOD_IN_DIRECT                1
43034 +#define METHOD_OUT_DIRECT               2
43035 +#define METHOD_NEITHER                  3
43036 +
43037 +#define FILE_ANY_ACCESS                 0
43038 +#define FILE_READ_ACCESS          ( 0x0001 )
43039 +#define FILE_WRITE_ACCESS         ( 0x0002 )
43040 +
43041 +#endif
43042 +
43043 +#endif
43044 +
43045 diff --git a/drivers/gpu/drm/mrst/pvr/include4/pdumpdefs.h b/drivers/gpu/drm/mrst/pvr/include4/pdumpdefs.h
43046 new file mode 100644
43047 index 0000000..3a2e4c1
43048 --- /dev/null
43049 +++ b/drivers/gpu/drm/mrst/pvr/include4/pdumpdefs.h
43050 @@ -0,0 +1,99 @@
43051 +/**********************************************************************
43052 + *
43053 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43054 + *
43055 + * This program is free software; you can redistribute it and/or modify it
43056 + * under the terms and conditions of the GNU General Public License,
43057 + * version 2, as published by the Free Software Foundation.
43058 + *
43059 + * This program is distributed in the hope it will be useful but, except
43060 + * as otherwise stated in writing, without any warranty; without even the
43061 + * implied warranty of merchantability or fitness for a particular purpose.
43062 + * See the GNU General Public License for more details.
43063 + *
43064 + * You should have received a copy of the GNU General Public License along with
43065 + * this program; if not, write to the Free Software Foundation, Inc.,
43066 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43067 + *
43068 + * The full GNU General Public License is included in this distribution in
43069 + * the file called "COPYING".
43070 + *
43071 + * Contact Information:
43072 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43073 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43074 + *
43075 + ******************************************************************************/
43076 +
43077 +#if !defined (__PDUMPDEFS_H__)
43078 +#define __PDUMPDEFS_H__
43079 +
43080 +typedef enum _PDUMP_PIXEL_FORMAT_
43081 +{
43082 +       PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
43083 +       PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1,
43084 +       PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2,
43085 +       PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3,
43086 +       PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4,
43087 +       PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5,
43088 +       PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6,
43089 +       PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7,
43090 +       PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8,
43091 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9,
43092 +       PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10,
43093 +       PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11,
43094 +       PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12,
43095 +       PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13,
43096 +       PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14,
43097 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15,
43098 +       PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16,
43099 +       PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17,
43100 +       PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18,
43101 +       PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19,
43102 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20,
43103 +       PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21,
43104 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22,
43105 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23,
43106 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24,
43107 +       PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25,
43108 +       PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26,
43109 +       PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27,
43110 +       PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28,
43111 +       PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29,
43112 +       PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30,
43113 +       PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31,
43114 +       PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32,
43115 +       PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33,
43116 +       PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34,
43117 +       PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35,
43118 +       PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36,
43119 +       PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37,
43120 +       PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38,
43121 +
43122 +       PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
43123 +
43124 +} PDUMP_PIXEL_FORMAT;
43125 +
43126 +typedef enum _PDUMP_MEM_FORMAT_
43127 +{
43128 +       PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0,
43129 +       PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1,
43130 +       PVRSRV_PDUMP_MEM_FORMAT_TILED = 8,
43131 +       PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9,
43132 +       PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10,
43133 +
43134 +       PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff
43135 +} PDUMP_MEM_FORMAT;
43136 +
43137 +typedef enum _PDUMP_POLL_OPERATOR
43138 +{
43139 +       PDUMP_POLL_OPERATOR_EQUAL = 0,
43140 +       PDUMP_POLL_OPERATOR_LESS = 1,
43141 +       PDUMP_POLL_OPERATOR_LESSEQUAL = 2,
43142 +       PDUMP_POLL_OPERATOR_GREATER = 3,
43143 +       PDUMP_POLL_OPERATOR_GREATEREQUAL = 4,
43144 +       PDUMP_POLL_OPERATOR_NOTEQUAL = 5,
43145 +} PDUMP_POLL_OPERATOR;
43146 +
43147 +
43148 +#endif
43149 +
43150 diff --git a/drivers/gpu/drm/mrst/pvr/include4/pvr_debug.h b/drivers/gpu/drm/mrst/pvr/include4/pvr_debug.h
43151 new file mode 100644
43152 index 0000000..fe99f45
43153 --- /dev/null
43154 +++ b/drivers/gpu/drm/mrst/pvr/include4/pvr_debug.h
43155 @@ -0,0 +1,127 @@
43156 +/**********************************************************************
43157 + *
43158 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43159 + *
43160 + * This program is free software; you can redistribute it and/or modify it
43161 + * under the terms and conditions of the GNU General Public License,
43162 + * version 2, as published by the Free Software Foundation.
43163 + *
43164 + * This program is distributed in the hope it will be useful but, except
43165 + * as otherwise stated in writing, without any warranty; without even the
43166 + * implied warranty of merchantability or fitness for a particular purpose.
43167 + * See the GNU General Public License for more details.
43168 + *
43169 + * You should have received a copy of the GNU General Public License along with
43170 + * this program; if not, write to the Free Software Foundation, Inc.,
43171 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43172 + *
43173 + * The full GNU General Public License is included in this distribution in
43174 + * the file called "COPYING".
43175 + *
43176 + * Contact Information:
43177 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43178 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43179 + *
43180 + ******************************************************************************/
43181 +
43182 +#ifndef __PVR_DEBUG_H__
43183 +#define __PVR_DEBUG_H__
43184 +
43185 +
43186 +#include "img_types.h"
43187 +
43188 +#if defined (__cplusplus)
43189 +extern "C" {
43190 +#endif
43191 +
43192 +#define PVR_MAX_DEBUG_MESSAGE_LEN      (512)
43193 +
43194 +#define DBGPRIV_FATAL          0x01UL
43195 +#define DBGPRIV_ERROR          0x02UL
43196 +#define DBGPRIV_WARNING                0x04UL
43197 +#define DBGPRIV_MESSAGE                0x08UL
43198 +#define DBGPRIV_VERBOSE                0x10UL
43199 +#define DBGPRIV_CALLTRACE      0x20UL
43200 +#define DBGPRIV_ALLOC          0x40UL
43201 +#define DBGPRIV_ALLLEVELS      (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING | DBGPRIV_MESSAGE | DBGPRIV_VERBOSE)
43202 +
43203 +
43204 +
43205 +#define PVR_DBG_FATAL          DBGPRIV_FATAL,__FILE__, __LINE__
43206 +#define PVR_DBG_ERROR          DBGPRIV_ERROR,__FILE__, __LINE__
43207 +#define PVR_DBG_WARNING                DBGPRIV_WARNING,__FILE__, __LINE__
43208 +#define PVR_DBG_MESSAGE                DBGPRIV_MESSAGE,__FILE__, __LINE__
43209 +#define PVR_DBG_VERBOSE                DBGPRIV_VERBOSE,__FILE__, __LINE__
43210 +#define PVR_DBG_CALLTRACE      DBGPRIV_CALLTRACE,__FILE__, __LINE__
43211 +#define PVR_DBG_ALLOC          DBGPRIV_ALLOC,__FILE__, __LINE__
43212 +
43213 +#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
43214 +#define PVRSRV_NEED_PVR_ASSERT
43215 +#endif
43216 +
43217 +#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
43218 +#define PVRSRV_NEED_PVR_DPF
43219 +#endif
43220 +
43221 +#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
43222 +#define PVRSRV_NEED_PVR_TRACE
43223 +#endif
43224 +
43225 +
43226 +#if defined(PVRSRV_NEED_PVR_ASSERT)
43227 +
43228 +       #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__);
43229 +
43230 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
43231 +                                                                                                          IMG_UINT32 ui32Line);
43232 +
43233 +                       #if defined(PVR_DBG_BREAK_ASSERT_FAIL)
43234 +                               #define PVR_DBG_BREAK   PVRSRVDebugAssertFail("PVR_DBG_BREAK", 0)
43235 +                       #else
43236 +                               #define PVR_DBG_BREAK
43237 +                       #endif
43238 +
43239 +#else
43240 +
43241 +       #define PVR_ASSERT(EXPR)
43242 +       #define PVR_DBG_BREAK
43243 +
43244 +#endif
43245 +
43246 +
43247 +#if defined(PVRSRV_NEED_PVR_DPF)
43248 +
43249 +       #define PVR_DPF(X)              PVRSRVDebugPrintf X
43250 +
43251 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
43252 +                                                                                                  const IMG_CHAR *pszFileName,
43253 +                                                                                                  IMG_UINT32 ui32Line,
43254 +                                                                                                  const IMG_CHAR *pszFormat,
43255 +                                                                                                  ...);
43256 +
43257 +#else
43258 +
43259 +       #define PVR_DPF(X)
43260 +
43261 +#endif
43262 +
43263 +
43264 +#if defined(PVRSRV_NEED_PVR_TRACE)
43265 +
43266 +       #define PVR_TRACE(X)    PVRSRVTrace X
43267 +
43268 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... );
43269 +
43270 +#else
43271 +
43272 +       #define PVR_TRACE(X)
43273 +
43274 +#endif
43275 +
43276 +
43277 +#if defined (__cplusplus)
43278 +}
43279 +#endif
43280 +
43281 +#endif
43282 +
43283 diff --git a/drivers/gpu/drm/mrst/pvr/include4/pvrmodule.h b/drivers/gpu/drm/mrst/pvr/include4/pvrmodule.h
43284 new file mode 100644
43285 index 0000000..5f77d1c
43286 --- /dev/null
43287 +++ b/drivers/gpu/drm/mrst/pvr/include4/pvrmodule.h
43288 @@ -0,0 +1,31 @@
43289 +/**********************************************************************
43290 + *
43291 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43292 + *
43293 + * This program is free software; you can redistribute it and/or modify it
43294 + * under the terms and conditions of the GNU General Public License,
43295 + * version 2, as published by the Free Software Foundation.
43296 + *
43297 + * This program is distributed in the hope it will be useful but, except
43298 + * as otherwise stated in writing, without any warranty; without even the
43299 + * implied warranty of merchantability or fitness for a particular purpose.
43300 + * See the GNU General Public License for more details.
43301 + *
43302 + * You should have received a copy of the GNU General Public License along with
43303 + * this program; if not, write to the Free Software Foundation, Inc.,
43304 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43305 + *
43306 + * The full GNU General Public License is included in this distribution in
43307 + * the file called "COPYING".
43308 + *
43309 + * Contact Information:
43310 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43311 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43312 + *
43313 + ******************************************************************************/
43314 +
43315 +#ifndef        _PVRMODULE_H_
43316 +#define        _PVRMODULE_H_
43317 +MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
43318 +MODULE_LICENSE("GPL");
43319 +#endif
43320 diff --git a/drivers/gpu/drm/mrst/pvr/include4/pvrversion.h b/drivers/gpu/drm/mrst/pvr/include4/pvrversion.h
43321 new file mode 100644
43322 index 0000000..585e49b
43323 --- /dev/null
43324 +++ b/drivers/gpu/drm/mrst/pvr/include4/pvrversion.h
43325 @@ -0,0 +1,38 @@
43326 +/**********************************************************************
43327 + *
43328 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43329 + *
43330 + * This program is free software; you can redistribute it and/or modify it
43331 + * under the terms and conditions of the GNU General Public License,
43332 + * version 2, as published by the Free Software Foundation.
43333 + *
43334 + * This program is distributed in the hope it will be useful but, except
43335 + * as otherwise stated in writing, without any warranty; without even the
43336 + * implied warranty of merchantability or fitness for a particular purpose.
43337 + * See the GNU General Public License for more details.
43338 + *
43339 + * You should have received a copy of the GNU General Public License along with
43340 + * this program; if not, write to the Free Software Foundation, Inc.,
43341 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43342 + *
43343 + * The full GNU General Public License is included in this distribution in
43344 + * the file called "COPYING".
43345 + *
43346 + * Contact Information:
43347 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43348 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43349 + *
43350 + ******************************************************************************/
43351 +
43352 +#ifndef _PVRVERSION_H_
43353 +#define _PVRVERSION_H_
43354 +
43355 +#define PVRVERSION_MAJ 1
43356 +#define PVRVERSION_MIN 5
43357 +#define PVRVERSION_BRANCH 15
43358 +#define PVRVERSION_BUILD 3014
43359 +#define PVRVERSION_STRING "1.5.15.3014"
43360 +#define PVRVERSION_FILE "eurasiacon.pj"
43361 +
43362 +#endif
43363 +
43364 diff --git a/drivers/gpu/drm/mrst/pvr/include4/regpaths.h b/drivers/gpu/drm/mrst/pvr/include4/regpaths.h
43365 new file mode 100644
43366 index 0000000..8dac213
43367 --- /dev/null
43368 +++ b/drivers/gpu/drm/mrst/pvr/include4/regpaths.h
43369 @@ -0,0 +1,43 @@
43370 +/**********************************************************************
43371 + *
43372 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43373 + *
43374 + * This program is free software; you can redistribute it and/or modify it
43375 + * under the terms and conditions of the GNU General Public License,
43376 + * version 2, as published by the Free Software Foundation.
43377 + *
43378 + * This program is distributed in the hope it will be useful but, except
43379 + * as otherwise stated in writing, without any warranty; without even the
43380 + * implied warranty of merchantability or fitness for a particular purpose.
43381 + * See the GNU General Public License for more details.
43382 + *
43383 + * You should have received a copy of the GNU General Public License along with
43384 + * this program; if not, write to the Free Software Foundation, Inc.,
43385 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43386 + *
43387 + * The full GNU General Public License is included in this distribution in
43388 + * the file called "COPYING".
43389 + *
43390 + * Contact Information:
43391 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43392 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43393 + *
43394 + ******************************************************************************/
43395 +
43396 +#ifndef __REGPATHS_H__
43397 +#define __REGPATHS_H__
43398 +
43399 +#define POWERVR_REG_ROOT                               "Drivers\\Display\\PowerVR"
43400 +#define POWERVR_CHIP_KEY                               "\\SGX1\\"
43401 +
43402 +#define POWERVR_EURASIA_KEY                            "PowerVREurasia\\"
43403 +
43404 +#define POWERVR_SERVICES_KEY                   "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\PowerVR\\"
43405 +
43406 +#define PVRSRV_REGISTRY_ROOT                   POWERVR_EURASIA_KEY "HWSettings\\PVRSRVKM"
43407 +
43408 +
43409 +#define MAX_REG_STRING_SIZE 128
43410 +
43411 +
43412 +#endif
43413 diff --git a/drivers/gpu/drm/mrst/pvr/include4/services.h b/drivers/gpu/drm/mrst/pvr/include4/services.h
43414 new file mode 100644
43415 index 0000000..7b8159d
43416 --- /dev/null
43417 +++ b/drivers/gpu/drm/mrst/pvr/include4/services.h
43418 @@ -0,0 +1,872 @@
43419 +/**********************************************************************
43420 + *
43421 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
43422 + *
43423 + * This program is free software; you can redistribute it and/or modify it
43424 + * under the terms and conditions of the GNU General Public License,
43425 + * version 2, as published by the Free Software Foundation.
43426 + *
43427 + * This program is distributed in the hope it will be useful but, except
43428 + * as otherwise stated in writing, without any warranty; without even the
43429 + * implied warranty of merchantability or fitness for a particular purpose.
43430 + * See the GNU General Public License for more details.
43431 + *
43432 + * You should have received a copy of the GNU General Public License along with
43433 + * this program; if not, write to the Free Software Foundation, Inc.,
43434 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
43435 + *
43436 + * The full GNU General Public License is included in this distribution in
43437 + * the file called "COPYING".
43438 + *
43439 + * Contact Information:
43440 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
43441 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
43442 + *
43443 + ******************************************************************************/
43444 +
43445 +#ifndef __SERVICES_H__
43446 +#define __SERVICES_H__
43447 +
43448 +#if defined (__cplusplus)
43449 +extern "C" {
43450 +#endif
43451 +
43452 +#include "img_defs.h"
43453 +#include "servicesext.h"
43454 +#include "pdumpdefs.h"
43455 +
43456 +
43457 +#define PVRSRV_4K_PAGE_SIZE            4096UL
43458 +
43459 +#define PVRSRV_MAX_CMD_SIZE            1024
43460 +
43461 +#define PVRSRV_MAX_DEVICES             16
43462 +
43463 +#define EVENTOBJNAME_MAXLENGTH (50)
43464 +
43465 +#define PVRSRV_MEM_READ                                                (1UL<<0)
43466 +#define PVRSRV_MEM_WRITE                                       (1UL<<1)
43467 +#define PVRSRV_MEM_CACHE_CONSISTENT                    (1UL<<2)
43468 +#define PVRSRV_MEM_NO_SYNCOBJ                          (1UL<<3)
43469 +#define PVRSRV_MEM_INTERLEAVED                         (1UL<<4)
43470 +#define PVRSRV_MEM_DUMMY                                       (1UL<<5)
43471 +#define PVRSRV_MEM_EDM_PROTECT                         (1UL<<6)
43472 +#define PVRSRV_MEM_ZERO                                                (1UL<<7)
43473 +#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR      (1UL<<8)
43474 +#define PVRSRV_MEM_RAM_BACKED_ALLOCATION       (1UL<<9)
43475 +#define PVRSRV_MEM_NO_RESMAN                           (1UL<<10)
43476 +#define PVRSRV_MEM_EXPORTED                                    (1UL<<11)
43477 +
43478 +
43479 +#define PVRSRV_HAP_CACHED                                      (1UL<<12)
43480 +#define PVRSRV_HAP_UNCACHED                                    (1UL<<13)
43481 +#define PVRSRV_HAP_WRITECOMBINE                                (1UL<<14)
43482 +#define PVRSRV_HAP_CACHETYPE_MASK                      (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE)
43483 +#define PVRSRV_HAP_KERNEL_ONLY                         (1UL<<15)
43484 +#define PVRSRV_HAP_SINGLE_PROCESS                      (1UL<<16)
43485 +#define PVRSRV_HAP_MULTI_PROCESS                       (1UL<<17)
43486 +#define PVRSRV_HAP_FROM_EXISTING_PROCESS       (1UL<<18)
43487 +#define PVRSRV_HAP_NO_CPU_VIRTUAL                      (1UL<<19)
43488 +#define PVRSRV_HAP_MAPTYPE_MASK                                (PVRSRV_HAP_KERNEL_ONLY \
43489 +                                            |PVRSRV_HAP_SINGLE_PROCESS \
43490 +                                            |PVRSRV_HAP_MULTI_PROCESS \
43491 +                                            |PVRSRV_HAP_FROM_EXISTING_PROCESS \
43492 +                                            |PVRSRV_HAP_NO_CPU_VIRTUAL)
43493 +
43494 +#define PVRSRV_MEM_CACHED                                      PVRSRV_HAP_CACHED
43495 +#define PVRSRV_MEM_UNCACHED                                    PVRSRV_HAP_UNCACHED
43496 +#define PVRSRV_MEM_WRITECOMBINE                                PVRSRV_HAP_WRITECOMBINE
43497 +
43498 +#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT    (24)
43499 +
43500 +#define PVRSRV_MAP_NOUSERVIRTUAL            (1UL<<27)
43501 +
43502 +#define PVRSRV_NO_CONTEXT_LOSS                                 0
43503 +#define PVRSRV_SEVERE_LOSS_OF_CONTEXT                  1
43504 +#define PVRSRV_PRE_STATE_CHANGE_MASK                   0x80
43505 +
43506 +
43507 +#define PVRSRV_DEFAULT_DEV_COOKIE                      (1)
43508 +
43509 +
43510 +#define PVRSRV_MISC_INFO_TIMER_PRESENT                         (1UL<<0)
43511 +#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT                     (1UL<<1)
43512 +#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT                      (1UL<<2)
43513 +#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT     (1UL<<3)
43514 +#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT                    (1UL<<4)
43515 +#define PVRSRV_MISC_INFO_CPUCACHEFLUSH_PRESENT         (1UL<<5)
43516 +
43517 +#define PVRSRV_MISC_INFO_RESET_PRESENT                         (1UL<<31)
43518 +
43519 +#define PVRSRV_PDUMP_MAX_FILENAME_SIZE                 20
43520 +#define PVRSRV_PDUMP_MAX_COMMENT_SIZE                  200
43521 +
43522 +
43523 +#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT              0x00000001
43524 +
43525 +#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA                  0x00000001
43526 +#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG                   0x00000002
43527 +
43528 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC                      0x00000001
43529 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC                      0x00000002
43530 +
43531 +typedef enum _PVRSRV_DEVICE_TYPE_
43532 +{
43533 +       PVRSRV_DEVICE_TYPE_UNKNOWN                      = 0 ,
43534 +       PVRSRV_DEVICE_TYPE_MBX1                         = 1 ,
43535 +       PVRSRV_DEVICE_TYPE_MBX1_LITE            = 2 ,
43536 +
43537 +       PVRSRV_DEVICE_TYPE_M24VA                        = 3,
43538 +       PVRSRV_DEVICE_TYPE_MVDA2                        = 4,
43539 +       PVRSRV_DEVICE_TYPE_MVED1                        = 5,
43540 +       PVRSRV_DEVICE_TYPE_MSVDX                        = 6,
43541 +
43542 +       PVRSRV_DEVICE_TYPE_SGX                          = 7,
43543 +
43544 +       PVRSRV_DEVICE_TYPE_VGX                          = 8,
43545 +
43546 +       PVRSRV_DEVICE_TYPE_TOPAZ                        = 9,
43547 +
43548 +       PVRSRV_DEVICE_TYPE_EXT                          = 10,
43549 +
43550 +    PVRSRV_DEVICE_TYPE_LAST             = 10,
43551 +
43552 +       PVRSRV_DEVICE_TYPE_FORCE_I32            = 0x7fffffff
43553 +
43554 +} PVRSRV_DEVICE_TYPE;
43555 +
43556 +#define HEAP_ID( _dev_ , _dev_heap_idx_ )      (  ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1))  )
43557 +#define HEAP_IDX( _heap_id_ )                          ( (_heap_id_)&((1<<24) - 1 ) )
43558 +#define HEAP_DEV( _heap_id_ )                          ( (_heap_id_)>>24 )
43559 +
43560 +#define PVRSRV_UNDEFINED_HEAP_ID                       (~0LU)
43561 +
43562 +typedef enum
43563 +{
43564 +       IMG_EGL                         = 0x00000001,
43565 +       IMG_OPENGLES1           = 0x00000002,
43566 +       IMG_OPENGLES2           = 0x00000003,
43567 +       IMG_D3DM                        = 0x00000004,
43568 +       IMG_SRV_UM                      = 0x00000005,
43569 +       IMG_OPENVG                      = 0x00000006,
43570 +       IMG_SRVCLIENT           = 0x00000007,
43571 +       IMG_VISTAKMD            = 0x00000008,
43572 +       IMG_VISTA3DNODE         = 0x00000009,
43573 +       IMG_VISTAMVIDEONODE     = 0x0000000A,
43574 +       IMG_VISTAVPBNODE        = 0x0000000B,
43575 +       IMG_OPENGL                      = 0x0000000C,
43576 +       IMG_D3D                         = 0x0000000D,
43577 +#if defined(SUPPORT_GRAPHICS_HAL)
43578 +       IMG_GRAPHICS_HAL        = 0x0000000E
43579 +#endif
43580 +
43581 +} IMG_MODULE_ID;
43582 +
43583 +
43584 +#define APPHINT_MAX_STRING_SIZE        256
43585 +
43586 +typedef enum
43587 +{
43588 +       IMG_STRING_TYPE         = 1,
43589 +       IMG_FLOAT_TYPE          ,
43590 +       IMG_UINT_TYPE           ,
43591 +       IMG_INT_TYPE            ,
43592 +       IMG_FLAG_TYPE
43593 +}IMG_DATA_TYPE;
43594 +
43595 +
43596 +typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
43597 +
43598 +typedef struct _PVRSRV_DEVICE_IDENTIFIER_
43599 +{
43600 +       PVRSRV_DEVICE_TYPE              eDeviceType;
43601 +       PVRSRV_DEVICE_CLASS             eDeviceClass;
43602 +       IMG_UINT32                              ui32DeviceIndex;
43603 +
43604 +} PVRSRV_DEVICE_IDENTIFIER;
43605 +
43606 +
43607 +typedef struct _PVRSRV_CLIENT_DEV_DATA_
43608 +{
43609 +       IMG_UINT32              ui32NumDevices;                         
43610 +       PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES];           
43611 +       PVRSRV_ERROR    (*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);        
43612 +       PVRSRV_ERROR    (*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA);         
43613 +
43614 +} PVRSRV_CLIENT_DEV_DATA;
43615 +
43616 +
43617 +typedef struct _PVRSRV_CONNECTION_
43618 +{
43619 +       IMG_HANDLE hServices;
43620 +       IMG_UINT32 ui32ProcessID;
43621 +       PVRSRV_CLIENT_DEV_DATA  sClientDevData;
43622 +}PVRSRV_CONNECTION;
43623 +
43624 +
43625 +typedef struct _PVRSRV_DEV_DATA_
43626 +{
43627 +       PVRSRV_CONNECTION       sConnection;
43628 +       IMG_HANDLE                      hDevCookie;
43629 +
43630 +} PVRSRV_DEV_DATA;
43631 +
43632 +typedef struct _PVRSRV_MEMUPDATE_
43633 +{
43634 +       IMG_UINT32                      ui32UpdateAddr;
43635 +       IMG_UINT32                      ui32UpdateVal;
43636 +} PVRSRV_MEMUPDATE;
43637 +
43638 +typedef struct _PVRSRV_HWREG_
43639 +{
43640 +       IMG_UINT32                      ui32RegAddr;
43641 +       IMG_UINT32                      ui32RegVal;
43642 +} PVRSRV_HWREG;
43643 +
43644 +typedef struct _PVRSRV_MEMBLK_
43645 +{
43646 +       IMG_DEV_VIRTADDR        sDevVirtAddr;
43647 +       IMG_HANDLE                      hOSMemHandle;
43648 +       IMG_HANDLE                      hOSWrapMem;
43649 +       IMG_HANDLE                      hBuffer;
43650 +       IMG_HANDLE                      hResItem;
43651 +       IMG_SYS_PHYADDR         *psIntSysPAddr;
43652 +
43653 +} PVRSRV_MEMBLK;
43654 +
43655 +typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO;
43656 +
43657 +typedef struct _PVRSRV_CLIENT_MEM_INFO_
43658 +{
43659 +
43660 +       IMG_PVOID                               pvLinAddr;
43661 +
43662 +
43663 +       IMG_PVOID                               pvLinAddrKM;
43664 +
43665 +
43666 +       IMG_DEV_VIRTADDR                sDevVAddr;
43667 +
43668 +
43669 +
43670 +
43671 +
43672 +
43673 +       IMG_CPU_PHYADDR                 sCpuPAddr;
43674 +
43675 +
43676 +       IMG_UINT32                              ui32Flags;
43677 +
43678 +
43679 +
43680 +
43681 +       IMG_UINT32                              ui32ClientFlags;
43682 +
43683 +
43684 +       IMG_SIZE_T                              ui32AllocSize;
43685 +
43686 +
43687 +
43688 +       struct _PVRSRV_CLIENT_SYNC_INFO_        *psClientSyncInfo;
43689 +
43690 +
43691 +       IMG_HANDLE                                                      hMappingInfo;
43692 +
43693 +
43694 +       IMG_HANDLE                                                      hKernelMemInfo;
43695 +
43696 +
43697 +       IMG_HANDLE                                                      hResItem;
43698 +
43699 +#if defined(SUPPORT_MEMINFO_IDS)
43700 +       #if !defined(USE_CODE)
43701 +
43702 +       IMG_UINT64                                                      ui64Stamp;
43703 +       #else
43704 +       IMG_UINT32                                                      dummy1;
43705 +       IMG_UINT32                                                      dummy2;
43706 +       #endif
43707 +#endif
43708 +
43709 +
43710 +
43711 +
43712 +       struct _PVRSRV_CLIENT_MEM_INFO_         *psNext;
43713 +
43714 +} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO;
43715 +
43716 +
43717 +#define PVRSRV_MAX_CLIENT_HEAPS (32)
43718 +typedef struct _PVRSRV_HEAP_INFO_
43719 +{
43720 +       IMG_UINT32                      ui32HeapID;
43721 +       IMG_HANDLE                      hDevMemHeap;
43722 +       IMG_DEV_VIRTADDR        sDevVAddrBase;
43723 +       IMG_UINT32                      ui32HeapByteSize;
43724 +       IMG_UINT32                      ui32Attribs;
43725 +}PVRSRV_HEAP_INFO;
43726 +
43727 +
43728 +
43729 +
43730 +typedef struct _PVRSRV_EVENTOBJECT_
43731 +{
43732 +
43733 +       IMG_CHAR        szName[EVENTOBJNAME_MAXLENGTH];
43734 +
43735 +       IMG_HANDLE      hOSEventKM;
43736 +
43737 +} PVRSRV_EVENTOBJECT;
43738 +
43739 +typedef struct _PVRSRV_MISC_INFO_
43740 +{
43741 +       IMG_UINT32      ui32StateRequest;
43742 +       IMG_UINT32      ui32StatePresent;
43743 +
43744 +
43745 +       IMG_VOID        *pvSOCTimerRegisterKM;
43746 +       IMG_VOID        *pvSOCTimerRegisterUM;
43747 +       IMG_HANDLE      hSOCTimerRegisterOSMemHandle;
43748 +       IMG_HANDLE      hSOCTimerRegisterMappingInfo;
43749 +
43750 +
43751 +       IMG_VOID        *pvSOCClockGateRegs;
43752 +       IMG_UINT32      ui32SOCClockGateRegsSize;
43753 +
43754 +
43755 +       IMG_CHAR        *pszMemoryStr;
43756 +       IMG_UINT32      ui32MemoryStrLen;
43757 +
43758 +
43759 +       PVRSRV_EVENTOBJECT      sGlobalEventObject;
43760 +       IMG_HANDLE                      hOSGlobalEvent;
43761 +
43762 +
43763 +       IMG_UINT32      aui32DDKVersion[4];
43764 +
43765 +       
43766 +       
43767 +       IMG_BOOL        bCPUCacheFlushAll;
43768 +       
43769 +       IMG_BOOL        bDeferCPUCacheFlush;
43770 +       
43771 +       IMG_PVOID       pvRangeAddrStart;
43772 +       
43773 +       IMG_PVOID       pvRangeAddrEnd;
43774 +
43775 +} PVRSRV_MISC_INFO;
43776 +
43777 +
43778 +typedef enum _PVRSRV_CLIENT_EVENT_
43779 +{
43780 +       PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,
43781 +} PVRSRV_CLIENT_EVENT;
43782 +
43783 +IMG_IMPORT
43784 +PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent,
43785 +                                                                                       PVRSRV_DEV_DATA *psDevData,
43786 +                                                                                       IMG_PVOID pvData);
43787 +
43788 +IMG_IMPORT
43789 +PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION *psConnection);
43790 +
43791 +IMG_IMPORT
43792 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(PVRSRV_CONNECTION *psConnection);
43793 +
43794 +IMG_IMPORT
43795 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION                   *psConnection,
43796 +                                                                                                       IMG_UINT32                                      *puiNumDevices,
43797 +                                                                                                       PVRSRV_DEVICE_IDENTIFIER        *puiDevIDs);
43798 +IMG_IMPORT
43799 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION  *psConnection,
43800 +                                                                                                       IMG_UINT32                      uiDevIndex,
43801 +                                                                                                       PVRSRV_DEV_DATA         *psDevData,
43802 +                                                                                                       PVRSRV_DEVICE_TYPE      eDeviceType);
43803 +IMG_IMPORT
43804 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
43805 +
43806 +IMG_IMPORT
43807 +PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo);
43808 +
43809 +#if 1
43810 +IMG_IMPORT
43811 +IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
43812 +
43813 +IMG_IMPORT
43814 +IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
43815 +
43816 +IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs);
43817 +#endif
43818 +
43819 +IMG_IMPORT
43820 +PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection,
43821 +                                                       IMG_HANDLE hOSEvent,
43822 +                                                       volatile IMG_UINT32 *pui32LinMemAddr,
43823 +                                                       IMG_UINT32 ui32Value,
43824 +                                                       IMG_UINT32 ui32Mask,
43825 +                                                       IMG_UINT32 ui32Waitus,
43826 +                                                       IMG_UINT32 ui32Tries);
43827 +
43828 +IMG_IMPORT
43829 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43830 +                                                                                       IMG_HANDLE *phDevMemContext,
43831 +                                                                                       IMG_UINT32 *pui32SharedHeapCount,
43832 +                                                                                       PVRSRV_HEAP_INFO *psHeapInfo);
43833 +
43834 +IMG_IMPORT
43835 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43836 +                                                                                       IMG_HANDLE                      hDevMemContext);
43837 +
43838 +IMG_IMPORT
43839 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43840 +                                                                                       IMG_HANDLE hDevMemContext,
43841 +                                                                                       IMG_UINT32 *pui32SharedHeapCount,
43842 +                                                                                       PVRSRV_HEAP_INFO *psHeapInfo);
43843 +
43844 +#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
43845 +       #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
43846 +               (PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \
43847 +                       ": " logStr " (size = 0x%lx)", ui32Size)), \
43848 +               PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo))
43849 +#else
43850 +       #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
43851 +               PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)
43852 +#endif
43853 +
43854 +
43855 +IMG_IMPORT
43856 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA       *psDevData,
43857 +                                                                       IMG_HANDLE              hDevMemHeap,
43858 +                                                                       IMG_UINT32              ui32Attribs,
43859 +                                                                       IMG_SIZE_T              ui32Size,
43860 +                                                                       IMG_SIZE_T              ui32Alignment,
43861 +                                                                       PVRSRV_CLIENT_MEM_INFO  **ppsMemInfo);
43862 +
43863 +IMG_IMPORT
43864 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA        *psDevData,
43865 +                                                               PVRSRV_CLIENT_MEM_INFO          *psMemInfo);
43866 +
43867 +IMG_IMPORT
43868 +PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA      *psDevData,
43869 +                                                                                               PVRSRV_CLIENT_MEM_INFO          *psMemInfo,
43870 +                                                                                               IMG_HANDLE                                      *phMemInfo);
43871 +
43872 +IMG_IMPORT
43873 +PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43874 +                                                                                       IMG_HANDLE                      hDevMemHeap,
43875 +                                                                                       IMG_DEV_VIRTADDR        *psDevVAddr,
43876 +                                                                                       IMG_SIZE_T                      ui32Size,
43877 +                                                                                       IMG_SIZE_T                      ui32Alignment,
43878 +                                                                                       PVRSRV_CLIENT_MEM_INFO          **ppsMemInfo);
43879 +IMG_IMPORT
43880 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43881 +                                                                                                       PVRSRV_CLIENT_MEM_INFO *psMemInfo);
43882 +
43883 +IMG_IMPORT
43884 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43885 +                                                                       IMG_HANDLE hKernelMemInfo,
43886 +                                                                       IMG_HANDLE hDstDevMemHeap,
43887 +                                                                       PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
43888 +
43889 +IMG_IMPORT
43890 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43891 +                                                                               PVRSRV_CLIENT_MEM_INFO *psMemInfo);
43892 +
43893 +IMG_IMPORT
43894 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA        *psDevData,
43895 +                                                                       PVRSRV_CLIENT_MEM_INFO          *psMemInfo,
43896 +                                                                       IMG_SYS_PHYADDR                         *psSysPAddr,
43897 +                                                                       IMG_UINT32                                      ui32Flags);
43898 +IMG_IMPORT
43899 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43900 +                                                                       PVRSRV_CLIENT_MEM_INFO          *psMemInfo,
43901 +                                                                       IMG_UINT32                                      ui32Flags);
43902 +
43903 +IMG_IMPORT
43904 +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43905 +                                                                                               IMG_HANDLE                              hDevMemContext,
43906 +                                                                                               IMG_SIZE_T                              ui32ByteSize, 
43907 +                                                                                               IMG_SIZE_T                              ui32PageOffset,
43908 +                                                                                               IMG_BOOL                                bPhysContig,
43909 +                                                                                               IMG_SYS_PHYADDR                 *psSysPAddr,
43910 +                                                                                               IMG_VOID                                *pvLinAddr,
43911 +                                                                                               IMG_UINT32                              ui32Flags,
43912 +                                                                                               PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
43913 +IMG_IMPORT
43914 +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43915 +                                                                                               IMG_HANDLE                              hDevMemContext,
43916 +                                                                                               IMG_SIZE_T                              ui32ByteSize,
43917 +                                                                                               IMG_SIZE_T                              ui32PageOffset,
43918 +                                                                                               IMG_BOOL                                bPhysContig,
43919 +                                                                                               IMG_SYS_PHYADDR                 *psSysPAddr,
43920 +                                                                                               IMG_VOID                                *pvLinAddr,
43921 +                                                                                               PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
43922 +IMG_IMPORT
43923 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43924 +                                                                                               PVRSRV_CLIENT_MEM_INFO *psMemInfo);
43925 +
43926 +PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA                      *psDevData,
43927 +                                                                                               PVRSRV_CLIENT_MEM_INFO  *psClientMemInfo,
43928 +                                                                                               IMG_UINT32                              ui32Attribs);
43929 +
43930 +IMG_IMPORT
43931 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43932 +                                                                               IMG_HANDLE hDevMemContext,
43933 +                                                                               IMG_HANDLE hDeviceClassBuffer,
43934 +                                                                               PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
43935 +IMG_IMPORT
43936 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData,
43937 +                                                                               PVRSRV_CLIENT_MEM_INFO *psMemInfo);
43938 +
43939 +IMG_IMPORT
43940 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43941 +                                                                         IMG_SYS_PHYADDR sSysPhysAddr,
43942 +                                                                         IMG_UINT32 uiSizeInBytes,
43943 +                                                                         IMG_PVOID *ppvUserAddr,
43944 +                                                                         IMG_UINT32 *puiActualSize,
43945 +                                                                         IMG_PVOID *ppvProcess);
43946 +
43947 +IMG_IMPORT
43948 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43949 +                                                                               IMG_PVOID pvUserAddr,
43950 +                                                                               IMG_PVOID pvProcess);
43951 +
43952 +typedef enum _PVRSRV_SYNCVAL_MODE_
43953 +{
43954 +       PVRSRV_SYNCVAL_READ                             = IMG_TRUE,
43955 +       PVRSRV_SYNCVAL_WRITE                    = IMG_FALSE,
43956 +
43957 +} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE;
43958 +
43959 +typedef IMG_UINT32 PVRSRV_SYNCVAL;
43960 +
43961 +IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43962 +       PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
43963 +
43964 +IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43965 +       PVRSRV_SYNCVAL_MODE eMode);
43966 +
43967 +IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43968 +       PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
43969 +
43970 +IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43971 +       PVRSRV_SYNCVAL_MODE eMode);
43972 +
43973 +IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43974 +       PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired);
43975 +
43976 +IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43977 +       PVRSRV_SYNCVAL_MODE eMode);
43978 +
43979 +IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo,
43980 +       PVRSRV_SYNCVAL_MODE eMode);
43981 +
43982 +
43983 +IMG_IMPORT
43984 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection,
43985 +                                                                                                       PVRSRV_DEVICE_CLASS DeviceClass,
43986 +                                                                                                       IMG_UINT32 *pui32DevCount,
43987 +                                                                                                       IMG_UINT32 *pui32DevID);
43988 +
43989 +IMG_IMPORT
43990 +IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
43991 +                                                                                       IMG_UINT32 ui32DeviceID);
43992 +
43993 +IMG_IMPORT
43994 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION      *psConnection, IMG_HANDLE hDevice);
43995 +
43996 +IMG_IMPORT
43997 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice,
43998 +                                                                                       IMG_UINT32              *pui32Count,
43999 +                                                                                       DISPLAY_FORMAT  *psFormat);
44000 +
44001 +IMG_IMPORT
44002 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice,
44003 +                                                                               IMG_UINT32              *pui32Count,
44004 +                                                                               DISPLAY_FORMAT  *psFormat,
44005 +                                                                               DISPLAY_DIMS    *psDims);
44006 +
44007 +IMG_IMPORT
44008 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice,
44009 +                                                                               IMG_HANDLE *phBuffer);
44010 +
44011 +IMG_IMPORT
44012 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice,
44013 +                                                                               DISPLAY_INFO* psDisplayInfo);
44014 +
44015 +IMG_IMPORT
44016 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE                          hDevice,
44017 +                                                                                                       IMG_UINT32                              ui32Flags,
44018 +                                                                                                       DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
44019 +                                                                                                       DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
44020 +                                                                                                       IMG_UINT32                              ui32BufferCount,
44021 +                                                                                                       IMG_UINT32                              ui32OEMFlags,
44022 +                                                                                                       IMG_UINT32                              *pui32SwapChainID,
44023 +                                                                                                       IMG_HANDLE                              *phSwapChain);
44024 +
44025 +IMG_IMPORT
44026 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice,
44027 +                                                                                       IMG_HANDLE              hSwapChain);
44028 +
44029 +IMG_IMPORT
44030 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice,
44031 +                                                                               IMG_HANDLE      hSwapChain,
44032 +                                                                               IMG_RECT        *psDstRect);
44033 +
44034 +IMG_IMPORT
44035 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice,
44036 +                                                                               IMG_HANDLE      hSwapChain,
44037 +                                                                               IMG_RECT        *psSrcRect);
44038 +
44039 +IMG_IMPORT
44040 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice,
44041 +                                                                                       IMG_HANDLE      hSwapChain,
44042 +                                                                                       IMG_UINT32      ui32CKColour);
44043 +
44044 +IMG_IMPORT
44045 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice,
44046 +                                                                                       IMG_HANDLE      hSwapChain,
44047 +                                                                                       IMG_UINT32      ui32CKColour);
44048 +
44049 +IMG_IMPORT
44050 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice,
44051 +                                                                       IMG_HANDLE hSwapChain,
44052 +                                                                       IMG_HANDLE *phBuffer);
44053 +
44054 +IMG_IMPORT
44055 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice,
44056 +                                                                               IMG_HANDLE hBuffer,
44057 +                                                                               IMG_UINT32 ui32ClipRectCount,
44058 +                                                                               IMG_RECT *psClipRect,
44059 +                                                                               IMG_UINT32 ui32SwapInterval,
44060 +                                                                               IMG_HANDLE hPrivateTag);
44061 +
44062 +IMG_IMPORT
44063 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice,
44064 +                                                                               IMG_HANDLE hSwapChain);
44065 +
44066 +
44067 +IMG_IMPORT
44068 +IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData,
44069 +                                                                                       IMG_UINT32 ui32DeviceID);
44070 +
44071 +IMG_IMPORT
44072 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection,
44073 +                                                                                               IMG_HANDLE hDevice);
44074 +
44075 +IMG_IMPORT
44076 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice,
44077 +                                                                                               BUFFER_INFO     *psBuffer);
44078 +
44079 +IMG_IMPORT
44080 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice,
44081 +                                                                                               IMG_UINT32 ui32BufferIndex,
44082 +                                                                                               IMG_HANDLE *phBuffer);
44083 +
44084 +
44085 +IMG_IMPORT
44086 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection);
44087 +
44088 +IMG_IMPORT
44089 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
44090 +
44091 +IMG_IMPORT
44092 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection);
44093 +
44094 +IMG_IMPORT
44095 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
44096 +                                                                                 PVRSRV_CLIENT_MEM_INFO *psMemInfo,
44097 +                                                                                 IMG_UINT32 ui32Offset,
44098 +                                                                                 IMG_UINT32 ui32Value,
44099 +                                                                                 IMG_UINT32 ui32Mask,
44100 +                                                                                 IMG_UINT32 ui32Flags);
44101 +
44102 +IMG_IMPORT
44103 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
44104 +                                                                                 PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
44105 +                                                                                 IMG_BOOL bIsRead,
44106 +                                                                                 IMG_UINT32 ui32Value,
44107 +                                                                                 IMG_UINT32 ui32Mask);
44108 +
44109 +IMG_IMPORT
44110 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection,
44111 +                                                                       IMG_PVOID pvAltLinAddr,
44112 +                                                                       PVRSRV_CLIENT_MEM_INFO *psMemInfo,
44113 +                                                                       IMG_UINT32 ui32Offset,
44114 +                                                                       IMG_UINT32 ui32Bytes,
44115 +                                                                       IMG_UINT32 ui32Flags);
44116 +
44117 +IMG_IMPORT
44118 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection,
44119 +                                                                               IMG_PVOID pvAltLinAddr,
44120 +                                                                               PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
44121 +                                                                               IMG_UINT32 ui32Offset,
44122 +                                                                               IMG_UINT32 ui32Bytes);
44123 +
44124 +IMG_IMPORT
44125 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_CONNECTION *psConnection,
44126 +                                                                                       IMG_UINT32 ui32RegAddr,
44127 +                                                                                       IMG_UINT32 ui32RegValue,
44128 +                                                                                       IMG_UINT32 ui32Flags);
44129 +
44130 +IMG_IMPORT
44131 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(IMG_CONST PVRSRV_CONNECTION *psConnection,
44132 +                                                                                                        IMG_UINT32 ui32RegAddr,
44133 +                                                                                                        IMG_UINT32 ui32RegValue,
44134 +                                                                                                        IMG_UINT32 ui32Mask,
44135 +                                                                                                        IMG_UINT32 ui32Flags);
44136 +IMG_IMPORT
44137 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
44138 +                                                                                       IMG_UINT32 ui32RegAddr,
44139 +                                                                                       IMG_UINT32 ui32RegValue,
44140 +                                                                                       IMG_UINT32 ui32Mask);
44141 +
44142 +IMG_IMPORT
44143 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection,
44144 +                                                                                       IMG_UINT32 ui32RegAddr,
44145 +                                                                                       IMG_UINT32 ui32RegValue);
44146 +IMG_IMPORT
44147 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection,
44148 +                                                                                               PVRSRV_CLIENT_MEM_INFO *psMemInfo,
44149 +                                                                                               IMG_UINT32 ui32Offset,
44150 +                                                                                               IMG_DEV_PHYADDR sPDDevPAddr);
44151 +
44152 +IMG_IMPORT
44153 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_CONNECTION *psConnection,
44154 +                                                                                               IMG_HANDLE                      hKernelMemInfo,
44155 +                                                                                               IMG_DEV_PHYADDR         *pPages,
44156 +                                                                                               IMG_UINT32                      ui32NumPages,
44157 +                                                                                               IMG_DEV_VIRTADDR        sDevAddr,
44158 +                                                                                               IMG_UINT32                      ui32Start,
44159 +                                                                                               IMG_UINT32                      ui32Length,
44160 +                                                                                               IMG_BOOL                        bContinuous);
44161 +
44162 +IMG_IMPORT
44163 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection,
44164 +                                                                                         IMG_UINT32 ui32Frame);
44165 +
44166 +IMG_IMPORT
44167 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection,
44168 +                                                                                        IMG_CONST IMG_CHAR *pszComment,
44169 +                                                                                        IMG_BOOL bContinuous);
44170 +
44171 +IMG_IMPORT
44172 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection,
44173 +                                                                                         IMG_BOOL bContinuous,
44174 +                                                                                         IMG_CONST IMG_CHAR *pszFormat, ...);
44175 +
44176 +IMG_IMPORT
44177 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection,
44178 +                                                                                                          IMG_UINT32 ui32Flags,
44179 +                                                                                                          IMG_CONST IMG_CHAR *pszFormat, ...);
44180 +
44181 +IMG_IMPORT
44182 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection,
44183 +                                                                                               IMG_CHAR *pszString,
44184 +                                                                                               IMG_BOOL bContinuous);
44185 +
44186 +IMG_IMPORT
44187 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection,
44188 +                                                                                               IMG_BOOL *pbIsCapturing);
44189 +
44190 +IMG_IMPORT
44191 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_CONNECTION *psConnection,
44192 +                                                                                       IMG_CHAR *pszFileName,
44193 +                                                                                       IMG_UINT32 ui32FileOffset,
44194 +                                                                                       IMG_UINT32 ui32Width,
44195 +                                                                                       IMG_UINT32 ui32Height,
44196 +                                                                                       IMG_UINT32 ui32StrideInBytes,
44197 +                                                                                       IMG_DEV_VIRTADDR sDevBaseAddr,
44198 +                                                                                       IMG_UINT32 ui32Size,
44199 +                                                                                       PDUMP_PIXEL_FORMAT ePixelFormat,
44200 +                                                                                       PDUMP_MEM_FORMAT eMemFormat,
44201 +                                                                                       IMG_UINT32 ui32PDumpFlags);
44202 +
44203 +IMG_IMPORT
44204 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_CONNECTION *psConnection,
44205 +                                                                                       IMG_CONST IMG_CHAR *pszFileName,
44206 +                                                                                       IMG_UINT32 ui32FileOffset,
44207 +                                                                                       IMG_UINT32 ui32Address,
44208 +                                                                                       IMG_UINT32 ui32Size,
44209 +                                                                                       IMG_UINT32 ui32PDumpFlags);
44210 +
44211 +
44212 +IMG_IMPORT
44213 +IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection);
44214 +
44215 +IMG_IMPORT
44216 +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_CONNECTION *psConnection,
44217 +                                                                                                               IMG_UINT32 ui32RegOffset,
44218 +                                                                                                               IMG_BOOL bLastFrame);
44219 +
44220 +IMG_IMPORT IMG_HANDLE  PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName);
44221 +IMG_IMPORT PVRSRV_ERROR        PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv);
44222 +IMG_IMPORT PVRSRV_ERROR        PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr);
44223 +
44224 +IMG_IMPORT IMG_UINT32 PVRSRVClockus (void);
44225 +IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus);
44226 +IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void);
44227 +IMG_IMPORT IMG_UINT32 IMG_CALLCONV PVRSRVGetCurrentProcessID(void);
44228 +IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale);
44229 +
44230 +
44231 +
44232 +
44233 +
44234 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID,
44235 +                                                                                                               const IMG_CHAR *pszAppName,
44236 +                                                                                                               IMG_VOID **ppvState);
44237 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID,
44238 +                                                                                IMG_VOID *pvHintState);
44239 +
44240 +IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID                     *pvHintState,
44241 +                                                                                                 const IMG_CHAR        *pszHintName,
44242 +                                                                                                 IMG_DATA_TYPE         eDataType,
44243 +                                                                                                 const IMG_VOID        *pvDefault,
44244 +                                                                                                 IMG_VOID                      *pvReturn);
44245 +
44246 +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
44247 +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T ui32Size);
44248 +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize);
44249 +IMG_IMPORT IMG_VOID  IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem);
44250 +IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
44251 +IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
44252 +
44253 +struct _PVRSRV_MUTEX_OPAQUE_STRUCT_;
44254 +typedef        struct  _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE;
44255 +
44256 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex);
44257 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex);
44258 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex);
44259 +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex);
44260 +
44261 +#if (defined(DEBUG) && defined(__linux__))
44262 +IMG_PVOID PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
44263 +IMG_PVOID PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
44264 +IMG_VOID  PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
44265 +IMG_PVOID PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
44266 +#endif
44267 +
44268 +IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
44269 +                                                                       IMG_HANDLE hOSEvent);
44270 +
44271 +IMG_IMPORT
44272 +PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(PVRSRV_CONNECTION *psConnection,
44273 +                                                                                                         IMG_HANDLE hKernelSyncInfo,
44274 +                                                                                                         IMG_UINT32 ui32ModifyFlags,
44275 +                                                                                                         IMG_UINT32 *pui32ReadOpsPending,
44276 +                                                                                                         IMG_UINT32 *pui32WriteOpsPending);
44277 +
44278 +IMG_IMPORT
44279 +PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(PVRSRV_CONNECTION *psConnection,
44280 +                                                                                                         IMG_HANDLE hKernelSyncInfo,
44281 +                                                                                                         IMG_UINT32 ui32ModifyFlags);
44282 +
44283 +
44284 +#define TIME_NOT_PASSED_UINT32(a,b,c)          ((a - b) < c)
44285 +
44286 +#if defined (__cplusplus)
44287 +}
44288 +#endif
44289 +#endif
44290 +
44291 diff --git a/drivers/gpu/drm/mrst/pvr/include4/servicesext.h b/drivers/gpu/drm/mrst/pvr/include4/servicesext.h
44292 new file mode 100644
44293 index 0000000..4bfb75c
44294 --- /dev/null
44295 +++ b/drivers/gpu/drm/mrst/pvr/include4/servicesext.h
44296 @@ -0,0 +1,648 @@
44297 +/**********************************************************************
44298 + *
44299 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
44300 + *
44301 + * This program is free software; you can redistribute it and/or modify it
44302 + * under the terms and conditions of the GNU General Public License,
44303 + * version 2, as published by the Free Software Foundation.
44304 + *
44305 + * This program is distributed in the hope it will be useful but, except
44306 + * as otherwise stated in writing, without any warranty; without even the
44307 + * implied warranty of merchantability or fitness for a particular purpose.
44308 + * See the GNU General Public License for more details.
44309 + *
44310 + * You should have received a copy of the GNU General Public License along with
44311 + * this program; if not, write to the Free Software Foundation, Inc.,
44312 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
44313 + *
44314 + * The full GNU General Public License is included in this distribution in
44315 + * the file called "COPYING".
44316 + *
44317 + * Contact Information:
44318 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
44319 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
44320 + *
44321 + ******************************************************************************/
44322 +
44323 +#if !defined (__SERVICESEXT_H__)
44324 +#define __SERVICESEXT_H__
44325 +
44326 +#define PVRSRV_LOCKFLG_READONLY        (1)
44327 +
44328 +typedef enum _PVRSRV_ERROR_
44329 +{
44330 +       PVRSRV_OK                                                               =  0,
44331 +       PVRSRV_ERROR_GENERIC                                    =  1,
44332 +       PVRSRV_ERROR_OUT_OF_MEMORY                              =  2,
44333 +       PVRSRV_ERROR_TOO_FEW_BUFFERS                    =  3,
44334 +       PVRSRV_ERROR_SYMBOL_NOT_FOUND                   =  4,
44335 +       PVRSRV_ERROR_OUT_OF_HSPACE                              =  5,
44336 +       PVRSRV_ERROR_INVALID_PARAMS                             =  6,
44337 +       PVRSRV_ERROR_TILE_MAP_FAILED                    =  7,
44338 +       PVRSRV_ERROR_INIT_FAILURE                               =  8,
44339 +       PVRSRV_ERROR_CANT_REGISTER_CALLBACK     =  9,
44340 +       PVRSRV_ERROR_INVALID_DEVICE                             = 10,
44341 +       PVRSRV_ERROR_NOT_OWNER                                  = 11,
44342 +       PVRSRV_ERROR_BAD_MAPPING                                = 12,
44343 +       PVRSRV_ERROR_TIMEOUT                                    = 13,
44344 +       PVRSRV_ERROR_NO_PRIMARY                                 = 14,
44345 +       PVRSRV_ERROR_FLIP_CHAIN_EXISTS                  = 15,
44346 +       PVRSRV_ERROR_CANNOT_ACQUIRE_SYSDATA     = 16,
44347 +       PVRSRV_ERROR_SCENE_INVALID                              = 17,
44348 +       PVRSRV_ERROR_STREAM_ERROR                               = 18,
44349 +       PVRSRV_ERROR_INVALID_INTERRUPT          = 19,
44350 +       PVRSRV_ERROR_FAILED_DEPENDENCIES                = 20,
44351 +       PVRSRV_ERROR_CMD_NOT_PROCESSED                  = 21,
44352 +       PVRSRV_ERROR_CMD_TOO_BIG                                = 22,
44353 +       PVRSRV_ERROR_DEVICE_REGISTER_FAILED     = 23,
44354 +       PVRSRV_ERROR_FIFO_SPACE                                 = 24,
44355 +       PVRSRV_ERROR_TA_RECOVERY                                = 25,
44356 +       PVRSRV_ERROR_INDOSORLOWPOWER                    = 26,
44357 +       PVRSRV_ERROR_TOOMANYBUFFERS                             = 27,
44358 +       PVRSRV_ERROR_NOT_SUPPORTED                              = 28,
44359 +       PVRSRV_ERROR_PROCESSING_BLOCKED                 = 29,
44360 +
44361 +
44362 +       PVRSRV_ERROR_CANNOT_FLUSH_QUEUE                 = 31,
44363 +       PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE             = 32,
44364 +       PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS   = 33,
44365 +       PVRSRV_ERROR_RETRY                                              = 34,
44366 +
44367 +       PVRSRV_ERROR_DDK_VERSION_MISMATCH               = 35,
44368 +       PVRSRV_ERROR_BUILD_MISMATCH                             = 36,
44369 +       PVRSRV_ERROR_PDUMP_BUF_OVERFLOW,
44370 +
44371 +       PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
44372 +
44373 +} PVRSRV_ERROR;
44374 +
44375 +
44376 +typedef enum _PVRSRV_DEVICE_CLASS_
44377 +{
44378 +       PVRSRV_DEVICE_CLASS_3D                          = 0 ,
44379 +       PVRSRV_DEVICE_CLASS_DISPLAY                     = 1 ,
44380 +       PVRSRV_DEVICE_CLASS_BUFFER                      = 2 ,
44381 +       PVRSRV_DEVICE_CLASS_VIDEO                       = 3 ,
44382 +
44383 +       PVRSRV_DEVICE_CLASS_FORCE_I32           = 0x7fffffff
44384 +
44385 +} PVRSRV_DEVICE_CLASS;
44386 +
44387 +
44388 +
44389 +typedef enum _PVRSRV_SYS_POWER_STATE_
44390 +{
44391 +       PVRSRV_SYS_POWER_STATE_Unspecified              = -1,
44392 +       PVRSRV_SYS_POWER_STATE_D0                               = 0,
44393 +       PVRSRV_SYS_POWER_STATE_D1                               = 1,
44394 +       PVRSRV_SYS_POWER_STATE_D2                               = 2,
44395 +       PVRSRV_SYS_POWER_STATE_D3                               = 3,
44396 +       PVRSRV_SYS_POWER_STATE_D4                               = 4,
44397 +
44398 +       PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff
44399 +
44400 +} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE;
44401 +
44402 +
44403 +typedef enum _PVRSRV_DEV_POWER_STATE_
44404 +{
44405 +       PVRSRV_DEV_POWER_STATE_DEFAULT  = -1,
44406 +       PVRSRV_DEV_POWER_STATE_ON               = 0,
44407 +       PVRSRV_DEV_POWER_STATE_IDLE             = 1,
44408 +       PVRSRV_DEV_POWER_STATE_OFF              = 2,
44409 +
44410 +       PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff
44411 +
44412 +} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE;
44413 +
44414 +
44415 +typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE                              hDevHandle,
44416 +                                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState,
44417 +                                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState);
44418 +typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE                             hDevHandle,
44419 +                                                                               PVRSRV_DEV_POWER_STATE  eNewPowerState,
44420 +                                                                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
44421 +
44422 +typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE                          hDevHandle,
44423 +                                                                                                  IMG_BOOL                                     bIdleDevice,
44424 +                                                                                                  PVRSRV_DEV_POWER_STATE       eCurrentPowerState);
44425 +typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE                         hDevHandle,
44426 +                                                                                                       IMG_BOOL                                bIdleDevice,
44427 +                                                                                                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
44428 +
44429 +
44430 +typedef enum _PVRSRV_PIXEL_FORMAT_ {
44431 +
44432 +       PVRSRV_PIXEL_FORMAT_UNKNOWN                     =  0,
44433 +       PVRSRV_PIXEL_FORMAT_RGB565                      =  1,
44434 +       PVRSRV_PIXEL_FORMAT_RGB555                      =  2,
44435 +       PVRSRV_PIXEL_FORMAT_RGB888                      =  3,
44436 +       PVRSRV_PIXEL_FORMAT_BGR888                      =  4,
44437 +       PVRSRV_PIXEL_FORMAT_GREY_SCALE          =  8,
44438 +       PVRSRV_PIXEL_FORMAT_PAL12                       = 13,
44439 +       PVRSRV_PIXEL_FORMAT_PAL8                        = 14,
44440 +       PVRSRV_PIXEL_FORMAT_PAL4                        = 15,
44441 +       PVRSRV_PIXEL_FORMAT_PAL2                        = 16,
44442 +       PVRSRV_PIXEL_FORMAT_PAL1                        = 17,
44443 +       PVRSRV_PIXEL_FORMAT_ARGB1555            = 18,
44444 +       PVRSRV_PIXEL_FORMAT_ARGB4444            = 19,
44445 +       PVRSRV_PIXEL_FORMAT_ARGB8888            = 20,
44446 +       PVRSRV_PIXEL_FORMAT_ABGR8888            = 21,
44447 +       PVRSRV_PIXEL_FORMAT_YV12                        = 22,
44448 +       PVRSRV_PIXEL_FORMAT_I420                        = 23,
44449 +    PVRSRV_PIXEL_FORMAT_IMC2            = 25,
44450 +       PVRSRV_PIXEL_FORMAT_XRGB8888,
44451 +       PVRSRV_PIXEL_FORMAT_XBGR8888,
44452 +       PVRSRV_PIXEL_FORMAT_BGRA8888,
44453 +       PVRSRV_PIXEL_FORMAT_XRGB4444,
44454 +       PVRSRV_PIXEL_FORMAT_ARGB8332,
44455 +       PVRSRV_PIXEL_FORMAT_A2RGB10,
44456 +       PVRSRV_PIXEL_FORMAT_A2BGR10,
44457 +       PVRSRV_PIXEL_FORMAT_P8,
44458 +       PVRSRV_PIXEL_FORMAT_L8,
44459 +       PVRSRV_PIXEL_FORMAT_A8L8,
44460 +       PVRSRV_PIXEL_FORMAT_A4L4,
44461 +       PVRSRV_PIXEL_FORMAT_L16,
44462 +       PVRSRV_PIXEL_FORMAT_L6V5U5,
44463 +       PVRSRV_PIXEL_FORMAT_V8U8,
44464 +       PVRSRV_PIXEL_FORMAT_V16U16,
44465 +       PVRSRV_PIXEL_FORMAT_QWVU8888,
44466 +       PVRSRV_PIXEL_FORMAT_XLVU8888,
44467 +       PVRSRV_PIXEL_FORMAT_QWVU16,
44468 +       PVRSRV_PIXEL_FORMAT_D16,
44469 +       PVRSRV_PIXEL_FORMAT_D24S8,
44470 +       PVRSRV_PIXEL_FORMAT_D24X8,
44471 +
44472 +
44473 +       PVRSRV_PIXEL_FORMAT_ABGR16,
44474 +       PVRSRV_PIXEL_FORMAT_ABGR16F,
44475 +       PVRSRV_PIXEL_FORMAT_ABGR32,
44476 +       PVRSRV_PIXEL_FORMAT_ABGR32F,
44477 +       PVRSRV_PIXEL_FORMAT_B10GR11,
44478 +       PVRSRV_PIXEL_FORMAT_GR88,
44479 +       PVRSRV_PIXEL_FORMAT_BGR32,
44480 +       PVRSRV_PIXEL_FORMAT_GR32,
44481 +       PVRSRV_PIXEL_FORMAT_E5BGR9,
44482 +
44483 +
44484 +       PVRSRV_PIXEL_FORMAT_DXT1,
44485 +       PVRSRV_PIXEL_FORMAT_DXT2,
44486 +       PVRSRV_PIXEL_FORMAT_DXT3,
44487 +       PVRSRV_PIXEL_FORMAT_DXT4,
44488 +       PVRSRV_PIXEL_FORMAT_DXT5,
44489 +
44490 +
44491 +       PVRSRV_PIXEL_FORMAT_R8G8_B8G8,
44492 +       PVRSRV_PIXEL_FORMAT_G8R8_G8B8,
44493 +
44494 +
44495 +       PVRSRV_PIXEL_FORMAT_NV11,
44496 +       PVRSRV_PIXEL_FORMAT_NV12,
44497 +
44498 +
44499 +       PVRSRV_PIXEL_FORMAT_YUY2,
44500 +       PVRSRV_PIXEL_FORMAT_YUV420,
44501 +       PVRSRV_PIXEL_FORMAT_YUV444,
44502 +       PVRSRV_PIXEL_FORMAT_VUY444,
44503 +       PVRSRV_PIXEL_FORMAT_YUYV,
44504 +       PVRSRV_PIXEL_FORMAT_YVYU,
44505 +       PVRSRV_PIXEL_FORMAT_UYVY,
44506 +       PVRSRV_PIXEL_FORMAT_VYUY,
44507 +
44508 +       PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY,
44509 +       PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV,
44510 +       PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU,
44511 +       PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY,
44512 +       PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV,
44513 +
44514 +
44515 +       PVRSRV_PIXEL_FORMAT_A32B32G32R32,
44516 +       PVRSRV_PIXEL_FORMAT_A32B32G32R32F,
44517 +       PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT,
44518 +       PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT,
44519 +
44520 +
44521 +       PVRSRV_PIXEL_FORMAT_B32G32R32,
44522 +       PVRSRV_PIXEL_FORMAT_B32G32R32F,
44523 +       PVRSRV_PIXEL_FORMAT_B32G32R32_UINT,
44524 +       PVRSRV_PIXEL_FORMAT_B32G32R32_SINT,
44525 +
44526 +
44527 +       PVRSRV_PIXEL_FORMAT_G32R32,
44528 +       PVRSRV_PIXEL_FORMAT_G32R32F,
44529 +       PVRSRV_PIXEL_FORMAT_G32R32_UINT,
44530 +       PVRSRV_PIXEL_FORMAT_G32R32_SINT,
44531 +
44532 +
44533 +       PVRSRV_PIXEL_FORMAT_D32F,
44534 +       PVRSRV_PIXEL_FORMAT_R32,
44535 +       PVRSRV_PIXEL_FORMAT_R32F,
44536 +       PVRSRV_PIXEL_FORMAT_R32_UINT,
44537 +       PVRSRV_PIXEL_FORMAT_R32_SINT,
44538 +
44539 +
44540 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16,
44541 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16F,
44542 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT,
44543 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM,
44544 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT,
44545 +       PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM,
44546 +
44547 +
44548 +       PVRSRV_PIXEL_FORMAT_G16R16,
44549 +       PVRSRV_PIXEL_FORMAT_G16R16F,
44550 +       PVRSRV_PIXEL_FORMAT_G16R16_UINT,
44551 +       PVRSRV_PIXEL_FORMAT_G16R16_UNORM,
44552 +       PVRSRV_PIXEL_FORMAT_G16R16_SINT,
44553 +       PVRSRV_PIXEL_FORMAT_G16R16_SNORM,
44554 +
44555 +
44556 +       PVRSRV_PIXEL_FORMAT_R16,
44557 +       PVRSRV_PIXEL_FORMAT_R16F,
44558 +       PVRSRV_PIXEL_FORMAT_R16_UINT,
44559 +       PVRSRV_PIXEL_FORMAT_R16_UNORM,
44560 +       PVRSRV_PIXEL_FORMAT_R16_SINT,
44561 +       PVRSRV_PIXEL_FORMAT_R16_SNORM,
44562 +
44563 +
44564 +       PVRSRV_PIXEL_FORMAT_X8R8G8B8,
44565 +       PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM,
44566 +       PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB,
44567 +
44568 +       PVRSRV_PIXEL_FORMAT_A8R8G8B8,
44569 +       PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM,
44570 +       PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB,
44571 +
44572 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8,
44573 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT,
44574 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM,
44575 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB,
44576 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT,
44577 +       PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM,
44578 +
44579 +
44580 +       PVRSRV_PIXEL_FORMAT_G8R8,
44581 +       PVRSRV_PIXEL_FORMAT_G8R8_UINT,
44582 +       PVRSRV_PIXEL_FORMAT_G8R8_UNORM,
44583 +       PVRSRV_PIXEL_FORMAT_G8R8_SINT,
44584 +       PVRSRV_PIXEL_FORMAT_G8R8_SNORM,
44585 +
44586 +
44587 +       PVRSRV_PIXEL_FORMAT_A8,
44588 +       PVRSRV_PIXEL_FORMAT_R8,
44589 +       PVRSRV_PIXEL_FORMAT_R8_UINT,
44590 +       PVRSRV_PIXEL_FORMAT_R8_UNORM,
44591 +       PVRSRV_PIXEL_FORMAT_R8_SINT,
44592 +       PVRSRV_PIXEL_FORMAT_R8_SNORM,
44593 +
44594 +
44595 +       PVRSRV_PIXEL_FORMAT_A2B10G10R10,
44596 +       PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM,
44597 +       PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT,
44598 +
44599 +
44600 +       PVRSRV_PIXEL_FORMAT_B10G11R11,
44601 +       PVRSRV_PIXEL_FORMAT_B10G11R11F,
44602 +
44603 +
44604 +       PVRSRV_PIXEL_FORMAT_X24G8R32,
44605 +       PVRSRV_PIXEL_FORMAT_G8R24,
44606 +       PVRSRV_PIXEL_FORMAT_X8R24,
44607 +       PVRSRV_PIXEL_FORMAT_E5B9G9R9,
44608 +       PVRSRV_PIXEL_FORMAT_R1,
44609 +
44610 +       PVRSRV_PIXEL_FORMAT_BC1,
44611 +       PVRSRV_PIXEL_FORMAT_BC1_UNORM,
44612 +       PVRSRV_PIXEL_FORMAT_BC1_SRGB,
44613 +       PVRSRV_PIXEL_FORMAT_BC2,
44614 +       PVRSRV_PIXEL_FORMAT_BC2_UNORM,
44615 +       PVRSRV_PIXEL_FORMAT_BC2_SRGB,
44616 +       PVRSRV_PIXEL_FORMAT_BC3,
44617 +       PVRSRV_PIXEL_FORMAT_BC3_UNORM,
44618 +       PVRSRV_PIXEL_FORMAT_BC3_SRGB,
44619 +       PVRSRV_PIXEL_FORMAT_BC4,
44620 +       PVRSRV_PIXEL_FORMAT_BC4_UNORM,
44621 +       PVRSRV_PIXEL_FORMAT_BC4_SNORM,
44622 +       PVRSRV_PIXEL_FORMAT_BC5,
44623 +       PVRSRV_PIXEL_FORMAT_BC5_UNORM,
44624 +       PVRSRV_PIXEL_FORMAT_BC5_SNORM,
44625 +
44626 +
44627 +       PVRSRV_PIXEL_FORMAT_L_F16,
44628 +       PVRSRV_PIXEL_FORMAT_L_F16_REP,
44629 +       PVRSRV_PIXEL_FORMAT_L_F16_A_F16,
44630 +       PVRSRV_PIXEL_FORMAT_A_F16,
44631 +       PVRSRV_PIXEL_FORMAT_B16G16R16F,
44632 +
44633 +       PVRSRV_PIXEL_FORMAT_L_F32,
44634 +       PVRSRV_PIXEL_FORMAT_A_F32,
44635 +       PVRSRV_PIXEL_FORMAT_L_F32_A_F32,
44636 +
44637 +
44638 +       PVRSRV_PIXEL_FORMAT_PVRTC2,
44639 +       PVRSRV_PIXEL_FORMAT_PVRTC4,
44640 +       PVRSRV_PIXEL_FORMAT_PVRTCII2,
44641 +       PVRSRV_PIXEL_FORMAT_PVRTCII4,
44642 +       PVRSRV_PIXEL_FORMAT_PVRTCIII,
44643 +       PVRSRV_PIXEL_FORMAT_PVRO8,
44644 +       PVRSRV_PIXEL_FORMAT_PVRO88,
44645 +       PVRSRV_PIXEL_FORMAT_PT1,
44646 +       PVRSRV_PIXEL_FORMAT_PT2,
44647 +       PVRSRV_PIXEL_FORMAT_PT4,
44648 +       PVRSRV_PIXEL_FORMAT_PT8,
44649 +       PVRSRV_PIXEL_FORMAT_PTW,
44650 +       PVRSRV_PIXEL_FORMAT_PTB,
44651 +       PVRSRV_PIXEL_FORMAT_MONO8,
44652 +       PVRSRV_PIXEL_FORMAT_MONO16,
44653 +
44654 +
44655 +       PVRSRV_PIXEL_FORMAT_C0_YUYV,
44656 +       PVRSRV_PIXEL_FORMAT_C0_UYVY,
44657 +       PVRSRV_PIXEL_FORMAT_C0_YVYU,
44658 +       PVRSRV_PIXEL_FORMAT_C0_VYUY,
44659 +       PVRSRV_PIXEL_FORMAT_C1_YUYV,
44660 +       PVRSRV_PIXEL_FORMAT_C1_UYVY,
44661 +       PVRSRV_PIXEL_FORMAT_C1_YVYU,
44662 +       PVRSRV_PIXEL_FORMAT_C1_VYUY,
44663 +
44664 +
44665 +       PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV,
44666 +       PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU,
44667 +       PVRSRV_PIXEL_FORMAT_C0_YUV420_3P,
44668 +       PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV,
44669 +       PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU,
44670 +       PVRSRV_PIXEL_FORMAT_C1_YUV420_3P,
44671 +
44672 +       PVRSRV_PIXEL_FORMAT_A2B10G10R10F,
44673 +       PVRSRV_PIXEL_FORMAT_B8G8R8_SINT,
44674 +       PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK,
44675 +
44676 +       PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff,
44677 +} PVRSRV_PIXEL_FORMAT;
44678 +
44679 +typedef enum _PVRSRV_ALPHA_FORMAT_ {
44680 +       PVRSRV_ALPHA_FORMAT_UNKNOWN             =  0x00000000,
44681 +       PVRSRV_ALPHA_FORMAT_PRE                 =  0x00000001,
44682 +       PVRSRV_ALPHA_FORMAT_NONPRE              =  0x00000002,
44683 +       PVRSRV_ALPHA_FORMAT_MASK                =  0x0000000F,
44684 +} PVRSRV_ALPHA_FORMAT;
44685 +
44686 +typedef enum _PVRSRV_COLOURSPACE_FORMAT_ {
44687 +       PVRSRV_COLOURSPACE_FORMAT_UNKNOWN               =  0x00000000,
44688 +       PVRSRV_COLOURSPACE_FORMAT_LINEAR                =  0x00010000,
44689 +       PVRSRV_COLOURSPACE_FORMAT_NONLINEAR             =  0x00020000,
44690 +       PVRSRV_COLOURSPACE_FORMAT_MASK                  =  0x000F0000,
44691 +} PVRSRV_COLOURSPACE_FORMAT;
44692 +
44693 +
44694 +typedef enum _PVRSRV_ROTATION_ {
44695 +       PVRSRV_ROTATE_0         =       0,
44696 +       PVRSRV_ROTATE_90        =       1,
44697 +       PVRSRV_ROTATE_180       =       2,
44698 +       PVRSRV_ROTATE_270       =       3,
44699 +       PVRSRV_FLIP_Y
44700 +
44701 +} PVRSRV_ROTATION;
44702 +
44703 +#define PVRSRV_CREATE_SWAPCHAIN_SHARED         (1<<0)
44704 +#define PVRSRV_CREATE_SWAPCHAIN_QUERY          (1<<1)
44705 +#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY     (1<<2)
44706 +
44707 +typedef struct _PVRSRV_SYNC_DATA_
44708 +{
44709 +
44710 +       IMG_UINT32                                      ui32WriteOpsPending;
44711 +       volatile IMG_UINT32                     ui32WriteOpsComplete;
44712 +
44713 +
44714 +       IMG_UINT32                                      ui32ReadOpsPending;
44715 +       volatile IMG_UINT32                     ui32ReadOpsComplete;
44716 +
44717 +
44718 +       IMG_UINT32                                      ui32LastOpDumpVal;
44719 +       IMG_UINT32                                      ui32LastReadOpDumpVal;
44720 +
44721 +} PVRSRV_SYNC_DATA;
44722 +
44723 +typedef struct _PVRSRV_CLIENT_SYNC_INFO_
44724 +{
44725 +
44726 +       PVRSRV_SYNC_DATA                        *psSyncData;
44727 +
44728 +
44729 +
44730 +
44731 +
44732 +       IMG_DEV_VIRTADDR                sWriteOpsCompleteDevVAddr;
44733 +
44734 +
44735 +       IMG_DEV_VIRTADDR                sReadOpsCompleteDevVAddr;
44736 +
44737 +
44738 +       IMG_HANDLE                                      hMappingInfo;
44739 +
44740 +
44741 +       IMG_HANDLE                                      hKernelSyncInfo;
44742 +
44743 +} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO;
44744 +
44745 +
44746 +typedef struct PVRSRV_RESOURCE_TAG
44747 +{
44748 +       volatile IMG_UINT32 ui32Lock;
44749 +       IMG_UINT32                      ui32ID;
44750 +}PVRSRV_RESOURCE;
44751 +typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE;
44752 +
44753 +
44754 +typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE);
44755 +typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE);
44756 +
44757 +typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
44758 +typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
44759 +
44760 +
44761 +typedef struct _IMG_RECT_
44762 +{
44763 +       IMG_INT32       x0;
44764 +       IMG_INT32       y0;
44765 +       IMG_INT32       x1;
44766 +       IMG_INT32       y1;
44767 +}IMG_RECT;
44768 +
44769 +typedef struct _IMG_RECT_16_
44770 +{
44771 +       IMG_INT16       x0;
44772 +       IMG_INT16       y0;
44773 +       IMG_INT16       x1;
44774 +       IMG_INT16       y1;
44775 +}IMG_RECT_16;
44776 +
44777 +
44778 +typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE,
44779 +                                                                                       IMG_HANDLE,
44780 +                                                                                       IMG_SYS_PHYADDR**,
44781 +                                                                                       IMG_SIZE_T*,
44782 +                                                                                       IMG_VOID**,
44783 +                                                                                       IMG_HANDLE*,
44784 +                                                                                       IMG_BOOL*);
44785 +
44786 +
44787 +typedef struct DISPLAY_DIMS_TAG
44788 +{
44789 +       IMG_UINT32      ui32ByteStride;
44790 +       IMG_UINT32      ui32Width;
44791 +       IMG_UINT32      ui32Height;
44792 +} DISPLAY_DIMS;
44793 +
44794 +
44795 +typedef struct DISPLAY_FORMAT_TAG
44796 +{
44797 +
44798 +       PVRSRV_PIXEL_FORMAT             pixelformat;
44799 +} DISPLAY_FORMAT;
44800 +
44801 +typedef struct DISPLAY_SURF_ATTRIBUTES_TAG
44802 +{
44803 +
44804 +       PVRSRV_PIXEL_FORMAT             pixelformat;
44805 +
44806 +       DISPLAY_DIMS                    sDims;
44807 +} DISPLAY_SURF_ATTRIBUTES;
44808 +
44809 +
44810 +typedef struct DISPLAY_MODE_INFO_TAG
44811 +{
44812 +
44813 +       PVRSRV_PIXEL_FORMAT             pixelformat;
44814 +
44815 +       DISPLAY_DIMS                    sDims;
44816 +
44817 +       IMG_UINT32                              ui32RefreshHZ;
44818 +
44819 +       IMG_UINT32                              ui32OEMFlags;
44820 +} DISPLAY_MODE_INFO;
44821 +
44822 +
44823 +
44824 +#define MAX_DISPLAY_NAME_SIZE  (50)
44825 +
44826 +typedef struct DISPLAY_INFO_TAG
44827 +{
44828 +       IMG_UINT32 ui32MaxSwapChains;
44829 +
44830 +       IMG_UINT32 ui32MaxSwapChainBuffers;
44831 +
44832 +       IMG_UINT32 ui32MinSwapInterval;
44833 +
44834 +       IMG_UINT32 ui32MaxSwapInterval;
44835 +       
44836 +       IMG_UINT32 ui32PhysicalWidthmm;
44837 +       IMG_UINT32 ui32PhysicalHeightmm;
44838 +       
44839 +       IMG_CHAR        szDisplayName[MAX_DISPLAY_NAME_SIZE];
44840 +
44841 +#if defined(SUPPORT_HW_CURSOR)
44842 +       IMG_UINT16      ui32CursorWidth;
44843 +       IMG_UINT16      ui32CursorHeight;
44844 +#endif
44845 +
44846 +} DISPLAY_INFO;
44847 +
44848 +typedef struct ACCESS_INFO_TAG
44849 +{
44850 +       IMG_UINT32              ui32Size;
44851 +       IMG_UINT32      ui32FBPhysBaseAddress;
44852 +       IMG_UINT32              ui32FBMemAvailable;
44853 +       IMG_UINT32      ui32SysPhysBaseAddress;
44854 +       IMG_UINT32              ui32SysSize;
44855 +       IMG_UINT32              ui32DevIRQ;
44856 +}ACCESS_INFO;
44857 +
44858 +
44859 +typedef struct PVRSRV_CURSOR_SHAPE_TAG
44860 +{
44861 +       IMG_UINT16                      ui16Width;
44862 +       IMG_UINT16                      ui16Height;
44863 +       IMG_INT16                       i16XHot;
44864 +       IMG_INT16                       i16YHot;
44865 +
44866 +
44867 +       IMG_VOID*               pvMask;
44868 +       IMG_INT16                       i16MaskByteStride;
44869 +
44870 +
44871 +       IMG_VOID*                       pvColour;
44872 +       IMG_INT16                       i16ColourByteStride;
44873 +       PVRSRV_PIXEL_FORMAT     eColourPixelFormat;
44874 +} PVRSRV_CURSOR_SHAPE;
44875 +
44876 +#define PVRSRV_SET_CURSOR_VISIBILITY   (1<<0)
44877 +#define PVRSRV_SET_CURSOR_POSITION             (1<<1)
44878 +#define PVRSRV_SET_CURSOR_SHAPE                        (1<<2)
44879 +#define PVRSRV_SET_CURSOR_ROTATION             (1<<3)
44880 +
44881 +typedef struct PVRSRV_CURSOR_INFO_TAG
44882 +{
44883 +
44884 +       IMG_UINT32 ui32Flags;
44885 +
44886 +
44887 +       IMG_BOOL bVisible;
44888 +
44889 +
44890 +       IMG_INT16 i16XPos;
44891 +       IMG_INT16 i16YPos;
44892 +
44893 +
44894 +       PVRSRV_CURSOR_SHAPE sCursorShape;
44895 +
44896 +
44897 +       IMG_UINT32 ui32Rotation;
44898 +
44899 +} PVRSRV_CURSOR_INFO;
44900 +
44901 +
44902 +typedef struct _PVRSRV_REGISTRY_INFO_
44903 +{
44904 +    IMG_UINT32         ui32DevCookie;
44905 +    IMG_PCHAR          pszKey;
44906 +    IMG_PCHAR          pszValue;
44907 +    IMG_PCHAR          pszBuf;
44908 +    IMG_UINT32         ui32BufSize;
44909 +} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO;
44910 +
44911 +
44912 +PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
44913 +PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo);
44914 +
44915 +
44916 +#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE        (0 << 0)
44917 +#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE              (1 << 0)
44918 +
44919 +#define PVRSRV_BC_FLAGS_YUVCSC_BT601                   (0 << 1)
44920 +#define PVRSRV_BC_FLAGS_YUVCSC_BT709                   (1 << 1)
44921 +
44922 +#define MAX_BUFFER_DEVICE_NAME_SIZE    (50) 
44923 +
44924 +typedef struct BUFFER_INFO_TAG
44925 +{
44926 +       IMG_UINT32                      ui32BufferCount;
44927 +       IMG_UINT32                      ui32BufferDeviceID;
44928 +       PVRSRV_PIXEL_FORMAT     pixelformat;
44929 +       IMG_UINT32                      ui32ByteStride;
44930 +       IMG_UINT32                      ui32Width;
44931 +       IMG_UINT32                      ui32Height;
44932 +       IMG_UINT32                      ui32Flags;
44933 +       IMG_CHAR                        szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE];
44934 +} BUFFER_INFO;
44935 +
44936 +typedef enum _OVERLAY_DEINTERLACE_MODE_
44937 +{
44938 +       WEAVE=0x0,
44939 +       BOB_ODD,
44940 +       BOB_EVEN,
44941 +       BOB_EVEN_NONINTERLEAVED
44942 +} OVERLAY_DEINTERLACE_MODE;
44943 +
44944 +#endif
44945 diff --git a/drivers/gpu/drm/mrst/pvr/include4/sgx_options.h b/drivers/gpu/drm/mrst/pvr/include4/sgx_options.h
44946 new file mode 100644
44947 index 0000000..69dd25a
44948 --- /dev/null
44949 +++ b/drivers/gpu/drm/mrst/pvr/include4/sgx_options.h
44950 @@ -0,0 +1,224 @@
44951 +/**********************************************************************
44952 + *
44953 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
44954 + *
44955 + * This program is free software; you can redistribute it and/or modify it
44956 + * under the terms and conditions of the GNU General Public License,
44957 + * version 2, as published by the Free Software Foundation.
44958 + *
44959 + * This program is distributed in the hope it will be useful but, except
44960 + * as otherwise stated in writing, without any warranty; without even the
44961 + * implied warranty of merchantability or fitness for a particular purpose.
44962 + * See the GNU General Public License for more details.
44963 + *
44964 + * You should have received a copy of the GNU General Public License along with
44965 + * this program; if not, write to the Free Software Foundation, Inc.,
44966 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
44967 + *
44968 + * The full GNU General Public License is included in this distribution in
44969 + * the file called "COPYING".
44970 + *
44971 + * Contact Information:
44972 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
44973 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
44974 + *
44975 + ******************************************************************************/
44976 +
44977 +#if defined(DEBUG) || defined (INTERNAL_TEST)
44978 +#define DEBUG_SET_OFFSET       OPTIONS_BIT0
44979 +#define OPTIONS_BIT0           0x1
44980 +#else
44981 +#define OPTIONS_BIT0           0x0
44982 +#endif
44983 +
44984 +#if defined(PDUMP) || defined (INTERNAL_TEST)
44985 +#define PDUMP_SET_OFFSET       OPTIONS_BIT1
44986 +#define OPTIONS_BIT1           (0x1 << 1)
44987 +#else
44988 +#define OPTIONS_BIT1           0x0
44989 +#endif
44990 +
44991 +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST)
44992 +#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET                OPTIONS_BIT2
44993 +#define OPTIONS_BIT2           (0x1 << 2)
44994 +#else
44995 +#define OPTIONS_BIT2           0x0
44996 +#endif
44997 +
44998 +#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST)
44999 +#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3
45000 +#define OPTIONS_BIT3           (0x1 << 3)
45001 +#else
45002 +#define OPTIONS_BIT3           0x0
45003 +#endif
45004 +
45005 +
45006 +
45007 +#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST)
45008 +#define PVR_SECURE_HANDLES_SET_OFFSET  OPTIONS_BIT4
45009 +#define OPTIONS_BIT4           (0x1 << 4)
45010 +#else
45011 +#define OPTIONS_BIT4           0x0
45012 +#endif
45013 +
45014 +#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST)
45015 +#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET     OPTIONS_BIT5
45016 +#define OPTIONS_BIT5           (0x1 << 5)
45017 +#else
45018 +#define OPTIONS_BIT5           0x0
45019 +#endif
45020 +
45021 +#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST)
45022 +#define SGX_DMS_AGE_ENABLE_SET_OFFSET  OPTIONS_BIT6
45023 +#define OPTIONS_BIT6           (0x1 << 6)
45024 +#else
45025 +#define OPTIONS_BIT6           0x0
45026 +#endif
45027 +
45028 +#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST)
45029 +#define SGX_FAST_DPM_INIT_SET_OFFSET   OPTIONS_BIT8
45030 +#define OPTIONS_BIT8           (0x1 << 8)
45031 +#else
45032 +#define OPTIONS_BIT8           0x0
45033 +#endif
45034 +
45035 +#if defined(SGX_FEATURE_DCU) || defined (INTERNAL_TEST)
45036 +#define SGX_FEATURE_DCU_SET_OFFSET     OPTIONS_BIT9
45037 +#define OPTIONS_BIT9           (0x1 << 9)
45038 +#else
45039 +#define OPTIONS_BIT9           0x0
45040 +#endif
45041 +
45042 +#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
45043 +#define SGX_FEATURE_MP_SET_OFFSET      OPTIONS_BIT10
45044 +#define OPTIONS_BIT10          (0x1 << 10)
45045 +#else
45046 +#define OPTIONS_BIT10          0x0
45047 +#endif
45048 +
45049 +#if defined(SGX_FEATURE_MULTITHREADED_UKERNEL) || defined (INTERNAL_TEST)
45050 +#define SGX_FEATURE_MULTITHREADED_UKERNEL_SET_OFFSET   OPTIONS_BIT11
45051 +#define OPTIONS_BIT11          (0x1 << 11)
45052 +#else
45053 +#define OPTIONS_BIT11          0x0
45054 +#endif
45055 +
45056 +
45057 +
45058 +#if defined(SGX_FEATURE_OVERLAPPED_SPM) || defined (INTERNAL_TEST)
45059 +#define SGX_FEATURE_OVERLAPPED_SPM_SET_OFFSET  OPTIONS_BIT12
45060 +#define OPTIONS_BIT12          (0x1 << 12)
45061 +#else
45062 +#define OPTIONS_BIT12          0x0
45063 +#endif
45064 +
45065 +
45066 +#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST)
45067 +#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET    OPTIONS_BIT13
45068 +#define OPTIONS_BIT13          (0x1 << 13)
45069 +#else
45070 +#define OPTIONS_BIT13          0x0
45071 +#endif
45072 +
45073 +#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST)
45074 +#define SGX_SUPPORT_HWPROFILING_SET_OFFSET     OPTIONS_BIT14
45075 +#define OPTIONS_BIT14          (0x1 << 14)
45076 +#else
45077 +#define OPTIONS_BIT14          0x0
45078 +#endif
45079 +
45080 +
45081 +
45082 +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST)
45083 +#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET     OPTIONS_BIT15
45084 +#define OPTIONS_BIT15          (0x1 << 15)
45085 +#else
45086 +#define OPTIONS_BIT15          0x0
45087 +#endif
45088 +
45089 +#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST)
45090 +#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET    OPTIONS_BIT16
45091 +#define OPTIONS_BIT16          (0x1 << 16)
45092 +#else
45093 +#define OPTIONS_BIT16          0x0
45094 +#endif
45095 +
45096 +#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST)
45097 +#define SUPPORT_PERCONTEXT_PB_SET_OFFSET       OPTIONS_BIT17
45098 +#define OPTIONS_BIT17          (0x1 << 17)
45099 +#else
45100 +#define OPTIONS_BIT17          0x0
45101 +#endif
45102 +
45103 +#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST)
45104 +#define SUPPORT_SGX_HWPERF_SET_OFFSET  OPTIONS_BIT18
45105 +#define OPTIONS_BIT18          (0x1 << 18)
45106 +#else
45107 +#define OPTIONS_BIT18          0x0
45108 +#endif
45109 +
45110 +
45111 +
45112 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST)
45113 +#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET  OPTIONS_BIT19
45114 +#define OPTIONS_BIT19          (0x1 << 19)
45115 +#else
45116 +#define OPTIONS_BIT19          0x0
45117 +#endif
45118 +
45119 +#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST)
45120 +#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET     OPTIONS_BIT20
45121 +#define OPTIONS_BIT20          (0x1 << 20)
45122 +#else
45123 +#define OPTIONS_BIT20          0x0
45124 +#endif
45125 +
45126 +#if defined(SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST)
45127 +#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET  OPTIONS_BIT21
45128 +#define OPTIONS_BIT21          (0x1 << 21)
45129 +#else
45130 +#define OPTIONS_BIT21          0x0
45131 +#endif
45132 +
45133 +#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST)
45134 +#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22
45135 +#define OPTIONS_BIT22          (0x1 << 22)
45136 +#else
45137 +#define OPTIONS_BIT22          0x0
45138 +#endif
45139 +
45140 +
45141 +#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
45142 +#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET)
45143 +#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET   28UL
45144 +#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK             0xFF
45145 +#else
45146 +#define OPTIONS_HIGHBYTE       0x0
45147 +#endif
45148 +
45149 +
45150 +
45151 +#define SGX_BUILD_OPTIONS      \
45152 +       OPTIONS_BIT0 |\
45153 +       OPTIONS_BIT1 |\
45154 +       OPTIONS_BIT2 |\
45155 +       OPTIONS_BIT3 |\
45156 +       OPTIONS_BIT4 |\
45157 +       OPTIONS_BIT5 |\
45158 +       OPTIONS_BIT6 |\
45159 +       OPTIONS_BIT8 |\
45160 +       OPTIONS_BIT9 |\
45161 +       OPTIONS_BIT10 |\
45162 +       OPTIONS_BIT11 |\
45163 +       OPTIONS_BIT12 |\
45164 +       OPTIONS_BIT13 |\
45165 +       OPTIONS_BIT14 |\
45166 +       OPTIONS_BIT15 |\
45167 +       OPTIONS_BIT16 |\
45168 +       OPTIONS_BIT17 |\
45169 +       OPTIONS_BIT18 |\
45170 +       OPTIONS_BIT19 |\
45171 +       OPTIONS_BIT20 |\
45172 +       OPTIONS_BIT21 |\
45173 +       OPTIONS_HIGHBYTE
45174 +
45175 diff --git a/drivers/gpu/drm/mrst/pvr/include4/sgxapi_km.h b/drivers/gpu/drm/mrst/pvr/include4/sgxapi_km.h
45176 new file mode 100644
45177 index 0000000..6cdbc1a
45178 --- /dev/null
45179 +++ b/drivers/gpu/drm/mrst/pvr/include4/sgxapi_km.h
45180 @@ -0,0 +1,323 @@
45181 +/**********************************************************************
45182 + *
45183 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
45184 + *
45185 + * This program is free software; you can redistribute it and/or modify it
45186 + * under the terms and conditions of the GNU General Public License,
45187 + * version 2, as published by the Free Software Foundation.
45188 + *
45189 + * This program is distributed in the hope it will be useful but, except
45190 + * as otherwise stated in writing, without any warranty; without even the
45191 + * implied warranty of merchantability or fitness for a particular purpose.
45192 + * See the GNU General Public License for more details.
45193 + *
45194 + * You should have received a copy of the GNU General Public License along with
45195 + * this program; if not, write to the Free Software Foundation, Inc.,
45196 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
45197 + *
45198 + * The full GNU General Public License is included in this distribution in
45199 + * the file called "COPYING".
45200 + *
45201 + * Contact Information:
45202 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
45203 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
45204 + *
45205 + ******************************************************************************/
45206 +
45207 +#ifndef __SGXAPI_KM_H__
45208 +#define __SGXAPI_KM_H__
45209 +
45210 +#if defined (__cplusplus)
45211 +extern "C" {
45212 +#endif
45213 +
45214 +#include "sgxdefs.h"
45215 +
45216 +#if defined(__linux__) && !defined(USE_CODE)
45217 +       #if defined(__KERNEL__)
45218 +               #include <asm/unistd.h>
45219 +       #else
45220 +               #include <unistd.h>
45221 +       #endif
45222 +#endif
45223 +
45224 +#define SGX_UNDEFINED_HEAP_ID                                  (~0LU)
45225 +#define SGX_GENERAL_HEAP_ID                                            0
45226 +#define SGX_TADATA_HEAP_ID                                             1
45227 +#define SGX_KERNEL_CODE_HEAP_ID                                        2
45228 +#define SGX_KERNEL_DATA_HEAP_ID                                        3
45229 +#define SGX_PIXELSHADER_HEAP_ID                                        4
45230 +#define SGX_VERTEXSHADER_HEAP_ID                               5
45231 +#define SGX_PDSPIXEL_CODEDATA_HEAP_ID                  6
45232 +#define SGX_PDSVERTEX_CODEDATA_HEAP_ID                 7
45233 +#define SGX_SYNCINFO_HEAP_ID                                   8
45234 +#define SGX_3DPARAMETERS_HEAP_ID                               9
45235 +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
45236 +#define SGX_GENERAL_MAPPING_HEAP_ID                            10
45237 +#endif
45238 +#if defined(SGX_FEATURE_2D_HARDWARE)
45239 +#define SGX_2D_HEAP_ID                                                 11
45240 +#else
45241 +#if defined(FIX_HW_BRN_26915)
45242 +#define SGX_CGBUFFER_HEAP_ID                                   12
45243 +#endif
45244 +#endif
45245 +#define SGX_MAX_HEAP_ID                                                        13
45246 +
45247 +
45248 +#define SGX_MAX_TA_STATUS_VALS 32
45249 +#define SGX_MAX_3D_STATUS_VALS 3
45250 +
45251 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
45252 +#define SGX_MAX_TA_DST_SYNCS                   1
45253 +#define SGX_MAX_TA_SRC_SYNCS                   1
45254 +#define SGX_MAX_3D_SRC_SYNCS                   4
45255 +#else
45256 +#define SGX_MAX_SRC_SYNCS                              4
45257 +#endif
45258 +
45259 +#ifdef SUPPORT_SGX_HWPERF
45260 +
45261 +#define        PVRSRV_SGX_HWPERF_NUM_COUNTERS  9
45262 +
45263 +#define PVRSRV_SGX_HWPERF_INVALID                                      0x1
45264 +
45265 +#define PVRSRV_SGX_HWPERF_TRANSFER                                     0x2
45266 +#define PVRSRV_SGX_HWPERF_TA                                           0x3
45267 +#define PVRSRV_SGX_HWPERF_3D                                           0x4
45268 +#define PVRSRV_SGX_HWPERF_2D                                           0x5
45269 +
45270 +#define PVRSRV_SGX_HWPERF_MK_EVENT                                     0x101
45271 +#define PVRSRV_SGX_HWPERF_MK_TA                                                0x102
45272 +#define PVRSRV_SGX_HWPERF_MK_3D                                                0x103
45273 +#define PVRSRV_SGX_HWPERF_MK_2D                                                0x104
45274 +
45275 +#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT                    28
45276 +#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK                         ((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1)
45277 +#define PVRSRV_SGX_HWPERF_TYPE_OP_START                                (0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
45278 +#define PVRSRV_SGX_HWPERF_TYPE_OP_END                          (1Ul << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
45279 +
45280 +#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START          (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45281 +#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END                    (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45282 +#define PVRSRV_SGX_HWPERF_TYPE_TA_START                                (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45283 +#define PVRSRV_SGX_HWPERF_TYPE_TA_END                          (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45284 +#define PVRSRV_SGX_HWPERF_TYPE_3D_START                                (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45285 +#define PVRSRV_SGX_HWPERF_TYPE_3D_END                          (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45286 +#define PVRSRV_SGX_HWPERF_TYPE_2D_START                                (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45287 +#define PVRSRV_SGX_HWPERF_TYPE_2D_END                          (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45288 +
45289 +#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START          (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45290 +#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END                    (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45291 +#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START                     (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45292 +#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END                       (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45293 +#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START                     (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45294 +#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END                       (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45295 +#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START                     (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START)
45296 +#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END                       (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END)
45297 +
45298 +#define PVRSRV_SGX_HWPERF_OFF                                          (0x0)
45299 +#define PVRSRV_SGX_HWPERF_GRAPHICS_ON                          (1UL << 0)
45300 +#define PVRSRV_SGX_HWPERF_MK_EXECUTION_ON                      (1UL << 1)
45301 +
45302 +
45303 +typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_
45304 +{
45305 +       IMG_UINT32      ui32FrameNo;
45306 +       IMG_UINT32      ui32Type;
45307 +       IMG_UINT32      ui32Ordinal;
45308 +       IMG_UINT32      ui32Clocksx16;
45309 +       IMG_UINT32      ui32Counters[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
45310 +} PVRSRV_SGX_HWPERF_CB_ENTRY;
45311 +
45312 +
45313 +typedef struct _PVRSRV_SGX_HWPERF_CBDATA_
45314 +{
45315 +       IMG_UINT32      ui32FrameNo;
45316 +       IMG_UINT32      ui32Type;
45317 +       IMG_UINT32      ui32StartTimeWraps;
45318 +       IMG_UINT32      ui32StartTime;
45319 +       IMG_UINT32      ui32EndTimeWraps;
45320 +       IMG_UINT32      ui32EndTime;
45321 +       IMG_UINT32      ui32ClockSpeed;
45322 +       IMG_UINT32      ui32TimeMax;
45323 +} PVRSRV_SGX_HWPERF_CBDATA;
45324 +
45325 +
45326 +typedef struct _SGX_MISC_INFO_HWPERF_RETRIEVE_CB
45327 +{
45328 +       PVRSRV_SGX_HWPERF_CBDATA*       psHWPerfData;
45329 +       IMG_UINT32                                      ui32ArraySize;
45330 +       IMG_UINT32                                      ui32DataCount;
45331 +       IMG_UINT32                                      ui32Time;
45332 +} SGX_MISC_INFO_HWPERF_RETRIEVE_CB;
45333 +#endif
45334 +
45335 +
45336 +typedef struct _CTL_STATUS_
45337 +{
45338 +       IMG_DEV_VIRTADDR        sStatusDevAddr;
45339 +       IMG_UINT32                      ui32StatusValue;
45340 +} CTL_STATUS;
45341 +
45342 +
45343 +typedef enum _SGX_MISC_INFO_REQUEST_
45344 +{
45345 +       SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0,
45346 +       SGX_MISC_INFO_REQUEST_SGXREV,
45347 +       SGX_MISC_INFO_REQUEST_DRIVER_SGXREV,
45348 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
45349 +       SGX_MISC_INFO_REQUEST_MEMREAD,
45350 +#endif
45351 +#if defined(SUPPORT_SGX_HWPERF)
45352 +       SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS,
45353 +       SGX_MISC_INFO_REQUEST_HWPERF_CB_ON,
45354 +       SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF,
45355 +       SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB,
45356 +#endif
45357 +#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
45358 +       SGX_MISC_INFO_REQUEST_SET_BREAKPOINT,
45359 +#endif
45360 +       SGX_MISC_INFO_DUMP_DEBUG_INFO,
45361 +       SGX_MISC_INFO_PANIC,
45362 +       SGX_MISC_INFO_REQUEST_FORCE_I16                                 =  0x7fff
45363 +} SGX_MISC_INFO_REQUEST;
45364 +
45365 +
45366 +typedef struct _PVRSRV_SGX_MISCINFO_FEATURES
45367 +{
45368 +       IMG_UINT32                      ui32CoreRev;
45369 +       IMG_UINT32                      ui32CoreID;
45370 +       IMG_UINT32                      ui32DDKVersion;
45371 +       IMG_UINT32                      ui32DDKBuild;
45372 +       IMG_UINT32                      ui32CoreIdSW;
45373 +       IMG_UINT32                      ui32CoreRevSW;
45374 +       IMG_UINT32                      ui32BuildOptions;
45375 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
45376 +       IMG_UINT32                      ui32DeviceMemValue;
45377 +#endif
45378 +} PVRSRV_SGX_MISCINFO_FEATURES;
45379 +
45380 +
45381 +#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
45382 +typedef struct _SGX_BREAKPOINT_INFO
45383 +{
45384 +
45385 +       IMG_BOOL                                        bBPEnable;
45386 +
45387 +
45388 +
45389 +       IMG_UINT32                                      ui32BPIndex;
45390 +
45391 +       IMG_DEV_VIRTADDR                        sBPDevVAddr;
45392 +} SGX_BREAKPOINT_INFO;
45393 +#endif
45394 +
45395 +typedef struct _SGX_MISC_INFO_
45396 +{
45397 +       SGX_MISC_INFO_REQUEST   eRequest;
45398 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
45399 +       IMG_DEV_VIRTADDR                        sDevVAddr;
45400 +       IMG_HANDLE                                      hDevMemContext;
45401 +#endif
45402 +       union
45403 +       {
45404 +               IMG_UINT32      reserved;
45405 +               PVRSRV_SGX_MISCINFO_FEATURES                                            sSGXFeatures;
45406 +               IMG_UINT32                                                                                      ui32SGXClockSpeed;
45407 +#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
45408 +               SGX_BREAKPOINT_INFO                                                                     sSGXBreakpointInfo;
45409 +#endif
45410 +#ifdef SUPPORT_SGX_HWPERF
45411 +               IMG_UINT32                                                                                      ui32NewHWPerfStatus;
45412 +               SGX_MISC_INFO_HWPERF_RETRIEVE_CB                                        sRetrieveCB;
45413 +#endif
45414 +       } uData;
45415 +} SGX_MISC_INFO;
45416 +
45417 +#if defined(SGX_FEATURE_2D_HARDWARE)
45418 +#define PVRSRV_MAX_BLT_SRC_SYNCS               3
45419 +#endif
45420 +
45421 +
45422 +#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH          256
45423 +
45424 +typedef struct _SGX_KICKTA_DUMPBITMAP_
45425 +{
45426 +       IMG_DEV_VIRTADDR        sDevBaseAddr;
45427 +       IMG_UINT32                      ui32Flags;
45428 +       IMG_UINT32                      ui32Width;
45429 +       IMG_UINT32                      ui32Height;
45430 +       IMG_UINT32                      ui32Stride;
45431 +       IMG_UINT32                      ui32PDUMPFormat;
45432 +       IMG_UINT32                      ui32BytesPP;
45433 +       IMG_CHAR                        pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH];
45434 +} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP;
45435 +
45436 +#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE (16)
45437 +
45438 +typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_
45439 +{
45440 +
45441 +       IMG_UINT32                                              ui32CacheControl;
45442 +
45443 +} PVRSRV_SGX_PDUMP_CONTEXT;
45444 +
45445 +
45446 +typedef struct _SGX_KICKTA_DUMP_ROFF_
45447 +{
45448 +       IMG_HANDLE                      hKernelMemInfo;
45449 +       IMG_UINT32                      uiAllocIndex;
45450 +       IMG_UINT32                      ui32Offset;
45451 +       IMG_UINT32                      ui32Value;
45452 +       IMG_PCHAR                       pszName;
45453 +} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF;
45454 +
45455 +typedef struct _SGX_KICKTA_DUMP_BUFFER_
45456 +{
45457 +       IMG_UINT32                      ui32SpaceUsed;
45458 +       IMG_UINT32                      ui32Start;
45459 +       IMG_UINT32                      ui32End;
45460 +       IMG_UINT32                      ui32BufferSize;
45461 +       IMG_UINT32                      ui32BackEndLength;
45462 +       IMG_UINT32                      uiAllocIndex;
45463 +       IMG_HANDLE                      hKernelMemInfo;
45464 +       IMG_PVOID                       pvLinAddr;
45465 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
45466 +       IMG_HANDLE                      hCtrlKernelMemInfo;
45467 +       IMG_DEV_VIRTADDR        sCtrlDevVAddr;
45468 +#endif
45469 +       IMG_PCHAR                       pszName;
45470 +} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER;
45471 +
45472 +#ifdef PDUMP
45473 +typedef struct _SGX_KICKTA_PDUMP_
45474 +{
45475 +
45476 +       PSGX_KICKTA_DUMPBITMAP          psPDumpBitmapArray;
45477 +       IMG_UINT32                                              ui32PDumpBitmapSize;
45478 +
45479 +
45480 +       PSGX_KICKTA_DUMP_BUFFER psBufferArray;
45481 +       IMG_UINT32                                              ui32BufferArraySize;
45482 +
45483 +
45484 +       PSGX_KICKTA_DUMP_ROFF           psROffArray;
45485 +       IMG_UINT32                                              ui32ROffArraySize;
45486 +} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP;
45487 +#endif
45488 +
45489 +#if defined(TRANSFER_QUEUE)
45490 +#if defined(SGX_FEATURE_2D_HARDWARE)
45491 +#define SGX_MAX_2D_BLIT_CMD_SIZE               26
45492 +#define SGX_MAX_2D_SRC_SYNC_OPS                        3
45493 +#endif
45494 +#define SGX_MAX_TRANSFER_STATUS_VALS   2
45495 +#define SGX_MAX_TRANSFER_SYNC_OPS      5
45496 +#endif
45497 +
45498 +#if defined (__cplusplus)
45499 +}
45500 +#endif
45501 +
45502 +#endif
45503 +
45504 diff --git a/drivers/gpu/drm/mrst/pvr/include4/sgxscript.h b/drivers/gpu/drm/mrst/pvr/include4/sgxscript.h
45505 new file mode 100644
45506 index 0000000..fb5efbb
45507 --- /dev/null
45508 +++ b/drivers/gpu/drm/mrst/pvr/include4/sgxscript.h
45509 @@ -0,0 +1,81 @@
45510 +/**********************************************************************
45511 + *
45512 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
45513 + *
45514 + * This program is free software; you can redistribute it and/or modify it
45515 + * under the terms and conditions of the GNU General Public License,
45516 + * version 2, as published by the Free Software Foundation.
45517 + *
45518 + * This program is distributed in the hope it will be useful but, except
45519 + * as otherwise stated in writing, without any warranty; without even the
45520 + * implied warranty of merchantability or fitness for a particular purpose.
45521 + * See the GNU General Public License for more details.
45522 + *
45523 + * You should have received a copy of the GNU General Public License along with
45524 + * this program; if not, write to the Free Software Foundation, Inc.,
45525 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
45526 + *
45527 + * The full GNU General Public License is included in this distribution in
45528 + * the file called "COPYING".
45529 + *
45530 + * Contact Information:
45531 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
45532 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
45533 + *
45534 + ******************************************************************************/
45535 +
45536 +#ifndef __SGXSCRIPT_H__
45537 +#define __SGXSCRIPT_H__
45538 +
45539 +#if defined (__cplusplus)
45540 +extern "C" {
45541 +#endif
45542 +
45543 +#define        SGX_MAX_INIT_COMMANDS   64
45544 +#define        SGX_MAX_DEINIT_COMMANDS 16
45545 +
45546 +typedef        enum _SGX_INIT_OPERATION
45547 +{
45548 +       SGX_INIT_OP_ILLEGAL = 0,
45549 +       SGX_INIT_OP_WRITE_HW_REG,
45550 +#if defined(PDUMP)
45551 +       SGX_INIT_OP_PDUMP_HW_REG,
45552 +#endif
45553 +       SGX_INIT_OP_HALT
45554 +} SGX_INIT_OPERATION;
45555 +
45556 +typedef union _SGX_INIT_COMMAND
45557 +{
45558 +       SGX_INIT_OPERATION eOp;
45559 +       struct {
45560 +               SGX_INIT_OPERATION eOp;
45561 +               IMG_UINT32 ui32Offset;
45562 +               IMG_UINT32 ui32Value;
45563 +       } sWriteHWReg;
45564 +#if defined(PDUMP)
45565 +       struct {
45566 +               SGX_INIT_OPERATION eOp;
45567 +               IMG_UINT32 ui32Offset;
45568 +               IMG_UINT32 ui32Value;
45569 +       } sPDumpHWReg;
45570 +#endif
45571 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
45572 +       struct {
45573 +               SGX_INIT_OPERATION eOp;
45574 +       } sWorkaroundBRN22997;
45575 +#endif
45576 +} SGX_INIT_COMMAND;
45577 +
45578 +typedef struct _SGX_INIT_SCRIPTS_
45579 +{
45580 +       SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS];
45581 +       SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS];
45582 +       SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS];
45583 +} SGX_INIT_SCRIPTS;
45584 +
45585 +#if defined(__cplusplus)
45586 +}
45587 +#endif
45588 +
45589 +#endif
45590 +
45591 diff --git a/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore
45592 new file mode 100644
45593 index 0000000..f558f8b
45594 --- /dev/null
45595 +++ b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/.gitignore
45596 @@ -0,0 +1,6 @@
45597 +bin_pc_i686*
45598 +tmp_pc_i686*
45599 +host_pc_i686*
45600 +binary_pc_i686*
45601 +*.o
45602 +*.o.cmd
45603 diff --git a/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common
45604 new file mode 100644
45605 index 0000000..c3ab6f4
45606 --- /dev/null
45607 +++ b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/makefile.linux.common
45608 @@ -0,0 +1,41 @@
45609 +#
45610 +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
45611 +#
45612 +# This program is free software; you can redistribute it and/or modify it
45613 +# under the terms and conditions of the GNU General Public License,
45614 +# version 2, as published by the Free Software Foundation.
45615 +#
45616 +# This program is distributed in the hope it will be useful but, except
45617 +# as otherwise stated in writing, without any warranty; without even the
45618 +# implied warranty of merchantability or fitness for a particular purpose.
45619 +# See the GNU General Public License for more details.
45620 +#
45621 +# You should have received a copy of the GNU General Public License along with
45622 +# this program; if not, write to the Free Software Foundation, Inc.,
45623 +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
45624 +#
45625 +# The full GNU General Public License is included in this distribution in
45626 +# the file called "COPYING".
45627 +#
45628 +# Contact Information:
45629 +# Imagination Technologies Ltd. <gpl-support@imgtec.com>
45630 +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
45631 +#
45632 +#
45633 +#
45634 +
45635 +ifeq ($(SUPPORT_DRI_DRM),1)
45636 +DISPLAY_CONTROLLER_SOURCES_ROOT = $(KBUILDROOT)/$(DISPLAY_CONTROLLER_DIR)
45637 +else
45638 +DISPLAY_CONTROLLER_SOURCES_ROOT = ..
45639 +endif
45640 +
45641 +INCLUDES +=    -I$(EURASIAROOT)/include4 \
45642 +               -I$(EURASIAROOT)/services4/include \
45643 +               -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \
45644 +               -I$(EURASIAROOT)/services4/system/include \
45645 +               -I$(EURASIAROOT)/services4/srvkm/env/linux/mrst
45646 +
45647 +SOURCES        +=      $(DISPLAY_CONTROLLER_SOURCES_ROOT)/mrstlfb_displayclass.c \
45648 +                       $(DISPLAY_CONTROLLER_SOURCES_ROOT)/mrstlfb_linux.c
45649 +MODULE_CFLAGS += -DPVR_MRST_FB_SET_PAR_ON_INIT
45650 diff --git a/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h
45651 new file mode 100644
45652 index 0000000..9f4a116
45653 --- /dev/null
45654 +++ b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb.h
45655 @@ -0,0 +1,295 @@
45656 +/**********************************************************************
45657 + *
45658 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
45659 + *
45660 + * This program is free software; you can redistribute it and/or modify it
45661 + * under the terms and conditions of the GNU General Public License,
45662 + * version 2, as published by the Free Software Foundation.
45663 + *
45664 + * This program is distributed in the hope it will be useful but, except
45665 + * as otherwise stated in writing, without any warranty; without even the
45666 + * implied warranty of merchantability or fitness for a particular purpose.
45667 + * See the GNU General Public License for more details.
45668 + *
45669 + * You should have received a copy of the GNU General Public License along with
45670 + * this program; if not, write to the Free Software Foundation, Inc.,
45671 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
45672 + *
45673 + * The full GNU General Public License is included in this distribution in
45674 + * the file called "COPYING".
45675 + *
45676 + * Contact Information:
45677 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
45678 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
45679 + *
45680 + ******************************************************************************/
45681 +
45682 +#ifndef __MRSTLFB_H__
45683 +#define __MRSTLFB_H__
45684 +
45685 +#include <drm/drmP.h>
45686 +#include "psb_intel_reg.h"
45687 +
45688 +#define MRST_USING_INTERRUPTS
45689 +
45690 +#define PSB_HWSTAM                0x2098
45691 +#define PSB_INSTPM                0x20C0
45692 +#define PSB_INT_IDENTITY_R        0x20A4
45693 +#define _PSB_VSYNC_PIPEB_FLAG     (1<<5)
45694 +#define _PSB_VSYNC_PIPEA_FLAG     (1<<7)
45695 +#define _PSB_IRQ_SGX_FLAG         (1<<18)
45696 +#define _PSB_IRQ_MSVDX_FLAG       (1<<19)
45697 +#define _LNC_IRQ_TOPAZ_FLAG       (1<<20)
45698 +#define PSB_INT_MASK_R            0x20A8
45699 +#define PSB_INT_ENABLE_R          0x20A0
45700 +
45701 +/* IPC message and command defines used to enable/disable mipi panel voltages */
45702 +#define        IPC_MSG_PANEL_ON_OFF    0xE9
45703 +#define IPC_CMD_PANEL_ON       1
45704 +#define IPC_CMD_PANEL_OFF      0
45705 +
45706 +typedef void *   MRST_HANDLE;
45707 +
45708 +typedef enum tag_mrst_bool
45709 +{
45710 +       MRST_FALSE = 0,
45711 +       MRST_TRUE  = 1,
45712 +} MRST_BOOL, *MRST_PBOOL;
45713 +
45714 +typedef IMG_INT (* MRSTLFB_VSYNC_ISR_PFN)(struct drm_device* psDrmDevice, int iPipe);
45715 +
45716 +extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
45717 +
45718 +
45719 +typedef struct MRSTLFB_BUFFER_TAG
45720 +{
45721 +       
45722 +    IMG_UINT32                         ui32BufferSize;
45723 +       union {
45724 +               
45725 +               IMG_SYS_PHYADDR             *psNonCont;
45726 +               
45727 +               IMG_SYS_PHYADDR                         sCont;
45728 +       } uSysAddr;
45729 +       
45730 +       IMG_DEV_VIRTADDR                sDevVAddr;
45731 +       
45732 +    IMG_CPU_VIRTADDR                   sCPUVAddr;    
45733 +       
45734 +       PVRSRV_SYNC_DATA                *psSyncData;
45735 +       
45736 +       IMG_BOOL                                                bIsContiguous;
45737 +       
45738 +       IMG_BOOL                                                bIsAllocated;
45739 +
45740 +       IMG_UINT32                                              ui32OwnerTaskID;
45741 +
45742 +       struct MRSTLFB_BUFFER_TAG               *psNext;
45743 +} MRSTLFB_BUFFER;
45744 +
45745 +typedef struct MRSTLFB_VSYNC_FLIP_ITEM_TAG
45746 +{
45747 +
45748 +
45749 +
45750 +       MRST_HANDLE      hCmdComplete;
45751 +
45752 +       unsigned long    ulSwapInterval;
45753 +
45754 +       MRST_BOOL        bValid;
45755 +
45756 +       MRST_BOOL        bFlipped;
45757 +
45758 +       MRST_BOOL        bCmdCompleted;
45759 +
45760 +
45761 +
45762 +
45763 +
45764 +       IMG_DEV_VIRTADDR sDevVAddr;
45765 +} MRSTLFB_VSYNC_FLIP_ITEM;
45766 +
45767 +typedef struct MRSTLFB_SWAPCHAIN_TAG
45768 +{
45769 +       
45770 +       unsigned long       ulBufferCount;
45771 +       
45772 +       MRSTLFB_BUFFER     **ppsBuffer;
45773 +       
45774 +       MRSTLFB_VSYNC_FLIP_ITEM *psVSyncFlips;
45775 +
45776 +
45777 +       unsigned long       ulInsertIndex;
45778 +
45779 +
45780 +       unsigned long       ulRemoveIndex;
45781 +
45782 +       
45783 +       PVRSRV_DC_DISP2SRV_KMJTABLE     *psPVRJTable;
45784 +
45785 +
45786 +       MRST_BOOL           bFlushCommands;
45787 +
45788 +
45789 +       unsigned long       ulSetFlushStateRefCount;
45790 +
45791 +
45792 +       MRST_BOOL           bBlanked;
45793 +
45794 +
45795 +       spinlock_t         *psSwapChainLock;
45796 +
45797 +
45798 +       struct drm_driver         *psDrmDriver;
45799 +
45800 +
45801 +       struct drm_device         *psDrmDev;
45802 +
45803 +       struct MRSTLFB_SWAPCHAIN_TAG *psNext;
45804 +
45805 +       struct MRSTLFB_DEVINFO_TAG *psDevInfo;
45806 +
45807 +} MRSTLFB_SWAPCHAIN;
45808 +
45809 +typedef struct MRSTLFB_FBINFO_TAG
45810 +{
45811 +       unsigned long       ulFBSize;
45812 +       unsigned long       ulBufferSize;
45813 +       unsigned long       ulRoundedBufferSize;
45814 +       unsigned long       ulWidth;
45815 +       unsigned long       ulHeight;
45816 +       unsigned long       ulByteStride;
45817 +
45818 +
45819 +
45820 +       IMG_SYS_PHYADDR     sSysAddr;
45821 +       IMG_CPU_VIRTADDR    sCPUVAddr;
45822 +        IMG_DEV_VIRTADDR    sDevVAddr;
45823 +
45824 +
45825 +       PVRSRV_PIXEL_FORMAT ePixelFormat;
45826 +}MRSTLFB_FBINFO;
45827 +
45828 +/**
45829 + * If DRI is enable then extemding drm_device
45830 + */
45831 +typedef struct MRSTLFB_DEVINFO_TAG
45832 +{
45833 +       unsigned long           ulDeviceID;
45834 +
45835 +       struct drm_device       *psDrmDevice;
45836 +
45837 +       MRSTLFB_BUFFER          sSystemBuffer;
45838 +
45839 +
45840 +       PVRSRV_DC_DISP2SRV_KMJTABLE     sPVRJTable;
45841 +
45842 +
45843 +       PVRSRV_DC_SRV2DISP_KMJTABLE     sDCJTable;
45844 +
45845 +       
45846 +       unsigned long           ulRefCount;
45847 +
45848 +
45849 +       MRSTLFB_SWAPCHAIN      *psSwapChain;
45850 +
45851 +       IMG_UINT32                              ui32SwapChainNum;
45852 +
45853 +       IMG_UINT32                              ui32SwapChainIdCounter;
45854 +
45855 +       
45856 +       void *pvRegs;
45857 +
45858 +       
45859 +       MRST_BOOL               bFlushCommands;
45860 +
45861 +
45862 +       struct fb_info         *psLINFBInfo;
45863 +
45864 +
45865 +       struct notifier_block   sLINNotifBlock;
45866 +
45867 +
45868 +       MRST_BOOL               bDeviceSuspended;
45869 +
45870 +
45871 +       spinlock_t             sSwapChainLock;
45872 +
45873 +
45874 +
45875 +
45876 +
45877 +       IMG_DEV_VIRTADDR        sDisplayDevVAddr;
45878 +
45879 +       DISPLAY_INFO            sDisplayInfo;
45880 +
45881 +
45882 +       DISPLAY_FORMAT          sDisplayFormat;
45883 +
45884 +
45885 +       DISPLAY_DIMS            sDisplayDim;
45886 +
45887 +       IMG_UINT32                              ui32MainPipe;
45888 +
45889 +}  MRSTLFB_DEVINFO;
45890 +
45891 +#if 0
45892 +#define        MRSTLFB_PAGE_SIZE 4096
45893 +#define        MRSTLFB_PAGE_MASK (MRSTLFB_PAGE_SIZE - 1)
45894 +#define        MRSTLFB_PAGE_TRUNC (~MRSTLFB_PAGE_MASK)
45895 +
45896 +#define        MRSTLFB_PAGE_ROUNDUP(x) (((x) + MRSTLFB_PAGE_MASK) & MRSTLFB_PAGE_TRUNC)
45897 +#endif
45898 +
45899 +#ifdef DEBUG
45900 +#define        DEBUG_PRINTK(x) printk x
45901 +#else
45902 +#define        DEBUG_PRINTK(x)
45903 +#endif
45904 +
45905 +#define DISPLAY_DEVICE_NAME "PowerVR Moorestown Linux Display Driver"
45906 +#define        DRVNAME "mrstlfb"
45907 +#define        DEVNAME DRVNAME
45908 +#define        DRIVER_PREFIX DRVNAME
45909 +
45910 +typedef enum _MRST_ERROR_
45911 +{
45912 +       MRST_OK                             =  0,
45913 +       MRST_ERROR_GENERIC                  =  1,
45914 +       MRST_ERROR_OUT_OF_MEMORY            =  2,
45915 +       MRST_ERROR_TOO_FEW_BUFFERS          =  3,
45916 +       MRST_ERROR_INVALID_PARAMS           =  4,
45917 +       MRST_ERROR_INIT_FAILURE             =  5,
45918 +       MRST_ERROR_CANT_REGISTER_CALLBACK   =  6,
45919 +       MRST_ERROR_INVALID_DEVICE           =  7,
45920 +       MRST_ERROR_DEVICE_REGISTER_FAILED   =  8
45921 +} MRST_ERROR;
45922 +
45923 +
45924 +#ifndef UNREFERENCED_PARAMETER
45925 +#define        UNREFERENCED_PARAMETER(param) (param) = (param)
45926 +#endif
45927 +
45928 +MRST_ERROR MRSTLFBInit(struct drm_device * dev);
45929 +MRST_ERROR MRSTLFBDeinit(void);
45930 +
45931 +MRST_ERROR MRSTLFBAllocBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer);
45932 +MRST_ERROR MRSTLFBFreeBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, MRSTLFB_BUFFER **ppBuffer);
45933 +
45934 +void *MRSTLFBAllocKernelMem(unsigned long ulSize);
45935 +void MRSTLFBFreeKernelMem(void *pvMem);
45936 +MRST_ERROR MRSTLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
45937 +MRST_ERROR MRSTLFBInstallVSyncISR (MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_VSYNC_ISR_PFN pVsyncHandler);
45938 +MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo);
45939 +MRST_BOOL MRSTLFBVSyncIHandler(MRSTLFB_SWAPCHAIN *psSwapChain);
45940 +
45941 +void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo);
45942 +void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO *psDevInfo);
45943 +
45944 +void MRSTLFBEnableDisplayRegisterAccess(void);
45945 +void MRSTLFBDisableDisplayRegisterAccess(void);
45946 +
45947 +void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo,  unsigned long uiAddr);
45948 +
45949 +#endif 
45950 +
45951 diff --git a/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
45952 new file mode 100644
45953 index 0000000..adca7e2
45954 --- /dev/null
45955 +++ b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
45956 @@ -0,0 +1,2056 @@
45957 +/**********************************************************************
45958 + *
45959 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
45960 + *
45961 + * This program is free software; you can redistribute it and/or modify it
45962 + * under the terms and conditions of the GNU General Public License,
45963 + * version 2, as published by the Free Software Foundation.
45964 + *
45965 + * This program is distributed in the hope it will be useful but, except
45966 + * as otherwise stated in writing, without any warranty; without even the
45967 + * implied warranty of merchantability or fitness for a particular purpose.
45968 + * See the GNU General Public License for more details.
45969 + *
45970 + * You should have received a copy of the GNU General Public License along with
45971 + * this program; if not, write to the Free Software Foundation, Inc.,
45972 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
45973 + *
45974 + * The full GNU General Public License is included in this distribution in
45975 + * the file called "COPYING".
45976 + *
45977 + * Contact Information:
45978 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
45979 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
45980 + *
45981 + ******************************************************************************/
45982 +
45983 +#include <linux/version.h>
45984 +#include <linux/kernel.h>
45985 +#include <linux/console.h>
45986 +#include <linux/fb.h>
45987 +#include <linux/module.h>
45988 +#include <linux/string.h>
45989 +#include <linux/notifier.h>
45990 +#include <linux/spinlock.h>
45991 +#include <asm/ipc_defs.h>
45992 +
45993 +#include "img_defs.h"
45994 +#include "servicesext.h"
45995 +#include "kerneldisplay.h"
45996 +#include "mrstlfb.h"
45997 +
45998 +#include "psb_fb.h"
45999 +#include "psb_drv.h"
46000 +#include "ospm_power.h"
46001 +
46002 +#if !defined(SUPPORT_DRI_DRM)
46003 +#error "SUPPORT_DRI_DRM must be set"
46004 +#endif
46005 +
46006 +IMG_UINT32 gui32MRSTDisplayDeviceID;
46007 +
46008 +extern void MRSTLFBVSyncWriteReg(MRSTLFB_DEVINFO * psDevinfo, unsigned long ulOffset, unsigned long ulValue);
46009 +extern unsigned long MRSTLFBVSyncReadReg(MRSTLFB_DEVINFO * psDevinfo, unsigned long ulOffset);
46010 +
46011 +PVRSRV_ERROR MRSTLFBPrePowerState(IMG_HANDLE            hDevHandle,
46012 +                                 PVRSRV_DEV_POWER_STATE eNewPowerState,
46013 +                                 PVRSRV_DEV_POWER_STATE eCurrentPowerState);
46014 +
46015 +PVRSRV_ERROR MRSTLFBPostPowerState(IMG_HANDLE            hDevHandle,
46016 +                                  PVRSRV_DEV_POWER_STATE eNewPowerState,
46017 +                                  PVRSRV_DEV_POWER_STATE eCurrentPowerState);
46018 +
46019 +#ifdef MODESET_640x480
46020 +extern int psb_to_640 (struct fb_info* info);
46021 +#endif
46022 +
46023 +extern void mrst_init_LGE_MIPI(struct drm_device *dev);
46024 +extern void mrst_init_NSC_MIPI_bridge(struct drm_device *dev);
46025 +
46026 +struct psbfb_par {
46027 +  struct drm_device *dev;
46028 +  void *psbfb;
46029 +
46030 +  int dpms_state;
46031 +
46032 +  int crtc_count;
46033 +
46034 +  uint32_t crtc_ids[2];
46035 +};
46036 +
46037 +extern void* psbfb_vdc_reg(struct drm_device* dev);
46038 +
46039 +static void *gpvAnchor;
46040 +
46041 +
46042 +#define MRSTLFB_COMMAND_COUNT          1
46043 +
46044 +static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
46045 +
46046 +static MRSTLFB_DEVINFO * GetAnchorPtr(void)
46047 +{
46048 +       return (MRSTLFB_DEVINFO *)gpvAnchor;
46049 +}
46050 +
46051 +static void SetAnchorPtr(MRSTLFB_DEVINFO *psDevInfo)
46052 +{
46053 +       gpvAnchor = (void*)psDevInfo;
46054 +}
46055 +
46056 +
46057 +static void FlushInternalVSyncQueue(MRSTLFB_SWAPCHAIN *psSwapChain)
46058 +{
46059 +       MRSTLFB_VSYNC_FLIP_ITEM *psFlipItem;
46060 +       unsigned long            ulMaxIndex;
46061 +       unsigned long            i;
46062 +
46063 +
46064 +       psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
46065 +       ulMaxIndex = psSwapChain->ulBufferCount - 1;
46066 +
46067 +       for(i = 0; i < psSwapChain->ulBufferCount; i++)
46068 +       {
46069 +               if (psFlipItem->bValid == MRST_FALSE)
46070 +               {
46071 +                       continue;
46072 +               }
46073 +
46074 +               DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Flushing swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
46075 +
46076 +               if(psFlipItem->bFlipped == MRST_FALSE)
46077 +               {
46078 +                       
46079 +                       MRSTLFBFlip(psSwapChain->psDevInfo, (unsigned long)psFlipItem->sDevVAddr.uiAddr);
46080 +               }
46081 +               
46082 +               if(psFlipItem->bCmdCompleted == MRST_FALSE)
46083 +               {
46084 +                       DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Calling command complete for swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex));
46085 +
46086 +                       psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE);
46087 +               }
46088 +
46089 +
46090 +               psSwapChain->ulRemoveIndex++;
46091 +
46092 +               if(psSwapChain->ulRemoveIndex > ulMaxIndex)
46093 +               {
46094 +                       psSwapChain->ulRemoveIndex = 0;
46095 +               }
46096 +
46097 +
46098 +               psFlipItem->bFlipped = MRST_FALSE;
46099 +               psFlipItem->bCmdCompleted = MRST_FALSE;
46100 +               psFlipItem->bValid = MRST_FALSE;
46101 +
46102 +
46103 +               psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
46104 +       }
46105 +
46106 +       psSwapChain->ulInsertIndex = 0;
46107 +       psSwapChain->ulRemoveIndex = 0;
46108 +}
46109 +
46110 +static void SetFlushStateInternalNoLock(MRSTLFB_DEVINFO* psDevInfo,
46111 +                                        MRST_BOOL bFlushState)
46112 +{
46113 +       MRSTLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
46114 +
46115 +       if (psSwapChain == NULL)
46116 +       {
46117 +               return;
46118 +       }
46119 +
46120 +       if (bFlushState)
46121 +       {
46122 +               if (psSwapChain->ulSetFlushStateRefCount == 0)
46123 +               {
46124 +                       MRSTLFBDisableVSyncInterrupt(psDevInfo);
46125 +                       psSwapChain->bFlushCommands = MRST_TRUE;
46126 +                       FlushInternalVSyncQueue(psSwapChain);
46127 +               }
46128 +               psSwapChain->ulSetFlushStateRefCount++;
46129 +       }
46130 +       else
46131 +       {
46132 +               if (psSwapChain->ulSetFlushStateRefCount != 0)
46133 +               {
46134 +                       psSwapChain->ulSetFlushStateRefCount--;
46135 +                       if (psSwapChain->ulSetFlushStateRefCount == 0)
46136 +                       {
46137 +                               psSwapChain->bFlushCommands = MRST_FALSE;
46138 +                               MRSTLFBEnableVSyncInterrupt(psDevInfo);
46139 +                       }
46140 +               }
46141 +       }
46142 +}
46143 +
46144 +static IMG_VOID SetFlushStateInternal(MRSTLFB_DEVINFO* psDevInfo,
46145 +                                      MRST_BOOL bFlushState)
46146 +{
46147 +       unsigned long ulLockFlags;
46148 +
46149 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46150 +
46151 +       SetFlushStateInternalNoLock(psDevInfo, bFlushState);
46152 +
46153 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46154 +}
46155 +
46156 +static void SetFlushStateExternal(MRSTLFB_DEVINFO* psDevInfo,
46157 +                                  MRST_BOOL bFlushState)
46158 +{
46159 +       unsigned long ulLockFlags;
46160 +
46161 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46162 +
46163 +
46164 +       if (psDevInfo->bFlushCommands != bFlushState)
46165 +       {
46166 +               psDevInfo->bFlushCommands = bFlushState;
46167 +               SetFlushStateInternalNoLock(psDevInfo, bFlushState);
46168 +       }
46169 +
46170 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46171 +}
46172 +
46173 +static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
46174 +{
46175 +       MRSTLFB_DEVINFO *psDevInfo = (MRSTLFB_DEVINFO *)hDevice;
46176 +
46177 +       switch (ui32State)
46178 +       {
46179 +               case DC_STATE_FLUSH_COMMANDS:
46180 +                       SetFlushStateExternal(psDevInfo, MRST_TRUE);
46181 +                       break;
46182 +               case DC_STATE_NO_FLUSH_COMMANDS:
46183 +                       SetFlushStateExternal(psDevInfo, MRST_FALSE);
46184 +                       break;
46185 +               default:
46186 +                       break;
46187 +       }
46188 +
46189 +       return;
46190 +}
46191 +
46192 +static int FrameBufferEvents(struct notifier_block *psNotif,
46193 +                             unsigned long event, void *data)
46194 +{
46195 +       MRSTLFB_DEVINFO *psDevInfo;
46196 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46197 +       struct fb_event *psFBEvent = (struct fb_event *)data;
46198 +       MRST_BOOL bBlanked;
46199 +
46200 +
46201 +       if (event != FB_EVENT_BLANK)
46202 +       {
46203 +               return 0;
46204 +       }
46205 +
46206 +       psDevInfo = GetAnchorPtr();
46207 +       psSwapChain = psDevInfo->psSwapChain;
46208 +
46209 +       bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? MRST_TRUE: MRST_FALSE;
46210 +
46211 +       if (bBlanked != psSwapChain->bBlanked)
46212 +       {
46213 +               psSwapChain->bBlanked = bBlanked;
46214 +
46215 +               if (bBlanked)
46216 +               {
46217 +
46218 +                       SetFlushStateInternal(psDevInfo, MRST_TRUE);
46219 +               }
46220 +               else
46221 +               {
46222 +
46223 +                       SetFlushStateInternal(psDevInfo, MRST_FALSE);
46224 +               }
46225 +       }
46226 +
46227 +       return 0;
46228 +}
46229 +
46230 +
46231 +static MRST_ERROR UnblankDisplay(MRSTLFB_DEVINFO *psDevInfo)
46232 +{
46233 +       int res;
46234 +
46235 +       acquire_console_sem();
46236 +       res = fb_blank(psDevInfo->psLINFBInfo, 0);
46237 +       release_console_sem();
46238 +       if (res != 0)
46239 +       {
46240 +               printk(KERN_WARNING DRIVER_PREFIX
46241 +                       ": fb_blank failed (%d)", res);
46242 +               return (MRST_ERROR_GENERIC);
46243 +       }
46244 +
46245 +       return (MRST_OK);
46246 +}
46247 +
46248 +static MRST_ERROR EnableLFBEventNotification(MRSTLFB_DEVINFO *psDevInfo)
46249 +{
46250 +       int                res;
46251 +       MRST_ERROR         eError;
46252 +
46253 +       
46254 +       memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock));
46255 +
46256 +       psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents;
46257 +
46258 +       res = fb_register_client(&psDevInfo->sLINNotifBlock);
46259 +       if (res != 0)
46260 +       {
46261 +               printk(KERN_WARNING DRIVER_PREFIX
46262 +                       ": fb_register_client failed (%d)", res);
46263 +
46264 +               return (MRST_ERROR_GENERIC);
46265 +       }
46266 +
46267 +       eError = UnblankDisplay(psDevInfo);
46268 +       if (eError != MRST_OK)
46269 +       {
46270 +               DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
46271 +                       ": UnblankDisplay failed (%d)", eError));
46272 +               return eError;
46273 +       }
46274 +
46275 +       return (MRST_OK);
46276 +}
46277 +
46278 +static MRST_ERROR DisableLFBEventNotification(MRSTLFB_DEVINFO *psDevInfo)
46279 +{
46280 +       int res;
46281 +
46282 +
46283 +       res = fb_unregister_client(&psDevInfo->sLINNotifBlock);
46284 +       if (res != 0)
46285 +       {
46286 +               printk(KERN_WARNING DRIVER_PREFIX
46287 +                       ": fb_unregister_client failed (%d)", res);
46288 +               return (MRST_ERROR_GENERIC);
46289 +       }
46290 +
46291 +       return (MRST_OK);
46292 +}
46293 +
46294 +static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
46295 +                                 IMG_HANDLE *phDevice,
46296 +                                 PVRSRV_SYNC_DATA* psSystemBufferSyncData)
46297 +{
46298 +       MRSTLFB_DEVINFO *psDevInfo;
46299 +       MRST_ERROR eError;
46300 +
46301 +       UNREFERENCED_PARAMETER(ui32DeviceID);
46302 +
46303 +       psDevInfo = GetAnchorPtr();
46304 +
46305 +
46306 +       psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
46307 +
46308 +       eError = UnblankDisplay(psDevInfo);
46309 +       if (eError != MRST_OK)
46310 +       {
46311 +               DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
46312 +                       ": UnblankDisplay failed (%d)", eError));
46313 +               return (PVRSRV_ERROR_GENERIC);
46314 +       }
46315 +
46316 +
46317 +       *phDevice = (IMG_HANDLE)psDevInfo;
46318 +
46319 +       return (PVRSRV_OK);
46320 +}
46321 +
46322 +static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
46323 +{
46324 +       UNREFERENCED_PARAMETER(hDevice);
46325 +
46326 +       return (PVRSRV_OK);
46327 +}
46328 +
46329 +static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
46330 +                                  IMG_UINT32 *pui32NumFormats,
46331 +                                  DISPLAY_FORMAT *psFormat)
46332 +{
46333 +       MRSTLFB_DEVINFO *psDevInfo;
46334 +
46335 +       if(!hDevice || !pui32NumFormats)
46336 +       {
46337 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46338 +       }
46339 +
46340 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46341 +
46342 +       *pui32NumFormats = 1;
46343 +
46344 +       if(psFormat)
46345 +       {
46346 +               psFormat[0] = psDevInfo->sDisplayFormat;
46347 +       }
46348 +
46349 +       return (PVRSRV_OK);
46350 +}
46351 +
46352 +static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
46353 +                               DISPLAY_FORMAT *psFormat,
46354 +                               IMG_UINT32 *pui32NumDims,
46355 +                               DISPLAY_DIMS *psDim)
46356 +{
46357 +       MRSTLFB_DEVINFO *psDevInfo;
46358 +
46359 +       if(!hDevice || !psFormat || !pui32NumDims)
46360 +       {
46361 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46362 +       }
46363 +
46364 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46365 +
46366 +       *pui32NumDims = 1;
46367 +
46368 +
46369 +       if(psDim)
46370 +       {
46371 +               psDim[0] = psDevInfo->sDisplayDim;
46372 +       }
46373 +
46374 +       return (PVRSRV_OK);
46375 +}
46376 +
46377 +
46378 +static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
46379 +{
46380 +       MRSTLFB_DEVINFO *psDevInfo;
46381 +
46382 +       if(!hDevice || !phBuffer)
46383 +       {
46384 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46385 +       }
46386 +
46387 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46388 +
46389 +       
46390 +       
46391 +       *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer;
46392 +
46393 +       return (PVRSRV_OK);
46394 +}
46395 +
46396 +
46397 +static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
46398 +{
46399 +       MRSTLFB_DEVINFO *psDevInfo;
46400 +
46401 +       if(!hDevice || !psDCInfo)
46402 +       {
46403 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46404 +       }
46405 +
46406 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46407 +
46408 +       *psDCInfo = psDevInfo->sDisplayInfo;
46409 +
46410 +       return (PVRSRV_OK);
46411 +}
46412 +
46413 +static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE        hDevice,
46414 +                                    IMG_HANDLE        hBuffer,
46415 +                                    IMG_SYS_PHYADDR   **ppsSysAddr,
46416 +                                    IMG_UINT32        *pui32ByteSize,
46417 +                                    IMG_VOID          **ppvCpuVAddr,
46418 +                                    IMG_HANDLE        *phOSMapInfo,
46419 +                                    IMG_BOOL          *pbIsContiguous)
46420 +{
46421 +       MRSTLFB_DEVINFO *psDevInfo;
46422 +       MRSTLFB_BUFFER *psSystemBuffer;
46423 +
46424 +       if(!hDevice)
46425 +       {
46426 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46427 +       }
46428 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46429 +
46430 +       if(!hBuffer)
46431 +       {
46432 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46433 +       }
46434 +       psSystemBuffer = (MRSTLFB_BUFFER *)hBuffer;
46435 +
46436 +       if (!ppsSysAddr)
46437 +       {
46438 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46439 +       }
46440 +
46441 +       if( psSystemBuffer->bIsContiguous ) 
46442 +               *ppsSysAddr = &psSystemBuffer->uSysAddr.sCont;
46443 +       else
46444 +               *ppsSysAddr = psSystemBuffer->uSysAddr.psNonCont;
46445 +
46446 +       if (!pui32ByteSize)
46447 +       {
46448 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46449 +       }
46450 +       *pui32ByteSize = psSystemBuffer->ui32BufferSize;
46451 +
46452 +       if (ppvCpuVAddr)
46453 +       {
46454 +               *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
46455 +       }
46456 +
46457 +       if (phOSMapInfo)
46458 +       {
46459 +               *phOSMapInfo = (IMG_HANDLE)0;
46460 +       }
46461 +
46462 +       if (pbIsContiguous)
46463 +       {
46464 +               *pbIsContiguous = psSystemBuffer->bIsContiguous;
46465 +       }
46466 +
46467 +       return (PVRSRV_OK);
46468 +}
46469 +
46470 +
46471 +static MRST_ERROR MRSTLFBEnableSwapChains(MRSTLFB_DEVINFO *psDevInfo) 
46472 +{
46473 +       unsigned long ulLockFlags;
46474 +
46475 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46476 +
46477 +       if(!psDevInfo->bFlushCommands)
46478 +               MRSTLFBEnableVSyncInterrupt(psDevInfo);
46479 +
46480 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46481 +
46482 +       if (EnableLFBEventNotification(psDevInfo)!= MRST_OK)
46483 +       {
46484 +               printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n");
46485 +       }
46486 +
46487 +       return MRST_OK;
46488 +}
46489 +
46490 +static MRST_ERROR MRSTLFBDisableSwapChains(MRSTLFB_DEVINFO *psDevInfo) 
46491 +{
46492 +       MRST_ERROR eError;
46493 +       unsigned long ulLockFlags;
46494 +
46495 +       eError = DisableLFBEventNotification(psDevInfo);
46496 +       if (eError != MRST_OK)
46497 +       {
46498 +               printk(KERN_WARNING DRIVER_PREFIX ": Couldn't disable framebuffer event notification\n");
46499 +       }
46500 +
46501 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46502 +
46503 +       MRSTLFBDisableVSyncInterrupt(psDevInfo);
46504 +
46505 +       
46506 +       MRSTLFBFlip(psDevInfo, (unsigned long)psDevInfo->sSystemBuffer.sDevVAddr.uiAddr);
46507 +
46508 +       psDevInfo->psSwapChain = NULL;
46509 +
46510 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46511 +       return MRST_OK;
46512 +}
46513 +
46514 +
46515 +static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
46516 +                                      IMG_UINT32 ui32Flags,
46517 +                                      DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
46518 +                                      DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
46519 +                                      IMG_UINT32 ui32BufferCount,
46520 +                                      PVRSRV_SYNC_DATA **ppsSyncData,
46521 +                                      IMG_UINT32 ui32OEMFlags,
46522 +                                      IMG_HANDLE *phSwapChain,
46523 +                                      IMG_UINT32 *pui32SwapChainID)
46524 +{
46525 +       MRSTLFB_DEVINFO *psDevInfo;
46526 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46527 +       MRSTLFB_BUFFER **ppsBuffer;
46528 +       MRSTLFB_VSYNC_FLIP_ITEM *psVSyncFlips;
46529 +       IMG_UINT32 i;
46530 +       PVRSRV_ERROR eError = PVRSRV_ERROR_NOT_SUPPORTED;
46531 +       unsigned long ulLockFlags;
46532 +       struct drm_device* psDrmDev;
46533 +
46534 +       UNREFERENCED_PARAMETER(ui32OEMFlags);
46535 +       
46536 +       
46537 +       if(!hDevice
46538 +       || !psDstSurfAttrib
46539 +       || !psSrcSurfAttrib
46540 +       || !ppsSyncData
46541 +       || !phSwapChain)
46542 +       {
46543 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46544 +       }
46545 +
46546 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46547 +               
46548 +       
46549 +       if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
46550 +       {
46551 +               return (PVRSRV_ERROR_TOOMANYBUFFERS);
46552 +       }
46553 +       
46554 +       
46555 +       
46556 +
46557 +       
46558 +       if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat
46559 +       || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride
46560 +       || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width
46561 +       || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height)
46562 +       {
46563 +
46564 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46565 +       }
46566 +
46567 +       if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat
46568 +       || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride
46569 +       || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width
46570 +       || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height)
46571 +       {
46572 +
46573 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46574 +       }
46575 +
46576 +
46577 +       UNREFERENCED_PARAMETER(ui32Flags);
46578 +
46579 +
46580 +       psSwapChain = (MRSTLFB_SWAPCHAIN*)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_SWAPCHAIN));
46581 +       if(!psSwapChain)
46582 +       {
46583 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
46584 +       }
46585 +
46586 +       ppsBuffer = (MRSTLFB_BUFFER**)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_BUFFER*) * ui32BufferCount);
46587 +       if(!ppsBuffer)
46588 +       {
46589 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
46590 +               goto ErrorFreeSwapChain;
46591 +       }
46592 +
46593 +       psVSyncFlips = (MRSTLFB_VSYNC_FLIP_ITEM *)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_VSYNC_FLIP_ITEM) * ui32BufferCount);
46594 +       if (!psVSyncFlips)
46595 +       {
46596 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
46597 +               goto ErrorFreeBuffers;
46598 +       }
46599 +
46600 +       psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
46601 +       psSwapChain->ppsBuffer = ppsBuffer;
46602 +       psSwapChain->psVSyncFlips = psVSyncFlips;
46603 +       psSwapChain->ulInsertIndex = 0;
46604 +       psSwapChain->ulRemoveIndex = 0;
46605 +       psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable;
46606 +       psSwapChain->psSwapChainLock = &psDevInfo->sSwapChainLock;
46607 +
46608 +       
46609 +       
46610 +       for(i=0; i<ui32BufferCount; i++)
46611 +       {
46612 +               MRSTLFBAllocBuffer(psDevInfo, psDevInfo->sSystemBuffer.ui32BufferSize, &ppsBuffer[i] );
46613 +               ppsBuffer[i]->psSyncData = ppsSyncData[i];              
46614 +       }
46615 +
46616 +  
46617 +       for(i=0; i<ui32BufferCount-1; i++)
46618 +       {
46619 +               ppsBuffer[i]->psNext = ppsBuffer[i+1];
46620 +       }
46621 +       
46622 +       ppsBuffer[i]->psNext = ppsBuffer[0];
46623 +
46624 +       
46625 +       for(i=0; i<ui32BufferCount; i++)
46626 +       {
46627 +               psVSyncFlips[i].bValid = MRST_FALSE;
46628 +               psVSyncFlips[i].bFlipped = MRST_FALSE;
46629 +               psVSyncFlips[i].bCmdCompleted = MRST_FALSE;
46630 +       }
46631 +
46632 +
46633 +       psDrmDev = psDevInfo->psDrmDevice;
46634 +
46635 +       psSwapChain->psDevInfo = psDevInfo;
46636 +       psSwapChain->psDrmDev = psDrmDev;
46637 +       psSwapChain->psDrmDriver = psDrmDev->driver;
46638 +       psSwapChain->bBlanked = MRST_FALSE;
46639 +
46640 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46641 +   
46642 +       
46643 +       psSwapChain->bFlushCommands = psDevInfo->bFlushCommands;
46644 +
46645 +       if (psSwapChain->bFlushCommands)
46646 +       {
46647 +               psSwapChain->ulSetFlushStateRefCount = 1;
46648 +       }
46649 +       else
46650 +       {
46651 +               psSwapChain->ulSetFlushStateRefCount = 0;
46652 +       }
46653 +               
46654 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46655 +
46656 +       
46657 +       
46658 +
46659 +
46660 +
46661 +       
46662 +       *phSwapChain = (IMG_HANDLE)psSwapChain;
46663 +       *pui32SwapChainID = ++psDevInfo->ui32SwapChainIdCounter;
46664 +       psDevInfo->psSwapChain = psSwapChain;
46665 +
46666 +       if( psDevInfo->ui32SwapChainNum++ == 0)
46667 +       {
46668 +               MRSTLFBEnableSwapChains( psDevInfo );
46669 +       }
46670 +
46671 +       return (PVRSRV_OK);
46672 +
46673 +
46674 +       MRSTLFBFreeKernelMem(psVSyncFlips);
46675 +ErrorFreeBuffers:
46676 +       MRSTLFBFreeKernelMem(ppsBuffer);
46677 +ErrorFreeSwapChain:
46678 +       MRSTLFBFreeKernelMem(psSwapChain);
46679 +
46680 +       return eError;
46681 +}
46682 +
46683 +static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
46684 +       IMG_HANDLE hSwapChain)
46685 +{
46686 +       MRSTLFB_DEVINFO *psDevInfo;
46687 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46688 +       int i;
46689 +
46690 +
46691 +       if(!hDevice || !hSwapChain)
46692 +       {
46693 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46694 +       }
46695 +
46696 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46697 +       psSwapChain = (MRSTLFB_SWAPCHAIN*)hSwapChain;
46698 +
46699 +       
46700 +       FlushInternalVSyncQueue(psSwapChain);
46701 +
46702 +       
46703 +       if(--psDevInfo->ui32SwapChainNum == 0) 
46704 +       {
46705 +               MRSTLFBDisableSwapChains(psDevInfo);
46706 +       }
46707 +
46708 +       if( psDevInfo->psSwapChain == psSwapChain )
46709 +               psDevInfo->psSwapChain = IMG_NULL;
46710 +
46711 +
46712 +       
46713 +       for(i=0; i<     psSwapChain->ulBufferCount; i++)
46714 +       {
46715 +               MRSTLFBFreeBuffer(psDevInfo, &psSwapChain->ppsBuffer[i] );
46716 +       }
46717 +       MRSTLFBFreeKernelMem(psSwapChain->psVSyncFlips);
46718 +       MRSTLFBFreeKernelMem(psSwapChain->ppsBuffer);
46719 +       MRSTLFBFreeKernelMem(psSwapChain);
46720 +
46721 +       return (PVRSRV_OK);
46722 +}
46723 +
46724 +static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
46725 +       IMG_HANDLE hSwapChain,
46726 +       IMG_RECT *psRect)
46727 +{
46728 +       UNREFERENCED_PARAMETER(hDevice);
46729 +       UNREFERENCED_PARAMETER(hSwapChain);
46730 +       UNREFERENCED_PARAMETER(psRect);
46731 +
46732 +
46733 +
46734 +       return (PVRSRV_ERROR_NOT_SUPPORTED);
46735 +}
46736 +
46737 +static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
46738 +                                 IMG_HANDLE hSwapChain,
46739 +                                 IMG_RECT *psRect)
46740 +{
46741 +       UNREFERENCED_PARAMETER(hDevice);
46742 +       UNREFERENCED_PARAMETER(hSwapChain);
46743 +       UNREFERENCED_PARAMETER(psRect);
46744 +
46745 +
46746 +
46747 +       return (PVRSRV_ERROR_NOT_SUPPORTED);
46748 +}
46749 +
46750 +static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
46751 +                                      IMG_HANDLE hSwapChain,
46752 +                                      IMG_UINT32 ui32CKColour)
46753 +{
46754 +       UNREFERENCED_PARAMETER(hDevice);
46755 +       UNREFERENCED_PARAMETER(hSwapChain);
46756 +       UNREFERENCED_PARAMETER(ui32CKColour);
46757 +
46758 +
46759 +
46760 +       return (PVRSRV_ERROR_NOT_SUPPORTED);
46761 +}
46762 +
46763 +static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
46764 +                                      IMG_HANDLE hSwapChain,
46765 +                                      IMG_UINT32 ui32CKColour)
46766 +{
46767 +       UNREFERENCED_PARAMETER(hDevice);
46768 +       UNREFERENCED_PARAMETER(hSwapChain);
46769 +       UNREFERENCED_PARAMETER(ui32CKColour);
46770 +
46771 +
46772 +
46773 +       return (PVRSRV_ERROR_NOT_SUPPORTED);
46774 +}
46775 +
46776 +static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
46777 +                                 IMG_HANDLE hSwapChain,
46778 +                                 IMG_UINT32 *pui32BufferCount,
46779 +                                 IMG_HANDLE *phBuffer)
46780 +{
46781 +       MRSTLFB_DEVINFO   *psDevInfo;
46782 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46783 +       unsigned long      i;
46784 +
46785 +
46786 +       if(!hDevice
46787 +       || !hSwapChain
46788 +       || !pui32BufferCount
46789 +       || !phBuffer)
46790 +       {
46791 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46792 +       }
46793 +
46794 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46795 +       psSwapChain = (MRSTLFB_SWAPCHAIN*)hSwapChain;
46796 +       if (psSwapChain != psDevInfo->psSwapChain)
46797 +       {
46798 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46799 +       }
46800 +
46801 +
46802 +       *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
46803 +
46804 +
46805 +       for(i=0; i<psSwapChain->ulBufferCount; i++)
46806 +       {
46807 +               phBuffer[i] = (IMG_HANDLE)psSwapChain->ppsBuffer[i];
46808 +       }
46809 +       
46810 +       return (PVRSRV_OK);
46811 +}
46812 +
46813 +static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
46814 +                                   IMG_HANDLE hBuffer,
46815 +                                   IMG_UINT32 ui32SwapInterval,
46816 +                                   IMG_HANDLE hPrivateTag,
46817 +                                   IMG_UINT32 ui32ClipRectCount,
46818 +                                   IMG_RECT *psClipRect)
46819 +{
46820 +       MRSTLFB_DEVINFO *psDevInfo;
46821 +
46822 +       UNREFERENCED_PARAMETER(ui32SwapInterval);
46823 +       UNREFERENCED_PARAMETER(hPrivateTag);
46824 +       UNREFERENCED_PARAMETER(psClipRect);
46825 +
46826 +       if(!hDevice
46827 +       || !hBuffer
46828 +       || (ui32ClipRectCount != 0))
46829 +       {
46830 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46831 +       }
46832 +
46833 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46834 +
46835 +
46836 +       return (PVRSRV_OK);
46837 +}
46838 +
46839 +static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice,
46840 +                                   IMG_HANDLE hSwapChain)
46841 +{
46842 +       MRSTLFB_DEVINFO   *psDevInfo;
46843 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46844 +       unsigned long      ulLockFlags;
46845 +
46846 +       if(!hDevice || !hSwapChain)
46847 +       {
46848 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46849 +       }
46850 +
46851 +       psDevInfo = (MRSTLFB_DEVINFO*)hDevice;
46852 +       psSwapChain = (MRSTLFB_SWAPCHAIN*)hSwapChain;
46853 +       if (psSwapChain != psDevInfo->psSwapChain)
46854 +       {
46855 +               return (PVRSRV_ERROR_INVALID_PARAMS);
46856 +       }
46857 +
46858 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
46859 +
46860 +
46861 +       FlushInternalVSyncQueue(psSwapChain);
46862 +
46863 +       
46864 +       MRSTLFBFlip(psDevInfo, (unsigned long)(psDevInfo->sSystemBuffer.sDevVAddr.uiAddr));
46865 +
46866 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
46867 +
46868 +       return (PVRSRV_OK);
46869 +}
46870 +
46871 +MRST_BOOL MRSTLFBVSyncIHandler(MRSTLFB_SWAPCHAIN *psSwapChain)
46872 +{
46873 +       IMG_BOOL bStatus = IMG_TRUE;
46874 +       MRSTLFB_VSYNC_FLIP_ITEM *psFlipItem;
46875 +       unsigned long ulMaxIndex;
46876 +       unsigned long ulLockFlags;
46877 +
46878 +       psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
46879 +       ulMaxIndex = psSwapChain->ulBufferCount - 1;
46880 +
46881 +       spin_lock_irqsave(psSwapChain->psSwapChainLock, ulLockFlags);
46882 +
46883 +
46884 +       if (psSwapChain->bFlushCommands)
46885 +       {
46886 +               goto ExitUnlock;
46887 +       }
46888 +
46889 +       while(psFlipItem->bValid)
46890 +       {
46891 +
46892 +               if(psFlipItem->bFlipped)
46893 +               {
46894 +
46895 +                       if(!psFlipItem->bCmdCompleted)
46896 +                       {
46897 +
46898 +                               IMG_BOOL bScheduleMISR;
46899 +                               
46900 +                               bScheduleMISR = IMG_TRUE;
46901 +
46902 +                               
46903 +                               psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, bScheduleMISR);
46904 +
46905 +
46906 +                               psFlipItem->bCmdCompleted = MRST_TRUE;
46907 +                       }
46908 +
46909 +
46910 +                       psFlipItem->ulSwapInterval--;
46911 +
46912 +
46913 +                       if(psFlipItem->ulSwapInterval == 0)
46914 +                       {
46915 +
46916 +                               psSwapChain->ulRemoveIndex++;
46917 +
46918 +                               if(psSwapChain->ulRemoveIndex > ulMaxIndex)
46919 +                               {
46920 +                                       psSwapChain->ulRemoveIndex = 0;
46921 +                               }
46922 +
46923 +
46924 +                               psFlipItem->bCmdCompleted = MRST_FALSE;
46925 +                               psFlipItem->bFlipped = MRST_FALSE;
46926 +
46927 +
46928 +                               psFlipItem->bValid = MRST_FALSE;
46929 +                       }
46930 +                       else
46931 +                       {
46932 +
46933 +                               break;
46934 +                       }
46935 +               }
46936 +               else
46937 +               {
46938 +                       
46939 +                       MRSTLFBFlip(psSwapChain->psDevInfo, (unsigned long)psFlipItem->sDevVAddr.uiAddr);
46940 +                       
46941 +                       
46942 +                       psFlipItem->bFlipped = MRST_TRUE;
46943 +
46944 +
46945 +                       break;
46946 +               }
46947 +
46948 +
46949 +               psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex];
46950 +       }
46951 +
46952 +ExitUnlock:
46953 +       spin_unlock_irqrestore(psSwapChain->psSwapChainLock, ulLockFlags);
46954 +
46955 +       return bStatus;
46956 +}
46957 +
46958 +#if defined(MRST_USING_INTERRUPTS)
46959 +static int
46960 +MRSTLFBVSyncISR(struct drm_device *psDrmDevice, int iPipe)
46961 +{
46962 +    MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();       
46963 +
46964 +       
46965 +       if(!psDevInfo->psSwapChain)
46966 +       {
46967 +               return (IMG_TRUE);
46968 +       }
46969 +       
46970 +       (void) MRSTLFBVSyncIHandler(psDevInfo->psSwapChain);
46971 +       return 0;
46972 +}
46973 +#endif
46974 +
46975 +#if defined(MRST_USING_INTERRUPTS)
46976 +static IMG_BOOL
46977 +MRSTLFBISRHandler(IMG_VOID* pvDevInfo)
46978 +{
46979 +        MRSTLFB_DEVINFO *psDevInfo = (MRSTLFB_DEVINFO *)pvDevInfo;
46980 +#if 0
46981 +#ifdef MRST_USING_INTERRUPTS
46982 +       MRSTLFB_SWAPCHAIN *psSwapChain;
46983 +#endif
46984 +#endif
46985 +       unsigned long vdc_stat;
46986 +       struct drm_psb_private *dev_priv;
46987 +#if defined(SUPPORT_DRI_DRM)
46988 +       uint32_t pipea_stat = 0;
46989 +#endif
46990 +
46991 +        if (!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
46992 +                DRM_ERROR("ERROR: interrupt arrived but Display HW is power off\n");
46993 +                return IMG_FALSE;
46994 +        }
46995 +       
46996 +#if defined(SUPPORT_DRI_DRM)
46997 +       dev_priv = (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
46998 +
46999 +       pipea_stat = PSB_RVDC32(PIPEASTAT);
47000 +       //write back to clear all interrupt status bits and reset interrupts.
47001 +       PSB_WVDC32(pipea_stat, PIPEASTAT);
47002 +       
47003 +       vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
47004 +       vdc_stat &= dev_priv->vdc_irq_mask;
47005 +       if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
47006 +       {
47007 +               drm_handle_vblank(psDevInfo->psDrmDevice, 0);
47008 +       }
47009 +#endif
47010 +
47011 +/* Use drm_handle_vblank() as the VSync handler, otherwise kernel would panic if handle 
47012 + * the VSync event again. */
47013 +#if 0
47014 +#ifdef MRST_USING_INTERRUPTS
47015 +
47016 +       psSwapChain = psDevInfo->psSwapChain;
47017 +       vdc_stat = MRSTLFBVSyncReadReg(psDevInfo, PSB_INT_IDENTITY_R);
47018 +
47019 +       if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
47020 +       {
47021 +               if(!psDevInfo->psSwapChain)
47022 +               {
47023 +                       psSwapChain = psDevInfo->psSwapChain;
47024 +                       (void) MRSTLFBVSyncIHandler(psSwapChain);
47025 +               }
47026 +       }
47027 +#endif
47028 +#endif
47029 +
47030 +#if defined(SUPPORT_DRI_DRM)
47031 +       vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
47032 +       vdc_stat &= dev_priv->vdc_irq_mask;
47033 +       if (vdc_stat & _PSB_DPST_PIPEA_FLAG) {
47034 +
47035 +               /* Check for DPST related interrupts */
47036 +               if((pipea_stat & PIPE_DPST_EVENT_STATUS) &&
47037 +                  (dev_priv->psb_dpst_state != NULL)) {
47038 +                       uint32_t pwm_reg = 0;
47039 +                       uint32_t hist_reg = 0;
47040 +                       u32 irqCtrl = 0;
47041 +                       struct dpst_guardband guardband_reg;
47042 +                       struct dpst_ie_histogram_control ie_hist_cont_reg;
47043 +
47044 +                       hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
47045 +
47046 +                       /* Determine if this is histogram or pwm interrupt */
47047 +                       if(hist_reg & HISTOGRAM_INT_CTRL_CLEAR) {
47048 +                               /* Notify UM of histogram interrupt */
47049 +                               psb_dpst_notify_change_um(DPST_EVENT_HIST_INTERRUPT,
47050 +                               dev_priv->psb_dpst_state);
47051 +
47052 +                               /* disable dpst interrupts */
47053 +                               guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
47054 +                               guardband_reg.interrupt_enable = 0;
47055 +                               guardband_reg.interrupt_status = 1;
47056 +                               PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
47057 +
47058 +                               ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
47059 +                               ie_hist_cont_reg.ie_histogram_enable = 0;
47060 +                               PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
47061 +
47062 +                               irqCtrl = PSB_RVDC32(PIPEASTAT);
47063 +                               irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
47064 +                               PSB_WVDC32(irqCtrl, PIPEASTAT);
47065 +                       }
47066 +                       pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
47067 +                       if((pwm_reg & PWM_PHASEIN_INT_ENABLE) &&
47068 +                          !(pwm_reg & PWM_PHASEIN_ENABLE)) {
47069 +                               /* Notify UM of the phase complete */
47070 +                               psb_dpst_notify_change_um(DPST_EVENT_PHASE_COMPLETE,
47071 +                               dev_priv->psb_dpst_state);
47072 +
47073 +                               /* Temporarily get phase mngr ready to generate
47074 +                                * another interrupt until this can be moved to
47075 +                                * user mode */
47076 +                               /* PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
47077 +                                          PWM_CONTROL_LOGIC); */
47078 +                       }
47079 +               }
47080 +       }
47081 +#endif
47082 +       return IMG_TRUE;
47083 +}
47084 +#endif
47085 +
47086 +static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
47087 +                            IMG_UINT32  ui32DataSize,
47088 +                            IMG_VOID   *pvData)
47089 +{
47090 +       DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
47091 +       MRSTLFB_DEVINFO *psDevInfo;
47092 +       MRSTLFB_BUFFER *psBuffer;
47093 +       MRSTLFB_SWAPCHAIN *psSwapChain;
47094 +#if 0//defined(MRST_USING_INTERRUPTS)
47095 +       MRSTLFB_VSYNC_FLIP_ITEM* psFlipItem;
47096 +#endif
47097 +       unsigned long ulLockFlags;
47098 +
47099 +
47100 +       if(!hCmdCookie || !pvData)
47101 +       {
47102 +               return IMG_FALSE;
47103 +       }
47104 +
47105 +
47106 +       psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
47107 +
47108 +       if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
47109 +       {
47110 +               return IMG_FALSE;
47111 +       }
47112 +
47113 +
47114 +       psDevInfo = (MRSTLFB_DEVINFO*)psFlipCmd->hExtDevice;
47115 +
47116 +       psBuffer = (MRSTLFB_BUFFER*)psFlipCmd->hExtBuffer;
47117 +       psSwapChain = (MRSTLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain;
47118 +
47119 +       spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
47120 +
47121 +
47122 +
47123 +       if (psDevInfo->bDeviceSuspended)
47124 +       {
47125 +               psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
47126 +               goto ExitTrueUnlock;
47127 +       }
47128 +
47129 +#if 0 //defined(MRST_USING_INTERRUPTS)
47130 +       
47131 +       if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == MRST_TRUE || psBuffer == &psDevInfo->sSystemBuffer)
47132 +       {
47133 +#endif
47134 +               
47135 +               MRSTLFBFlip(psDevInfo, (unsigned long)psBuffer->sDevVAddr.uiAddr);
47136 +
47137 +               
47138 +       
47139 +               psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
47140 +
47141 +#if 0 //defined(MRST_USING_INTERRUPTS)
47142 +               goto ExitTrueUnlock;
47143 +       }
47144 +
47145 +       psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulInsertIndex];
47146 +
47147 +
47148 +       if(psFlipItem->bValid == MRST_FALSE)
47149 +       {
47150 +               unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1;
47151 +
47152 +               if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex)
47153 +               {
47154 +                       
47155 +                       MRSTLFBFlip(psDevInfo, (unsigned long)psBuffer->sDevVAddr.uiAddr);
47156 +
47157 +                       psFlipItem->bFlipped = MRST_TRUE;
47158 +               }
47159 +               else
47160 +               {
47161 +                       psFlipItem->bFlipped = MRST_FALSE;
47162 +               }
47163 +
47164 +               psFlipItem->hCmdComplete = (MRST_HANDLE)hCmdCookie;
47165 +               psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval;
47166 +               psFlipItem->sDevVAddr = psBuffer->sDevVAddr;
47167 +               psFlipItem->bValid = MRST_TRUE;
47168 +
47169 +               psSwapChain->ulInsertIndex++;
47170 +               if(psSwapChain->ulInsertIndex > ulMaxIndex)
47171 +               {
47172 +                       psSwapChain->ulInsertIndex = 0;
47173 +               }
47174 +
47175 +               goto ExitTrueUnlock;
47176 +       }
47177 +
47178 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
47179 +       return IMG_FALSE;
47180 +#endif
47181 +
47182 +ExitTrueUnlock:
47183 +       spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags);
47184 +       return IMG_TRUE;
47185 +}
47186 +
47187 +
47188 +#if defined(PVR_MRST_FB_SET_PAR_ON_INIT)
47189 +static void MRSTFBSetPar(struct fb_info *psLINFBInfo)
47190 +{
47191 +       acquire_console_sem();
47192 +
47193 +       if (psLINFBInfo->fbops->fb_set_par != NULL)
47194 +       {
47195 +               int res;
47196 +
47197 +               res = psLINFBInfo->fbops->fb_set_par(psLINFBInfo);
47198 +               if (res != 0)
47199 +               {
47200 +                       printk(KERN_WARNING DRIVER_PREFIX
47201 +                               ": fb_set_par failed: %d\n", res);
47202 +
47203 +               }
47204 +       }
47205 +       else
47206 +       {
47207 +               printk(KERN_WARNING DRIVER_PREFIX
47208 +                       ": fb_set_par not set - HW cursor may not work\n");
47209 +       }
47210 +
47211 +       release_console_sem();
47212 +}
47213 +#endif
47214 +
47215 +
47216 +static int MRSTLFBHandleChangeFB(struct drm_device* dev, struct psb_framebuffer *psbfb)
47217 +{
47218 +       MRSTLFB_DEVINFO *psDevInfo = GetAnchorPtr();
47219 +       int i;
47220 +       struct drm_psb_private * dev_priv;
47221 +       struct psb_gtt * pg;
47222 +       
47223 +       if( !psDevInfo->sSystemBuffer.bIsContiguous )
47224 +               MRSTLFBFreeKernelMem( psDevInfo->sSystemBuffer.uSysAddr.psNonCont );
47225 +       
47226 +       dev_priv = (struct drm_psb_private *)dev->dev_private;
47227 +       pg = dev_priv->pg;
47228 +
47229 +       
47230 +       psDevInfo->sDisplayDim.ui32ByteStride = psbfb->base.pitch;
47231 +       psDevInfo->sDisplayDim.ui32Width = psbfb->base.width;
47232 +       psDevInfo->sDisplayDim.ui32Height = psbfb->base.height;
47233 +
47234 +       psDevInfo->sSystemBuffer.ui32BufferSize = psbfb->size;
47235 +       //psDevInfo->sSystemBuffer.sCPUVAddr = psbfb->pvKMAddr;
47236 +       psDevInfo->sSystemBuffer.sCPUVAddr = pg->vram_addr;
47237 +       //psDevInfo->sSystemBuffer.sDevVAddr.uiAddr = psbfb->offsetGTT;
47238 +       psDevInfo->sSystemBuffer.sDevVAddr.uiAddr = 0;
47239 +       psDevInfo->sSystemBuffer.bIsAllocated = IMG_FALSE;      
47240 +
47241 +       if(psbfb->bo ) 
47242 +       {
47243 +               
47244 +               psDevInfo->sSystemBuffer.bIsContiguous = IMG_FALSE;
47245 +               psDevInfo->sSystemBuffer.uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( IMG_SYS_PHYADDR ) * psbfb->bo->ttm->num_pages);    
47246 +               for(i = 0;i < psbfb->bo->ttm->num_pages;++i) 
47247 +               {
47248 +                       struct page *p = ttm_tt_get_page( psbfb->bo->ttm, i);
47249 +                       psDevInfo->sSystemBuffer.uSysAddr.psNonCont[i].uiAddr = page_to_pfn(p) << PAGE_SHIFT;   
47250 +                       
47251 +               }
47252 +       } 
47253 +       else 
47254 +       {
47255 +               
47256 +               //struct drm_device * psDrmDevice = psDevInfo->psDrmDevice;     
47257 +               //struct drm_psb_private * dev_priv = (struct drm_psb_private *)psDrmDevice->dev_private;
47258 +               //struct psb_gtt * pg = dev_priv->pg;
47259 +
47260 +               psDevInfo->sSystemBuffer.bIsContiguous = IMG_TRUE;
47261 +               psDevInfo->sSystemBuffer.uSysAddr.sCont.uiAddr = pg->stolen_base;
47262 +       }
47263 +
47264 +       return 0;
47265 +}
47266 +
47267 +static int MRSTLFBFindMainPipe(struct drm_device *dev)  {
47268 +       struct drm_crtc *crtc;
47269 +
47270 +       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)  
47271 +       {
47272 +               if ( drm_helper_crtc_in_use(crtc) ) 
47273 +               {
47274 +                       struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
47275 +                       return psb_intel_crtc->pipe;
47276 +               }
47277 +       }       
47278 +       
47279 +       return 0;
47280 +}
47281 +
47282 +static MRST_ERROR InitDev(MRSTLFB_DEVINFO *psDevInfo)
47283 +{
47284 +       MRST_ERROR eError = MRST_ERROR_GENERIC;
47285 +       struct fb_info *psLINFBInfo;
47286 +       struct drm_device * psDrmDevice = psDevInfo->psDrmDevice;
47287 +       struct drm_framebuffer * psDrmFB;
47288 +       struct psb_framebuffer *psbfb;
47289 +       
47290 +
47291 +       int hdisplay;
47292 +       int vdisplay;
47293 +
47294 +       unsigned long FBSize;
47295 +
47296 +       psDrmFB = list_first_entry(&psDrmDevice->mode_config.fb_kernel_list,
47297 +                                  struct drm_framebuffer,
47298 +                                  filp_head);
47299 +       if(!psDrmFB) {
47300 +               printk(KERN_INFO"%s:Cannot find drm FB", __FUNCTION__);
47301 +               return eError;
47302 +       }
47303 +       psbfb = to_psb_fb(psDrmFB);
47304 +
47305 +       hdisplay = psDrmFB->width;
47306 +       vdisplay = psDrmFB->height;
47307 +       FBSize = psDrmFB->pitch * psDrmFB->height;
47308 +
47309 +       psLINFBInfo = (struct fb_info*)psDrmFB->fbdev;  
47310 +
47311 +#if defined(PVR_MRST_FB_SET_PAR_ON_INIT)
47312 +       MRSTFBSetPar(psLINFBInfo);
47313 +#endif
47314 +
47315 +       
47316 +       psDevInfo->sSystemBuffer.bIsContiguous = IMG_TRUE;
47317 +       psDevInfo->sSystemBuffer.bIsAllocated = IMG_FALSE;
47318 +
47319 +       MRSTLFBHandleChangeFB(psDrmDevice, psbfb);
47320 +
47321 +    
47322 +       psDevInfo->sDisplayFormat.pixelformat = PVRSRV_PIXEL_FORMAT_ARGB8888;
47323 +       psDevInfo->psLINFBInfo = psLINFBInfo;
47324 +
47325 +
47326 +       psDevInfo->ui32MainPipe = MRSTLFBFindMainPipe(psDevInfo->psDrmDevice);
47327 +       
47328 +       
47329 +       
47330 +       
47331 +       psDevInfo->pvRegs = psbfb_vdc_reg(psDevInfo->psDrmDevice);
47332 +
47333 +       if (psDevInfo->pvRegs == NULL)
47334 +       {
47335 +               eError = PVRSRV_ERROR_BAD_MAPPING;
47336 +               printk(KERN_WARNING DRIVER_PREFIX ": Couldn't map registers needed for flipping\n");
47337 +               return eError;
47338 +       }
47339 +
47340 +       return MRST_OK;
47341 +}
47342 +
47343 +static void DeInitDev(MRSTLFB_DEVINFO *psDevInfo)
47344 +{
47345 +
47346 +}
47347 +
47348 +MRST_ERROR MRSTLFBInit(struct drm_device * dev)
47349 +{
47350 +       MRSTLFB_DEVINFO         *psDevInfo;
47351 +       //struct drm_psb_private *psDrmPriv = (struct drm_psb_private *)dev->dev_private;
47352 +
47353 +       psDevInfo = GetAnchorPtr();
47354 +
47355 +       if (psDevInfo == NULL)
47356 +       {
47357 +               PFN_CMD_PROC                    pfnCmdProcList[MRSTLFB_COMMAND_COUNT];
47358 +               IMG_UINT32                              aui32SyncCountList[MRSTLFB_COMMAND_COUNT][2];
47359 +
47360 +               psDevInfo = (MRSTLFB_DEVINFO *)MRSTLFBAllocKernelMem(sizeof(MRSTLFB_DEVINFO));
47361 +
47362 +               if(!psDevInfo)
47363 +               {
47364 +                       return (MRST_ERROR_OUT_OF_MEMORY);
47365 +               }
47366 +
47367 +
47368 +               memset(psDevInfo, 0, sizeof(MRSTLFB_DEVINFO));
47369 +
47370 +
47371 +               SetAnchorPtr((void*)psDevInfo);
47372 +
47373 +               psDevInfo->psDrmDevice = dev;
47374 +               psDevInfo->ulRefCount = 0;
47375 +
47376 +
47377 +               if(InitDev(psDevInfo) != MRST_OK)
47378 +               {
47379 +                       return (MRST_ERROR_INIT_FAILURE);
47380 +               }
47381 +
47382 +               if(MRSTLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != MRST_OK)
47383 +               {
47384 +                       return (MRST_ERROR_INIT_FAILURE);
47385 +               }
47386 +
47387 +
47388 +               if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable))
47389 +               {
47390 +                       return (MRST_ERROR_INIT_FAILURE);
47391 +               }
47392 +
47393 +
47394 +               spin_lock_init(&psDevInfo->sSwapChainLock);
47395 +
47396 +               psDevInfo->psSwapChain = 0;
47397 +               psDevInfo->bFlushCommands = MRST_FALSE;
47398 +               psDevInfo->bDeviceSuspended = MRST_FALSE;
47399 +
47400 +               psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 3;
47401 +               psDevInfo->sDisplayInfo.ui32MaxSwapChains = 2;
47402 +               psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3;
47403 +               psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
47404 +
47405 +               strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
47406 +
47407 +               
47408 +       
47409 +
47410 +               DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
47411 +                       ": Maximum number of swap chain buffers: %lu\n",
47412 +                       psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));
47413 +
47414 +
47415 +               
47416 +
47417 +               psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE);
47418 +               psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice;
47419 +               psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice;
47420 +               psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats;
47421 +               psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims;
47422 +               psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer;
47423 +               psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo;
47424 +               psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr;
47425 +               psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain;
47426 +               psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain;
47427 +               psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect;
47428 +               psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect;
47429 +               psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey;
47430 +               psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey;
47431 +               psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers;
47432 +               psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer;
47433 +               psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem;
47434 +               psDevInfo->sDCJTable.pfnSetDCState = SetDCState;
47435 +
47436 +
47437 +               if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (
47438 +                       &psDevInfo->sDCJTable,
47439 +                       &psDevInfo->ulDeviceID ) != PVRSRV_OK)
47440 +               {
47441 +                       return (MRST_ERROR_DEVICE_REGISTER_FAILED);
47442 +               }
47443 +
47444 +               printk("Device ID: %lu\n", psDevInfo->ulDeviceID);
47445 +
47446 +#if defined (SYS_USING_INTERRUPTS)
47447 +               if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterSystemISRHandler(MRSTLFBISRHandler,
47448 +                                                                           psDevInfo,
47449 +                                                                           0,
47450 +                                                                           (IMG_UINT32)psDevInfo->ulDeviceID) != PVRSRV_OK)
47451 +               {
47452 +                       DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX "ISR Installation failed\n"));
47453 +                       return (MRST_ERROR_INIT_FAILURE);
47454 +               }
47455 +#endif
47456 +               if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterPowerDevice((IMG_UINT32)psDevInfo->ulDeviceID,
47457 +                                                                      MRSTLFBPrePowerState, MRSTLFBPostPowerState,
47458 +                                                                      IMG_NULL, IMG_NULL,
47459 +                                                                      psDevInfo,
47460 +                                                                      PVRSRV_DEV_POWER_STATE_ON,
47461 +                                                                      PVRSRV_DEV_POWER_STATE_ON) != PVRSRV_OK)
47462 +               {
47463 +                       return (MRST_ERROR_INIT_FAILURE);
47464 +               }
47465 +
47466 +               
47467 +
47468 +
47469 +
47470 +               
47471 +
47472 +
47473 +
47474 +
47475 +
47476 +#if defined (MRST_USING_INTERRUPTS)
47477 +       
47478 +       if(MRSTLFBInstallVSyncISR(psDevInfo,MRSTLFBVSyncISR) != MRST_OK)
47479 +       {
47480 +               DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX   "ISR Installation failed\n"));
47481 +               return (MRST_ERROR_INIT_FAILURE);
47482 +       }
47483 +#endif
47484 +
47485 +       
47486 +       pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
47487 +       
47488 +       
47489 +       aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; 
47490 +       aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; 
47491 +       
47492 +       
47493 +
47494 +
47495 +
47496 +       if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID,
47497 +                                                               &pfnCmdProcList[0],
47498 +                                                               aui32SyncCountList,
47499 +                                                               MRSTLFB_COMMAND_COUNT) != PVRSRV_OK)
47500 +         {
47501 +           printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n");
47502 +           return (MRST_ERROR_CANT_REGISTER_CALLBACK);
47503 +         }
47504 +
47505 +
47506 +       }
47507 +
47508 +       
47509 +       //psDrmPriv->psb_change_fb_handler = MRSTLFBHandleChangeFB;     
47510 +
47511 +       
47512 +       psDevInfo->ulRefCount++;
47513 +
47514 +       
47515 +       return (MRST_OK);       
47516 +}
47517 +
47518 +MRST_ERROR MRSTLFBDeinit(void)
47519 +{
47520 +       MRSTLFB_DEVINFO *psDevInfo, *psDevFirst;
47521 +
47522 +       psDevFirst = GetAnchorPtr();
47523 +       psDevInfo = psDevFirst;
47524 +
47525 +
47526 +       if (psDevInfo == NULL)
47527 +       {
47528 +               return (MRST_ERROR_GENERIC);
47529 +       }
47530 +
47531 +
47532 +       psDevInfo->ulRefCount--;
47533 +
47534 +       psDevInfo->psDrmDevice = NULL;
47535 +       if (psDevInfo->ulRefCount == 0)
47536 +       {
47537 +
47538 +               PVRSRV_DC_DISP2SRV_KMJTABLE     *psJTable = &psDevInfo->sPVRJTable;
47539 +
47540 +               if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList (psDevInfo->ulDeviceID, MRSTLFB_COMMAND_COUNT) != PVRSRV_OK)
47541 +               {
47542 +                       return (MRST_ERROR_GENERIC);
47543 +               }
47544 +
47545 +               if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterPowerDevice((IMG_UINT32)psDevInfo->ulDeviceID,
47546 +                                                                      IMG_NULL, IMG_NULL,
47547 +                                                                      IMG_NULL, IMG_NULL, IMG_NULL,
47548 +                                                                      PVRSRV_DEV_POWER_STATE_ON,
47549 +                                                                      PVRSRV_DEV_POWER_STATE_ON) != PVRSRV_OK)
47550 +               {
47551 +                       return (MRST_ERROR_GENERIC);
47552 +               }
47553 +
47554 +#if defined (SYS_USING_INTERRUPTS)
47555 +               if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterSystemISRHandler(IMG_NULL, IMG_NULL, 0,
47556 +                                                                           (IMG_UINT32)psDevInfo->ulDeviceID) != PVRSRV_OK)
47557 +               {
47558 +                       return (MRST_ERROR_GENERIC);
47559 +               }
47560 +#endif
47561 +
47562 +#if defined (MRST_USING_INTERRUPTS)
47563 +               
47564 +               if(MRSTLFBUninstallVSyncISR(psDevInfo) != MRST_OK)
47565 +               {
47566 +                       return (MRST_ERROR_GENERIC);
47567 +               }
47568 +#endif
47569 +
47570 +               if (psJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK)
47571 +               {
47572 +                       return (MRST_ERROR_GENERIC);
47573 +               }
47574 +
47575 +               DeInitDev(psDevInfo);
47576 +
47577 +
47578 +               MRSTLFBFreeKernelMem(psDevInfo);
47579 +       }
47580 +
47581 +
47582 +       SetAnchorPtr(NULL);
47583 +
47584 +
47585 +       return (MRST_OK);
47586 +}
47587 +
47588 +
47589 +/*
47590 + * save_display_registers
47591 + *
47592 + * Description: We are going to suspend so save current display
47593 + * register state.
47594 + */
47595 +static void save_display_registers(struct drm_device *dev)
47596 +{
47597 +       struct drm_psb_private *dev_priv = dev->dev_private;
47598 +       int i;
47599 +
47600 +       /* Display arbitration control + watermarks */
47601 +       dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
47602 +       dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
47603 +       dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
47604 +       dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
47605 +       dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
47606 +       dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
47607 +       dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
47608 +       dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
47609 +
47610 +       /* Pipe & plane A info */
47611 +       dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF);
47612 +       dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC);
47613 +       dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0);
47614 +       dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1);
47615 +       dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A);
47616 +       dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A);
47617 +       dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A);
47618 +       dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A);
47619 +       dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A);
47620 +       dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A);
47621 +       dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A);
47622 +       dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A);
47623 +       dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR);
47624 +       dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE);
47625 +       dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE);
47626 +       dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF);
47627 +       dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF);
47628 +       dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF);
47629 +
47630 +       /*save cursor regs*/
47631 +       dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
47632 +       dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
47633 +       dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
47634 +
47635 +       /*save palette (gamma) */
47636 +       for (i = 0; i < 256; i++)
47637 +               dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i<<2));
47638 +
47639 +       /*save performance state*/
47640 +       dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
47641 +
47642 +       /* LVDS state */
47643 +       dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL);
47644 +       dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
47645 +       dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS);
47646 +       dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL);
47647 +       dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2);
47648 +       dev_priv->saveLVDS = PSB_RVDC32(LVDS);
47649 +       dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
47650 +       dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON);
47651 +       dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF);
47652 +       dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE);
47653 +
47654 +       /* HW overlay */
47655 +       dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
47656 +       dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
47657 +       dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
47658 +       dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
47659 +       dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
47660 +       dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
47661 +       dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
47662 +
47663 +       /* MIPI DSI */
47664 +       dev_priv->saveMIPI = PSB_RVDC32(MIPI);
47665 +       dev_priv->saveDEVICE_READY_REG = PSB_RVDC32(DEVICE_READY_REG);
47666 +       dev_priv->saveINTR_EN_REG  = PSB_RVDC32(INTR_EN_REG);
47667 +       dev_priv->saveDSI_FUNC_PRG_REG  = PSB_RVDC32(DSI_FUNC_PRG_REG);
47668 +       dev_priv->saveHS_TX_TIMEOUT_REG = PSB_RVDC32(HS_TX_TIMEOUT_REG);
47669 +       dev_priv->saveLP_RX_TIMEOUT_REG = PSB_RVDC32(LP_RX_TIMEOUT_REG);
47670 +       dev_priv->saveTURN_AROUND_TIMEOUT_REG =
47671 +                               PSB_RVDC32(TURN_AROUND_TIMEOUT_REG);
47672 +       dev_priv->saveDEVICE_RESET_REG = PSB_RVDC32(DEVICE_RESET_REG);
47673 +       dev_priv->saveDPI_RESOLUTION_REG =
47674 +                               PSB_RVDC32(DPI_RESOLUTION_REG);
47675 +       dev_priv->saveHORIZ_SYNC_PAD_COUNT_REG =
47676 +                               PSB_RVDC32(HORIZ_SYNC_PAD_COUNT_REG);
47677 +       dev_priv->saveHORIZ_BACK_PORCH_COUNT_REG =
47678 +                               PSB_RVDC32(HORIZ_BACK_PORCH_COUNT_REG);
47679 +       dev_priv->saveHORIZ_FRONT_PORCH_COUNT_REG =
47680 +                               PSB_RVDC32(HORIZ_FRONT_PORCH_COUNT_REG);
47681 +       dev_priv->saveHORIZ_ACTIVE_AREA_COUNT_REG =
47682 +                               PSB_RVDC32(HORIZ_ACTIVE_AREA_COUNT_REG);
47683 +       dev_priv->saveVERT_SYNC_PAD_COUNT_REG =
47684 +                               PSB_RVDC32(VERT_SYNC_PAD_COUNT_REG);
47685 +       dev_priv->saveVERT_BACK_PORCH_COUNT_REG =
47686 +                               PSB_RVDC32(VERT_BACK_PORCH_COUNT_REG);
47687 +       dev_priv->saveVERT_FRONT_PORCH_COUNT_REG =
47688 +                               PSB_RVDC32(VERT_FRONT_PORCH_COUNT_REG);
47689 +       dev_priv->saveHIGH_LOW_SWITCH_COUNT_REG =
47690 +                               PSB_RVDC32(HIGH_LOW_SWITCH_COUNT_REG);
47691 +       dev_priv->saveINIT_COUNT_REG = PSB_RVDC32(INIT_COUNT_REG);
47692 +       dev_priv->saveMAX_RET_PAK_REG = PSB_RVDC32(MAX_RET_PAK_REG);
47693 +       dev_priv->saveVIDEO_FMT_REG = PSB_RVDC32(VIDEO_FMT_REG);
47694 +       dev_priv->saveEOT_DISABLE_REG = PSB_RVDC32(EOT_DISABLE_REG);
47695 +       dev_priv->saveLP_BYTECLK_REG = PSB_RVDC32(LP_BYTECLK_REG);
47696 +       dev_priv->saveHS_LS_DBI_ENABLE_REG =
47697 +                               PSB_RVDC32(HS_LS_DBI_ENABLE_REG);
47698 +       dev_priv->saveTXCLKESC_REG = PSB_RVDC32(TXCLKESC_REG);
47699 +       dev_priv->saveDPHY_PARAM_REG  = PSB_RVDC32(DPHY_PARAM_REG);
47700 +       dev_priv->saveMIPI_CONTROL_REG = PSB_RVDC32(MIPI_CONTROL_REG);
47701 +
47702 +       /* DPST registers */
47703 +       dev_priv->saveHISTOGRAM_INT_CONTROL_REG = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
47704 +       dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
47705 +}
47706 +
47707 +
47708 +/*
47709 + * restore_display_registers
47710 + *
47711 + * Description: We are going to resume so restore display register state.
47712 + */
47713 +static void restore_display_registers(struct drm_device *dev)
47714 +{
47715 +       struct drm_psb_private *dev_priv = dev->dev_private;
47716 +       unsigned long i, pp_stat;
47717 +
47718 +       /* Display arbitration + watermarks */
47719 +       PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
47720 +       PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
47721 +       PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
47722 +       PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
47723 +       PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
47724 +       PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
47725 +       PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
47726 +       PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
47727 +
47728 +       /*make sure VGA plane is off. it initializes to on after reset!*/
47729 +       PSB_WVDC32(0x80000000, VGACNTRL);
47730 +
47731 +       /* set the plls */
47732 +       PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0);
47733 +       PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1);
47734 +       /* Actually enable it */
47735 +       PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A);
47736 +       DRM_UDELAY(150);
47737 +
47738 +       /* Restore mode */
47739 +       PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A);
47740 +       PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A);
47741 +       PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A);
47742 +       PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A);
47743 +       PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A);
47744 +       PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A);
47745 +       PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC);
47746 +       PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A);
47747 +
47748 +       /*restore performance mode*/
47749 +       PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
47750 +
47751 +       /*enable the pipe*/
47752 +       if (dev_priv->iLVDS_enable)
47753 +               PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
47754 +
47755 +       /* set up MIPI */
47756 +       PSB_WVDC32(dev_priv->saveINTR_EN_REG, INTR_EN_REG);
47757 +       PSB_WVDC32(dev_priv->saveDSI_FUNC_PRG_REG, DSI_FUNC_PRG_REG);
47758 +       PSB_WVDC32(dev_priv->saveHS_TX_TIMEOUT_REG, HS_TX_TIMEOUT_REG);
47759 +       PSB_WVDC32(dev_priv->saveLP_RX_TIMEOUT_REG, LP_RX_TIMEOUT_REG);
47760 +       PSB_WVDC32(dev_priv->saveTURN_AROUND_TIMEOUT_REG,
47761 +                                       TURN_AROUND_TIMEOUT_REG);
47762 +       PSB_WVDC32(dev_priv->saveDEVICE_RESET_REG, DEVICE_RESET_REG);
47763 +       PSB_WVDC32(dev_priv->saveDPI_RESOLUTION_REG,
47764 +                                       DPI_RESOLUTION_REG);
47765 +       PSB_WVDC32(dev_priv->saveHORIZ_SYNC_PAD_COUNT_REG,
47766 +                                       HORIZ_SYNC_PAD_COUNT_REG);
47767 +       PSB_WVDC32(dev_priv->saveHORIZ_BACK_PORCH_COUNT_REG,
47768 +                                       HORIZ_BACK_PORCH_COUNT_REG);
47769 +       PSB_WVDC32(dev_priv->saveHORIZ_FRONT_PORCH_COUNT_REG,
47770 +                                       HORIZ_FRONT_PORCH_COUNT_REG);
47771 +       PSB_WVDC32(dev_priv->saveHORIZ_ACTIVE_AREA_COUNT_REG,
47772 +                                       HORIZ_ACTIVE_AREA_COUNT_REG);
47773 +       PSB_WVDC32(dev_priv->saveVERT_SYNC_PAD_COUNT_REG,
47774 +                                       VERT_SYNC_PAD_COUNT_REG);
47775 +       PSB_WVDC32(dev_priv->saveVERT_BACK_PORCH_COUNT_REG,
47776 +                                       VERT_BACK_PORCH_COUNT_REG);
47777 +       PSB_WVDC32(dev_priv->saveVERT_FRONT_PORCH_COUNT_REG,
47778 +                                       VERT_FRONT_PORCH_COUNT_REG);
47779 +       PSB_WVDC32(dev_priv->saveHIGH_LOW_SWITCH_COUNT_REG,
47780 +                                       HIGH_LOW_SWITCH_COUNT_REG);
47781 +       PSB_WVDC32(dev_priv->saveINIT_COUNT_REG, INIT_COUNT_REG);
47782 +       PSB_WVDC32(dev_priv->saveMAX_RET_PAK_REG, MAX_RET_PAK_REG);
47783 +       PSB_WVDC32(dev_priv->saveVIDEO_FMT_REG, VIDEO_FMT_REG);
47784 +       PSB_WVDC32(dev_priv->saveEOT_DISABLE_REG, EOT_DISABLE_REG);
47785 +       PSB_WVDC32(dev_priv->saveLP_BYTECLK_REG, LP_BYTECLK_REG);
47786 +       PSB_WVDC32(dev_priv->saveHS_LS_DBI_ENABLE_REG,
47787 +                                       HS_LS_DBI_ENABLE_REG);
47788 +       PSB_WVDC32(dev_priv->saveTXCLKESC_REG, TXCLKESC_REG);
47789 +       PSB_WVDC32(dev_priv->saveDPHY_PARAM_REG, DPHY_PARAM_REG);
47790 +       PSB_WVDC32(dev_priv->saveMIPI_CONTROL_REG, MIPI_CONTROL_REG);
47791 +
47792 +       /*set up the plane*/
47793 +       PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF);
47794 +       PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE);
47795 +       PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF);
47796 +
47797 +       /* Enable the plane */
47798 +       PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR);
47799 +       PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF);
47800 +
47801 +       /*Enable Cursor A*/
47802 +       PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
47803 +       PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
47804 +       PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
47805 +
47806 +       /* restore palette (gamma) */
47807 +       /*DRM_UDELAY(50000); */
47808 +       for (i = 0; i < 256; i++)
47809 +               PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i<<2));
47810 +
47811 +       if (dev_priv->iLVDS_enable) {
47812 +               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
47813 +               PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/
47814 +               PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
47815 +               PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
47816 +               PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS);
47817 +               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
47818 +               PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON);
47819 +               PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF);
47820 +               PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE);
47821 +               PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL);
47822 +       } else { /* enable MIPI */
47823 +               PSB_WVDC32(MIPI_PORT_EN | MIPI_BORDER_EN, MIPI); /*force on port*/
47824 +               PSB_WVDC32(1, DEVICE_READY_REG);/* force on to re-program */
47825 +               dev_priv->init_drvIC(dev);
47826 +               PSB_WVDC32(dev_priv->saveMIPI, MIPI); /*port 61190h*/
47827 +               PSB_WVDC32(dev_priv->saveDEVICE_READY_REG, DEVICE_READY_REG);
47828 +               if (dev_priv->saveDEVICE_READY_REG)
47829 +                       PSB_WVDC32(DPI_TURN_ON, DPI_CONTROL_REG);
47830 +               PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
47831 +               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
47832 +               PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
47833 +       }
47834 +
47835 +       /*wait for cycle delay*/
47836 +       do {
47837 +               pp_stat = PSB_RVDC32(PP_STATUS);
47838 +       } while (pp_stat & 0x08000000);
47839 +
47840 +       DRM_UDELAY(999);
47841 +       /*wait for panel power up*/
47842 +       do {
47843 +               pp_stat = PSB_RVDC32(PP_STATUS);
47844 +       } while (pp_stat & 0x10000000);
47845 +
47846 +       /* restore HW overlay */
47847 +       PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
47848 +       PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
47849 +       PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
47850 +       PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
47851 +       PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
47852 +       PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
47853 +       PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
47854 +
47855 +       /* DPST registers */
47856 +       PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, HISTOGRAM_INT_CONTROL);
47857 +       PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, HISTOGRAM_LOGIC_CONTROL);
47858 +}
47859 +
47860 +MRST_ERROR MRSTLFBAllocBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer)
47861 +{
47862 +       IMG_VOID *pvBuf;
47863 +       IMG_UINT32 ulPagesNumber;
47864 +       IMG_UINT32 ulCounter;
47865 +       int i;
47866 +
47867 +       pvBuf = __vmalloc( ui32Size, GFP_KERNEL | __GFP_HIGHMEM, __pgprot((pgprot_val(PAGE_KERNEL ) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) );
47868 +       if( pvBuf == NULL ) 
47869 +       {
47870 +               return MRST_ERROR_OUT_OF_MEMORY;
47871 +       }
47872 +
47873 +       ulPagesNumber = (ui32Size + PAGE_SIZE -1) / PAGE_SIZE;
47874 +
47875 +       *ppBuffer = MRSTLFBAllocKernelMem( sizeof( MRSTLFB_BUFFER ) );  
47876 +       (*ppBuffer)->sCPUVAddr = pvBuf;
47877 +       (*ppBuffer)->ui32BufferSize = ui32Size;
47878 +       (*ppBuffer)->uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( IMG_SYS_PHYADDR ) * ulPagesNumber);    
47879 +       (*ppBuffer)->bIsAllocated = IMG_TRUE;
47880 +       (*ppBuffer)->bIsContiguous = IMG_FALSE;
47881 +       (*ppBuffer)->ui32OwnerTaskID = task_tgid_nr(current);
47882 +
47883 +       i = 0;
47884 +       for(ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE) 
47885 +       {
47886 +               (*ppBuffer)->uSysAddr.psNonCont[i++].uiAddr = vmalloc_to_pfn( pvBuf + ulCounter ) << PAGE_SHIFT;
47887 +       }
47888 +       
47889 +       psb_gtt_map_pvr_memory( psDevInfo->psDrmDevice, 
47890 +                                                       (unsigned int)*ppBuffer, 
47891 +                                                       (*ppBuffer)->ui32OwnerTaskID,
47892 +                                                       (IMG_CPU_PHYADDR*) (*ppBuffer)->uSysAddr.psNonCont, 
47893 +                                                       ulPagesNumber,
47894 +                                                       (unsigned int *)&(*ppBuffer)->sDevVAddr.uiAddr );
47895 +
47896 +       (*ppBuffer)->sDevVAddr.uiAddr <<= PAGE_SHIFT;
47897 +
47898 +       return MRST_OK; 
47899 +}
47900 +
47901 +MRST_ERROR MRSTLFBFreeBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, MRSTLFB_BUFFER **ppBuffer)
47902 +{
47903 +       if( !(*ppBuffer)->bIsAllocated )
47904 +               return MRST_ERROR_INVALID_PARAMS;
47905 +       
47906 +       psb_gtt_unmap_pvr_memory( psDevInfo->psDrmDevice, 
47907 +                                                         (unsigned int)*ppBuffer,
47908 +                                                         (*ppBuffer)->ui32OwnerTaskID);
47909 +
47910 +       vfree( (*ppBuffer)->sCPUVAddr );
47911 +
47912 +       MRSTLFBFreeKernelMem( (*ppBuffer)->uSysAddr.psNonCont );
47913 +       
47914 +       MRSTLFBFreeKernelMem( *ppBuffer);
47915 +
47916 +       *ppBuffer = NULL;
47917 +
47918 +       return MRST_OK; 
47919 +}
47920 +
47921 +
47922 +
47923 +PVRSRV_ERROR MRSTLFBPrePowerState(IMG_HANDLE            hDevHandle,
47924 +                                 PVRSRV_DEV_POWER_STATE eNewPowerState,
47925 +                                 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
47926 +{
47927 +       MRSTLFB_DEVINFO* psDevInfo = (MRSTLFB_DEVINFO *)hDevHandle;
47928 +       struct drm_device* dev = psDevInfo->psDrmDevice;
47929 +       struct drm_psb_private *dev_priv = dev->dev_private;
47930 +       int pp_stat, ret;
47931 +
47932 +       if ((eNewPowerState == eCurrentPowerState) ||
47933 +           (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON))
47934 +               return PVRSRV_OK;
47935 +
47936 +       save_display_registers(dev);
47937 +
47938 +       if (dev_priv->iLVDS_enable) {
47939 +               /*shutdown the panel*/
47940 +               PSB_WVDC32(0, PP_CONTROL);
47941 +
47942 +               do {
47943 +                       pp_stat = PSB_RVDC32(PP_STATUS);
47944 +               } while (pp_stat & 0x80000000);
47945 +
47946 +               /*turn off the plane*/
47947 +               PSB_WVDC32(0x58000000, DSPACNTR);
47948 +               PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/
47949 +               msleep(4);
47950 +
47951 +               /*turn off pipe*/
47952 +               PSB_WVDC32(0x0, PIPEACONF);
47953 +               msleep(8);
47954 +
47955 +               /*turn off PLLs*/
47956 +               PSB_WVDC32(0, MRST_DPLL_A);
47957 +       } else {
47958 +               PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG);
47959 +               PSB_WVDC32(0x0, PIPEACONF);
47960 +               PSB_WVDC32(0x2faf0000, BLC_PWM_CTL);
47961 +               while (REG_READ(0x70008) & 0x40000000);
47962 +               while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
47963 +                                                       != DPI_FIFO_EMPTY);
47964 +               PSB_WVDC32(0, DEVICE_READY_REG);
47965 +
47966 +               /* turn off mipi panel power */
47967 +               ret = lnw_ipc_single_cmd(IPC_MSG_PANEL_ON_OFF, IPC_CMD_PANEL_OFF, 0, 0);
47968 +               if (ret)
47969 +                       printk(KERN_WARNING "IPC 0xE9 failed to turn off pnl pwr. Error is: %x\n", ret);
47970 +       }
47971 +
47972 +       return PVRSRV_OK;
47973 +}
47974 +
47975 +
47976 +PVRSRV_ERROR MRSTLFBPostPowerState(IMG_HANDLE            hDevHandle,
47977 +                                  PVRSRV_DEV_POWER_STATE eNewPowerState,
47978 +                                  PVRSRV_DEV_POWER_STATE eCurrentPowerState)
47979 +{
47980 +       MRSTLFB_DEVINFO* psDevInfo = (MRSTLFB_DEVINFO *)hDevHandle;
47981 +       struct drm_device* dev = psDevInfo->psDrmDevice;
47982 +       struct drm_psb_private *dev_priv = dev->dev_private;
47983 +       struct psb_gtt *pg = dev_priv->pg;
47984 +       int ret;
47985 +
47986 +       if ((eNewPowerState == eCurrentPowerState) ||
47987 +           (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF))
47988 +               return PVRSRV_OK;
47989 +
47990 +       PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
47991 +       pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
47992 +                             pg->gmch_ctrl | _PSB_GMCH_ENABLED);
47993 +
47994 +       /* Don't reinitialize the GTT as it is unnecessary.  The gtt is
47995 +        * stored in memory so it will automatically be restored.  All
47996 +        * we need to do is restore the PGETBL_CTL which we already do
47997 +        * above.
47998 +        */
47999 +       /*psb_gtt_init(dev_priv->pg, 1);*/
48000 +
48001 +       if (!dev_priv->iLVDS_enable) {
48002 +               /* turn on mipi panel power */
48003 +               ret = lnw_ipc_single_cmd(IPC_MSG_PANEL_ON_OFF, IPC_CMD_PANEL_ON, 0, 0);
48004 +               if (ret)
48005 +                       printk(KERN_WARNING "IPC 0xE9 failed to turn on pnl pwr.  Error is: %x\n", ret);
48006 +               msleep(2000); /* wait 2 seconds */
48007 +       }
48008 +
48009 +       restore_display_registers(dev);
48010 +
48011 +       return PVRSRV_OK;
48012 +}
48013 diff --git a/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
48014 new file mode 100644
48015 index 0000000..6001a9c
48016 --- /dev/null
48017 +++ b/drivers/gpu/drm/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
48018 @@ -0,0 +1,206 @@
48019 +/**********************************************************************
48020 + *
48021 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
48022 + *
48023 + * This program is free software; you can redistribute it and/or modify it
48024 + * under the terms and conditions of the GNU General Public License,
48025 + * version 2, as published by the Free Software Foundation.
48026 + *
48027 + * This program is distributed in the hope it will be useful but, except
48028 + * as otherwise stated in writing, without any warranty; without even the
48029 + * implied warranty of merchantability or fitness for a particular purpose.
48030 + * See the GNU General Public License for more details.
48031 + *
48032 + * You should have received a copy of the GNU General Public License along with
48033 + * this program; if not, write to the Free Software Foundation, Inc.,
48034 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48035 + *
48036 + * The full GNU General Public License is included in this distribution in
48037 + * the file called "COPYING".
48038 + *
48039 + * Contact Information:
48040 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
48041 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
48042 + *
48043 + ******************************************************************************/
48044 +
48045 +#ifndef AUTOCONF_INCLUDED
48046 +#include <linux/config.h>
48047 +#endif
48048 +
48049 +#include <linux/version.h>
48050 +
48051 +#include <linux/pci.h>
48052 +#include <linux/slab.h>
48053 +#include <linux/errno.h>
48054 +#include <linux/interrupt.h>
48055 +
48056 +#include <drm/drmP.h>
48057 +
48058 +#include <asm/io.h>
48059 +
48060 +#include "img_defs.h"
48061 +#include "servicesext.h"
48062 +#include "kerneldisplay.h"
48063 +#include "pvrmodule.h"
48064 +#include "pvr_drm.h"
48065 +#include "mrstlfb.h"
48066 +#include "kerneldisplay.h"
48067 +#include "sysirq.h"
48068 +
48069 +#include "psb_drv.h"
48070 +
48071 +#if !defined(SUPPORT_DRI_DRM)
48072 +#error "SUPPORT_DRI_DRM must be set"
48073 +#endif
48074 +
48075 +#define        MAKESTRING(x) # x
48076 +
48077 +#if !defined(DISPLAY_CONTROLLER)
48078 +#define DISPLAY_CONTROLLER pvrlfb
48079 +#endif
48080 +
48081 +//#define MAKENAME_HELPER(x, y) x ## y
48082 +//#define      MAKENAME2(x, y) MAKENAME_HELPER(x, y)
48083 +//#define      MAKENAME(x) MAKENAME2(DISPLAY_CONTROLLER, x)
48084 +
48085 +#define unref__ __attribute__ ((unused))
48086 +
48087 +
48088 +extern int fb_idx;
48089 +
48090 +void *MRSTLFBAllocKernelMem(unsigned long ulSize)
48091 +{
48092 +       return kmalloc(ulSize, GFP_KERNEL);
48093 +}
48094 +
48095 +void MRSTLFBFreeKernelMem(void *pvMem)
48096 +{
48097 +       kfree(pvMem);
48098 +}
48099 +
48100 +
48101 +MRST_ERROR MRSTLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
48102 +{
48103 +       if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
48104 +       {
48105 +               return (MRST_ERROR_INVALID_PARAMS);
48106 +       }
48107 +
48108 +
48109 +       *ppfnFuncTable = PVRGetDisplayClassJTable;
48110 +
48111 +       return (MRST_OK);
48112 +}
48113 +
48114 +static void MRSTLFBVSyncWriteReg(MRSTLFB_DEVINFO *psDevInfo, unsigned long ulOffset, unsigned long ulValue)
48115 +{
48116 +
48117 +       void *pvRegAddr = (void *)(psDevInfo->pvRegs + ulOffset);
48118 +       mb();
48119 +       iowrite32(ulValue, pvRegAddr);
48120 +}
48121 +
48122 +unsigned long MRSTLFBVSyncReadReg(MRSTLFB_DEVINFO * psDevinfo, unsigned long ulOffset)
48123 +{
48124 +       mb();
48125 +       return ioread32((char *)psDevinfo->pvRegs + ulOffset);
48126 +}
48127 +
48128 +void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
48129 +{
48130 +#if defined(MRST_USING_INTERRUPTS)
48131 +
48132 +#if defined(SUPPORT_DRI_DRM)
48133 +
48134 +    struct drm_psb_private *dev_priv =
48135 +       (struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private;
48136 +    dev_priv->vblanksEnabledForFlips = true;
48137 +    sysirq_enable_vblank(psDevinfo->psDrmDevice, 0);
48138 +
48139 +#else
48140 +
48141 +    unsigned long vdc_irq_mask;
48142 +
48143 +    vdc_irq_mask = ~MRSTLFBVSyncReadReg( psDevinfo, PSB_INT_MASK_R);
48144 +    vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
48145 +
48146 +    MRSTLFBVSyncWriteReg(psDevinfo, PSB_INT_MASK_R, ~vdc_irq_mask);
48147 +    MRSTLFBVSyncWriteReg(psDevinfo, PSB_INT_ENABLE_R, vdc_irq_mask);
48148 +
48149 +    {
48150 +       unsigned int writeVal = MRSTLFBVSyncReadReg(psDevinfo, PIPEASTAT);
48151 +       unsigned int mask = PIPE_START_VBLANK_INTERRUPT_ENABLE |  PIPE_VBLANK_INTERRUPT_ENABLE;
48152 +
48153 +       writeVal |= (mask | (mask >> 16));
48154 +       MRSTLFBVSyncWriteReg(psDevinfo, PIPEASTAT, writeVal);
48155 +       MRSTLFBVSyncReadReg(psDevinfo, PIPEASTAT);
48156 +    }
48157 +#endif
48158 +#endif
48159 +}
48160 +
48161 +void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
48162 +{
48163 +#if defined(MRST_USING_INTERRUPTS)
48164 +    struct drm_device * dev = psDevinfo->psDrmDevice;
48165 +    struct drm_psb_private *dev_priv =
48166 +       (struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private;
48167 +    dev_priv->vblanksEnabledForFlips = false;
48168 +    //Only turn off if DRM isn't currently using vblanks, otherwise, leave on.
48169 +    if (!dev->vblank_enabled[0])
48170 +       sysirq_disable_vblank(psDevinfo->psDrmDevice, 0);
48171 +#endif
48172 +}
48173 +
48174 +#if defined(MRST_USING_INTERRUPTS)
48175 +MRST_ERROR MRSTLFBInstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo, MRSTLFB_VSYNC_ISR_PFN pVsyncHandler)
48176 +{
48177 +       //struct drm_psb_private *dev_priv =
48178 +       //    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
48179 +       //dev_priv->psb_vsync_handler = pVsyncHandler;
48180 +       return (MRST_OK);
48181 +}
48182 +
48183 +
48184 +MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO    *psDevInfo)
48185 +{
48186 +       //struct drm_psb_private *dev_priv =
48187 +       //    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
48188 +       //dev_priv->psb_vsync_handler = NULL;
48189 +       return (MRST_OK);
48190 +}
48191 +#endif 
48192 +
48193 +
48194 +void MRSTLFBFlip(MRSTLFB_DEVINFO *psDevInfo,  unsigned long uiAddr)
48195 +{
48196 +       int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE);
48197 +       int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF);
48198 +
48199 +       if (IS_MRST(psDevInfo->psDrmDevice)) {
48200 +               MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
48201 +       } else {
48202 +               MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr);
48203 +       }
48204 +}
48205 +
48206 +
48207 +int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
48208 +{
48209 +       if(MRSTLFBInit(dev) != MRST_OK)
48210 +       {
48211 +               printk(KERN_WARNING DRIVER_PREFIX ": MRSTLFB_Init: MRSTLFBInit failed\n");
48212 +               return -ENODEV;
48213 +       }
48214 +
48215 +       return 0;
48216 +}
48217 +
48218 +void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev)
48219 +{    
48220 +       if(MRSTLFBDeinit() != MRST_OK)
48221 +       {
48222 +               printk(KERN_WARNING DRIVER_PREFIX "%s: can't deinit device\n", __FUNCTION__);
48223 +       }
48224 +}
48225 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/env/linux/pvr_drm_shared.h b/drivers/gpu/drm/mrst/pvr/services4/include/env/linux/pvr_drm_shared.h
48226 new file mode 100644
48227 index 0000000..573d9b9
48228 --- /dev/null
48229 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/env/linux/pvr_drm_shared.h
48230 @@ -0,0 +1,54 @@
48231 +/**********************************************************************
48232 + *
48233 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
48234 + *
48235 + * This program is free software; you can redistribute it and/or modify it
48236 + * under the terms and conditions of the GNU General Public License,
48237 + * version 2, as published by the Free Software Foundation.
48238 + *
48239 + * This program is distributed in the hope it will be useful but, except
48240 + * as otherwise stated in writing, without any warranty; without even the
48241 + * implied warranty of merchantability or fitness for a particular purpose.
48242 + * See the GNU General Public License for more details.
48243 + *
48244 + * You should have received a copy of the GNU General Public License along with
48245 + * this program; if not, write to the Free Software Foundation, Inc.,
48246 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48247 + *
48248 + * The full GNU General Public License is included in this distribution in
48249 + * the file called "COPYING".
48250 + *
48251 + * Contact Information:
48252 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
48253 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
48254 + *
48255 + ******************************************************************************/
48256 +
48257 +#if !defined(__PVR_DRM_SHARED_H__)
48258 +#define __PVR_DRM_SHARED_H__
48259 +
48260 +#if defined(SUPPORT_DRI_DRM)
48261 +
48262 +#define PVR_DRM_SRVKM_CMD      0x12
48263 +#define        PVR_DRM_DISP_CMD        0x13
48264 +#define        PVR_DRM_BC_CMD          0x14
48265 +#define PVR_DRM_IS_MASTER_CMD  0x15
48266 +#define PVR_DRM_UNPRIV_CMD     0x16
48267 +#define PVR_DRM_DBGDRV_CMD     0x1E
48268 +
48269 +#define        PVR_DRM_UNPRIV_INIT_SUCCESFUL   0
48270 +#define        PVR_DRM_UNPRIV_BUSID_TYPE       1
48271 +#define        PVR_DRM_UNPRIV_BUSID_FIELD      2
48272 +
48273 +#define        PVR_DRM_BUS_TYPE_PCI            0
48274 +
48275 +#define        PVR_DRM_PCI_DOMAIN              0
48276 +#define        PVR_DRM_PCI_BUS                 1
48277 +#define        PVR_DRM_PCI_DEV                 2
48278 +#define        PVR_DRM_PCI_FUNC                3
48279 +
48280 +#endif
48281 +
48282 +#endif
48283 +
48284 +
48285 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/kernelbuffer.h b/drivers/gpu/drm/mrst/pvr/services4/include/kernelbuffer.h
48286 new file mode 100644
48287 index 0000000..33aa49c
48288 --- /dev/null
48289 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/kernelbuffer.h
48290 @@ -0,0 +1,60 @@
48291 +/**********************************************************************
48292 + *
48293 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
48294 + *
48295 + * This program is free software; you can redistribute it and/or modify it
48296 + * under the terms and conditions of the GNU General Public License,
48297 + * version 2, as published by the Free Software Foundation.
48298 + *
48299 + * This program is distributed in the hope it will be useful but, except
48300 + * as otherwise stated in writing, without any warranty; without even the
48301 + * implied warranty of merchantability or fitness for a particular purpose.
48302 + * See the GNU General Public License for more details.
48303 + *
48304 + * You should have received a copy of the GNU General Public License along with
48305 + * this program; if not, write to the Free Software Foundation, Inc.,
48306 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48307 + *
48308 + * The full GNU General Public License is included in this distribution in
48309 + * the file called "COPYING".
48310 + *
48311 + * Contact Information:
48312 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
48313 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
48314 + *
48315 + ******************************************************************************/
48316 +
48317 +#if !defined (__KERNELBUFFER_H__)
48318 +#define __KERNELBUFFER_H__
48319 +
48320 +typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_HANDLE*);
48321 +typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_HANDLE);
48322 +typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*);
48323 +typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*);
48324 +
48325 +typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG
48326 +{
48327 +       IMG_UINT32                                                      ui32TableSize;
48328 +       PFN_OPEN_BC_DEVICE                                      pfnOpenBCDevice;
48329 +       PFN_CLOSE_BC_DEVICE                                     pfnCloseBCDevice;
48330 +       PFN_GET_BC_INFO                                         pfnGetBCInfo;
48331 +       PFN_GET_BC_BUFFER                                       pfnGetBCBuffer;
48332 +       PFN_GET_BUFFER_ADDR                                     pfnGetBufferAddr;
48333 +
48334 +} PVRSRV_BC_SRV2BUFFER_KMJTABLE;
48335 +
48336 +
48337 +typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*);
48338 +typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32);
48339 +
48340 +typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG
48341 +{
48342 +       IMG_UINT32                                                      ui32TableSize;
48343 +       PFN_BC_REGISTER_BUFFER_DEV                      pfnPVRSRVRegisterBCDevice;
48344 +       PFN_BC_REMOVE_BUFFER_DEV                        pfnPVRSRVRemoveBCDevice;
48345 +
48346 +} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE;
48347 +
48348 +typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE);
48349 +
48350 +#endif
48351 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/kerneldisplay.h b/drivers/gpu/drm/mrst/pvr/services4/include/kerneldisplay.h
48352 new file mode 100644
48353 index 0000000..f735503
48354 --- /dev/null
48355 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/kerneldisplay.h
48356 @@ -0,0 +1,153 @@
48357 +/**********************************************************************
48358 + *
48359 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
48360 + *
48361 + * This program is free software; you can redistribute it and/or modify it
48362 + * under the terms and conditions of the GNU General Public License,
48363 + * version 2, as published by the Free Software Foundation.
48364 + *
48365 + * This program is distributed in the hope it will be useful but, except
48366 + * as otherwise stated in writing, without any warranty; without even the
48367 + * implied warranty of merchantability or fitness for a particular purpose.
48368 + * See the GNU General Public License for more details.
48369 + *
48370 + * You should have received a copy of the GNU General Public License along with
48371 + * this program; if not, write to the Free Software Foundation, Inc.,
48372 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48373 + *
48374 + * The full GNU General Public License is included in this distribution in
48375 + * the file called "COPYING".
48376 + *
48377 + * Contact Information:
48378 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
48379 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
48380 + *
48381 + ******************************************************************************/
48382 +
48383 +#if !defined (__KERNELDISPLAY_H__)
48384 +#define __KERNELDISPLAY_H__
48385 +
48386 +typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);
48387 +typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);
48388 +typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);
48389 +typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,
48390 +                                                                                DISPLAY_FORMAT*,
48391 +                                                                                IMG_UINT32*,
48392 +                                                                                DISPLAY_DIMS*);
48393 +typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);
48394 +typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);
48395 +typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,
48396 +                                                                                               IMG_UINT32,
48397 +                                                                                               DISPLAY_SURF_ATTRIBUTES*,
48398 +                                                                                               DISPLAY_SURF_ATTRIBUTES*,
48399 +                                                                                               IMG_UINT32,
48400 +                                                                                               PVRSRV_SYNC_DATA**,
48401 +                                                                                               IMG_UINT32,
48402 +                                                                                               IMG_HANDLE*,
48403 +                                                                                               IMG_UINT32*);
48404 +typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE,
48405 +                                                                                                IMG_HANDLE);
48406 +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
48407 +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
48408 +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
48409 +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
48410 +typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,
48411 +                                                                                  IMG_HANDLE,
48412 +                                                                                  IMG_UINT32*,
48413 +                                                                                  IMG_HANDLE*);
48414 +typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,
48415 +                                                                                         IMG_HANDLE,
48416 +                                                                                         IMG_UINT32,
48417 +                                                                                         IMG_HANDLE,
48418 +                                                                                         IMG_UINT32,
48419 +                                                                                         IMG_RECT*);
48420 +typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE);
48421 +typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);
48422 +
48423 +typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG
48424 +{
48425 +       IMG_UINT32                                              ui32TableSize;
48426 +       PFN_OPEN_DC_DEVICE                              pfnOpenDCDevice;
48427 +       PFN_CLOSE_DC_DEVICE                             pfnCloseDCDevice;
48428 +       PFN_ENUM_DC_FORMATS                             pfnEnumDCFormats;
48429 +       PFN_ENUM_DC_DIMS                                pfnEnumDCDims;
48430 +       PFN_GET_DC_SYSTEMBUFFER                 pfnGetDCSystemBuffer;
48431 +       PFN_GET_DC_INFO                                 pfnGetDCInfo;
48432 +       PFN_GET_BUFFER_ADDR                             pfnGetBufferAddr;
48433 +       PFN_CREATE_DC_SWAPCHAIN                 pfnCreateDCSwapChain;
48434 +       PFN_DESTROY_DC_SWAPCHAIN                pfnDestroyDCSwapChain;
48435 +       PFN_SET_DC_DSTRECT                              pfnSetDCDstRect;
48436 +       PFN_SET_DC_SRCRECT                              pfnSetDCSrcRect;
48437 +       PFN_SET_DC_DSTCK                                pfnSetDCDstColourKey;
48438 +       PFN_SET_DC_SRCCK                                pfnSetDCSrcColourKey;
48439 +       PFN_GET_DC_BUFFERS                              pfnGetDCBuffers;
48440 +       PFN_SWAP_TO_DC_BUFFER                   pfnSwapToDCBuffer;
48441 +       PFN_SWAP_TO_DC_SYSTEM                   pfnSwapToDCSystem;
48442 +       PFN_SET_DC_STATE                                pfnSetDCState;
48443 +
48444 +} PVRSRV_DC_SRV2DISP_KMJTABLE;
48445 +
48446 +typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);
48447 +
48448 +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);
48449 +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);
48450 +typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);
48451 +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);
48452 +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);
48453 +typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);
48454 +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);
48455 +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,
48456 +                                                                                         PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
48457 +                                                                                         IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
48458 +
48459 +typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
48460 +{
48461 +       IMG_UINT32                                              ui32TableSize;
48462 +       PFN_DC_REGISTER_DISPLAY_DEV             pfnPVRSRVRegisterDCDevice;
48463 +       PFN_DC_REMOVE_DISPLAY_DEV               pfnPVRSRVRemoveDCDevice;
48464 +       PFN_DC_OEM_FUNCTION                             pfnPVRSRVOEMFunction;
48465 +       PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList;
48466 +       PFN_DC_REMOVE_COMMANDPROCLIST   pfnPVRSRVRemoveCmdProcList;
48467 +       PFN_DC_CMD_COMPLETE                             pfnPVRSRVCmdComplete;
48468 +       PFN_DC_REGISTER_SYS_ISR                 pfnPVRSRVRegisterSystemISRHandler;
48469 +       PFN_DC_REGISTER_POWER                   pfnPVRSRVRegisterPowerDevice;
48470 +} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
48471 +
48472 +
48473 +typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG
48474 +{
48475 +
48476 +       IMG_HANDLE hExtDevice;
48477 +
48478 +
48479 +       IMG_HANDLE hExtSwapChain;
48480 +
48481 +
48482 +       IMG_HANDLE hExtBuffer;
48483 +
48484 +
48485 +       IMG_HANDLE hPrivateTag;
48486 +
48487 +
48488 +       IMG_UINT32 ui32ClipRectCount;
48489 +
48490 +
48491 +       IMG_RECT *psClipRect;
48492 +
48493 +
48494 +       IMG_UINT32      ui32SwapInterval;
48495 +
48496 +} DISPLAYCLASS_FLIP_COMMAND;
48497 +
48498 +#define DC_FLIP_COMMAND                0
48499 +
48500 +#define DC_STATE_NO_FLUSH_COMMANDS             0
48501 +#define DC_STATE_FLUSH_COMMANDS                        1
48502 +
48503 +
48504 +typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);
48505 +
48506 +
48507 +
48508 +#endif
48509 +
48510 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge.h b/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge.h
48511 new file mode 100644
48512 index 0000000..3893db7
48513 --- /dev/null
48514 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge.h
48515 @@ -0,0 +1,1383 @@
48516 +/**********************************************************************
48517 + *
48518 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
48519 + *
48520 + * This program is free software; you can redistribute it and/or modify it
48521 + * under the terms and conditions of the GNU General Public License,
48522 + * version 2, as published by the Free Software Foundation.
48523 + *
48524 + * This program is distributed in the hope it will be useful but, except
48525 + * as otherwise stated in writing, without any warranty; without even the
48526 + * implied warranty of merchantability or fitness for a particular purpose.
48527 + * See the GNU General Public License for more details.
48528 + *
48529 + * You should have received a copy of the GNU General Public License along with
48530 + * this program; if not, write to the Free Software Foundation, Inc.,
48531 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48532 + *
48533 + * The full GNU General Public License is included in this distribution in
48534 + * the file called "COPYING".
48535 + *
48536 + * Contact Information:
48537 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
48538 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
48539 + *
48540 + ******************************************************************************/
48541 +
48542 +#ifndef __PVR_BRIDGE_H__
48543 +#define __PVR_BRIDGE_H__
48544 +
48545 +#if defined (__cplusplus)
48546 +extern "C" {
48547 +#endif
48548 +
48549 +#include "servicesint.h"
48550 +
48551 +#ifdef __linux__
48552 +
48553 +               #include <linux/ioctl.h>
48554 +
48555 +    #define PVRSRV_IOC_GID      'g'
48556 +    #define PVRSRV_IO(INDEX)    _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
48557 +    #define PVRSRV_IOW(INDEX)   _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
48558 +    #define PVRSRV_IOR(INDEX)   _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
48559 +    #define PVRSRV_IOWR(INDEX)  _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE)
48560 +
48561 +#else
48562 +
48563 +                       #error Unknown platform: Cannot define ioctls
48564 +
48565 +       #define PVRSRV_IO(INDEX)    (PVRSRV_IOC_GID + INDEX)
48566 +       #define PVRSRV_IOW(INDEX)   (PVRSRV_IOC_GID + INDEX)
48567 +       #define PVRSRV_IOR(INDEX)   (PVRSRV_IOC_GID + INDEX)
48568 +       #define PVRSRV_IOWR(INDEX)  (PVRSRV_IOC_GID + INDEX)
48569 +
48570 +       #define PVRSRV_BRIDGE_BASE                  PVRSRV_IOC_GID
48571 +#endif
48572 +
48573 +
48574 +#define PVRSRV_BRIDGE_CORE_CMD_FIRST                   0UL
48575 +#define PVRSRV_BRIDGE_ENUM_DEVICES                             PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0)
48576 +#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO               PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1)
48577 +#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO               PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2)
48578 +#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT             PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3)
48579 +#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT            PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4)
48580 +#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO              PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5)
48581 +#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM                  PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6)
48582 +#define PVRSRV_BRIDGE_FREE_DEVICEMEM                   PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7)
48583 +#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM                        PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8)
48584 +#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE              PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9)
48585 +#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE             PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10)
48586 +#define        PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA           PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11)
48587 +#define PVRSRV_BRIDGE_CONNECT_SERVICES                 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12)
48588 +#define PVRSRV_BRIDGE_DISCONNECT_SERVICES              PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13)
48589 +#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM                  PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14)
48590 +#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO                        PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15)
48591 +#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM              PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16)
48592 +#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM                 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17)
48593 +#define PVRSRV_BRIDGE_MAP_EXT_MEMORY                   PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18)
48594 +#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY                 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19)
48595 +#define PVRSRV_BRIDGE_MAP_DEV_MEMORY                   PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20)
48596 +#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY                 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21)
48597 +#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY   PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22)
48598 +#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23)
48599 +#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER             PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24)
48600 +#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25)
48601 +#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM                 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26)
48602 +#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA                        PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
48603 +#define PVRSRV_BRIDGE_CORE_CMD_LAST                            (PVRSRV_BRIDGE_CORE_CMD_FIRST+27)
48604 +
48605 +#define PVRSRV_BRIDGE_SIM_CMD_FIRST                            (PVRSRV_BRIDGE_CORE_CMD_LAST+1)
48606 +#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT             PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0)
48607 +#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS             PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1)
48608 +#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS   PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
48609 +#define PVRSRV_BRIDGE_SIM_CMD_LAST                             (PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
48610 +
48611 +#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST                        (PVRSRV_BRIDGE_SIM_CMD_LAST+1)
48612 +#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE               PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0)
48613 +#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE             PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1)
48614 +#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP            PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
48615 +#define PVRSRV_BRIDGE_MAPPING_CMD_LAST                 (PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2)
48616 +
48617 +#define PVRSRV_BRIDGE_STATS_CMD_FIRST                  (PVRSRV_BRIDGE_MAPPING_CMD_LAST+1)
48618 +#define        PVRSRV_BRIDGE_GET_FB_STATS                              PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
48619 +#define PVRSRV_BRIDGE_STATS_CMD_LAST                   (PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
48620 +
48621 +#define PVRSRV_BRIDGE_MISC_CMD_FIRST                   (PVRSRV_BRIDGE_STATS_CMD_LAST+1)
48622 +#define PVRSRV_BRIDGE_GET_MISC_INFO                            PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0)
48623 +#define PVRSRV_BRIDGE_RELEASE_MISC_INFO                        PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
48624 +#define PVRSRV_BRIDGE_MISC_CMD_LAST                            (PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
48625 +
48626 +#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST                        (PVRSRV_BRIDGE_MISC_CMD_LAST+1)
48627 +#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
48628 +#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES              PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0)
48629 +#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES            PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
48630 +#endif
48631 +#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST                 (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
48632 +
48633 +#if defined(PDUMP)
48634 +#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST                  (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
48635 +#define PVRSRV_BRIDGE_PDUMP_INIT                       PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0)
48636 +#define PVRSRV_BRIDGE_PDUMP_MEMPOL                     PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1)
48637 +#define PVRSRV_BRIDGE_PDUMP_DUMPMEM                    PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2)
48638 +#define PVRSRV_BRIDGE_PDUMP_REG                                PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3)
48639 +#define PVRSRV_BRIDGE_PDUMP_REGPOL                     PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4)
48640 +#define PVRSRV_BRIDGE_PDUMP_COMMENT                    PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5)
48641 +#define PVRSRV_BRIDGE_PDUMP_SETFRAME                   PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6)
48642 +#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING                        PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7)
48643 +#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP                 PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8)
48644 +#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG                        PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9)
48645 +#define PVRSRV_BRIDGE_PDUMP_SYNCPOL                    PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10)
48646 +#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC                   PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11)
48647 +#define PVRSRV_BRIDGE_PDUMP_MEMPAGES                   PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12)
48648 +#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO                 PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13)
48649 +#define PVRSRV_BRIDGE_PDUMP_PDREG                      PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+14)
48650 +#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR             PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15)
48651 +#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ       PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16)
48652 +#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE                     PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17)
48653 +#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE                      PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
48654 +#define PVRSRV_BRIDGE_PDUMP_CMD_LAST                   (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18)
48655 +#else
48656 +#define PVRSRV_BRIDGE_PDUMP_CMD_LAST                   PVRSRV_BRIDGE_OVERLAY_CMD_LAST
48657 +#endif
48658 +
48659 +#define PVRSRV_BRIDGE_OEM_CMD_FIRST                            (PVRSRV_BRIDGE_PDUMP_CMD_LAST+1)
48660 +#define PVRSRV_BRIDGE_GET_OEMJTABLE                            PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
48661 +#define PVRSRV_BRIDGE_OEM_CMD_LAST                             (PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
48662 +
48663 +#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST               (PVRSRV_BRIDGE_OEM_CMD_LAST+1)
48664 +#define PVRSRV_BRIDGE_ENUM_CLASS                               PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
48665 +#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST                        (PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0)
48666 +
48667 +#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST              (PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1)
48668 +#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE            PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0)
48669 +#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE   PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1)
48670 +#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS   PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2)
48671 +#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS              PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3)
48672 +#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER  PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4)
48673 +#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO               PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5)
48674 +#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN               PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6)
48675 +#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN              PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7)
48676 +#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT            PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8)
48677 +#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT            PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9)
48678 +#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY               PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10)
48679 +#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY               PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11)
48680 +#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS            PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12)
48681 +#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13)
48682 +#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
48683 +#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST               (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
48684 +
48685 +
48686 +#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST               (PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1)
48687 +#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE  PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0)
48688 +#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1)
48689 +#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO             PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2)
48690 +#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER   PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
48691 +#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST                        (PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3)
48692 +
48693 +#define PVRSRV_BRIDGE_WRAP_CMD_FIRST                   (PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1)
48694 +#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY                  PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0)
48695 +#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY                        PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
48696 +#define PVRSRV_BRIDGE_WRAP_CMD_LAST                            (PVRSRV_BRIDGE_WRAP_CMD_FIRST+1)
48697 +
48698 +#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST              (PVRSRV_BRIDGE_WRAP_CMD_LAST+1)
48699 +#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM             PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0)
48700 +#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM              PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1)
48701 +#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM                  PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2)
48702 +#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM                        PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
48703 +#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST               (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
48704 +
48705 +#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST  (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
48706 +#define PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR        PVRSRV_IOWR(PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
48707 +#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST   (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
48708 +
48709 +#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST                        (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST+1)
48710 +#define PVRSRV_BRIDGE_INITSRV_CONNECT                  PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0)
48711 +#define PVRSRV_BRIDGE_INITSRV_DISCONNECT               PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
48712 +#define PVRSRV_BRIDGE_INITSRV_CMD_LAST                 (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
48713 +
48714 +#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST   (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1)
48715 +#define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT                        PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0)
48716 +#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN                        PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1)
48717 +#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE               PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
48718 +#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST            (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2)
48719 +
48720 +#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST               (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1)
48721 +#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS  PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0)
48722 +#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
48723 +#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST                        (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
48724 +
48725 +#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD              (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1)
48726 +
48727 +
48728 +#define PVRSRV_KERNEL_MODE_CLIENT                              1
48729 +
48730 +typedef struct PVRSRV_BRIDGE_RETURN_TAG
48731 +{
48732 +       PVRSRV_ERROR eError;
48733 +       IMG_VOID *pvData;
48734 +
48735 +}PVRSRV_BRIDGE_RETURN;
48736 +
48737 +
48738 +typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
48739 +{
48740 +       IMG_UINT32                              ui32BridgeID;
48741 +       IMG_UINT32                              ui32Size;
48742 +       IMG_VOID                                *pvParamIn;
48743 +       IMG_UINT32                              ui32InBufferSize;
48744 +       IMG_VOID                                *pvParamOut;
48745 +       IMG_UINT32                              ui32OutBufferSize;
48746 +
48747 +       IMG_HANDLE                              hKernelServices;
48748 +}PVRSRV_BRIDGE_PACKAGE;
48749 +
48750 +
48751 +
48752 +
48753 +
48754 +typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG
48755 +{
48756 +       IMG_UINT32                      ui32BridgeFlags;
48757 +       IMG_UINT32                      uiDevIndex;
48758 +       PVRSRV_DEVICE_TYPE      eDeviceType;
48759 +
48760 +} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO;
48761 +
48762 +
48763 +typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG
48764 +{
48765 +       IMG_UINT32                      ui32BridgeFlags;
48766 +       PVRSRV_DEVICE_CLASS sDeviceClass;
48767 +} PVRSRV_BRIDGE_IN_ENUMCLASS;
48768 +
48769 +
48770 +typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG
48771 +{
48772 +       IMG_UINT32                      ui32BridgeFlags;
48773 +       IMG_HANDLE                      hDeviceKM;
48774 +} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE;
48775 +
48776 +
48777 +typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG
48778 +{
48779 +       IMG_UINT32                      ui32BridgeFlags;
48780 +       IMG_HANDLE                      hDeviceKM;
48781 +} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS;
48782 +
48783 +
48784 +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG
48785 +{
48786 +       IMG_UINT32                      ui32BridgeFlags;
48787 +       IMG_HANDLE                      hDeviceKM;
48788 +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER;
48789 +
48790 +
48791 +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG
48792 +{
48793 +       IMG_UINT32                      ui32BridgeFlags;
48794 +       IMG_HANDLE                      hDeviceKM;
48795 +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO;
48796 +
48797 +
48798 +typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG
48799 +{
48800 +       IMG_UINT32                      ui32BridgeFlags;
48801 +       IMG_HANDLE                      hDeviceKM;
48802 +} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE;
48803 +
48804 +
48805 +typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG
48806 +{
48807 +       IMG_UINT32                      ui32BridgeFlags;
48808 +       IMG_HANDLE                      hDeviceKM;
48809 +} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO;
48810 +
48811 +
48812 +
48813 +typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG
48814 +{
48815 +       IMG_UINT32                      ui32BridgeFlags;
48816 +       IMG_HANDLE                      hDevCookie;
48817 +
48818 +} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO;
48819 +
48820 +
48821 +
48822 +typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG
48823 +{
48824 +       IMG_UINT32                      ui32BridgeFlags;
48825 +       PVRSRV_DEVICE_CLASS DeviceClass;
48826 +       IMG_VOID*                       pvDevInfo;
48827 +
48828 +}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO;
48829 +
48830 +
48831 +
48832 +typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG
48833 +{
48834 +       IMG_UINT32                      ui32BridgeFlags;
48835 +       IMG_HANDLE                      hDevCookie;
48836 +       IMG_HANDLE                      hDevMemContext;
48837 +
48838 +}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO;
48839 +
48840 +
48841 +
48842 +typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG
48843 +{
48844 +       IMG_UINT32                      ui32BridgeFlags;
48845 +       IMG_HANDLE                      hDevCookie;
48846 +
48847 +}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT;
48848 +
48849 +
48850 +
48851 +typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG
48852 +{
48853 +       IMG_UINT32                      ui32BridgeFlags;
48854 +       IMG_HANDLE                      hDevCookie;
48855 +       IMG_HANDLE                      hDevMemContext;
48856 +
48857 +}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT;
48858 +
48859 +
48860 +
48861 +typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG
48862 +{
48863 +       IMG_UINT32                      ui32BridgeFlags;
48864 +       IMG_HANDLE                      hDevCookie;
48865 +       IMG_HANDLE                      hDevMemHeap;
48866 +       IMG_UINT32                      ui32Attribs;
48867 +       IMG_SIZE_T                      ui32Size;
48868 +       IMG_SIZE_T                      ui32Alignment;
48869 +
48870 +}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM;
48871 +
48872 +
48873 +typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG
48874 +{
48875 +       IMG_UINT32                              ui32BridgeFlags;
48876 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48877 +
48878 +}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER;
48879 +
48880 +
48881 +typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG
48882 +{
48883 +       IMG_UINT32                              ui32BridgeFlags;
48884 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48885 +       IMG_PVOID                                pvLinAddr;
48886 +       IMG_HANDLE                               hMappingInfo;
48887 +
48888 +}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER;
48889 +
48890 +
48891 +typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG
48892 +{
48893 +       IMG_UINT32                              ui32BridgeFlags;
48894 +       IMG_HANDLE                              hDevCookie;
48895 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48896 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
48897 +
48898 +}PVRSRV_BRIDGE_IN_FREEDEVICEMEM;
48899 +
48900 +
48901 +typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG
48902 +{
48903 +       IMG_UINT32                              ui32BridgeFlags;
48904 +       IMG_HANDLE                              hDevCookie;
48905 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48906 +
48907 +}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM;
48908 +
48909 +
48910 +typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG
48911 +{
48912 +       IMG_UINT32                      ui32BridgeFlags;
48913 +       IMG_UINT32                      ui32Flags;
48914 +
48915 +} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM;
48916 +
48917 +
48918 +typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG
48919 +{
48920 +       IMG_UINT32                      ui32BridgeFlags;
48921 +       IMG_HANDLE                      hDevCookie;
48922 +       IMG_SIZE_T                      ui32QueueSize;
48923 +
48924 +}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE;
48925 +
48926 +
48927 +
48928 +typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG
48929 +{
48930 +       IMG_UINT32                      ui32BridgeFlags;
48931 +       IMG_HANDLE                      hDevCookie;
48932 +       PVRSRV_QUEUE_INFO       *psQueueInfo;
48933 +
48934 +}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE;
48935 +
48936 +
48937 +
48938 +typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG
48939 +{
48940 +       IMG_UINT32                      ui32BridgeFlags;
48941 +       IMG_HANDLE                      hMHandle;
48942 +} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA;
48943 +
48944 +
48945 +
48946 +typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG
48947 +{
48948 +       IMG_UINT32                      ui32BridgeFlags;
48949 +       IMG_HANDLE                      hMHandle;
48950 +} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA;
48951 +
48952 +
48953 +
48954 +typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG
48955 +{
48956 +       IMG_UINT32                      ui32BridgeFlags;
48957 +       IMG_HANDLE                      hDevMemHeap;
48958 +       IMG_DEV_VIRTADDR        *psDevVAddr;
48959 +       IMG_SIZE_T                      ui32Size;
48960 +       IMG_SIZE_T                      ui32Alignment;
48961 +
48962 +}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM;
48963 +
48964 +
48965 +typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG
48966 +{
48967 +       PVRSRV_ERROR                    eError;
48968 +       IMG_HANDLE              hKernelServices;
48969 +}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES;
48970 +
48971 +
48972 +typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG
48973 +{
48974 +       PVRSRV_ERROR                    eError;
48975 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48976 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
48977 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
48978 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
48979 +
48980 +}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM;
48981 +
48982 +
48983 +
48984 +typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG
48985 +{
48986 +       IMG_UINT32                              ui32BridgeFlags;
48987 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
48988 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
48989 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
48990 +
48991 +}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM;
48992 +
48993 +
48994 +
48995 +typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG
48996 +{
48997 +       IMG_UINT32                              ui32BridgeFlags;
48998 +       IMG_HANDLE                              hKernelMemInfo;
48999 +       IMG_HANDLE                              hDstDevMemHeap;
49000 +
49001 +}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY;
49002 +
49003 +
49004 +
49005 +typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG
49006 +{
49007 +       PVRSRV_ERROR                    eError;
49008 +       PVRSRV_KERNEL_MEM_INFO  *psDstKernelMemInfo;
49009 +       PVRSRV_KERNEL_SYNC_INFO *psDstKernelSyncInfo;
49010 +       PVRSRV_CLIENT_MEM_INFO  sDstClientMemInfo;
49011 +       PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo;
49012 +
49013 +}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY;
49014 +
49015 +
49016 +
49017 +typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG
49018 +{
49019 +       IMG_UINT32                                      ui32BridgeFlags;
49020 +       PVRSRV_KERNEL_MEM_INFO          *psKernelMemInfo;
49021 +       PVRSRV_CLIENT_MEM_INFO          sClientMemInfo;
49022 +       PVRSRV_CLIENT_SYNC_INFO         sClientSyncInfo;
49023 +
49024 +}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY;
49025 +
49026 +
49027 +
49028 +typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG
49029 +{
49030 +       IMG_UINT32                              ui32BridgeFlags;
49031 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49032 +       IMG_SYS_PHYADDR                 *psSysPAddr;
49033 +       IMG_UINT32                              ui32Flags;
49034 +
49035 +}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY;
49036 +
49037 +
49038 +typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG
49039 +{
49040 +       IMG_UINT32                                      ui32BridgeFlags;
49041 +       PVRSRV_CLIENT_MEM_INFO          sClientMemInfo;
49042 +       PVRSRV_CLIENT_SYNC_INFO         sClientSyncInfo;
49043 +       IMG_UINT32                                      ui32Flags;
49044 +
49045 +}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY;
49046 +
49047 +
49048 +typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG
49049 +{
49050 +       IMG_UINT32                                      ui32BridgeFlags;
49051 +       IMG_HANDLE              hDeviceClassBuffer;
49052 +       IMG_HANDLE              hDevMemContext;
49053 +
49054 +}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY;
49055 +
49056 +
49057 +
49058 +typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG
49059 +{
49060 +       PVRSRV_ERROR                    eError;
49061 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49062 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49063 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49064 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
49065 +       IMG_HANDLE                              hMappingInfo;
49066 +
49067 +}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY;
49068 +
49069 +
49070 +
49071 +typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG
49072 +{
49073 +       IMG_UINT32                              ui32BridgeFlags;
49074 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49075 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49076 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49077 +
49078 +}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY;
49079 +
49080 +
49081 +
49082 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG
49083 +{
49084 +       IMG_UINT32 ui32BridgeFlags;
49085 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49086 +       IMG_UINT32 ui32Offset;
49087 +       IMG_UINT32 ui32Value;
49088 +       IMG_UINT32 ui32Mask;
49089 +       IMG_UINT32 ui32Flags;
49090 +
49091 +}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL;
49092 +
49093 +
49094 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG
49095 +{
49096 +       IMG_UINT32 ui32BridgeFlags;
49097 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
49098 +       IMG_BOOL bIsRead;
49099 +       IMG_UINT32 ui32Value;
49100 +       IMG_UINT32 ui32Mask;
49101 +
49102 +}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL;
49103 +
49104 +
49105 +
49106 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG
49107 +{
49108 +       IMG_UINT32 ui32BridgeFlags;
49109 +       IMG_PVOID pvLinAddr;
49110 +       IMG_PVOID pvAltLinAddr;
49111 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49112 +       IMG_UINT32 ui32Offset;
49113 +       IMG_UINT32 ui32Bytes;
49114 +       IMG_UINT32 ui32Flags;
49115 +
49116 +}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM;
49117 +
49118 +
49119 +
49120 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG
49121 +{
49122 +       IMG_UINT32 ui32BridgeFlags;
49123 +       IMG_PVOID pvAltLinAddr;
49124 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
49125 +       IMG_UINT32 ui32Offset;
49126 +       IMG_UINT32 ui32Bytes;
49127 +
49128 +}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC;
49129 +
49130 +
49131 +
49132 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG
49133 +{
49134 +       IMG_UINT32 ui32BridgeFlags;
49135 +       PVRSRV_HWREG sHWReg;
49136 +       IMG_UINT32 ui32Flags;
49137 +
49138 +}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG;
49139 +
49140 +
49141 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG
49142 +{
49143 +       IMG_UINT32 ui32BridgeFlags;
49144 +       PVRSRV_HWREG sHWReg;
49145 +       IMG_UINT32 ui32Mask;
49146 +       IMG_UINT32 ui32Flags;
49147 +}PVRSRV_BRIDGE_IN_PDUMP_REGPOL;
49148 +
49149 +
49150 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG
49151 +{
49152 +       IMG_UINT32 ui32BridgeFlags;
49153 +       PVRSRV_HWREG sHWReg;
49154 +       IMG_UINT32 ui32Flags;
49155 +
49156 +}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG;
49157 +
49158 +
49159 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG
49160 +{
49161 +       IMG_UINT32                      ui32BridgeFlags;
49162 +       IMG_HANDLE                      hKernelMemInfo;
49163 +       IMG_DEV_PHYADDR         *pPages;
49164 +       IMG_UINT32                      ui32NumPages;
49165 +       IMG_DEV_VIRTADDR        sDevAddr;
49166 +       IMG_UINT32                      ui32Start;
49167 +       IMG_UINT32                      ui32Length;
49168 +       IMG_BOOL                        bContinuous;
49169 +
49170 +}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES;
49171 +
49172 +
49173 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG
49174 +{
49175 +       IMG_UINT32 ui32BridgeFlags;
49176 +       IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
49177 +       IMG_UINT32 ui32Flags;
49178 +
49179 +}PVRSRV_BRIDGE_IN_PDUMP_COMMENT;
49180 +
49181 +
49182 +
49183 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG
49184 +{
49185 +       IMG_UINT32 ui32BridgeFlags;
49186 +       IMG_UINT32 ui32Frame;
49187 +
49188 +}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME;
49189 +
49190 +
49191 +
49192 +
49193 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG
49194 +{
49195 +       IMG_UINT32 ui32BridgeFlags;
49196 +       IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
49197 +       IMG_UINT32 ui32FileOffset;
49198 +       IMG_UINT32 ui32Width;
49199 +       IMG_UINT32 ui32Height;
49200 +       IMG_UINT32 ui32StrideInBytes;
49201 +       IMG_DEV_VIRTADDR sDevBaseAddr;
49202 +       IMG_UINT32 ui32Size;
49203 +       PDUMP_PIXEL_FORMAT ePixelFormat;
49204 +       PDUMP_MEM_FORMAT eMemFormat;
49205 +       IMG_UINT32 ui32Flags;
49206 +
49207 +}PVRSRV_BRIDGE_IN_PDUMP_BITMAP;
49208 +
49209 +
49210 +
49211 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG
49212 +{
49213 +       IMG_UINT32 ui32BridgeFlags;
49214 +       IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
49215 +       IMG_UINT32 ui32FileOffset;
49216 +       IMG_UINT32 ui32Address;
49217 +       IMG_UINT32 ui32Size;
49218 +       IMG_UINT32 ui32Flags;
49219 +
49220 +}PVRSRV_BRIDGE_IN_PDUMP_READREG;
49221 +
49222 +
49223 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG
49224 +{
49225 +       IMG_UINT32 ui32BridgeFlags;
49226 +       IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
49227 +       IMG_BOOL bContinuous;
49228 +
49229 +}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO;
49230 +
49231 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG
49232 +{
49233 +       IMG_UINT32 ui32BridgeFlags;
49234 +       IMG_HANDLE hKernelMemInfo;
49235 +       IMG_UINT32 ui32Offset;
49236 +       IMG_DEV_PHYADDR sPDDevPAddr;
49237 +}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR;
49238 +
49239 +
49240 +typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG
49241 +{
49242 +       IMG_UINT32 ui32BridgeFlags;
49243 +       IMG_UINT32 ui32RegOffset;
49244 +       IMG_BOOL bLastFrame;
49245 +}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ;
49246 +
49247 +
49248 +typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG
49249 +{
49250 +       PVRSRV_ERROR eError;
49251 +       IMG_UINT32 ui32NumDevices;
49252 +       PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES];
49253 +
49254 +}PVRSRV_BRIDGE_OUT_ENUMDEVICE;
49255 +
49256 +
49257 +
49258 +typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG
49259 +{
49260 +
49261 +       PVRSRV_ERROR            eError;
49262 +       IMG_HANDLE                      hDevCookie;
49263 +
49264 +} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO;
49265 +
49266 +
49267 +
49268 +typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG
49269 +{
49270 +       PVRSRV_ERROR eError;
49271 +       IMG_UINT32 ui32NumDevices;
49272 +       IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES];
49273 +
49274 +}PVRSRV_BRIDGE_OUT_ENUMCLASS;
49275 +
49276 +
49277 +
49278 +typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG
49279 +{
49280 +       IMG_UINT32              ui32BridgeFlags;
49281 +       IMG_UINT32              ui32DeviceID;
49282 +       IMG_HANDLE              hDevCookie;
49283 +
49284 +}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE;
49285 +
49286 +
49287 +typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG
49288 +{
49289 +       PVRSRV_ERROR    eError;
49290 +       IMG_HANDLE              hDeviceKM;
49291 +
49292 +}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE;
49293 +
49294 +
49295 +
49296 +typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG
49297 +{
49298 +       IMG_UINT32                              ui32BridgeFlags;
49299 +       IMG_HANDLE              hDevCookie;
49300 +       IMG_HANDLE                              hDevMemContext;
49301 +       IMG_VOID                                *pvLinAddr;
49302 +       IMG_SIZE_T              ui32ByteSize;
49303 +       IMG_SIZE_T              ui32PageOffset;
49304 +       IMG_BOOL                bPhysContig;
49305 +       IMG_UINT32                              ui32NumPageTableEntries;
49306 +       IMG_SYS_PHYADDR         *psSysPAddr;
49307 +       IMG_UINT32                              ui32Flags;
49308 +
49309 +}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY;
49310 +
49311 +
49312 +typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG
49313 +{
49314 +       PVRSRV_ERROR    eError;
49315 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49316 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49317 +
49318 +}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY;
49319 +
49320 +
49321 +typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG
49322 +{
49323 +       IMG_UINT32 ui32BridgeFlags;
49324 +       IMG_HANDLE hKernelMemInfo;
49325 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49326 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49327 +
49328 +}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY;
49329 +
49330 +
49331 +#define PVRSRV_MAX_DC_DISPLAY_FORMATS                  10
49332 +#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS               10
49333 +#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS                        4
49334 +#define PVRSRV_MAX_DC_CLIP_RECTS                               32
49335 +
49336 +
49337 +typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG
49338 +{
49339 +       PVRSRV_ERROR    eError;
49340 +       IMG_UINT32              ui32Count;
49341 +       DISPLAY_FORMAT  asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS];
49342 +
49343 +}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS;
49344 +
49345 +
49346 +
49347 +typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG
49348 +{
49349 +       IMG_UINT32              ui32BridgeFlags;
49350 +       IMG_HANDLE              hDeviceKM;
49351 +       DISPLAY_FORMAT  sFormat;
49352 +
49353 +}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS;
49354 +
49355 +
49356 +
49357 +typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG
49358 +{
49359 +       PVRSRV_ERROR    eError;
49360 +       IMG_UINT32              ui32Count;
49361 +       DISPLAY_DIMS    asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS];
49362 +
49363 +}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS;
49364 +
49365 +
49366 +
49367 +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG
49368 +{
49369 +       PVRSRV_ERROR    eError;
49370 +       DISPLAY_INFO    sDisplayInfo;
49371 +
49372 +}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO;
49373 +
49374 +
49375 +
49376 +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG
49377 +{
49378 +       PVRSRV_ERROR    eError;
49379 +       IMG_HANDLE              hBuffer;
49380 +
49381 +}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER;
49382 +
49383 +
49384 +
49385 +typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG
49386 +{
49387 +       IMG_UINT32                              ui32BridgeFlags;
49388 +       IMG_HANDLE                              hDeviceKM;
49389 +       IMG_UINT32                              ui32Flags;
49390 +       DISPLAY_SURF_ATTRIBUTES sDstSurfAttrib;
49391 +       DISPLAY_SURF_ATTRIBUTES sSrcSurfAttrib;
49392 +       IMG_UINT32                              ui32BufferCount;
49393 +       IMG_UINT32                              ui32OEMFlags;
49394 +       IMG_UINT32                              ui32SwapChainID;
49395 +
49396 +} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN;
49397 +
49398 +
49399 +
49400 +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG
49401 +{
49402 +       PVRSRV_ERROR            eError;
49403 +       IMG_HANDLE                      hSwapChain;
49404 +       IMG_UINT32                      ui32SwapChainID;
49405 +
49406 +} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN;
49407 +
49408 +
49409 +
49410 +typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG
49411 +{
49412 +       IMG_UINT32                      ui32BridgeFlags;
49413 +       IMG_HANDLE                      hDeviceKM;
49414 +       IMG_HANDLE                      hSwapChain;
49415 +
49416 +} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN;
49417 +
49418 +
49419 +
49420 +typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG
49421 +{
49422 +       IMG_UINT32                      ui32BridgeFlags;
49423 +       IMG_HANDLE                      hDeviceKM;
49424 +       IMG_HANDLE                      hSwapChain;
49425 +       IMG_RECT                        sRect;
49426 +
49427 +} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT;
49428 +
49429 +
49430 +
49431 +typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG
49432 +{
49433 +       IMG_UINT32                      ui32BridgeFlags;
49434 +       IMG_HANDLE                      hDeviceKM;
49435 +       IMG_HANDLE                      hSwapChain;
49436 +       IMG_UINT32                      ui32CKColour;
49437 +
49438 +} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY;
49439 +
49440 +
49441 +
49442 +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG
49443 +{
49444 +       IMG_UINT32                      ui32BridgeFlags;
49445 +       IMG_HANDLE                      hDeviceKM;
49446 +       IMG_HANDLE                      hSwapChain;
49447 +
49448 +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS;
49449 +
49450 +
49451 +
49452 +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG
49453 +{
49454 +       PVRSRV_ERROR            eError;
49455 +       IMG_UINT32                      ui32BufferCount;
49456 +       IMG_HANDLE                      ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
49457 +
49458 +} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS;
49459 +
49460 +
49461 +
49462 +typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG
49463 +{
49464 +       IMG_UINT32                      ui32BridgeFlags;
49465 +       IMG_HANDLE                      hDeviceKM;
49466 +       IMG_HANDLE                      hBuffer;
49467 +       IMG_UINT32                      ui32SwapInterval;
49468 +       IMG_HANDLE                      hPrivateTag;
49469 +       IMG_UINT32                      ui32ClipRectCount;
49470 +       IMG_RECT                        sClipRect[PVRSRV_MAX_DC_CLIP_RECTS];
49471 +
49472 +} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER;
49473 +
49474 +
49475 +
49476 +typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG
49477 +{
49478 +       IMG_UINT32                      ui32BridgeFlags;
49479 +       IMG_HANDLE                      hDeviceKM;
49480 +       IMG_HANDLE                      hSwapChain;
49481 +
49482 +} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM;
49483 +
49484 +
49485 +
49486 +typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG
49487 +{
49488 +       IMG_UINT32                      ui32BridgeFlags;
49489 +       IMG_UINT32                      ui32DeviceID;
49490 +       IMG_HANDLE                      hDevCookie;
49491 +
49492 +} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE;
49493 +
49494 +
49495 +
49496 +typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG
49497 +{
49498 +       PVRSRV_ERROR            eError;
49499 +       IMG_HANDLE                      hDeviceKM;
49500 +
49501 +} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE;
49502 +
49503 +
49504 +
49505 +typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG
49506 +{
49507 +       PVRSRV_ERROR            eError;
49508 +       BUFFER_INFO                     sBufferInfo;
49509 +
49510 +} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO;
49511 +
49512 +
49513 +
49514 +typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG
49515 +{
49516 +       IMG_UINT32                      ui32BridgeFlags;
49517 +       IMG_HANDLE                      hDeviceKM;
49518 +       IMG_UINT32                      ui32BufferIndex;
49519 +
49520 +} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER;
49521 +
49522 +
49523 +
49524 +typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG
49525 +{
49526 +       PVRSRV_ERROR            eError;
49527 +       IMG_HANDLE                      hBuffer;
49528 +
49529 +} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER;
49530 +
49531 +
49532 +
49533 +typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG
49534 +{
49535 +       PVRSRV_ERROR            eError;
49536 +       IMG_UINT32                      ui32ClientHeapCount;
49537 +       PVRSRV_HEAP_INFO        sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
49538 +
49539 +} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO;
49540 +
49541 +
49542 +
49543 +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG
49544 +{
49545 +       PVRSRV_ERROR            eError;
49546 +       IMG_HANDLE                      hDevMemContext;
49547 +       IMG_UINT32                      ui32ClientHeapCount;
49548 +       PVRSRV_HEAP_INFO        sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
49549 +
49550 +} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT;
49551 +
49552 +
49553 +
49554 +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG
49555 +{
49556 +       PVRSRV_ERROR            eError;
49557 +       IMG_HANDLE                      hDevMemHeap;
49558 +
49559 +} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP;
49560 +
49561 +
49562 +
49563 +typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG
49564 +{
49565 +       PVRSRV_ERROR                    eError;
49566 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49567 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
49568 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49569 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49570 +
49571 +} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM;
49572 +
49573 +
49574 +
49575 +typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG
49576 +{
49577 +       PVRSRV_ERROR                    eError;
49578 +       IMG_HANDLE                              hMemInfo;
49579 +#if defined(SUPPORT_MEMINFO_IDS)
49580 +       IMG_UINT64                              ui64Stamp;
49581 +#endif
49582 +
49583 +} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM;
49584 +
49585 +
49586 +typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG
49587 +{
49588 +       PVRSRV_ERROR                    eError;
49589 +       IMG_PVOID                               pvLinAddr;
49590 +       IMG_HANDLE                              hMappingInfo;
49591 +
49592 +}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER;
49593 +
49594 +
49595 +
49596 +typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG
49597 +{
49598 +       PVRSRV_ERROR eError;
49599 +       IMG_SIZE_T ui32Total;
49600 +       IMG_SIZE_T ui32Free;
49601 +       IMG_SIZE_T ui32LargestBlock;
49602 +
49603 +} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM;
49604 +
49605 +
49606 +#include "pvrmmap.h"
49607 +typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG
49608 +{
49609 +    PVRSRV_ERROR               eError;
49610 +
49611 +
49612 +     IMG_UINT32                        ui32MMapOffset;
49613 +
49614 +
49615 +    IMG_UINT32                 ui32ByteOffset;
49616 +
49617 +
49618 +    IMG_UINT32                         ui32RealByteSize;
49619 +
49620 +
49621 +    IMG_UINT32                 ui32UserVAddr;
49622 +
49623 +} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA;
49624 +
49625 +typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG
49626 +{
49627 +    PVRSRV_ERROR               eError;
49628 +
49629 +
49630 +    IMG_BOOL                   bMUnmap;
49631 +
49632 +
49633 +    IMG_UINT32                 ui32UserVAddr;
49634 +
49635 +
49636 +    IMG_UINT32                 ui32RealByteSize;
49637 +} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA;
49638 +
49639 +typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG
49640 +{
49641 +       IMG_UINT32                      ui32BridgeFlags;
49642 +       PVRSRV_MISC_INFO        sMiscInfo;
49643 +
49644 +}PVRSRV_BRIDGE_IN_GET_MISC_INFO;
49645 +
49646 +
49647 +
49648 +typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG
49649 +{
49650 +       PVRSRV_ERROR            eError;
49651 +       PVRSRV_MISC_INFO        sMiscInfo;
49652 +
49653 +}PVRSRV_BRIDGE_OUT_GET_MISC_INFO;
49654 +
49655 +
49656 +
49657 +typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG
49658 +{
49659 +       IMG_UINT32                      ui32BridgeFlags;
49660 +       PVRSRV_MISC_INFO        sMiscInfo;
49661 +
49662 +}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO;
49663 +
49664 +
49665 +
49666 +typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG
49667 +{
49668 +       PVRSRV_ERROR            eError;
49669 +       PVRSRV_MISC_INFO        sMiscInfo;
49670 +
49671 +}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO;
49672 +
49673 +
49674 +
49675 +
49676 +typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG
49677 +{
49678 +       PVRSRV_ERROR eError;
49679 +       IMG_BOOL bIsCapturing;
49680 +
49681 +} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING;
49682 +
49683 +
49684 +typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG
49685 +{
49686 +       IMG_UINT32 ui32BridgeFlags;
49687 +       IMG_SIZE_T ui32Total;
49688 +       IMG_SIZE_T ui32Available;
49689 +
49690 +} PVRSRV_BRIDGE_IN_GET_FB_STATS;
49691 +
49692 +
49693 +
49694 +typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG
49695 +{
49696 +       IMG_UINT32                      ui32BridgeFlags;
49697 +       IMG_HANDLE                      hDevCookie;
49698 +       IMG_SYS_PHYADDR         sSysPhysAddr;
49699 +       IMG_UINT32                      uiSizeInBytes;
49700 +
49701 +} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE;
49702 +
49703 +
49704 +
49705 +typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG
49706 +{
49707 +       IMG_PVOID                       pvUserAddr;
49708 +       IMG_UINT32                      uiActualSize;
49709 +       IMG_PVOID                       pvProcess;
49710 +
49711 +} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE;
49712 +
49713 +
49714 +
49715 +typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG
49716 +{
49717 +       IMG_UINT32                      ui32BridgeFlags;
49718 +       IMG_HANDLE                      hDevCookie;
49719 +       IMG_PVOID                       pvUserAddr;
49720 +       IMG_PVOID                       pvProcess;
49721 +
49722 +} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE;
49723 +
49724 +
49725 +
49726 +typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG
49727 +{
49728 +       IMG_PVOID                       *ppvTbl;
49729 +       IMG_UINT32                      uiTblSize;
49730 +
49731 +} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP;
49732 +
49733 +
49734 +
49735 +typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG
49736 +{
49737 +       IMG_UINT32                      ui32BridgeFlags;
49738 +       IMG_HANDLE                      hDevCookie;
49739 +       IMG_PVOID                       pvProcess;
49740 +
49741 +} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS;
49742 +
49743 +
49744 +typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG
49745 +{
49746 +       IMG_SYS_PHYADDR         sRegsPhysBase;
49747 +       IMG_VOID                        *pvRegsBase;
49748 +       IMG_PVOID                       pvProcess;
49749 +       IMG_UINT32                      ulNoOfEntries;
49750 +       IMG_PVOID                       pvTblLinAddr;
49751 +
49752 +} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS;
49753 +
49754 +
49755 +typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG
49756 +{
49757 +       IMG_UINT32                      ui32BridgeFlags;
49758 +       IMG_HANDLE                      hDevCookie;
49759 +       IMG_PVOID                       pvProcess;
49760 +       IMG_VOID                        *pvRegsBase;
49761 +
49762 +} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS;
49763 +
49764 +typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG
49765 +{
49766 +       IMG_UINT32                      ui32BridgeFlags;
49767 +       IMG_HANDLE                      hDevCookie;
49768 +       IMG_UINT32                      ui32StatusAndMask;
49769 +       PVRSRV_ERROR            eError;
49770 +
49771 +} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT;
49772 +
49773 +typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG
49774 +{
49775 +       IMG_UINT32                      ui32BridgeFlags;
49776 +       IMG_BOOL                        bInitSuccesful;
49777 +} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT;
49778 +
49779 +
49780 +typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG
49781 +{
49782 +       IMG_UINT32 ui32BridgeFlags;
49783 +    IMG_UINT32 ui32Flags;
49784 +    IMG_SIZE_T ui32Size;
49785 +}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM;
49786 +
49787 +typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG
49788 +{
49789 +       PVRSRV_ERROR                    eError;
49790 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49791 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49792 +}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM;
49793 +
49794 +typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG
49795 +{
49796 +       IMG_UINT32                              ui32BridgeFlags;
49797 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49798 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49799 +}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM;
49800 +
49801 +typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG
49802 +{
49803 +       PVRSRV_ERROR eError;
49804 +}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM;
49805 +
49806 +typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG
49807 +{
49808 +       IMG_UINT32 ui32BridgeFlags;
49809 +       IMG_HANDLE hKernelMemInfo;
49810 +}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM;
49811 +
49812 +typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG
49813 +{
49814 +       PVRSRV_CLIENT_MEM_INFO  sClientMemInfo;
49815 +       PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
49816 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo;
49817 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
49818 +       PVRSRV_ERROR eError;
49819 +}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM;
49820 +
49821 +typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG
49822 +{
49823 +       IMG_UINT32 ui32BridgeFlags;
49824 +       PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
49825 +}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM;
49826 +
49827 +typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG
49828 +{
49829 +       PVRSRV_ERROR eError;
49830 +}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM;
49831 +
49832 +typedef struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR_TAG
49833 +{
49834 +       IMG_UINT32 ui32BridgeFlags;
49835 +    IMG_HANDLE hDevMemContext;
49836 +}PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR;
49837 +
49838 +typedef struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR_TAG
49839 +{
49840 +    IMG_DEV_PHYADDR sPDDevPAddr;
49841 +       PVRSRV_ERROR eError;
49842 +}PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR;
49843 +
49844 +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG
49845 +{
49846 +       IMG_UINT32 ui32BridgeFlags;
49847 +       IMG_HANDLE      hOSEventKM;
49848 +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT;
49849 +
49850 +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG
49851 +{
49852 +       PVRSRV_EVENTOBJECT sEventObject;
49853 +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN;
49854 +
49855 +typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG
49856 +{
49857 +       IMG_HANDLE hOSEvent;
49858 +       PVRSRV_ERROR eError;
49859 +} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN;
49860 +
49861 +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG
49862 +{
49863 +       PVRSRV_EVENTOBJECT sEventObject;
49864 +       IMG_HANDLE hOSEventKM;
49865 +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE;
49866 +
49867 +typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG
49868 +{
49869 +       IMG_UINT32 ui32BridgeFlags;
49870 +       IMG_HANDLE hKernelSyncInfo;
49871 +       IMG_UINT32 ui32ModifyFlags;
49872 +
49873 +} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS;
49874 +
49875 +typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG
49876 +{
49877 +       IMG_UINT32 ui32BridgeFlags;
49878 +       IMG_HANDLE hKernelSyncInfo;
49879 +       IMG_UINT32 ui32ModifyFlags;
49880 +
49881 +} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS;
49882 +
49883 +typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG
49884 +{
49885 +       PVRSRV_ERROR eError;
49886 +
49887 +
49888 +       IMG_UINT32 ui32ReadOpsPending;
49889 +       IMG_UINT32 ui32WriteOpsPending;
49890 +
49891 +} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS;
49892 +
49893 +#if defined (__cplusplus)
49894 +}
49895 +#endif
49896 +
49897 +#endif
49898 +
49899 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge_km.h b/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge_km.h
49900 new file mode 100644
49901 index 0000000..9c4b054
49902 --- /dev/null
49903 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/pvr_bridge_km.h
49904 @@ -0,0 +1,288 @@
49905 +/**********************************************************************
49906 + *
49907 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
49908 + *
49909 + * This program is free software; you can redistribute it and/or modify it
49910 + * under the terms and conditions of the GNU General Public License,
49911 + * version 2, as published by the Free Software Foundation.
49912 + *
49913 + * This program is distributed in the hope it will be useful but, except
49914 + * as otherwise stated in writing, without any warranty; without even the
49915 + * implied warranty of merchantability or fitness for a particular purpose.
49916 + * See the GNU General Public License for more details.
49917 + *
49918 + * You should have received a copy of the GNU General Public License along with
49919 + * this program; if not, write to the Free Software Foundation, Inc.,
49920 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
49921 + *
49922 + * The full GNU General Public License is included in this distribution in
49923 + * the file called "COPYING".
49924 + *
49925 + * Contact Information:
49926 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
49927 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
49928 + *
49929 + ******************************************************************************/
49930 +
49931 +#ifndef __PVR_BRIDGE_KM_H_
49932 +#define __PVR_BRIDGE_KM_H_
49933 +
49934 +#if defined (__cplusplus)
49935 +extern "C" {
49936 +#endif
49937 +
49938 +#include "pvr_bridge.h"
49939 +#include "perproc.h"
49940 +
49941 +#if defined(__linux__)
49942 +PVRSRV_ERROR LinuxBridgeInit(IMG_VOID);
49943 +IMG_VOID LinuxBridgeDeInit(IMG_VOID);
49944 +#endif
49945 +
49946 +IMG_IMPORT
49947 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
49948 +                                                                                                  PVRSRV_DEVICE_IDENTIFIER *psDevIdList);
49949 +
49950 +IMG_IMPORT
49951 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32                 uiDevIndex,
49952 +                                                                                                       PVRSRV_DEVICE_TYPE      eDeviceType,
49953 +                                                                                                       IMG_HANDLE                      *phDevCookie);
49954 +
49955 +IMG_IMPORT
49956 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
49957 +                                                                                                        PVRSRV_QUEUE_INFO **ppsQueueInfo);
49958 +
49959 +IMG_IMPORT
49960 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
49961 +
49962 +IMG_IMPORT
49963 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
49964 +                                                                                                       PVRSRV_HEAP_INFO *psHeapInfo);
49965 +
49966 +IMG_IMPORT
49967 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE                                    hDevCookie,
49968 +                                                                                                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
49969 +                                                                                                                IMG_HANDLE                                     *phDevMemContext,
49970 +                                                                                                                IMG_UINT32                                     *pui32ClientHeapCount,
49971 +                                                                                                                PVRSRV_HEAP_INFO                       *psHeapInfo,
49972 +                                                                                                                IMG_BOOL                                       *pbCreated,
49973 +                                                                                                                IMG_BOOL                                       *pbShared);
49974 +
49975 +
49976 +IMG_IMPORT
49977 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
49978 +                                                                                                                 IMG_HANDLE hDevMemContext,
49979 +                                                                                                                 IMG_BOOL *pbDestroyed);
49980 +
49981 +
49982 +IMG_IMPORT
49983 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE                              hDevCookie,
49984 +                                                                                                                       IMG_HANDLE                      hDevMemContext,
49985 +                                                                                                                       IMG_UINT32                      *pui32ClientHeapCount,
49986 +                                                                                                                       PVRSRV_HEAP_INFO        *psHeapInfo,
49987 +                                                                                                                       IMG_BOOL                        *pbShared
49988 +                                       );
49989 +
49990 +
49991 +IMG_IMPORT
49992 +PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE                                   hDevCookie,
49993 +                                                                                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
49994 +                                                                                                IMG_HANDLE                                     hDevMemHeap,
49995 +                                                                                                IMG_UINT32                                     ui32Flags,
49996 +                                                                                                IMG_SIZE_T                                     ui32Size,
49997 +                                                                                                IMG_SIZE_T                                     ui32Alignment,
49998 +                                                                                                PVRSRV_KERNEL_MEM_INFO         **ppsMemInfo);
49999 +
50000 +
50001 +#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
50002 +       #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
50003 +               (PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \
50004 +                       ", " #alignment "," #memInfo "): " logStr " (size = 0x%;x)", size)),\
50005 +                       _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo))
50006 +#else
50007 +       #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo, logStr) \
50008 +                       _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, memInfo)
50009 +#endif
50010 +
50011 +
50012 +IMG_IMPORT
50013 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE                     hDevCookie,
50014 +                                                                                               PVRSRV_KERNEL_MEM_INFO  *psMemInfo);
50015 +
50016 +IMG_IMPORT
50017 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE                       hDevCookie,
50018 +                                                                                               PVRSRV_KERNEL_MEM_INFO  *psMemInfo);
50019 +
50020 +IMG_IMPORT
50021 +PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE           hDevMemHeap,
50022 +                                                                                                                IMG_DEV_VIRTADDR       *psDevVAddr,
50023 +                                                                                                                IMG_SIZE_T                     ui32Size,
50024 +                                                                                                                IMG_SIZE_T                     ui32Alignment,
50025 +                                                                                                                PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
50026 +
50027 +IMG_IMPORT
50028 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
50029 +
50030 +IMG_IMPORT
50031 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA      *psPerProc,
50032 +                                                                                                 PVRSRV_KERNEL_MEM_INFO        *psSrcMemInfo,
50033 +                                                                                                 IMG_HANDLE                            hDstDevMemHeap,
50034 +                                                                                                 PVRSRV_KERNEL_MEM_INFO        **ppsDstMemInfo);
50035 +
50036 +IMG_IMPORT
50037 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
50038 +
50039 +IMG_IMPORT
50040 +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE                             hDevCookie,
50041 +                                                                                               PVRSRV_PER_PROCESS_DATA *psPerProc,
50042 +                                                                                               IMG_HANDLE                              hDevMemContext,
50043 +                                                                                               IMG_SIZE_T                              ui32ByteSize,
50044 +                                                                                               IMG_SIZE_T                              ui32PageOffset,
50045 +                                                                                               IMG_BOOL                                bPhysContig,
50046 +                                                                                               IMG_SYS_PHYADDR                 *psSysAddr,
50047 +                                                                                               IMG_VOID                                *pvLinAddr,
50048 +                                                                                               IMG_UINT32                              ui32Flags,
50049 +                                                                                               PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
50050 +
50051 +IMG_IMPORT
50052 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
50053 +
50054 +IMG_IMPORT
50055 +PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass,
50056 +                                                                IMG_UINT32 *pui32DevCount,
50057 +                                                                IMG_UINT32 *pui32DevID );
50058 +
50059 +IMG_IMPORT
50060 +PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA      *psPerProc,
50061 +                                                                 IMG_UINT32                            ui32DeviceID,
50062 +                                                                 IMG_HANDLE                            hDevCookie,
50063 +                                                                 IMG_HANDLE                            *phDeviceKM);
50064 +
50065 +IMG_IMPORT
50066 +PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
50067 +
50068 +IMG_IMPORT
50069 +PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM,
50070 +                                                                  IMG_UINT32 *pui32Count,
50071 +                                                                  DISPLAY_FORMAT *psFormat);
50072 +
50073 +IMG_IMPORT
50074 +PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM,
50075 +                                                               DISPLAY_FORMAT *psFormat,
50076 +                                                               IMG_UINT32 *pui32Count,
50077 +                                                               DISPLAY_DIMS *psDim);
50078 +
50079 +IMG_IMPORT
50080 +PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM,
50081 +                                                                          IMG_HANDLE *phBuffer);
50082 +
50083 +IMG_IMPORT
50084 +PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM,
50085 +                                                          DISPLAY_INFO *psDisplayInfo);
50086 +IMG_IMPORT
50087 +PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
50088 +                                                                          IMG_HANDLE                           hDeviceKM,
50089 +                                                                          IMG_UINT32                           ui32Flags,
50090 +                                                                          DISPLAY_SURF_ATTRIBUTES      *psDstSurfAttrib,
50091 +                                                                          DISPLAY_SURF_ATTRIBUTES      *psSrcSurfAttrib,
50092 +                                                                          IMG_UINT32                           ui32BufferCount,
50093 +                                                                          IMG_UINT32                           ui32OEMFlags,
50094 +                                                                          IMG_HANDLE                           *phSwapChain,
50095 +                                                                          IMG_UINT32                           *pui32SwapChainID);
50096 +IMG_IMPORT
50097 +PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE     hSwapChain);
50098 +IMG_IMPORT
50099 +PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE   hDeviceKM,
50100 +                                                                 IMG_HANDLE    hSwapChain,
50101 +                                                                 IMG_RECT      *psRect);
50102 +IMG_IMPORT
50103 +PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE   hDeviceKM,
50104 +                                                                 IMG_HANDLE    hSwapChain,
50105 +                                                                 IMG_RECT      *psRect);
50106 +IMG_IMPORT
50107 +PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE      hDeviceKM,
50108 +                                                                          IMG_HANDLE   hSwapChain,
50109 +                                                                          IMG_UINT32   ui32CKColour);
50110 +IMG_IMPORT
50111 +PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE      hDeviceKM,
50112 +                                                                       IMG_HANDLE              hSwapChain,
50113 +                                                                       IMG_UINT32              ui32CKColour);
50114 +IMG_IMPORT
50115 +PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE   hDeviceKM,
50116 +                                                                 IMG_HANDLE    hSwapChain,
50117 +                                                                 IMG_UINT32    *pui32BufferCount,
50118 +                                                                 IMG_HANDLE    *phBuffer);
50119 +IMG_IMPORT
50120 +PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
50121 +                                                                       IMG_HANDLE      hBuffer,
50122 +                                                                       IMG_UINT32      ui32SwapInterval,
50123 +                                                                       IMG_HANDLE      hPrivateTag,
50124 +                                                                       IMG_UINT32      ui32ClipRectCount,
50125 +                                                                       IMG_RECT        *psClipRect);
50126 +IMG_IMPORT
50127 +PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
50128 +                                                                       IMG_HANDLE      hSwapChain);
50129 +
50130 +IMG_IMPORT
50131 +PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA      *psPerProc,
50132 +                                                                 IMG_UINT32                            ui32DeviceID,
50133 +                                                                 IMG_HANDLE                            hDevCookie,
50134 +                                                                 IMG_HANDLE                            *phDeviceKM);
50135 +IMG_IMPORT
50136 +PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback);
50137 +
50138 +IMG_IMPORT
50139 +PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE      hDeviceKM,
50140 +                                                          BUFFER_INFO  *psBufferInfo);
50141 +IMG_IMPORT
50142 +PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE    hDeviceKM,
50143 +                                                                IMG_UINT32     ui32BufferIndex,
50144 +                                                                IMG_HANDLE     *phBuffer);
50145 +
50146 +
50147 +IMG_IMPORT
50148 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
50149 +                                                                                                          IMG_HANDLE                           hDevMemContext,
50150 +                                                                                                          IMG_HANDLE                           hDeviceClassBuffer,
50151 +                                                                                                          PVRSRV_KERNEL_MEM_INFO       **ppsMemInfo,
50152 +                                                                                                          IMG_HANDLE                           *phOSMapInfo);
50153 +
50154 +IMG_IMPORT
50155 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
50156 +
50157 +IMG_IMPORT
50158 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
50159 +                                                                                                  IMG_SIZE_T *pui32Total,
50160 +                                                                                                  IMG_SIZE_T *pui32Free,
50161 +                                                                                                  IMG_SIZE_T *pui32LargestBlock);
50162 +IMG_IMPORT
50163 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE                                     hDevCookie,
50164 +                                                                                               IMG_HANDLE                                      hDevMemContext,
50165 +                                                                                               PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo);
50166 +IMG_IMPORT
50167 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
50168 +
50169 +IMG_IMPORT
50170 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo);
50171 +
50172 +PVRSRV_ERROR PVRSRVGetFBStatsKM(IMG_SIZE_T     *pui32Total,
50173 +                                                               IMG_SIZE_T      *pui32Available);
50174 +
50175 +IMG_IMPORT PVRSRV_ERROR
50176 +PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA   *psPerProc,
50177 +                                                        IMG_UINT32                             ui32Flags,
50178 +                                                        IMG_SIZE_T                             ui32Size,
50179 +                                                        PVRSRV_KERNEL_MEM_INFO         **ppsKernelMemInfo);
50180 +
50181 +IMG_IMPORT PVRSRV_ERROR
50182 +PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
50183 +
50184 +IMG_IMPORT PVRSRV_ERROR
50185 +PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
50186 +
50187 +#if defined (__cplusplus)
50188 +}
50189 +#endif
50190 +
50191 +#endif
50192 +
50193 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/pvrmmap.h b/drivers/gpu/drm/mrst/pvr/services4/include/pvrmmap.h
50194 new file mode 100644
50195 index 0000000..7270f54
50196 --- /dev/null
50197 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/pvrmmap.h
50198 @@ -0,0 +1,36 @@
50199 +/**********************************************************************
50200 + *
50201 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
50202 + *
50203 + * This program is free software; you can redistribute it and/or modify it
50204 + * under the terms and conditions of the GNU General Public License,
50205 + * version 2, as published by the Free Software Foundation.
50206 + *
50207 + * This program is distributed in the hope it will be useful but, except
50208 + * as otherwise stated in writing, without any warranty; without even the
50209 + * implied warranty of merchantability or fitness for a particular purpose.
50210 + * See the GNU General Public License for more details.
50211 + *
50212 + * You should have received a copy of the GNU General Public License along with
50213 + * this program; if not, write to the Free Software Foundation, Inc.,
50214 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
50215 + *
50216 + * The full GNU General Public License is included in this distribution in
50217 + * the file called "COPYING".
50218 + *
50219 + * Contact Information:
50220 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
50221 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
50222 + *
50223 + ******************************************************************************/
50224 +
50225 +#ifndef __PVRMMAP_H__
50226 +#define __PVRMMAP_H__
50227 +
50228 +PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle);
50229 +
50230 +
50231 +IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle);
50232 +
50233 +#endif
50234 +
50235 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/servicesint.h b/drivers/gpu/drm/mrst/pvr/services4/include/servicesint.h
50236 new file mode 100644
50237 index 0000000..a024fd5
50238 --- /dev/null
50239 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/servicesint.h
50240 @@ -0,0 +1,266 @@
50241 +/**********************************************************************
50242 + *
50243 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
50244 + *
50245 + * This program is free software; you can redistribute it and/or modify it
50246 + * under the terms and conditions of the GNU General Public License,
50247 + * version 2, as published by the Free Software Foundation.
50248 + *
50249 + * This program is distributed in the hope it will be useful but, except
50250 + * as otherwise stated in writing, without any warranty; without even the
50251 + * implied warranty of merchantability or fitness for a particular purpose.
50252 + * See the GNU General Public License for more details.
50253 + *
50254 + * You should have received a copy of the GNU General Public License along with
50255 + * this program; if not, write to the Free Software Foundation, Inc.,
50256 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
50257 + *
50258 + * The full GNU General Public License is included in this distribution in
50259 + * the file called "COPYING".
50260 + *
50261 + * Contact Information:
50262 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
50263 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
50264 + *
50265 + ******************************************************************************/
50266 +
50267 +#if !defined (__SERVICESINT_H__)
50268 +#define __SERVICESINT_H__
50269 +
50270 +#if defined (__cplusplus)
50271 +extern "C" {
50272 +#endif
50273 +
50274 +#include "services.h"
50275 +#include "sysinfo.h"
50276 +
50277 +#define HWREC_DEFAULT_TIMEOUT  (500)
50278 +
50279 +#define DRIVERNAME_MAXLENGTH   (100)
50280 +
50281 +
50282 +
50283 +typedef struct _PVRSRV_KERNEL_MEM_INFO_
50284 +{
50285 +
50286 +       IMG_PVOID                               pvLinAddrKM;
50287 +
50288 +
50289 +       IMG_DEV_VIRTADDR                sDevVAddr;
50290 +
50291 +
50292 +       IMG_UINT32                              ui32Flags;
50293 +
50294 +
50295 +       IMG_SIZE_T                              ui32AllocSize;
50296 +
50297 +
50298 +       PVRSRV_MEMBLK                   sMemBlk;
50299 +
50300 +
50301 +       IMG_PVOID                               pvSysBackupBuffer;
50302 +
50303 +
50304 +       IMG_UINT32                              ui32RefCount;
50305 +
50306 +
50307 +       IMG_BOOL                                bPendingFree;
50308 +
50309 +
50310 +       #if defined(SUPPORT_MEMINFO_IDS)
50311 +       #if !defined(USE_CODE)
50312 +       
50313 +       IMG_UINT64                              ui64Stamp;
50314 +       #else 
50315 +       IMG_UINT32                              dummy1;
50316 +       IMG_UINT32                              dummy2;
50317 +       #endif 
50318 +       #endif 
50319 +
50320 +       
50321 +       struct _PVRSRV_KERNEL_SYNC_INFO_        *psKernelSyncInfo;
50322 +
50323 +} PVRSRV_KERNEL_MEM_INFO;
50324 +
50325 +
50326 +typedef struct _PVRSRV_KERNEL_SYNC_INFO_
50327 +{
50328 +
50329 +       PVRSRV_SYNC_DATA                *psSyncData;
50330 +
50331 +
50332 +       IMG_DEV_VIRTADDR                sWriteOpsCompleteDevVAddr;
50333 +
50334 +
50335 +       IMG_DEV_VIRTADDR                sReadOpsCompleteDevVAddr;
50336 +
50337 +
50338 +       PVRSRV_KERNEL_MEM_INFO  *psSyncDataMemInfoKM;
50339 +
50340 +
50341 +       IMG_HANDLE                              hResItem;
50342 +       
50343 +        
50344 +        
50345 +        IMG_UINT32              ui32RefCount;
50346 +
50347 +} PVRSRV_KERNEL_SYNC_INFO;
50348 +
50349 +typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_
50350 +{
50351 +
50352 +       IMG_UINT32                      ui32ReadOpsPendingVal;
50353 +       IMG_DEV_VIRTADDR        sReadOpsCompleteDevVAddr;
50354 +       IMG_UINT32                      ui32WriteOpsPendingVal;
50355 +       IMG_DEV_VIRTADDR        sWriteOpsCompleteDevVAddr;
50356 +} PVRSRV_DEVICE_SYNC_OBJECT;
50357 +
50358 +typedef struct _PVRSRV_SYNC_OBJECT
50359 +{
50360 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM;
50361 +       IMG_UINT32                              ui32WriteOpsPending;
50362 +       IMG_UINT32                              ui32ReadOpsPending;
50363 +
50364 +}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT;
50365 +
50366 +typedef struct _PVRSRV_COMMAND
50367 +{
50368 +       IMG_SIZE_T                      ui32CmdSize;
50369 +       IMG_UINT32                      ui32DevIndex;
50370 +       IMG_UINT32                      CommandType;
50371 +       IMG_UINT32                      ui32DstSyncCount;
50372 +       IMG_UINT32                      ui32SrcSyncCount;
50373 +       PVRSRV_SYNC_OBJECT      *psDstSync;
50374 +       PVRSRV_SYNC_OBJECT      *psSrcSync;
50375 +       IMG_SIZE_T                      ui32DataSize;
50376 +       IMG_UINT32                      ui32ProcessID;
50377 +       IMG_VOID                        *pvData;
50378 +}PVRSRV_COMMAND, *PPVRSRV_COMMAND;
50379 +
50380 +
50381 +typedef struct _PVRSRV_QUEUE_INFO_
50382 +{
50383 +       IMG_VOID                        *pvLinQueueKM;
50384 +       IMG_VOID                        *pvLinQueueUM;
50385 +       volatile IMG_SIZE_T     ui32ReadOffset;
50386 +       volatile IMG_SIZE_T     ui32WriteOffset;
50387 +       IMG_UINT32                      *pui32KickerAddrKM;
50388 +       IMG_UINT32                      *pui32KickerAddrUM;
50389 +       IMG_SIZE_T                      ui32QueueSize;
50390 +
50391 +       IMG_UINT32                      ui32ProcessID;
50392 +
50393 +       IMG_HANDLE                      hMemBlock[2];
50394 +
50395 +       struct _PVRSRV_QUEUE_INFO_ *psNextKM;
50396 +}PVRSRV_QUEUE_INFO;
50397 +
50398 +typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*,
50399 +                                                                               PVRSRV_COMMAND**,
50400 +                                                                               IMG_UINT32,
50401 +                                                                               IMG_UINT16,
50402 +                                                                               IMG_UINT32,
50403 +                                                                               PVRSRV_KERNEL_SYNC_INFO*[],
50404 +                                                                               IMG_UINT32,
50405 +                                                                               PVRSRV_KERNEL_SYNC_INFO*[],
50406 +                                                                               IMG_UINT32);
50407 +typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL);
50408 +
50409 +
50410 +typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG
50411 +{
50412 +       PFN_GET_BUFFER_ADDR             pfnGetBufferAddr;
50413 +       IMG_HANDLE                              hDevMemContext;
50414 +       IMG_HANDLE                              hExtDevice;
50415 +       IMG_HANDLE                              hExtBuffer;
50416 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
50417 +
50418 +} PVRSRV_DEVICECLASS_BUFFER;
50419 +
50420 +
50421 +typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG
50422 +{
50423 +       IMG_HANDLE hDeviceKM;
50424 +       IMG_HANDLE      hServices;
50425 +} PVRSRV_CLIENT_DEVICECLASS_INFO;
50426 +
50427 +
50428 +#ifdef INLINE_IS_PRAGMA
50429 +#pragma inline(PVRSRVGetWriteOpsPending)
50430 +#endif
50431 +static INLINE
50432 +IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
50433 +{
50434 +       IMG_UINT32 ui32WriteOpsPending;
50435 +
50436 +       if(bIsReadOp)
50437 +       {
50438 +               ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
50439 +       }
50440 +       else
50441 +       {
50442 +
50443 +
50444 +
50445 +               ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++;
50446 +       }
50447 +
50448 +       return ui32WriteOpsPending;
50449 +}
50450 +
50451 +#ifdef INLINE_IS_PRAGMA
50452 +#pragma inline(PVRSRVGetReadOpsPending)
50453 +#endif
50454 +static INLINE
50455 +IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp)
50456 +{
50457 +       IMG_UINT32 ui32ReadOpsPending;
50458 +
50459 +       if(bIsReadOp)
50460 +       {
50461 +               ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending++;
50462 +       }
50463 +       else
50464 +       {
50465 +               ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
50466 +       }
50467 +
50468 +       return ui32ReadOpsPending;
50469 +}
50470 +
50471 +IMG_IMPORT
50472 +PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
50473 +                                                               PVRSRV_COMMAND *psCommand);
50474 +
50475 +
50476 +
50477 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
50478 +PVRSRVGetMMUContextPDDevPAddr(const PVRSRV_CONNECTION *psConnection,
50479 +                              IMG_HANDLE hDevMemContext,
50480 +                              IMG_DEV_PHYADDR *sPDDevPAddr);
50481 +
50482 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
50483 +PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
50484 +                                               IMG_UINT32 ui32Flags,
50485 +                                               IMG_SIZE_T ui32Size,
50486 +                                               PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
50487 +
50488 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
50489 +PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection,
50490 +                                          PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
50491 +
50492 +IMG_IMPORT PVRSRV_ERROR
50493 +PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection,
50494 +                        PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
50495 +
50496 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
50497 +PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection,
50498 +                    IMG_HANDLE hKernelMemInfo,
50499 +                    PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
50500 +
50501 +
50502 +#if defined (__cplusplus)
50503 +}
50504 +#endif
50505 +#endif
50506 +
50507 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/sgx_bridge.h b/drivers/gpu/drm/mrst/pvr/services4/include/sgx_bridge.h
50508 new file mode 100644
50509 index 0000000..b2bfc0f
50510 --- /dev/null
50511 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/sgx_bridge.h
50512 @@ -0,0 +1,477 @@
50513 +/**********************************************************************
50514 + *
50515 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
50516 + *
50517 + * This program is free software; you can redistribute it and/or modify it
50518 + * under the terms and conditions of the GNU General Public License,
50519 + * version 2, as published by the Free Software Foundation.
50520 + *
50521 + * This program is distributed in the hope it will be useful but, except
50522 + * as otherwise stated in writing, without any warranty; without even the
50523 + * implied warranty of merchantability or fitness for a particular purpose.
50524 + * See the GNU General Public License for more details.
50525 + *
50526 + * You should have received a copy of the GNU General Public License along with
50527 + * this program; if not, write to the Free Software Foundation, Inc.,
50528 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
50529 + *
50530 + * The full GNU General Public License is included in this distribution in
50531 + * the file called "COPYING".
50532 + *
50533 + * Contact Information:
50534 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
50535 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
50536 + *
50537 + ******************************************************************************/
50538 +
50539 +#if !defined(__SGX_BRIDGE_H__)
50540 +#define __SGX_BRIDGE_H__
50541 +
50542 +#include "sgxapi_km.h"
50543 +#include "sgxinfo.h"
50544 +#include "pvr_bridge.h"
50545 +
50546 +#if defined (__cplusplus)
50547 +extern "C" {
50548 +#endif
50549 +
50550 +
50551 +#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
50552 +#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO                        PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0)
50553 +#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO            PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1)
50554 +#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO   PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2)
50555 +#define PVRSRV_BRIDGE_SGX_DOKICK                               PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3)
50556 +#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR              PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4)
50557 +#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD            PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5)
50558 +
50559 +#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE   PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
50560 +
50561 +#define PVRSRV_BRIDGE_SGX_GETMMUPDADDR                 PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+10)
50562 +
50563 +#if defined(TRANSFER_QUEUE)
50564 +#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER                       PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13)
50565 +#endif
50566 +#define PVRSRV_BRIDGE_SGX_GETMISCINFO                          PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14)
50567 +#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT                      PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15)
50568 +#define PVRSRV_BRIDGE_SGX_DEVINITPART2                         PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16)
50569 +
50570 +#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC                     PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17)
50571 +#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC                    PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18)
50572 +#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC                      PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19)
50573 +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT   PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20)
50574 +#define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET       PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21)
50575 +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22)
50576 +#if defined(SGX_FEATURE_2D_HARDWARE)
50577 +#define PVRSRV_BRIDGE_SGX_SUBMIT2D                                     PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23)
50578 +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT       PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24)
50579 +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT     PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25)
50580 +#endif
50581 +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26)
50582 +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT       PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27)
50583 +
50584 +#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES              PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28)
50585 +
50586 +#if defined(SUPPORT_SGX_HWPERF)
50587 +#define PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS           PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29)
50588 +#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB                       PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
50589 +#endif
50590 +
50591 +#if defined(PDUMP)
50592 +#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY           PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
50593 +#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
50594 +#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS      PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
50595 +#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
50596 +#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB                               PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
50597 +#endif
50598 +
50599 +
50600 +
50601 +#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+35)
50602 +
50603 +
50604 +typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
50605 +{
50606 +       IMG_UINT32 ui32BridgeFlags;
50607 +       IMG_HANDLE hDevMemHeap;
50608 +       IMG_DEV_VIRTADDR sDevVAddr;
50609 +}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR;
50610 +
50611 +
50612 +typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
50613 +{
50614 +       PVRSRV_ERROR            eError;
50615 +       IMG_DEV_PHYADDR         DevPAddr;
50616 +       IMG_CPU_PHYADDR         CpuPAddr;
50617 +}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
50618 +
50619 +
50620 +typedef struct PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR_TAG
50621 +{
50622 +       IMG_UINT32                              ui32BridgeFlags;
50623 +       IMG_HANDLE                              hDevCookie;
50624 +       IMG_HANDLE                              hDevMemContext;
50625 +}PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR;
50626 +
50627 +
50628 +typedef struct PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR_TAG
50629 +{
50630 +       IMG_DEV_PHYADDR                 sPDDevPAddr;
50631 +       PVRSRV_ERROR                    eError;
50632 +}PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR;
50633 +
50634 +
50635 +typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
50636 +{
50637 +       IMG_UINT32                                      ui32BridgeFlags;
50638 +       IMG_HANDLE                                      hDevCookie;
50639 +}PVRSRV_BRIDGE_IN_GETCLIENTINFO;
50640 +
50641 +
50642 +typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG
50643 +{
50644 +       SGX_INTERNAL_DEVINFO    sSGXInternalDevInfo;
50645 +       PVRSRV_ERROR                            eError;
50646 +}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO;
50647 +
50648 +
50649 +typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG
50650 +{
50651 +       IMG_UINT32                              ui32BridgeFlags;
50652 +       IMG_HANDLE                              hDevCookie;
50653 +}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO;
50654 +
50655 +
50656 +typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG
50657 +{
50658 +       SGX_CLIENT_INFO         sClientInfo;
50659 +       PVRSRV_ERROR                    eError;
50660 +}PVRSRV_BRIDGE_OUT_GETCLIENTINFO;
50661 +
50662 +
50663 +typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG
50664 +{
50665 +       IMG_UINT32                              ui32BridgeFlags;
50666 +       IMG_HANDLE                              hDevCookie;
50667 +       SGX_CLIENT_INFO         sClientInfo;
50668 +}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO;
50669 +
50670 +
50671 +typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG
50672 +{
50673 +       IMG_UINT32                              ui32BridgeFlags;
50674 +       IMG_HANDLE                              hDevCookie;
50675 +}PVRSRV_BRIDGE_IN_ISPBREAKPOLL;
50676 +
50677 +
50678 +typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG
50679 +{
50680 +       IMG_UINT32                              ui32BridgeFlags;
50681 +       IMG_HANDLE                              hDevCookie;
50682 +       SGX_CCB_KICK                    sCCBKick;
50683 +}PVRSRV_BRIDGE_IN_DOKICK;
50684 +
50685 +
50686 +typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG
50687 +{
50688 +       IMG_UINT32                              ui32BridgeFlags;
50689 +       IMG_HANDLE                              hDevCookie;
50690 +}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES;
50691 +
50692 +
50693 +#if defined(TRANSFER_QUEUE)
50694 +
50695 +typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG
50696 +{
50697 +       IMG_UINT32                              ui32BridgeFlags;
50698 +       IMG_HANDLE                              hDevCookie;
50699 +       PVRSRV_TRANSFER_SGX_KICK                        sKick;
50700 +}PVRSRV_BRIDGE_IN_SUBMITTRANSFER;
50701 +
50702 +#if defined(SGX_FEATURE_2D_HARDWARE)
50703 +
50704 +typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG
50705 +{
50706 +       IMG_UINT32                              ui32BridgeFlags;
50707 +       IMG_HANDLE                              hDevCookie;
50708 +       PVRSRV_2D_SGX_KICK                              sKick;
50709 +} PVRSRV_BRIDGE_IN_SUBMIT2D;
50710 +#endif
50711 +#endif
50712 +
50713 +
50714 +typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG
50715 +{
50716 +       IMG_UINT32                              ui32BridgeFlags;
50717 +       IMG_HANDLE                              hDevCookie;
50718 +    IMG_PCHAR                          pszKey;
50719 +    IMG_PCHAR                          pszValue;
50720 +}PVRSRV_BRIDGE_IN_READREGDWORD;
50721 +
50722 +
50723 +typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG
50724 +{
50725 +       PVRSRV_ERROR    eError;
50726 +       IMG_UINT32              ui32Data;
50727 +}PVRSRV_BRIDGE_OUT_READREGDWORD;
50728 +
50729 +
50730 +typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG
50731 +{
50732 +       IMG_UINT32              ui32BridgeFlags;
50733 +       IMG_HANDLE              hDevCookie;
50734 +       SGX_MISC_INFO   *psMiscInfo;
50735 +}PVRSRV_BRIDGE_IN_SGXGETMISCINFO;
50736 +
50737 +typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG
50738 +{
50739 +       IMG_UINT32              ui32BridgeFlags;
50740 +       IMG_HANDLE              hDevCookie;
50741 +}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT;
50742 +
50743 +typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG
50744 +{
50745 +       PVRSRV_ERROR                    eError;
50746 +       SGX_BRIDGE_INFO_FOR_SRVINIT     sInitInfo;
50747 +}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT;
50748 +
50749 +typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG
50750 +{
50751 +       IMG_UINT32              ui32BridgeFlags;
50752 +       IMG_HANDLE              hDevCookie;
50753 +       SGX_BRIDGE_INIT_INFO    sInitInfo;
50754 +}PVRSRV_BRIDGE_IN_SGXDEVINITPART2;
50755 +
50756 +
50757 +typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG
50758 +{
50759 +       IMG_UINT32                              ui32BridgeFlags;
50760 +       IMG_HANDLE                              hDevCookie;
50761 +       IMG_HANDLE                              hKernSyncInfo;
50762 +       IMG_BOOL                                bWaitForComplete;
50763 +}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE;
50764 +
50765 +
50766 +#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10
50767 +
50768 +typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG
50769 +{
50770 +       IMG_UINT32 ui32BridgeFlags;
50771 +       IMG_HANDLE hDevCookie;
50772 +       IMG_BOOL bLockOnFailure;
50773 +       IMG_UINT32 ui32TotalPBSize;
50774 +}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC;
50775 +
50776 +typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG
50777 +{
50778 +       IMG_HANDLE hKernelMemInfo;
50779 +       IMG_HANDLE hSharedPBDesc;
50780 +       IMG_HANDLE hSharedPBDescKernelMemInfoHandle;
50781 +       IMG_HANDLE hHWPBDescKernelMemInfoHandle;
50782 +       IMG_HANDLE hBlockKernelMemInfoHandle;
50783 +       IMG_HANDLE hHWBlockKernelMemInfoHandle;
50784 +       IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
50785 +       IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount;
50786 +       PVRSRV_ERROR eError;
50787 +}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC;
50788 +
50789 +typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG
50790 +{
50791 +       IMG_UINT32 ui32BridgeFlags;
50792 +       IMG_HANDLE hSharedPBDesc;
50793 +}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC;
50794 +
50795 +typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG
50796 +{
50797 +       PVRSRV_ERROR eError;
50798 +}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC;
50799 +
50800 +
50801 +typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG
50802 +{
50803 +       IMG_UINT32 ui32BridgeFlags;
50804 +       IMG_HANDLE hDevCookie;
50805 +       IMG_HANDLE hSharedPBDescKernelMemInfo;
50806 +       IMG_HANDLE hHWPBDescKernelMemInfo;
50807 +       IMG_HANDLE hBlockKernelMemInfo;
50808 +       IMG_HANDLE hHWBlockKernelMemInfo;
50809 +       IMG_UINT32 ui32TotalPBSize;
50810 +       IMG_HANDLE *phKernelMemInfoHandles;
50811 +       IMG_UINT32 ui32KernelMemInfoHandlesCount;
50812 +}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC;
50813 +
50814 +typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG
50815 +{
50816 +       PVRSRV_ERROR eError;
50817 +       IMG_HANDLE hSharedPBDesc;
50818 +}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC;
50819 +
50820 +
50821 +#ifdef PDUMP
50822 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG
50823 +{
50824 +       IMG_UINT32 ui32BridgeFlags;
50825 +       SGX_KICKTA_DUMP_BUFFER *psBufferArray;
50826 +       IMG_UINT32 ui32BufferArrayLength;
50827 +       IMG_BOOL bDumpPolls;
50828 +} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY;
50829 +
50830 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG
50831 +{
50832 +       IMG_UINT32 ui32BridgeFlags;
50833 +       IMG_HANDLE hDevCookie;
50834 +       IMG_UINT32 ui32DumpFrameNum;
50835 +       IMG_BOOL bLastFrame;
50836 +       IMG_UINT32 *pui32Registers;
50837 +       IMG_UINT32 ui32NumRegisters;
50838 +}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS;
50839 +
50840 +typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG
50841 +{
50842 +       IMG_UINT32 ui32BridgeFlags;
50843 +       IMG_UINT32 ui32DumpFrameNum;
50844 +       IMG_BOOL bLastFrame;
50845 +       IMG_UINT32 *pui32Registers;
50846 +       IMG_UINT32 ui32NumRegisters;
50847 +}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS;
50848 +
50849 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG
50850 +{
50851 +       IMG_UINT32 ui32BridgeFlags;
50852 +       IMG_HANDLE hDevCookie;
50853 +       IMG_UINT32 ui32DumpFrameNum;
50854 +       IMG_UINT32 ui32TAKickCount;
50855 +       IMG_BOOL bLastFrame;
50856 +       IMG_UINT32 *pui32Registers;
50857 +       IMG_UINT32 ui32NumRegisters;
50858 +}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS;
50859 +
50860 +typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG
50861 +{
50862 +       IMG_UINT32                      ui32BridgeFlags;
50863 +       IMG_HANDLE                      hDevCookie;
50864 +       IMG_CHAR                        szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
50865 +       IMG_UINT32                      ui32FileOffset;
50866 +       IMG_UINT32                      ui32PDumpFlags;
50867 +
50868 +}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB;
50869 +
50870 +#endif
50871 +
50872 +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
50873 +{
50874 +       IMG_UINT32 ui32BridgeFlags;
50875 +       IMG_HANDLE hDevCookie;
50876 +       IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
50877 +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
50878 +
50879 +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
50880 +{
50881 +       PVRSRV_ERROR eError;
50882 +       IMG_HANDLE hHWRenderContext;
50883 +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
50884 +
50885 +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
50886 +{
50887 +       IMG_UINT32 ui32BridgeFlags;
50888 +       IMG_HANDLE hDevCookie;
50889 +       IMG_HANDLE hHWRenderContext;
50890 +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT;
50891 +
50892 +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
50893 +{
50894 +       IMG_UINT32 ui32BridgeFlags;
50895 +       IMG_HANDLE hDevCookie;
50896 +       IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
50897 +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
50898 +
50899 +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
50900 +{
50901 +       PVRSRV_ERROR eError;
50902 +       IMG_HANDLE hHWTransferContext;
50903 +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
50904 +
50905 +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
50906 +{
50907 +       IMG_UINT32 ui32BridgeFlags;
50908 +       IMG_HANDLE hDevCookie;
50909 +       IMG_HANDLE hHWTransferContext;
50910 +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT;
50911 +
50912 +typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG
50913 +{
50914 +       IMG_UINT32 ui32BridgeFlags;
50915 +       IMG_HANDLE hDevCookie;
50916 +       IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr;
50917 +}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET;
50918 +
50919 +
50920 +#if defined(SGX_FEATURE_2D_HARDWARE)
50921 +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
50922 +{
50923 +       IMG_UINT32 ui32BridgeFlags;
50924 +       IMG_HANDLE hDevCookie;
50925 +       IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
50926 +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
50927 +
50928 +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
50929 +{
50930 +       PVRSRV_ERROR eError;
50931 +       IMG_HANDLE hHW2DContext;
50932 +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
50933 +
50934 +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
50935 +{
50936 +       IMG_UINT32 ui32BridgeFlags;
50937 +       IMG_HANDLE hDevCookie;
50938 +       IMG_HANDLE hHW2DContext;
50939 +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT;
50940 +
50941 +#define        SGX2D_MAX_BLT_CMD_SIZ           256
50942 +#endif
50943 +
50944 +
50945 +typedef struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS_TAG
50946 +{
50947 +       IMG_UINT32              ui32BridgeFlags;
50948 +       IMG_HANDLE              hDevCookie;
50949 +       IMG_UINT32              ui32Reg;
50950 +       IMG_BOOL                bNew;
50951 +       IMG_UINT32              ui32New;
50952 +       IMG_UINT32              ui32NewReset;
50953 +       IMG_UINT32              ui32CountersReg;
50954 +       IMG_UINT32              ui32Reg2;
50955 +} PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS;
50956 +
50957 +typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS_TAG
50958 +{
50959 +       PVRSRV_ERROR                            eError;
50960 +       IMG_UINT32                                      ui32Old;
50961 +       IMG_BOOL                                        bActive;
50962 +       PVRSRV_SGXDEV_DIFF_INFO         sDiffs;
50963 +} PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS;
50964 +
50965 +
50966 +#if defined(SUPPORT_SGX_HWPERF)
50967 +typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG
50968 +{
50969 +       IMG_UINT32                                      ui32BridgeFlags;
50970 +       IMG_HANDLE                                      hDevCookie;
50971 +       IMG_UINT32                                      ui32ArraySize;
50972 +       PVRSRV_SGX_HWPERF_CB_ENTRY      *psHWPerfCBData;
50973 +} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB;
50974 +
50975 +typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG
50976 +{
50977 +       PVRSRV_ERROR            eError;
50978 +       IMG_UINT32                      ui32DataCount;
50979 +       IMG_UINT32                      ui32ClockSpeed;
50980 +       IMG_UINT32                      ui32HostTimeStamp;
50981 +} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB;
50982 +#endif
50983 +
50984 +#if defined (__cplusplus)
50985 +}
50986 +#endif
50987 +
50988 +#endif
50989 +
50990 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/sgx_mkif_km.h b/drivers/gpu/drm/mrst/pvr/services4/include/sgx_mkif_km.h
50991 new file mode 100644
50992 index 0000000..99f29db
50993 --- /dev/null
50994 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/sgx_mkif_km.h
50995 @@ -0,0 +1,334 @@
50996 +/**********************************************************************
50997 + *
50998 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
50999 + *
51000 + * This program is free software; you can redistribute it and/or modify it
51001 + * under the terms and conditions of the GNU General Public License,
51002 + * version 2, as published by the Free Software Foundation.
51003 + *
51004 + * This program is distributed in the hope it will be useful but, except
51005 + * as otherwise stated in writing, without any warranty; without even the
51006 + * implied warranty of merchantability or fitness for a particular purpose.
51007 + * See the GNU General Public License for more details.
51008 + *
51009 + * You should have received a copy of the GNU General Public License along with
51010 + * this program; if not, write to the Free Software Foundation, Inc.,
51011 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
51012 + *
51013 + * The full GNU General Public License is included in this distribution in
51014 + * the file called "COPYING".
51015 + *
51016 + * Contact Information:
51017 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
51018 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
51019 + *
51020 + ******************************************************************************/
51021 +
51022 +#if !defined (__SGX_MKIF_KM_H__)
51023 +#define __SGX_MKIF_KM_H__
51024 +
51025 +#include "img_types.h"
51026 +#include "servicesint.h"
51027 +#include "sgxapi_km.h"
51028 +
51029 +
51030 +#if defined(SGX_FEATURE_MP)
51031 +       #define SGX_REG_BANK_SHIFT                      (12)
51032 +       #define SGX_REG_BANK_SIZE                       (0x4000)
51033 +       #if defined(SGX541)
51034 +               #define SGX_REG_BANK_BASE_INDEX         (1)
51035 +               #define SGX_REG_BANK_MASTER_INDEX       (SGX_REG_BANK_BASE_INDEX + SGX_FEATURE_MP_CORE_COUNT)
51036 +       #else
51037 +               #define SGX_REG_BANK_BASE_INDEX         (2)
51038 +               #define SGX_REG_BANK_MASTER_INDEX       (1)
51039 +       #endif
51040 +       #define SGX_MP_CORE_SELECT(x,i)         (x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE))
51041 +       #define SGX_MP_MASTER_SELECT(x)         (x + (SGX_REG_BANK_MASTER_INDEX * SGX_REG_BANK_SIZE))
51042 +#else
51043 +       #define SGX_MP_CORE_SELECT(x,i)         (x)
51044 +#endif
51045 +
51046 +
51047 +typedef struct _SGXMKIF_COMMAND_
51048 +{
51049 +       IMG_UINT32                              ui32ServiceAddress;
51050 +       IMG_UINT32                              ui32CacheControl;
51051 +       IMG_UINT32                              ui32Data[2];
51052 +} SGXMKIF_COMMAND;
51053 +
51054 +
51055 +typedef struct _PVRSRV_SGX_KERNEL_CCB_
51056 +{
51057 +       SGXMKIF_COMMAND         asCommands[256];
51058 +} PVRSRV_SGX_KERNEL_CCB;
51059 +
51060 +
51061 +typedef struct _PVRSRV_SGX_CCB_CTL_
51062 +{
51063 +       IMG_UINT32                              ui32WriteOffset;
51064 +       IMG_UINT32                              ui32ReadOffset;
51065 +} PVRSRV_SGX_CCB_CTL;
51066 +
51067 +
51068 +typedef struct _SGXMKIF_HOST_CTL_
51069 +{
51070 +#if defined(PVRSRV_USSE_EDM_BREAKPOINTS)
51071 +       IMG_UINT32                              ui32BreakpointDisable;
51072 +       IMG_UINT32                              ui32Continue;
51073 +#endif
51074 +
51075 +       volatile IMG_UINT32             ui32InitStatus;
51076 +       volatile IMG_UINT32             ui32PowerStatus;
51077 +       volatile IMG_UINT32             ui32CleanupStatus;
51078 +#if defined(SUPPORT_HW_RECOVERY)
51079 +       IMG_UINT32                              ui32uKernelDetectedLockups;
51080 +       IMG_UINT32                              ui32HostDetectedLockups;
51081 +       IMG_UINT32                              ui32HWRecoverySampleRate;
51082 +#endif
51083 +       IMG_UINT32                              ui32uKernelTimerClock;
51084 +       IMG_UINT32                              ui32ActivePowManSampleRate;
51085 +       IMG_UINT32                              ui32InterruptFlags;
51086 +       IMG_UINT32                              ui32InterruptClearFlags;
51087 +
51088 +
51089 +       IMG_UINT32                              ui32NumActivePowerEvents;
51090 +
51091 +#if defined(SUPPORT_SGX_HWPERF)
51092 +       IMG_UINT32                      ui32HWPerfFlags;
51093 +#endif
51094 +
51095 +
51096 +       IMG_UINT32                      ui32TimeWraps;
51097 +} SGXMKIF_HOST_CTL;
51098 +
51099 +#define        SGXMKIF_CMDTA_CTRLFLAGS_READY                   0x00000001
51100 +typedef struct _SGXMKIF_CMDTA_SHARED_
51101 +{
51102 +       IMG_UINT32                      ui32CtrlFlags;
51103 +
51104 +       IMG_UINT32                      ui32NumTAStatusVals;
51105 +       IMG_UINT32                      ui32Num3DStatusVals;
51106 +
51107 +
51108 +       IMG_UINT32                      ui32TATQSyncWriteOpsPendingVal;
51109 +       IMG_DEV_VIRTADDR        sTATQSyncWriteOpsCompleteDevVAddr;
51110 +       IMG_UINT32                      ui32TATQSyncReadOpsPendingVal;
51111 +       IMG_DEV_VIRTADDR        sTATQSyncReadOpsCompleteDevVAddr;
51112 +
51113 +
51114 +       IMG_UINT32                      ui323DTQSyncWriteOpsPendingVal;
51115 +       IMG_DEV_VIRTADDR        s3DTQSyncWriteOpsCompleteDevVAddr;
51116 +       IMG_UINT32                      ui323DTQSyncReadOpsPendingVal;
51117 +       IMG_DEV_VIRTADDR        s3DTQSyncReadOpsCompleteDevVAddr;
51118 +
51119 +
51120 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
51121 +
51122 +       IMG_UINT32                                      ui32NumTASrcSyncs;
51123 +       PVRSRV_DEVICE_SYNC_OBJECT       asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS];
51124 +       IMG_UINT32                                      ui32NumTADstSyncs;
51125 +       PVRSRV_DEVICE_SYNC_OBJECT       asTADstSyncs[SGX_MAX_TA_DST_SYNCS];
51126 +       IMG_UINT32                                      ui32Num3DSrcSyncs;
51127 +       PVRSRV_DEVICE_SYNC_OBJECT       as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS];
51128 +#else
51129 +
51130 +       IMG_UINT32                      ui32NumSrcSyncs;
51131 +       PVRSRV_DEVICE_SYNC_OBJECT       asSrcSyncs[SGX_MAX_SRC_SYNCS];
51132 +#endif
51133 +
51134 +
51135 +       PVRSRV_DEVICE_SYNC_OBJECT       sTA3DDependency;
51136 +
51137 +       CTL_STATUS                      sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
51138 +       CTL_STATUS                      sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
51139 +
51140 +} SGXMKIF_CMDTA_SHARED;
51141 +
51142 +#define SGXTQ_MAX_STATUS                                               SGX_MAX_TRANSFER_STATUS_VALS + 2
51143 +
51144 +#define SGXMKIF_TQFLAGS_NOSYNCUPDATE                   0x00000001
51145 +#define SGXMKIF_TQFLAGS_KEEPPENDING                            0x00000002
51146 +#define SGXMKIF_TQFLAGS_TATQ_SYNC                              0x00000004
51147 +#define SGXMKIF_TQFLAGS_3DTQ_SYNC                              0x00000008
51148 +#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH)
51149 +#define SGXMKIF_TQFLAGS_CTXSWITCH                              0x00000010
51150 +#endif
51151 +#define SGXMKIF_TQFLAGS_DUMMYTRANSFER                  0x00000020
51152 +
51153 +typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
51154 +{
51155 +
51156 +
51157 +       IMG_UINT32              ui32SrcReadOpPendingVal;
51158 +       IMG_DEV_VIRTADDR        sSrcReadOpsCompleteDevAddr;
51159 +
51160 +       IMG_UINT32              ui32SrcWriteOpPendingVal;
51161 +       IMG_DEV_VIRTADDR        sSrcWriteOpsCompleteDevAddr;
51162 +
51163 +
51164 +
51165 +       IMG_UINT32              ui32DstReadOpPendingVal;
51166 +       IMG_DEV_VIRTADDR        sDstReadOpsCompleteDevAddr;
51167 +
51168 +       IMG_UINT32              ui32DstWriteOpPendingVal;
51169 +       IMG_DEV_VIRTADDR        sDstWriteOpsCompleteDevAddr;
51170 +
51171 +
51172 +       IMG_UINT32              ui32TASyncWriteOpsPendingVal;
51173 +       IMG_DEV_VIRTADDR        sTASyncWriteOpsCompleteDevVAddr;
51174 +       IMG_UINT32              ui32TASyncReadOpsPendingVal;
51175 +       IMG_DEV_VIRTADDR        sTASyncReadOpsCompleteDevVAddr;
51176 +
51177 +
51178 +       IMG_UINT32              ui323DSyncWriteOpsPendingVal;
51179 +       IMG_DEV_VIRTADDR        s3DSyncWriteOpsCompleteDevVAddr;
51180 +       IMG_UINT32              ui323DSyncReadOpsPendingVal;
51181 +       IMG_DEV_VIRTADDR        s3DSyncReadOpsCompleteDevVAddr;
51182 +
51183 +       IMG_UINT32              ui32NumStatusVals;
51184 +       CTL_STATUS      sCtlStatusInfo[SGXTQ_MAX_STATUS];
51185 +} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED;
51186 +
51187 +
51188 +#if defined(SGX_FEATURE_2D_HARDWARE)
51189 +typedef struct _SGXMKIF_2DCMD_SHARED_ {
51190 +
51191 +       IMG_UINT32                      ui32NumSrcSync;
51192 +       PVRSRV_DEVICE_SYNC_OBJECT       sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS];
51193 +
51194 +
51195 +       PVRSRV_DEVICE_SYNC_OBJECT       sDstSyncData;
51196 +
51197 +
51198 +       PVRSRV_DEVICE_SYNC_OBJECT       sTASyncData;
51199 +
51200 +
51201 +       PVRSRV_DEVICE_SYNC_OBJECT       s3DSyncData;
51202 +} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED;
51203 +#endif
51204 +
51205 +
51206 +typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
51207 +{
51208 +       IMG_DEV_VIRTADDR        sAccessDevAddr;
51209 +       IMG_UINT32                      ui32NumSyncObjects;
51210 +
51211 +       PVRSRV_DEVICE_SYNC_OBJECT       asSyncData[1];
51212 +} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST;
51213 +
51214 +
51215 +#define PVRSRV_USSE_EDM_INIT_COMPLETE                  (1UL << 0)
51216 +
51217 +#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE                           (1UL << 2)
51218 +#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE                       (1UL << 3)
51219 +#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE      (1UL << 4)
51220 +#define PVRSRV_USSE_EDM_POWMAN_NO_WORK                                         (1UL << 5)
51221 +
51222 +#define PVRSRV_USSE_EDM_INTERRUPT_HWR                  (1UL << 0)
51223 +#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1)
51224 +
51225 +#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE    (1UL << 0)
51226 +
51227 +#define PVRSRV_USSE_MISCINFO_READY             0x1UL
51228 +#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES  0x2UL
51229 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
51230 +#define PVRSRV_USSE_MISCINFO_MEMREAD                   0x4UL
51231 +
51232 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
51233 +#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL              0x1UL << 31;
51234 +#endif
51235 +#endif
51236 +
51237 +
51238 +#define        PVRSRV_CLEANUPCMD_RT            0x1
51239 +#define        PVRSRV_CLEANUPCMD_RC            0x2
51240 +#define        PVRSRV_CLEANUPCMD_TC            0x3
51241 +#define        PVRSRV_CLEANUPCMD_2DC           0x4
51242 +#define        PVRSRV_CLEANUPCMD_PB            0x5
51243 +
51244 +#define PVRSRV_POWERCMD_POWEROFF       0x1
51245 +#define PVRSRV_POWERCMD_IDLE           0x2
51246 +#define PVRSRV_POWERCMD_RESUME         0x3
51247 +
51248 +
51249 +#if defined(SGX_FEATURE_BIF_NUM_DIRLISTS)
51250 +#define SGX_BIF_DIR_LIST_INDEX_EDM     (SGX_FEATURE_BIF_NUM_DIRLISTS - 1)
51251 +#else
51252 +#define SGX_BIF_DIR_LIST_INDEX_EDM     (0)
51253 +#endif
51254 +
51255 +#define        SGX_BIF_INVALIDATE_PTCACHE      0x1
51256 +#define        SGX_BIF_INVALIDATE_PDCACHE      0x2
51257 +#define SGX_BIF_INVALIDATE_SLCACHE     0x4
51258 +
51259 +
51260 +typedef struct _SGX_MISCINFO_STRUCT_SIZES_
51261 +{
51262 +#if defined (SGX_FEATURE_2D_HARDWARE)
51263 +       IMG_UINT32      ui32Sizeof_2DCMD;
51264 +       IMG_UINT32      ui32Sizeof_2DCMD_SHARED;
51265 +#endif
51266 +       IMG_UINT32      ui32Sizeof_CMDTA;
51267 +       IMG_UINT32      ui32Sizeof_CMDTA_SHARED;
51268 +       IMG_UINT32      ui32Sizeof_TRANSFERCMD;
51269 +       IMG_UINT32      ui32Sizeof_TRANSFERCMD_SHARED;
51270 +       IMG_UINT32      ui32Sizeof_3DREGISTERS;
51271 +       IMG_UINT32      ui32Sizeof_HWPBDESC;
51272 +       IMG_UINT32      ui32Sizeof_HWRENDERCONTEXT;
51273 +       IMG_UINT32      ui32Sizeof_HWRENDERDETAILS;
51274 +       IMG_UINT32      ui32Sizeof_HWRTDATA;
51275 +       IMG_UINT32      ui32Sizeof_HWRTDATASET;
51276 +       IMG_UINT32      ui32Sizeof_HWTRANSFERCONTEXT;
51277 +       IMG_UINT32      ui32Sizeof_HOST_CTL;
51278 +       IMG_UINT32      ui32Sizeof_COMMAND;
51279 +} SGX_MISCINFO_STRUCT_SIZES;
51280 +
51281 +
51282 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
51283 +typedef struct _PVRSRV_SGX_MISCINFO_MEMREAD
51284 +{
51285 +       IMG_DEV_VIRTADDR        sDevVAddr;
51286 +       IMG_DEV_PHYADDR         sPDDevPAddr;
51287 +} PVRSRV_SGX_MISCINFO_MEMREAD;
51288 +#endif
51289 +
51290 +typedef struct _PVRSRV_SGX_MISCINFO_INFO
51291 +{
51292 +       IMG_UINT32                                              ui32MiscInfoFlags;
51293 +       PVRSRV_SGX_MISCINFO_FEATURES    sSGXFeatures;
51294 +       SGX_MISCINFO_STRUCT_SIZES               sSGXStructSizes;
51295 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
51296 +       PVRSRV_SGX_MISCINFO_MEMREAD             sSGXMemReadData;
51297 +#endif
51298 +} PVRSRV_SGX_MISCINFO_INFO;
51299 +
51300 +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
51301 +#define SGXMK_TRACE_BUFFER_SIZE 512
51302 +#endif
51303 +
51304 +#define SGXMKIF_HWPERF_CB_SIZE                                 0x100
51305 +
51306 +#if defined(SUPPORT_SGX_HWPERF)
51307 +typedef struct _SGXMKIF_HWPERF_CB_ENTRY_
51308 +{
51309 +       IMG_UINT32      ui32FrameNo;
51310 +       IMG_UINT32      ui32Type;
51311 +       IMG_UINT32      ui32Ordinal;
51312 +       IMG_UINT32      ui32TimeWraps;
51313 +       IMG_UINT32      ui32Time;
51314 +       IMG_UINT32      ui32Counters[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
51315 +} SGXMKIF_HWPERF_CB_ENTRY;
51316 +
51317 +typedef struct _SGXMKIF_HWPERF_CB_
51318 +{
51319 +       IMG_UINT32                              ui32Woff;
51320 +       IMG_UINT32                              ui32Roff;
51321 +       IMG_UINT32                              ui32OrdinalGRAPHICS;
51322 +       IMG_UINT32                              ui32OrdinalMK_EXECUTION;
51323 +       SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE];
51324 +} SGXMKIF_HWPERF_CB;
51325 +#endif
51326 +
51327 +
51328 +#endif
51329 +
51330 diff --git a/drivers/gpu/drm/mrst/pvr/services4/include/sgxinfo.h b/drivers/gpu/drm/mrst/pvr/services4/include/sgxinfo.h
51331 new file mode 100644
51332 index 0000000..8caa7af
51333 --- /dev/null
51334 +++ b/drivers/gpu/drm/mrst/pvr/services4/include/sgxinfo.h
51335 @@ -0,0 +1,288 @@
51336 +/**********************************************************************
51337 + *
51338 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
51339 + *
51340 + * This program is free software; you can redistribute it and/or modify it
51341 + * under the terms and conditions of the GNU General Public License,
51342 + * version 2, as published by the Free Software Foundation.
51343 + *
51344 + * This program is distributed in the hope it will be useful but, except
51345 + * as otherwise stated in writing, without any warranty; without even the
51346 + * implied warranty of merchantability or fitness for a particular purpose.
51347 + * See the GNU General Public License for more details.
51348 + *
51349 + * You should have received a copy of the GNU General Public License along with
51350 + * this program; if not, write to the Free Software Foundation, Inc.,
51351 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
51352 + *
51353 + * The full GNU General Public License is included in this distribution in
51354 + * the file called "COPYING".
51355 + *
51356 + * Contact Information:
51357 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
51358 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
51359 + *
51360 + ******************************************************************************/
51361 +
51362 +#if !defined (__SGXINFO_H__)
51363 +#define __SGXINFO_H__
51364 +
51365 +#include "sgxscript.h"
51366 +#include "servicesint.h"
51367 +#include "services.h"
51368 +#include "sgxapi_km.h"
51369 +#include "sgx_mkif_km.h"
51370 +
51371 +
51372 +#define SGX_MAX_DEV_DATA                       24
51373 +#define        SGX_MAX_INIT_MEM_HANDLES        16
51374 +
51375 +
51376 +typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT
51377 +{
51378 +       IMG_DEV_PHYADDR sPDDevPAddr;
51379 +       PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
51380 +} SGX_BRIDGE_INFO_FOR_SRVINIT;
51381 +
51382 +
51383 +typedef enum _SGXMKIF_CMD_TYPE_
51384 +{
51385 +       SGXMKIF_CMD_TA                          = 0,
51386 +       SGXMKIF_CMD_TRANSFER            = 1,
51387 +       SGXMKIF_CMD_2D                          = 2,
51388 +       SGXMKIF_CMD_POWER                       = 3,
51389 +       SGXMKIF_CMD_CLEANUP                     = 4,
51390 +       SGXMKIF_CMD_GETMISCINFO         = 5,
51391 +       SGXMKIF_CMD_PROCESS_QUEUES      = 6,
51392 +       SGXMKIF_CMD_MAX                         = 7,
51393 +
51394 +       SGXMKIF_CMD_FORCE_I32           = -1,
51395 +
51396 +} SGXMKIF_CMD_TYPE;
51397 +
51398 +
51399 +typedef struct _SGX_BRIDGE_INIT_INFO_
51400 +{
51401 +       IMG_HANDLE      hKernelCCBMemInfo;
51402 +       IMG_HANDLE      hKernelCCBCtlMemInfo;
51403 +       IMG_HANDLE      hKernelCCBEventKickerMemInfo;
51404 +       IMG_HANDLE      hKernelSGXHostCtlMemInfo;
51405 +       IMG_HANDLE      hKernelSGXTA3DCtlMemInfo;
51406 +       IMG_HANDLE      hKernelSGXMiscMemInfo;
51407 +
51408 +       IMG_UINT32      aui32HostKickAddr[SGXMKIF_CMD_MAX];
51409 +
51410 +       SGX_INIT_SCRIPTS sScripts;
51411 +
51412 +       IMG_UINT32      ui32ClientBuildOptions;
51413 +       SGX_MISCINFO_STRUCT_SIZES       sSGXStructSizes;
51414 +
51415 +#if defined(SGX_SUPPORT_HWPROFILING)
51416 +       IMG_HANDLE      hKernelHWProfilingMemInfo;
51417 +#endif
51418 +#if defined(SUPPORT_SGX_HWPERF)
51419 +       IMG_HANDLE      hKernelHWPerfCBMemInfo;
51420 +#endif
51421 +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
51422 +       IMG_HANDLE      hKernelEDMStatusBufferMemInfo;
51423 +#endif
51424 +#if defined(SGX_FEATURE_OVERLAPPED_SPM)
51425 +       IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
51426 +#endif
51427 +#if defined(SGX_FEATURE_SPM_MODE_0)
51428 +       IMG_HANDLE hKernelTmpDPMStateMemInfo;
51429 +#endif
51430 +
51431 +       IMG_UINT32 ui32EDMTaskReg0;
51432 +       IMG_UINT32 ui32EDMTaskReg1;
51433 +
51434 +       IMG_UINT32 ui32ClkGateStatusReg;
51435 +       IMG_UINT32 ui32ClkGateStatusMask;
51436 +#if defined(SGX_FEATURE_MP)
51437 +       IMG_UINT32 ui32MasterClkGateStatusReg;
51438 +       IMG_UINT32 ui32MasterClkGateStatusMask;
51439 +#endif
51440 +
51441 +       IMG_UINT32 ui32CacheControl;
51442 +
51443 +       IMG_UINT32      asInitDevData[SGX_MAX_DEV_DATA];
51444 +       IMG_HANDLE      asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
51445 +
51446 +} SGX_BRIDGE_INIT_INFO;
51447 +
51448 +
51449 +typedef struct _SGX_DEVICE_SYNC_LIST_
51450 +{
51451 +       PSGXMKIF_HWDEVICE_SYNC_LIST     psHWDeviceSyncList;
51452 +
51453 +       IMG_HANDLE                              hKernelHWSyncListMemInfo;
51454 +       PVRSRV_CLIENT_MEM_INFO  *psHWDeviceSyncListClientMemInfo;
51455 +       PVRSRV_CLIENT_MEM_INFO  *psAccessResourceClientMemInfo;
51456 +
51457 +       volatile IMG_UINT32             *pui32Lock;
51458 +
51459 +       struct _SGX_DEVICE_SYNC_LIST_   *psNext;
51460 +
51461 +
51462 +       IMG_UINT32                      ui32NumSyncObjects;
51463 +       IMG_HANDLE                      ahSyncHandles[1];
51464 +} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST;
51465 +
51466 +
51467 +typedef struct _SGX_INTERNEL_STATUS_UPDATE_
51468 +{
51469 +       CTL_STATUS                              sCtlStatus;
51470 +       IMG_HANDLE                              hKernelMemInfo;
51471 +
51472 +       IMG_UINT32                              ui32LastStatusUpdateDumpVal;
51473 +} SGX_INTERNEL_STATUS_UPDATE;
51474 +
51475 +
51476 +typedef struct _SGX_CCB_KICK_
51477 +{
51478 +       SGXMKIF_COMMAND         sCommand;
51479 +       IMG_HANDLE                      hCCBKernelMemInfo;
51480 +
51481 +       IMG_UINT32      ui32NumDstSyncObjects;
51482 +       IMG_HANDLE      hKernelHWSyncListMemInfo;
51483 +
51484 +
51485 +       IMG_HANDLE      *pahDstSyncHandles;
51486 +
51487 +       IMG_UINT32      ui32NumTAStatusVals;
51488 +       IMG_UINT32      ui32Num3DStatusVals;
51489 +
51490 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
51491 +       SGX_INTERNEL_STATUS_UPDATE      asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
51492 +       SGX_INTERNEL_STATUS_UPDATE      as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS];
51493 +#else
51494 +       IMG_HANDLE      ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
51495 +       IMG_HANDLE      ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
51496 +#endif
51497 +
51498 +       IMG_BOOL        bFirstKickOrResume;
51499 +#if (defined(NO_HARDWARE) || defined(PDUMP))
51500 +       IMG_BOOL        bTerminateOrAbort;
51501 +#endif
51502 +#if defined(SUPPORT_SGX_HWPERF)
51503 +       IMG_BOOL                        bKickRender;
51504 +#endif
51505 +
51506 +
51507 +       IMG_UINT32      ui32CCBOffset;
51508 +
51509 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
51510 +
51511 +       IMG_UINT32      ui32NumTASrcSyncs;
51512 +       IMG_HANDLE      ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
51513 +       IMG_UINT32      ui32NumTADstSyncs;
51514 +       IMG_HANDLE      ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
51515 +       IMG_UINT32      ui32Num3DSrcSyncs;
51516 +       IMG_HANDLE      ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
51517 +#else
51518 +
51519 +       IMG_UINT32      ui32NumSrcSyncs;
51520 +       IMG_HANDLE      ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
51521 +#endif
51522 +
51523 +
51524 +       IMG_BOOL        bTADependency;
51525 +       IMG_HANDLE      hTA3DSyncInfo;
51526 +
51527 +       IMG_HANDLE      hTASyncInfo;
51528 +       IMG_HANDLE      h3DSyncInfo;
51529 +#if defined(PDUMP)
51530 +       IMG_UINT32      ui32CCBDumpWOff;
51531 +#endif
51532 +#if defined(NO_HARDWARE)
51533 +       IMG_UINT32      ui32WriteOpsPendingVal;
51534 +#endif
51535 +} SGX_CCB_KICK;
51536 +
51537 +
51538 +#define SGX_KERNEL_USE_CODE_BASE_INDEX         15
51539 +
51540 +
51541 +typedef struct _SGX_CLIENT_INFO_
51542 +{
51543 +       IMG_UINT32                                      ui32ProcessID;
51544 +       IMG_VOID                                        *pvProcess;
51545 +       PVRSRV_MISC_INFO                        sMiscInfo;
51546 +
51547 +       IMG_UINT32                                      asDevData[SGX_MAX_DEV_DATA];
51548 +
51549 +} SGX_CLIENT_INFO;
51550 +
51551 +typedef struct _SGX_INTERNAL_DEVINFO_
51552 +{
51553 +       IMG_UINT32                      ui32Flags;
51554 +       IMG_HANDLE                      hHostCtlKernelMemInfoHandle;
51555 +       IMG_BOOL                        bForcePTOff;
51556 +} SGX_INTERNAL_DEVINFO;
51557 +
51558 +
51559 +#if defined(TRANSFER_QUEUE)
51560 +typedef struct _PVRSRV_TRANSFER_SGX_KICK_
51561 +{
51562 +       IMG_HANDLE              hCCBMemInfo;
51563 +       IMG_UINT32              ui32SharedCmdCCBOffset;
51564 +
51565 +       IMG_DEV_VIRTADDR        sHWTransferContextDevVAddr;
51566 +
51567 +       IMG_HANDLE              hTASyncInfo;
51568 +       IMG_HANDLE              h3DSyncInfo;
51569 +
51570 +       IMG_UINT32              ui32NumSrcSync;
51571 +       IMG_HANDLE              ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
51572 +
51573 +       IMG_UINT32              ui32NumDstSync;
51574 +       IMG_HANDLE              ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
51575 +
51576 +       IMG_UINT32              ui32Flags;
51577 +
51578 +       IMG_UINT32              ui32PDumpFlags;
51579 +#if defined(PDUMP)
51580 +       IMG_UINT32              ui32CCBDumpWOff;
51581 +#endif
51582 +} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK;
51583 +
51584 +#if defined(SGX_FEATURE_2D_HARDWARE)
51585 +typedef struct _PVRSRV_2D_SGX_KICK_
51586 +{
51587 +       IMG_HANDLE              hCCBMemInfo;
51588 +       IMG_UINT32              ui32SharedCmdCCBOffset;
51589 +
51590 +       IMG_DEV_VIRTADDR        sHW2DContextDevVAddr;
51591 +
51592 +       IMG_UINT32              ui32NumSrcSync;
51593 +       IMG_HANDLE              ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
51594 +
51595 +
51596 +       IMG_HANDLE              hDstSyncInfo;
51597 +
51598 +
51599 +       IMG_HANDLE              hTASyncInfo;
51600 +
51601 +
51602 +       IMG_HANDLE              h3DSyncInfo;
51603 +
51604 +       IMG_UINT32              ui32PDumpFlags;
51605 +#if defined(PDUMP)
51606 +       IMG_UINT32              ui32CCBDumpWOff;
51607 +#endif
51608 +} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK;
51609 +#endif
51610 +#endif
51611 +
51612 +#define PVRSRV_SGX_DIFF_NUM_COUNTERS   9
51613 +
51614 +typedef struct _PVRSRV_SGXDEV_DIFF_INFO_
51615 +{
51616 +       IMG_UINT32      aui32Counters[PVRSRV_SGX_DIFF_NUM_COUNTERS];
51617 +       IMG_UINT32      ui32Time[3];
51618 +       IMG_UINT32      ui32Marker[2];
51619 +} PVRSRV_SGXDEV_DIFF_INFO, *PPVRSRV_SGXDEV_DIFF_INFO;
51620 +
51621 +
51622 +
51623 +#endif
51624 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/.gitignore
51625 new file mode 100644
51626 index 0000000..2f89523
51627 --- /dev/null
51628 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/.gitignore
51629 @@ -0,0 +1,5 @@
51630 +bin_pc_i686*
51631 +tmp_pc_i686*
51632 +host_pc_i686*
51633 +*.o
51634 +*.o.cmd
51635 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c
51636 new file mode 100644
51637 index 0000000..118c1d2
51638 --- /dev/null
51639 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.c
51640 @@ -0,0 +1,3426 @@
51641 +/**********************************************************************
51642 + *
51643 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
51644 + *
51645 + * This program is free software; you can redistribute it and/or modify it
51646 + * under the terms and conditions of the GNU General Public License,
51647 + * version 2, as published by the Free Software Foundation.
51648 + *
51649 + * This program is distributed in the hope it will be useful but, except
51650 + * as otherwise stated in writing, without any warranty; without even the
51651 + * implied warranty of merchantability or fitness for a particular purpose.
51652 + * See the GNU General Public License for more details.
51653 + *
51654 + * You should have received a copy of the GNU General Public License along with
51655 + * this program; if not, write to the Free Software Foundation, Inc.,
51656 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
51657 + *
51658 + * The full GNU General Public License is included in this distribution in
51659 + * the file called "COPYING".
51660 + *
51661 + * Contact Information:
51662 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
51663 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
51664 + *
51665 + ******************************************************************************/
51666 +
51667 +
51668 +
51669 +#include <stddef.h>
51670 +
51671 +#include "img_defs.h"
51672 +#include "services.h"
51673 +#include "pvr_bridge_km.h"
51674 +#include "pvr_debug.h"
51675 +#include "ra.h"
51676 +#include "pvr_bridge.h"
51677 +#if defined(SUPPORT_SGX)
51678 +#include "sgx_bridge.h"
51679 +#endif
51680 +#if defined(SUPPORT_VGX)
51681 +#include "vgx_bridge.h"
51682 +#endif
51683 +#if defined(SUPPORT_MSVDX)
51684 +#include "msvdx_bridge.h"
51685 +#endif
51686 +#include "perproc.h"
51687 +#include "device.h"
51688 +#include "buffer_manager.h"
51689 +
51690 +#include "pdump_km.h"
51691 +#include "syscommon.h"
51692 +
51693 +#include "bridged_pvr_bridge.h"
51694 +#if defined(SUPPORT_SGX)
51695 +#include "bridged_sgx_bridge.h"
51696 +#endif
51697 +#if defined(SUPPORT_VGX)
51698 +#include "bridged_vgx_bridge.h"
51699 +#endif
51700 +#if defined(SUPPORT_MSVDX)
51701 +#include "bridged_msvdx_bridge.h"
51702 +#endif
51703 +
51704 +#include "env_data.h"
51705 +
51706 +#if defined (__linux__)
51707 +#include "mmap.h"
51708 +#endif
51709 +
51710 +#include "srvkm.h"
51711 +
51712 +PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
51713 +
51714 +#if defined(DEBUG_BRIDGE_KM)
51715 +PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
51716 +#endif
51717 +
51718 +#if defined(PVR_SECURE_HANDLES)
51719 +static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
51720 +static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
51721 +#else
51722 +static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL;
51723 +#endif
51724 +
51725 +
51726 +#if defined(DEBUG_BRIDGE_KM)
51727 +PVRSRV_ERROR
51728 +CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
51729 +                                       IMG_UINT32 ui32BridgeID,
51730 +                                       IMG_VOID *pvDest,
51731 +                                       IMG_VOID *pvSrc,
51732 +                                       IMG_UINT32 ui32Size)
51733 +{
51734 +       g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size;
51735 +       g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size;
51736 +       return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
51737 +}
51738 +PVRSRV_ERROR
51739 +CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
51740 +                                 IMG_UINT32 ui32BridgeID,
51741 +                                 IMG_VOID *pvDest,
51742 +                                 IMG_VOID *pvSrc,
51743 +                                 IMG_UINT32 ui32Size)
51744 +{
51745 +       g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size;
51746 +       g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size;
51747 +       return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
51748 +}
51749 +#endif
51750 +
51751 +
51752 +static IMG_INT
51753 +PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID,
51754 +                                                IMG_VOID *psBridgeIn,
51755 +                                                PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
51756 +                                                PVRSRV_PER_PROCESS_DATA *psPerProc)
51757 +{
51758 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
51759 +
51760 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
51761 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
51762 +
51763 +       psEnumDeviceOUT->eError =
51764 +               PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
51765 +                                                                psEnumDeviceOUT->asDeviceIdentifier);
51766 +
51767 +       return 0;
51768 +}
51769 +
51770 +static IMG_INT
51771 +PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID,
51772 +                                                 PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
51773 +                                                 PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
51774 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
51775 +{
51776 +       IMG_HANDLE hDevCookieInt;
51777 +
51778 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
51779 +
51780 +       psAcquireDevInfoOUT->eError =
51781 +               PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
51782 +                                                                 psAcquireDevInfoIN->eDeviceType,
51783 +                                                                 &hDevCookieInt);
51784 +       if(psAcquireDevInfoOUT->eError != PVRSRV_OK)
51785 +       {
51786 +               return 0;
51787 +       }
51788 +
51789 +
51790 +               psAcquireDevInfoOUT->eError =
51791 +               PVRSRVAllocHandle(psPerProc->psHandleBase,
51792 +                                                 &psAcquireDevInfoOUT->hDevCookie,
51793 +                                                 hDevCookieInt,
51794 +                                                 PVRSRV_HANDLE_TYPE_DEV_NODE,
51795 +                                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
51796 +
51797 +       return 0;
51798 +}
51799 +
51800 +
51801 +static IMG_INT
51802 +PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
51803 +                                                          PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
51804 +                                                          PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
51805 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
51806 +{
51807 +       IMG_HANDLE hDevCookieInt;
51808 +       IMG_HANDLE hDevMemContextInt;
51809 +       IMG_UINT32 i;
51810 +       IMG_BOOL bCreated;
51811 +
51812 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
51813 +
51814 +
51815 +       NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1);
51816 +
51817 +       psCreateDevMemContextOUT->eError =
51818 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
51819 +                                                  psCreateDevMemContextIN->hDevCookie,
51820 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
51821 +
51822 +       if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
51823 +       {
51824 +               return 0;
51825 +       }
51826 +
51827 +       psCreateDevMemContextOUT->eError =
51828 +               PVRSRVCreateDeviceMemContextKM(hDevCookieInt,
51829 +                                                                          psPerProc,
51830 +                                                                          &hDevMemContextInt,
51831 +                                                                          &psCreateDevMemContextOUT->ui32ClientHeapCount,
51832 +                                                                          &psCreateDevMemContextOUT->sHeapInfo[0],
51833 +                                                                          &bCreated,
51834 +                                                                          pbSharedDeviceMemHeap);
51835 +
51836 +       if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
51837 +       {
51838 +               return 0;
51839 +       }
51840 +
51841 +
51842 +       if(bCreated)
51843 +       {
51844 +               PVRSRVAllocHandleNR(psPerProc->psHandleBase,
51845 +                                                 &psCreateDevMemContextOUT->hDevMemContext,
51846 +                                                 hDevMemContextInt,
51847 +                                                 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
51848 +                                                 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
51849 +       }
51850 +       else
51851 +       {
51852 +               psCreateDevMemContextOUT->eError =
51853 +                       PVRSRVFindHandle(psPerProc->psHandleBase,
51854 +                                                        &psCreateDevMemContextOUT->hDevMemContext,
51855 +                                                        hDevMemContextInt,
51856 +                                                        PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
51857 +               if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
51858 +               {
51859 +                       return 0;
51860 +               }
51861 +       }
51862 +
51863 +       for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++)
51864 +       {
51865 +               IMG_HANDLE hDevMemHeapExt;
51866 +
51867 +#if defined(PVR_SECURE_HANDLES)
51868 +               if(abSharedDeviceMemHeap[i])
51869 +#endif
51870 +               {
51871 +
51872 +                       PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
51873 +                                                         psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
51874 +                                                         PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
51875 +                                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
51876 +               }
51877 +#if defined(PVR_SECURE_HANDLES)
51878 +               else
51879 +               {
51880 +
51881 +                       if(bCreated)
51882 +                       {
51883 +                               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
51884 +                                                                        psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
51885 +                                                                        PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
51886 +                                                                        PVRSRV_HANDLE_ALLOC_FLAG_NONE,
51887 +                                                                        psCreateDevMemContextOUT->hDevMemContext);
51888 +                       }
51889 +                       else
51890 +                       {
51891 +                               psCreateDevMemContextOUT->eError =
51892 +                                       PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt,
51893 +                                                                        psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
51894 +                                                                        PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
51895 +                               if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
51896 +                               {
51897 +                                       return 0;
51898 +                               }
51899 +                       }
51900 +               }
51901 +#endif
51902 +               psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
51903 +       }
51904 +
51905 +       COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc);
51906 +
51907 +       return 0;
51908 +}
51909 +
51910 +static IMG_INT
51911 +PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
51912 +                                                               PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
51913 +                                                               PVRSRV_BRIDGE_RETURN *psRetOUT,
51914 +                                                               PVRSRV_PER_PROCESS_DATA *psPerProc)
51915 +{
51916 +       IMG_HANDLE hDevCookieInt;
51917 +       IMG_HANDLE hDevMemContextInt;
51918 +       IMG_BOOL bDestroyed;
51919 +
51920 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
51921 +
51922 +       psRetOUT->eError =
51923 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
51924 +                                                  psDestroyDevMemContextIN->hDevCookie,
51925 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
51926 +
51927 +       if(psRetOUT->eError != PVRSRV_OK)
51928 +       {
51929 +               return 0;
51930 +       }
51931 +
51932 +       psRetOUT->eError =
51933 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
51934 +                                                  psDestroyDevMemContextIN->hDevMemContext,
51935 +                                                  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
51936 +
51937 +       if(psRetOUT->eError != PVRSRV_OK)
51938 +       {
51939 +               return 0;
51940 +       }
51941 +
51942 +       psRetOUT->eError =
51943 +               PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed);
51944 +
51945 +       if(psRetOUT->eError != PVRSRV_OK)
51946 +       {
51947 +               return 0;
51948 +       }
51949 +
51950 +       if(bDestroyed)
51951 +       {
51952 +               psRetOUT->eError =
51953 +                       PVRSRVReleaseHandle(psPerProc->psHandleBase,
51954 +                                                               psDestroyDevMemContextIN->hDevMemContext,
51955 +                                                               PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
51956 +       }
51957 +
51958 +       return 0;
51959 +}
51960 +
51961 +
51962 +static IMG_INT
51963 +PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID,
51964 +                                                          PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
51965 +                                                          PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
51966 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
51967 +{
51968 +       IMG_HANDLE hDevCookieInt;
51969 +       IMG_HANDLE hDevMemContextInt;
51970 +       IMG_UINT32 i;
51971 +
51972 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
51973 +
51974 +       NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS);
51975 +
51976 +       psGetDevMemHeapInfoOUT->eError =
51977 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
51978 +                                                  psGetDevMemHeapInfoIN->hDevCookie,
51979 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
51980 +
51981 +       if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
51982 +       {
51983 +               return 0;
51984 +       }
51985 +
51986 +       psGetDevMemHeapInfoOUT->eError =
51987 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
51988 +                                                  psGetDevMemHeapInfoIN->hDevMemContext,
51989 +                                                  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
51990 +
51991 +       if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
51992 +       {
51993 +               return 0;
51994 +       }
51995 +
51996 +       psGetDevMemHeapInfoOUT->eError =
51997 +               PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
51998 +                                                                          hDevMemContextInt,
51999 +                                                                          &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
52000 +                                                                          &psGetDevMemHeapInfoOUT->sHeapInfo[0],
52001 +                                                                          pbSharedDeviceMemHeap);
52002 +
52003 +       if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
52004 +       {
52005 +               return 0;
52006 +       }
52007 +
52008 +       for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
52009 +       {
52010 +               IMG_HANDLE hDevMemHeapExt;
52011 +
52012 +#if defined(PVR_SECURE_HANDLES)
52013 +               if(abSharedDeviceMemHeap[i])
52014 +#endif
52015 +               {
52016 +
52017 +                       PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
52018 +                                                         psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
52019 +                                                         PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
52020 +                                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
52021 +               }
52022 +#if defined(PVR_SECURE_HANDLES)
52023 +               else
52024 +               {
52025 +
52026 +                       psGetDevMemHeapInfoOUT->eError =
52027 +                               PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt,
52028 +                                                                psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
52029 +                                                                PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
52030 +                       if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
52031 +                       {
52032 +                               return 0;
52033 +                       }
52034 +               }
52035 +#endif
52036 +               psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
52037 +       }
52038 +
52039 +       COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc);
52040 +
52041 +       return 0;
52042 +}
52043 +
52044 +
52045 +#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
52046 +IMG_INT
52047 +PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
52048 +                                          PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
52049 +                                          PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
52050 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc);
52051 +#else
52052 +static IMG_INT
52053 +PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
52054 +                                          PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
52055 +                                          PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
52056 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
52057 +{
52058 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo;
52059 +       IMG_HANDLE hDevCookieInt;
52060 +       IMG_HANDLE hDevMemHeapInt;
52061 +
52062 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
52063 +
52064 +       NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2);
52065 +
52066 +       psAllocDeviceMemOUT->eError =
52067 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
52068 +                                                  psAllocDeviceMemIN->hDevCookie,
52069 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
52070 +
52071 +       if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
52072 +       {
52073 +               return 0;
52074 +       }
52075 +
52076 +       psAllocDeviceMemOUT->eError =
52077 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
52078 +                                                  psAllocDeviceMemIN->hDevMemHeap,
52079 +                                                  PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
52080 +
52081 +       if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
52082 +       {
52083 +               return 0;
52084 +       }
52085 +
52086 +       psAllocDeviceMemOUT->eError =
52087 +               PVRSRVAllocDeviceMemKM(hDevCookieInt,
52088 +                                                          psPerProc,
52089 +                                                          hDevMemHeapInt,
52090 +                                                          psAllocDeviceMemIN->ui32Attribs,
52091 +                                                          psAllocDeviceMemIN->ui32Size,
52092 +                                                          psAllocDeviceMemIN->ui32Alignment,
52093 +                                                          &psMemInfo,
52094 +                                                          "" );
52095 +
52096 +       if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
52097 +       {
52098 +               return 0;
52099 +       }
52100 +
52101 +       OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo,
52102 +                        0,
52103 +                        sizeof(psAllocDeviceMemOUT->sClientMemInfo));
52104 +
52105 +       psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
52106 +                       psMemInfo->pvLinAddrKM;
52107 +
52108 +#if defined (__linux__)
52109 +       psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0;
52110 +#else
52111 +       psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM;
52112 +#endif
52113 +       psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
52114 +       psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
52115 +       psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
52116 +       psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
52117 +
52118 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
52119 +                                         &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
52120 +                                         psMemInfo,
52121 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO,
52122 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
52123 +
52124 +       if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
52125 +       {
52126 +
52127 +               OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
52128 +                                0,
52129 +                                sizeof (PVRSRV_CLIENT_SYNC_INFO));
52130 +               psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
52131 +               psAllocDeviceMemOUT->psKernelSyncInfo = IMG_NULL;
52132 +       }
52133 +       else
52134 +       {
52135 +
52136 +               psAllocDeviceMemOUT->psKernelSyncInfo = psMemInfo->psKernelSyncInfo;
52137 +
52138 +               psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
52139 +                       psMemInfo->psKernelSyncInfo->psSyncData;
52140 +               psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
52141 +                       psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
52142 +               psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
52143 +                       psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
52144 +
52145 +               psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
52146 +                       psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
52147 +
52148 +               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
52149 +                                                        &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo,
52150 +                                                        psMemInfo->psKernelSyncInfo,
52151 +                                                        PVRSRV_HANDLE_TYPE_SYNC_INFO,
52152 +                                                        PVRSRV_HANDLE_ALLOC_FLAG_NONE,
52153 +                                                        psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
52154 +
52155 +               psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
52156 +                       &psAllocDeviceMemOUT->sClientSyncInfo;
52157 +
52158 +       }
52159 +
52160 +       COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc);
52161 +
52162 +       return 0;
52163 +}
52164 +
52165 +#endif
52166 +
52167 +static IMG_INT
52168 +PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
52169 +                                         PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
52170 +                                         PVRSRV_BRIDGE_RETURN *psRetOUT,
52171 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52172 +{
52173 +       IMG_HANDLE hDevCookieInt;
52174 +       IMG_VOID *pvKernelMemInfo;
52175 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
52176 +
52177 +
52178 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
52179 +
52180 +       psRetOUT->eError =
52181 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
52182 +                                                  psFreeDeviceMemIN->hDevCookie,
52183 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
52184 +
52185 +       if(psRetOUT->eError != PVRSRV_OK)
52186 +       {
52187 +               return 0;
52188 +       }
52189 +
52190 +       psRetOUT->eError =
52191 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
52192 +                                                  psFreeDeviceMemIN->psKernelMemInfo,
52193 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52194 +
52195 +       if(psRetOUT->eError != PVRSRV_OK)
52196 +       {
52197 +               return 0;
52198 +       }
52199 +
52200 +
52201 +       psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)pvKernelMemInfo;
52202 +
52203 +       if (psKernelMemInfo->ui32RefCount == 1)
52204 +       {
52205 +               psRetOUT->eError =
52206 +                       PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
52207 +       }
52208 +       else
52209 +       {
52210 +               PVR_DPF((PVR_DBG_WARNING, "PVRSRVFreeDeviceMemBW: mappings are open "
52211 +                                                                 "in other processes, deferring free!"));
52212 +
52213 +               psKernelMemInfo->bPendingFree = IMG_TRUE;
52214 +               psRetOUT->eError = PVRSRV_OK;
52215 +       }
52216 +
52217 +       if(psRetOUT->eError != PVRSRV_OK)
52218 +       {
52219 +               return 0;
52220 +       }
52221 +
52222 +       psRetOUT->eError =
52223 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
52224 +                                                       psFreeDeviceMemIN->psKernelMemInfo,
52225 +                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
52226 +
52227 +       return 0;
52228 +}
52229 +
52230 +
52231 +static IMG_INT
52232 +PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID,
52233 +                                         PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
52234 +                                         PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
52235 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52236 +{
52237 +       IMG_HANDLE hDevCookieInt;
52238 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
52239 +
52240 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EXPORT_DEVICEMEM);
52241 +
52242 +
52243 +       psExportDeviceMemOUT->eError =
52244 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
52245 +                                                  psExportDeviceMemIN->hDevCookie,
52246 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
52247 +
52248 +       if(psExportDeviceMemOUT->eError != PVRSRV_OK)
52249 +       {
52250 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie"));
52251 +               return 0;
52252 +       }
52253 +
52254 +
52255 +       psExportDeviceMemOUT->eError =
52256 +               PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo,
52257 +                                                  psExportDeviceMemIN->psKernelMemInfo,
52258 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52259 +
52260 +       if(psExportDeviceMemOUT->eError != PVRSRV_OK)
52261 +       {
52262 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
52263 +               return 0;
52264 +       }
52265 +
52266 +
52267 +       psExportDeviceMemOUT->eError =
52268 +               PVRSRVFindHandle(KERNEL_HANDLE_BASE,
52269 +                                                        &psExportDeviceMemOUT->hMemInfo,
52270 +                                                        psKernelMemInfo,
52271 +                                                        PVRSRV_HANDLE_TYPE_MEM_INFO);
52272 +       if(psExportDeviceMemOUT->eError == PVRSRV_OK)
52273 +       {
52274 +
52275 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
52276 +               return 0;
52277 +       }
52278 +
52279 +
52280 +       psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
52281 +                                                                                                       &psExportDeviceMemOUT->hMemInfo,
52282 +                                                                                                       psKernelMemInfo,
52283 +                                                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO,
52284 +                                                                                                       PVRSRV_HANDLE_ALLOC_FLAG_NONE);
52285 +       if (psExportDeviceMemOUT->eError != PVRSRV_OK)
52286 +       {
52287 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list"));
52288 +               return 0;
52289 +       }
52290 +
52291 +
52292 +       psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
52293 +
52294 +       return 0;
52295 +}
52296 +
52297 +
52298 +static IMG_INT
52299 +PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
52300 +                                                        PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
52301 +                                                        PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
52302 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
52303 +{
52304 +       PVRSRV_KERNEL_MEM_INFO  *psSrcKernelMemInfo = IMG_NULL;
52305 +       PVRSRV_KERNEL_MEM_INFO  *psDstKernelMemInfo = IMG_NULL;
52306 +       IMG_HANDLE                              hDstDevMemHeap = IMG_NULL;
52307 +
52308 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEV_MEMORY);
52309 +
52310 +       NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2);
52311 +
52312 +
52313 +       psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
52314 +                                                                                               (IMG_VOID**)&psSrcKernelMemInfo,
52315 +                                                                                               psMapDevMemIN->hKernelMemInfo,
52316 +                                                                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
52317 +       if(psMapDevMemOUT->eError != PVRSRV_OK)
52318 +       {
52319 +               return 0;
52320 +       }
52321 +
52322 +
52323 +       psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
52324 +                                                                                               &hDstDevMemHeap,
52325 +                                                                                               psMapDevMemIN->hDstDevMemHeap,
52326 +                                                                                               PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
52327 +       if(psMapDevMemOUT->eError != PVRSRV_OK)
52328 +       {
52329 +               return 0;
52330 +       }
52331 +
52332 +
52333 +       psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
52334 +                                                                                                 psSrcKernelMemInfo,
52335 +                                                                                                 hDstDevMemHeap,
52336 +                                                                                                 &psDstKernelMemInfo);
52337 +       if(psMapDevMemOUT->eError != PVRSRV_OK)
52338 +       {
52339 +               return 0;
52340 +       }
52341 +
52342 +       OSMemSet(&psMapDevMemOUT->sDstClientMemInfo,
52343 +                        0,
52344 +                        sizeof(psMapDevMemOUT->sDstClientMemInfo));
52345 +       OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo,
52346 +                        0,
52347 +                        sizeof(psMapDevMemOUT->sDstClientSyncInfo));
52348 +
52349 +       psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
52350 +                       psDstKernelMemInfo->pvLinAddrKM;
52351 +
52352 +       psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0;
52353 +       psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr;
52354 +       psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags;
52355 +       psMapDevMemOUT->sDstClientMemInfo.ui32AllocSize = psDstKernelMemInfo->ui32AllocSize;
52356 +       psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
52357 +
52358 +
52359 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
52360 +                                         &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
52361 +                                         psDstKernelMemInfo,
52362 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO,
52363 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
52364 +       psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
52365 +       psMapDevMemOUT->psDstKernelSyncInfo = IMG_NULL;
52366 +
52367 +
52368 +       if(psDstKernelMemInfo->psKernelSyncInfo)
52369 +       {
52370 +               psMapDevMemOUT->psDstKernelSyncInfo = psDstKernelMemInfo->psKernelSyncInfo;
52371 +
52372 +               psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
52373 +                       psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
52374 +               psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
52375 +                       psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
52376 +               psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
52377 +                       psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
52378 +
52379 +               psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
52380 +                       psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
52381 +
52382 +               psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
52383 +
52384 +               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
52385 +                                         &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo,
52386 +                                         psDstKernelMemInfo->psKernelSyncInfo,
52387 +                                         PVRSRV_HANDLE_TYPE_SYNC_INFO,
52388 +                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
52389 +                                         psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
52390 +       }
52391 +
52392 +       COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc);
52393 +
52394 +       return 0;
52395 +}
52396 +
52397 +
52398 +static IMG_INT
52399 +PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
52400 +                                                        PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
52401 +                                                        PVRSRV_BRIDGE_RETURN *psRetOUT,
52402 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
52403 +{
52404 +       PVRSRV_KERNEL_MEM_INFO  *psKernelMemInfo = IMG_NULL;
52405 +
52406 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
52407 +
52408 +       psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
52409 +                                                                                       (IMG_VOID**)&psKernelMemInfo,
52410 +                                                                                       psUnmapDevMemIN->psKernelMemInfo,
52411 +                                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
52412 +       if(psRetOUT->eError != PVRSRV_OK)
52413 +       {
52414 +               return 0;
52415 +       }
52416 +
52417 +       psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
52418 +       if(psRetOUT->eError != PVRSRV_OK)
52419 +       {
52420 +               return 0;
52421 +       }
52422 +
52423 +       psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
52424 +                                                       psUnmapDevMemIN->psKernelMemInfo,
52425 +                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
52426 +
52427 +       return 0;
52428 +}
52429 +
52430 +
52431 +
52432 +static IMG_INT
52433 +PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
52434 +                                                        PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
52435 +                                                        PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
52436 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
52437 +{
52438 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo;
52439 +       IMG_HANDLE hOSMapInfo;
52440 +       IMG_HANDLE hDeviceClassBufferInt;
52441 +       IMG_HANDLE hDevMemContextInt;
52442 +       PVRSRV_HANDLE_TYPE eHandleType;
52443 +
52444 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
52445 +
52446 +       NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2);
52447 +
52448 +
52449 +       psMapDevClassMemOUT->eError =
52450 +               PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, &hDeviceClassBufferInt,
52451 +                                                                 &eHandleType,
52452 +                                                                 psMapDevClassMemIN->hDeviceClassBuffer);
52453 +
52454 +       if(psMapDevClassMemOUT->eError != PVRSRV_OK)
52455 +       {
52456 +               return 0;
52457 +       }
52458 +
52459 +
52460 +       psMapDevClassMemOUT->eError =
52461 +       PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
52462 +                                  psMapDevClassMemIN->hDevMemContext,
52463 +                                  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
52464 +
52465 +       if(psMapDevClassMemOUT->eError != PVRSRV_OK)
52466 +       {
52467 +               return 0;
52468 +       }
52469 +
52470 +
52471 +       switch(eHandleType)
52472 +       {
52473 +#if defined(PVR_SECURE_HANDLES)
52474 +               case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
52475 +               case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
52476 +#else
52477 +               case PVRSRV_HANDLE_TYPE_NONE:
52478 +#endif
52479 +                       break;
52480 +               default:
52481 +                       psMapDevClassMemOUT->eError = PVRSRV_ERROR_GENERIC;
52482 +                       return 0;
52483 +       }
52484 +
52485 +       psMapDevClassMemOUT->eError =
52486 +               PVRSRVMapDeviceClassMemoryKM(psPerProc,
52487 +                                                                        hDevMemContextInt,
52488 +                                                                        hDeviceClassBufferInt,
52489 +                                                                        &psMemInfo,
52490 +                                                                        &hOSMapInfo);
52491 +       if(psMapDevClassMemOUT->eError != PVRSRV_OK)
52492 +       {
52493 +               return 0;
52494 +       }
52495 +
52496 +       OSMemSet(&psMapDevClassMemOUT->sClientMemInfo,
52497 +                        0,
52498 +                        sizeof(psMapDevClassMemOUT->sClientMemInfo));
52499 +       OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo,
52500 +                        0,
52501 +                        sizeof(psMapDevClassMemOUT->sClientSyncInfo));
52502 +
52503 +       psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
52504 +                       psMemInfo->pvLinAddrKM;
52505 +
52506 +       psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0;
52507 +       psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
52508 +       psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
52509 +       psMapDevClassMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
52510 +       psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
52511 +
52512 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
52513 +                                         &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
52514 +                                         psMemInfo,
52515 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO,
52516 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE,
52517 +                                         psMapDevClassMemIN->hDeviceClassBuffer);
52518 +
52519 +       psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
52520 +       psMapDevClassMemOUT->psKernelSyncInfo = IMG_NULL;
52521 +
52522 +
52523 +       if(psMemInfo->psKernelSyncInfo)
52524 +       {
52525 +               psMapDevClassMemOUT->psKernelSyncInfo = psMemInfo->psKernelSyncInfo;
52526 +
52527 +               psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
52528 +                       psMemInfo->psKernelSyncInfo->psSyncData;
52529 +               psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
52530 +                       psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
52531 +               psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
52532 +                       psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
52533 +
52534 +               psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
52535 +                       psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
52536 +
52537 +               psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
52538 +
52539 +               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
52540 +                                                 &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo,
52541 +                                                 psMemInfo->psKernelSyncInfo,
52542 +                                                 PVRSRV_HANDLE_TYPE_SYNC_INFO,
52543 +                                                 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
52544 +                                                 psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
52545 +       }
52546 +
52547 +       COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc);
52548 +
52549 +       return 0;
52550 +}
52551 +
52552 +static IMG_INT
52553 +PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
52554 +                                                          PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
52555 +                                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
52556 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
52557 +{
52558 +       IMG_VOID *pvKernelMemInfo;
52559 +
52560 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
52561 +
52562 +       psRetOUT->eError =
52563 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
52564 +                                                  psUnmapDevClassMemIN->psKernelMemInfo,
52565 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52566 +       if(psRetOUT->eError != PVRSRV_OK)
52567 +       {
52568 +               return 0;
52569 +       }
52570 +
52571 +       psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
52572 +
52573 +       if(psRetOUT->eError != PVRSRV_OK)
52574 +       {
52575 +               return 0;
52576 +       }
52577 +
52578 +       psRetOUT->eError =
52579 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
52580 +                                                       psUnmapDevClassMemIN->psKernelMemInfo,
52581 +                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
52582 +
52583 +       return 0;
52584 +}
52585 +
52586 +
52587 +#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW)
52588 +IMG_INT
52589 +PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
52590 +                                         PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
52591 +                                         PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
52592 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc);
52593 +#else
52594 +static IMG_INT
52595 +PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
52596 +                                         PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
52597 +                                         PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
52598 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52599 +{
52600 +       IMG_HANDLE hDevCookieInt;
52601 +       IMG_HANDLE hDevMemContextInt;
52602 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo;
52603 +       IMG_UINT32 ui32PageTableSize = 0;
52604 +       IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
52605 +
52606 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
52607 +
52608 +       NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2);
52609 +
52610 +
52611 +       psWrapExtMemOUT->eError =
52612 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
52613 +                                                  psWrapExtMemIN->hDevCookie,
52614 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
52615 +       if(psWrapExtMemOUT->eError != PVRSRV_OK)
52616 +       {
52617 +               return 0;
52618 +       }
52619 +
52620 +
52621 +       psWrapExtMemOUT->eError =
52622 +       PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
52623 +                                  psWrapExtMemIN->hDevMemContext,
52624 +                                  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
52625 +
52626 +       if(psWrapExtMemOUT->eError != PVRSRV_OK)
52627 +       {
52628 +               return 0;
52629 +       }
52630 +
52631 +       if(psWrapExtMemIN->ui32NumPageTableEntries)
52632 +       {
52633 +               ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
52634 +                                               * sizeof(IMG_SYS_PHYADDR);
52635 +
52636 +               ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
52637 +                                 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
52638 +                                 ui32PageTableSize,
52639 +                                 (IMG_VOID **)&psSysPAddr, 0,
52640 +                                 "Page Table"));
52641 +
52642 +               if(CopyFromUserWrapper(psPerProc,
52643 +                                                          ui32BridgeID,
52644 +                                                          psSysPAddr,
52645 +                                                          psWrapExtMemIN->psSysPAddr,
52646 +                                                          ui32PageTableSize) != PVRSRV_OK)
52647 +               {
52648 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,      ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
52649 +
52650 +                       return -EFAULT;
52651 +               }
52652 +       }
52653 +
52654 +       psWrapExtMemOUT->eError =
52655 +               PVRSRVWrapExtMemoryKM(hDevCookieInt,
52656 +                                                         psPerProc,
52657 +                                                         hDevMemContextInt,
52658 +                                                         psWrapExtMemIN->ui32ByteSize,
52659 +                                                         psWrapExtMemIN->ui32PageOffset,
52660 +                                                         psWrapExtMemIN->bPhysContig,
52661 +                                                         psSysPAddr,
52662 +                                                         psWrapExtMemIN->pvLinAddr,
52663 +                                                         psWrapExtMemIN->ui32Flags,
52664 +                                                         &psMemInfo);
52665 +       if(psWrapExtMemIN->ui32NumPageTableEntries)
52666 +       {
52667 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
52668 +                         ui32PageTableSize,
52669 +                         (IMG_VOID *)psSysPAddr, 0);
52670 +
52671 +       }
52672 +       if(psWrapExtMemOUT->eError != PVRSRV_OK)
52673 +       {
52674 +               return 0;
52675 +       }
52676 +
52677 +       psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
52678 +                       psMemInfo->pvLinAddrKM;
52679 +
52680 +
52681 +       psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
52682 +       psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
52683 +       psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
52684 +       psWrapExtMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize;
52685 +       psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
52686 +
52687 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
52688 +                                         &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
52689 +                                         psMemInfo,
52690 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO,
52691 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
52692 +
52693 +
52694 +       psWrapExtMemOUT->sClientSyncInfo.psSyncData =
52695 +               psMemInfo->psKernelSyncInfo->psSyncData;
52696 +       psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
52697 +               psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
52698 +       psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
52699 +               psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
52700 +
52701 +       psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
52702 +               psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
52703 +
52704 +       psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo;
52705 +
52706 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
52707 +                                         &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo,
52708 +                                         (IMG_HANDLE)psMemInfo->psKernelSyncInfo,
52709 +                                         PVRSRV_HANDLE_TYPE_SYNC_INFO,
52710 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE,
52711 +                                         psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
52712 +
52713 +       COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc);
52714 +
52715 +       return 0;
52716 +}
52717 +#endif
52718 +
52719 +static IMG_INT
52720 +PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
52721 +                                               PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
52722 +                                               PVRSRV_BRIDGE_RETURN *psRetOUT,
52723 +                                               PVRSRV_PER_PROCESS_DATA *psPerProc)
52724 +{
52725 +       IMG_VOID *pvMemInfo;
52726 +
52727 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
52728 +
52729 +       psRetOUT->eError =
52730 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
52731 +                                                  &pvMemInfo,
52732 +                                                  psUnwrapExtMemIN->hKernelMemInfo,
52733 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52734 +       if(psRetOUT->eError != PVRSRV_OK)
52735 +       {
52736 +               return 0;
52737 +       }
52738 +
52739 +       psRetOUT->eError =
52740 +               PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
52741 +       if(psRetOUT->eError != PVRSRV_OK)
52742 +       {
52743 +               return 0;
52744 +       }
52745 +
52746 +       psRetOUT->eError =
52747 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
52748 +                                                  psUnwrapExtMemIN->hKernelMemInfo,
52749 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52750 +
52751 +       return 0;
52752 +}
52753 +
52754 +static IMG_INT
52755 +PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
52756 +                                                PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
52757 +                                                PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
52758 +                                                PVRSRV_PER_PROCESS_DATA *psPerProc)
52759 +{
52760 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
52761 +
52762 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52763 +
52764 +       psGetFreeDeviceMemOUT->eError =
52765 +               PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
52766 +                                                                &psGetFreeDeviceMemOUT->ui32Total,
52767 +                                                                &psGetFreeDeviceMemOUT->ui32Free,
52768 +                                                                &psGetFreeDeviceMemOUT->ui32LargestBlock);
52769 +
52770 +       return 0;
52771 +}
52772 +
52773 +static IMG_INT
52774 +PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID,
52775 +                                                                 PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
52776 +                                                                 PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
52777 +                                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
52778 +{
52779 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
52780 +
52781 +#if defined (__linux__)
52782 +       psMMapDataOUT->eError =
52783 +               PVRMMapOSMemHandleToMMapData(psPerProc,
52784 +                                                                               psMMapDataIN->hMHandle,
52785 +                                                                               &psMMapDataOUT->ui32MMapOffset,
52786 +                                                                               &psMMapDataOUT->ui32ByteOffset,
52787 +                                                                               &psMMapDataOUT->ui32RealByteSize,
52788 +                                                                               &psMMapDataOUT->ui32UserVAddr);
52789 +#else
52790 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52791 +       PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
52792 +
52793 +       psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
52794 +#endif
52795 +       return 0;
52796 +}
52797 +
52798 +
52799 +static IMG_INT
52800 +PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID,
52801 +                                                                 PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
52802 +                                                                 PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
52803 +                                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
52804 +{
52805 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
52806 +
52807 +#if defined (__linux__)
52808 +       psMMapDataOUT->eError =
52809 +               PVRMMapReleaseMMapData(psPerProc,
52810 +                                                                               psMMapDataIN->hMHandle,
52811 +                                                                               &psMMapDataOUT->bMUnmap,
52812 +                                                                               &psMMapDataOUT->ui32RealByteSize,
52813 +                                                                               &psMMapDataOUT->ui32UserVAddr);
52814 +#else
52815 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52816 +       PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
52817 +
52818 +       psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
52819 +#endif
52820 +       return 0;
52821 +}
52822 +
52823 +
52824 +#ifdef PDUMP
52825 +static IMG_INT
52826 +PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID,
52827 +                                         IMG_VOID *psBridgeIn,
52828 +                                         PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
52829 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52830 +{
52831 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
52832 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
52833 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52834 +
52835 +       psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
52836 +       psPDumpIsCapturingOUT->eError = PVRSRV_OK;
52837 +
52838 +       return 0;
52839 +}
52840 +
52841 +static IMG_INT
52842 +PDumpCommentBW(IMG_UINT32 ui32BridgeID,
52843 +                          PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
52844 +                          PVRSRV_BRIDGE_RETURN *psRetOUT,
52845 +                          PVRSRV_PER_PROCESS_DATA *psPerProc)
52846 +{
52847 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
52848 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52849 +
52850 +       psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
52851 +                                                                         psPDumpCommentIN->ui32Flags);
52852 +       return 0;
52853 +}
52854 +
52855 +static IMG_INT
52856 +PDumpSetFrameBW(IMG_UINT32 ui32BridgeID,
52857 +                               PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
52858 +                               PVRSRV_BRIDGE_RETURN *psRetOUT,
52859 +                               PVRSRV_PER_PROCESS_DATA *psPerProc)
52860 +{
52861 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
52862 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52863 +
52864 +       psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
52865 +
52866 +       return 0;
52867 +}
52868 +
52869 +static IMG_INT
52870 +PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID,
52871 +                                       PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
52872 +                                       PVRSRV_BRIDGE_RETURN *psRetOUT,
52873 +                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
52874 +{
52875 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
52876 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52877 +
52878 +       psRetOUT->eError =
52879 +               PDumpRegWithFlagsKM(psPDumpRegDumpIN->sHWReg.ui32RegAddr,
52880 +                                                       psPDumpRegDumpIN->sHWReg.ui32RegVal,
52881 +                                                       psPDumpRegDumpIN->ui32Flags);
52882 +
52883 +       return 0;
52884 +}
52885 +
52886 +static IMG_INT
52887 +PDumpRegPolBW(IMG_UINT32 ui32BridgeID,
52888 +                         PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
52889 +                         PVRSRV_BRIDGE_RETURN *psRetOUT,
52890 +                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52891 +{
52892 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
52893 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52894 +
52895 +       psRetOUT->eError =
52896 +               PDumpRegPolWithFlagsKM(psPDumpRegPolIN->sHWReg.ui32RegAddr,
52897 +                                                          psPDumpRegPolIN->sHWReg.ui32RegVal,
52898 +                                                          psPDumpRegPolIN->ui32Mask,
52899 +                                                          psPDumpRegPolIN->ui32Flags);
52900 +
52901 +       return 0;
52902 +}
52903 +
52904 +static IMG_INT
52905 +PDumpMemPolBW(IMG_UINT32 ui32BridgeID,
52906 +                         PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
52907 +                         PVRSRV_BRIDGE_RETURN *psRetOUT,
52908 +                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52909 +{
52910 +       IMG_VOID *pvMemInfo;
52911 +
52912 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
52913 +
52914 +       psRetOUT->eError =
52915 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
52916 +                                                  &pvMemInfo,
52917 +                                                  psPDumpMemPolIN->psKernelMemInfo,
52918 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52919 +       if(psRetOUT->eError != PVRSRV_OK)
52920 +       {
52921 +               return 0;
52922 +       }
52923 +
52924 +       psRetOUT->eError =
52925 +               PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
52926 +                                         psPDumpMemPolIN->ui32Offset,
52927 +                                         psPDumpMemPolIN->ui32Value,
52928 +                                         psPDumpMemPolIN->ui32Mask,
52929 +                                         PDUMP_POLL_OPERATOR_EQUAL,
52930 +                                         psPDumpMemPolIN->ui32Flags,
52931 +                                         MAKEUNIQUETAG(pvMemInfo));
52932 +
52933 +       return 0;
52934 +}
52935 +
52936 +static IMG_INT
52937 +PDumpMemBW(IMG_UINT32 ui32BridgeID,
52938 +                  PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
52939 +                  PVRSRV_BRIDGE_RETURN *psRetOUT,
52940 +                  PVRSRV_PER_PROCESS_DATA *psPerProc)
52941 +{
52942 +       IMG_VOID *pvMemInfo;
52943 +
52944 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
52945 +
52946 +       psRetOUT->eError =
52947 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
52948 +                                                  &pvMemInfo,
52949 +                                                  psPDumpMemDumpIN->psKernelMemInfo,
52950 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
52951 +       if(psRetOUT->eError != PVRSRV_OK)
52952 +       {
52953 +               return 0;
52954 +       }
52955 +
52956 +       psRetOUT->eError =
52957 +               PDumpMemUM(psPerProc,
52958 +                                  psPDumpMemDumpIN->pvAltLinAddr,
52959 +                                  psPDumpMemDumpIN->pvLinAddr,
52960 +                                  pvMemInfo,
52961 +                                  psPDumpMemDumpIN->ui32Offset,
52962 +                                  psPDumpMemDumpIN->ui32Bytes,
52963 +                                  psPDumpMemDumpIN->ui32Flags,
52964 +                                  MAKEUNIQUETAG(pvMemInfo));
52965 +
52966 +       return 0;
52967 +}
52968 +
52969 +static IMG_INT
52970 +PDumpBitmapBW(IMG_UINT32 ui32BridgeID,
52971 +                         PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
52972 +                         PVRSRV_BRIDGE_RETURN *psRetOUT,
52973 +                         PVRSRV_PER_PROCESS_DATA *psPerProc)
52974 +{
52975 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
52976 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
52977 +
52978 +       psRetOUT->eError =
52979 +               PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0],
52980 +                                         psPDumpBitmapIN->ui32FileOffset,
52981 +                                         psPDumpBitmapIN->ui32Width,
52982 +                                         psPDumpBitmapIN->ui32Height,
52983 +                                         psPDumpBitmapIN->ui32StrideInBytes,
52984 +                                         psPDumpBitmapIN->sDevBaseAddr,
52985 +                                         psPDumpBitmapIN->ui32Size,
52986 +                                         psPDumpBitmapIN->ePixelFormat,
52987 +                                         psPDumpBitmapIN->eMemFormat,
52988 +                                         psPDumpBitmapIN->ui32Flags);
52989 +
52990 +       return 0;
52991 +}
52992 +
52993 +static IMG_INT
52994 +PDumpReadRegBW(IMG_UINT32 ui32BridgeID,
52995 +                          PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
52996 +                          PVRSRV_BRIDGE_RETURN *psRetOUT,
52997 +                          PVRSRV_PER_PROCESS_DATA *psPerProc)
52998 +{
52999 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
53000 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53001 +
53002 +       psRetOUT->eError =
53003 +               PDumpReadRegKM(&psPDumpReadRegIN->szFileName[0],
53004 +                                          psPDumpReadRegIN->ui32FileOffset,
53005 +                                          psPDumpReadRegIN->ui32Address,
53006 +                                          psPDumpReadRegIN->ui32Size,
53007 +                                          psPDumpReadRegIN->ui32Flags);
53008 +
53009 +       return 0;
53010 +}
53011 +
53012 +static IMG_INT
53013 +PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID,
53014 +                                 PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
53015 +                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
53016 +                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53017 +{
53018 +       IMG_UINT32 ui32PDumpFlags;
53019 +
53020 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
53021 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53022 +
53023 +       ui32PDumpFlags = 0;
53024 +       if(psPDumpDriverInfoIN->bContinuous)
53025 +       {
53026 +               ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
53027 +       }
53028 +       psRetOUT->eError =
53029 +               PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
53030 +                                                 ui32PDumpFlags);
53031 +
53032 +       return 0;
53033 +}
53034 +
53035 +static IMG_INT
53036 +PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID,
53037 +                               PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
53038 +                               PVRSRV_BRIDGE_RETURN *psRetOUT,
53039 +                               PVRSRV_PER_PROCESS_DATA *psPerProc)
53040 +{
53041 +       IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
53042 +       IMG_VOID *pvSyncInfo;
53043 +
53044 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
53045 +
53046 +       psRetOUT->eError =
53047 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
53048 +                                                  psPDumpSyncDumpIN->psKernelSyncInfo,
53049 +                                                  PVRSRV_HANDLE_TYPE_SYNC_INFO);
53050 +       if(psRetOUT->eError != PVRSRV_OK)
53051 +       {
53052 +               return 0;
53053 +       }
53054 +
53055 +       psRetOUT->eError =
53056 +               PDumpMemUM(psPerProc,
53057 +                                  psPDumpSyncDumpIN->pvAltLinAddr,
53058 +                                  IMG_NULL,
53059 +                                  ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
53060 +                                  psPDumpSyncDumpIN->ui32Offset,
53061 +                                  ui32Bytes,
53062 +                                  0,
53063 +                                  MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
53064 +
53065 +       return 0;
53066 +}
53067 +
53068 +static IMG_INT
53069 +PDumpSyncPolBW(IMG_UINT32 ui32BridgeID,
53070 +                          PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
53071 +                          PVRSRV_BRIDGE_RETURN *psRetOUT,
53072 +                          PVRSRV_PER_PROCESS_DATA *psPerProc)
53073 +{
53074 +       IMG_UINT32 ui32Offset;
53075 +       IMG_VOID *pvSyncInfo;
53076 +
53077 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
53078 +
53079 +       psRetOUT->eError =
53080 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
53081 +                                                  psPDumpSyncPolIN->psKernelSyncInfo,
53082 +                                                  PVRSRV_HANDLE_TYPE_SYNC_INFO);
53083 +       if(psRetOUT->eError != PVRSRV_OK)
53084 +       {
53085 +               return 0;
53086 +       }
53087 +
53088 +       if(psPDumpSyncPolIN->bIsRead)
53089 +       {
53090 +               ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
53091 +       }
53092 +       else
53093 +       {
53094 +               ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
53095 +       }
53096 +
53097 +       psRetOUT->eError =
53098 +               PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
53099 +                                         ui32Offset,
53100 +                                         psPDumpSyncPolIN->ui32Value,
53101 +                                         psPDumpSyncPolIN->ui32Mask,
53102 +                                         PDUMP_POLL_OPERATOR_EQUAL,
53103 +                                         0,
53104 +                                         MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
53105 +
53106 +       return 0;
53107 +}
53108 +
53109 +static IMG_INT
53110 +PDumpPDRegBW(IMG_UINT32 ui32BridgeID,
53111 +                        PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG *psPDumpPDRegDumpIN,
53112 +                        PVRSRV_BRIDGE_RETURN *psRetOUT,
53113 +                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53114 +{
53115 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_PDREG);
53116 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53117 +
53118 +       PDumpPDReg(psPDumpPDRegDumpIN->sHWReg.ui32RegAddr,
53119 +                          psPDumpPDRegDumpIN->sHWReg.ui32RegVal,
53120 +                          PDUMP_PD_UNIQUETAG);
53121 +
53122 +       psRetOUT->eError = PVRSRV_OK;
53123 +       return 0;
53124 +}
53125 +
53126 +static IMG_INT
53127 +PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID,
53128 +                                                PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN,
53129 +                                                PVRSRV_BRIDGE_RETURN *psRetOUT,
53130 +                                                PVRSRV_PER_PROCESS_DATA *psPerProc)
53131 +{
53132 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
53133 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53134 +
53135 +       PDumpCycleCountRegRead(psPDumpCycleCountRegReadIN->ui32RegOffset,
53136 +                                                  psPDumpCycleCountRegReadIN->bLastFrame);
53137 +
53138 +       psRetOUT->eError = PVRSRV_OK;
53139 +
53140 +       return 0;
53141 +}
53142 +
53143 +static IMG_INT
53144 +PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
53145 +                                 PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
53146 +                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
53147 +                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53148 +{
53149 +       IMG_VOID *pvMemInfo;
53150 +
53151 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
53152 +
53153 +       psRetOUT->eError =
53154 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
53155 +                                                  psPDumpPDDevPAddrIN->hKernelMemInfo,
53156 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
53157 +       if(psRetOUT->eError != PVRSRV_OK)
53158 +       {
53159 +               return 0;
53160 +       }
53161 +
53162 +       psRetOUT->eError =
53163 +               PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
53164 +                                                 psPDumpPDDevPAddrIN->ui32Offset,
53165 +                                                 psPDumpPDDevPAddrIN->sPDDevPAddr,
53166 +                                                 MAKEUNIQUETAG(pvMemInfo),
53167 +                                                 PDUMP_PD_UNIQUETAG);
53168 +       return 0;
53169 +}
53170 +
53171 +static IMG_INT
53172 +PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID,
53173 +                                         IMG_VOID *psBridgeIn,
53174 +                                         PVRSRV_BRIDGE_RETURN *psRetOUT,
53175 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
53176 +{
53177 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
53178 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
53179 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53180 +
53181 +       psRetOUT->eError = PDumpStartInitPhaseKM();
53182 +
53183 +       return 0;
53184 +}
53185 +
53186 +static IMG_INT
53187 +PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID,
53188 +                                         IMG_VOID *psBridgeIn,
53189 +                                         PVRSRV_BRIDGE_RETURN *psRetOUT,
53190 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
53191 +{
53192 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
53193 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
53194 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53195 +
53196 +       psRetOUT->eError = PDumpStopInitPhaseKM();
53197 +
53198 +       return 0;
53199 +}
53200 +
53201 +#endif
53202 +
53203 +
53204 +static IMG_INT
53205 +PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
53206 +                                       PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
53207 +                                       PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
53208 +                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
53209 +{
53210 +       PVRSRV_ERROR eError;
53211 +
53212 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
53213 +
53214 +       OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
53215 +                 &psGetMiscInfoIN->sMiscInfo,
53216 +                 sizeof(PVRSRV_MISC_INFO));
53217 +
53218 +       if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
53219 +           ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0))
53220 +       {
53221 +
53222 +               psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
53223 +               return 0;
53224 +       }
53225 +
53226 +       if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
53227 +           ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0))
53228 +       {
53229 +
53230 +               ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
53231 +                                   OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
53232 +                                   psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
53233 +                                   (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
53234 +                                                       "Output string buffer"));
53235 +
53236 +               psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
53237 +
53238 +
53239 +               eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
53240 +                                          psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
53241 +                                          psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
53242 +                                          psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
53243 +
53244 +
53245 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
53246 +                         psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
53247 +                        (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
53248 +               psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = IMG_NULL;
53249 +
53250 +
53251 +               psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
53252 +
53253 +               if(eError != PVRSRV_OK)
53254 +               {
53255 +
53256 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
53257 +                       return -EFAULT;
53258 +               }
53259 +       }
53260 +       else
53261 +       {
53262 +               psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
53263 +       }
53264 +
53265 +
53266 +       if (psGetMiscInfoOUT->eError != PVRSRV_OK)
53267 +       {
53268 +               return 0;
53269 +       }
53270 +
53271 +
53272 +       if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
53273 +       {
53274 +               psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
53275 +                                                                                                       &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
53276 +                                                                                                       psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
53277 +                                                                                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
53278 +                                                                                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
53279 +
53280 +                       if (psGetMiscInfoOUT->eError != PVRSRV_OK)
53281 +                       {
53282 +                               return 0;
53283 +                       }
53284 +       }
53285 +
53286 +       if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
53287 +       {
53288 +
53289 +               psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
53290 +                                                 &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
53291 +                                                 psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
53292 +                                                 PVRSRV_HANDLE_TYPE_SOC_TIMER,
53293 +                                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
53294 +
53295 +               if (psGetMiscInfoOUT->eError != PVRSRV_OK)
53296 +               {
53297 +                       return 0;
53298 +               }
53299 +       }
53300 +
53301 +       return 0;
53302 +}
53303 +
53304 +static IMG_INT
53305 +PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
53306 +                               IMG_VOID *psBridgeIn,
53307 +                               PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
53308 +                               PVRSRV_PER_PROCESS_DATA *psPerProc)
53309 +{
53310 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
53311 +
53312 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
53313 +
53314 +       psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
53315 +       psConnectServicesOUT->eError = PVRSRV_OK;
53316 +
53317 +       return 0;
53318 +}
53319 +
53320 +static IMG_INT
53321 +PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID,
53322 +                                  IMG_VOID *psBridgeIn,
53323 +                                  PVRSRV_BRIDGE_RETURN *psRetOUT,
53324 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
53325 +{
53326 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53327 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
53328 +
53329 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES);
53330 +
53331 +
53332 +       psRetOUT->eError = PVRSRV_OK;
53333 +
53334 +       return 0;
53335 +}
53336 +
53337 +static IMG_INT
53338 +PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID,
53339 +                                       PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
53340 +                                       PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
53341 +                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
53342 +{
53343 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
53344 +
53345 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
53346 +
53347 +       psEnumDispClassOUT->eError =
53348 +               PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
53349 +                                                       &psEnumDispClassOUT->ui32NumDevices,
53350 +                                                       &psEnumDispClassOUT->ui32DevID[0]);
53351 +
53352 +       return 0;
53353 +}
53354 +
53355 +static IMG_INT
53356 +PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID,
53357 +                                        PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
53358 +                                        PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
53359 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53360 +{
53361 +       IMG_HANDLE hDevCookieInt;
53362 +       IMG_HANDLE hDispClassInfoInt;
53363 +
53364 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
53365 +
53366 +       NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1);
53367 +
53368 +       psOpenDispClassDeviceOUT->eError =
53369 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53370 +                                                  &hDevCookieInt,
53371 +                                                  psOpenDispClassDeviceIN->hDevCookie,
53372 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
53373 +       if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
53374 +       {
53375 +               return 0;
53376 +       }
53377 +
53378 +       psOpenDispClassDeviceOUT->eError =
53379 +               PVRSRVOpenDCDeviceKM(psPerProc,
53380 +                                                        psOpenDispClassDeviceIN->ui32DeviceID,
53381 +                                                        hDevCookieInt,
53382 +                                                        &hDispClassInfoInt);
53383 +
53384 +       if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
53385 +       {
53386 +               return 0;
53387 +       }
53388 +
53389 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
53390 +                                         &psOpenDispClassDeviceOUT->hDeviceKM,
53391 +                                         hDispClassInfoInt,
53392 +                                         PVRSRV_HANDLE_TYPE_DISP_INFO,
53393 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
53394 +       COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc);
53395 +
53396 +       return 0;
53397 +}
53398 +
53399 +static IMG_INT
53400 +PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID,
53401 +                                         PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
53402 +                                         PVRSRV_BRIDGE_RETURN *psRetOUT,
53403 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
53404 +{
53405 +       IMG_VOID *pvDispClassInfoInt;
53406 +
53407 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
53408 +
53409 +       psRetOUT->eError =
53410 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53411 +                                                  &pvDispClassInfoInt,
53412 +                                                  psCloseDispClassDeviceIN->hDeviceKM,
53413 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53414 +
53415 +       if(psRetOUT->eError != PVRSRV_OK)
53416 +       {
53417 +               return 0;
53418 +       }
53419 +
53420 +       psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
53421 +       if(psRetOUT->eError != PVRSRV_OK)
53422 +       {
53423 +               return 0;
53424 +       }
53425 +
53426 +       psRetOUT->eError =
53427 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
53428 +                                                       psCloseDispClassDeviceIN->hDeviceKM,
53429 +                                                       PVRSRV_HANDLE_TYPE_DISP_INFO);
53430 +       return 0;
53431 +}
53432 +
53433 +static IMG_INT
53434 +PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID,
53435 +                                         PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
53436 +                                         PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
53437 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
53438 +{
53439 +       IMG_VOID *pvDispClassInfoInt;
53440 +
53441 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
53442 +
53443 +       psEnumDispClassFormatsOUT->eError =
53444 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53445 +                                                  &pvDispClassInfoInt,
53446 +                                                  psEnumDispClassFormatsIN->hDeviceKM,
53447 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53448 +       if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
53449 +       {
53450 +               return 0;
53451 +       }
53452 +
53453 +       psEnumDispClassFormatsOUT->eError =
53454 +               PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
53455 +                                                         &psEnumDispClassFormatsOUT->ui32Count,
53456 +                                                         psEnumDispClassFormatsOUT->asFormat);
53457 +
53458 +       return 0;
53459 +}
53460 +
53461 +static IMG_INT
53462 +PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID,
53463 +                                  PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
53464 +                                  PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
53465 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
53466 +{
53467 +       IMG_VOID *pvDispClassInfoInt;
53468 +
53469 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
53470 +
53471 +       psEnumDispClassDimsOUT->eError =
53472 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53473 +                                                  &pvDispClassInfoInt,
53474 +                                                  psEnumDispClassDimsIN->hDeviceKM,
53475 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53476 +
53477 +       if(psEnumDispClassDimsOUT->eError != PVRSRV_OK)
53478 +       {
53479 +               return 0;
53480 +       }
53481 +
53482 +       psEnumDispClassDimsOUT->eError =
53483 +               PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
53484 +                                                  &psEnumDispClassDimsIN->sFormat,
53485 +                                                  &psEnumDispClassDimsOUT->ui32Count,
53486 +                                                  psEnumDispClassDimsOUT->asDim);
53487 +
53488 +       return 0;
53489 +}
53490 +
53491 +static IMG_INT
53492 +PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
53493 +                                                 PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,
53494 +                                                 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
53495 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53496 +{
53497 +       IMG_HANDLE hBufferInt;
53498 +       IMG_VOID *pvDispClassInfoInt;
53499 +
53500 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
53501 +
53502 +       NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1);
53503 +
53504 +       psGetDispClassSysBufferOUT->eError =
53505 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53506 +                                                  &pvDispClassInfoInt,
53507 +                                                  psGetDispClassSysBufferIN->hDeviceKM,
53508 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53509 +       if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
53510 +       {
53511 +               return 0;
53512 +       }
53513 +
53514 +       psGetDispClassSysBufferOUT->eError =
53515 +               PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt,
53516 +                                                                 &hBufferInt);
53517 +
53518 +       if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
53519 +       {
53520 +               return 0;
53521 +       }
53522 +
53523 +        
53524 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
53525 +                                                &psGetDispClassSysBufferOUT->hBuffer,
53526 +                                                hBufferInt,
53527 +                                                PVRSRV_HANDLE_TYPE_DISP_BUFFER,
53528 +                                                (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
53529 +                                                psGetDispClassSysBufferIN->hDeviceKM);
53530 +
53531 +       COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc);
53532 +
53533 +       return 0;
53534 +}
53535 +
53536 +static IMG_INT
53537 +PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID,
53538 +                                 PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
53539 +                                 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
53540 +                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53541 +{
53542 +       IMG_VOID *pvDispClassInfo;
53543 +
53544 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
53545 +
53546 +       psGetDispClassInfoOUT->eError =
53547 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53548 +                                                  &pvDispClassInfo,
53549 +                                                  psGetDispClassInfoIN->hDeviceKM,
53550 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53551 +       if(psGetDispClassInfoOUT->eError != PVRSRV_OK)
53552 +       {
53553 +               return 0;
53554 +       }
53555 +
53556 +       psGetDispClassInfoOUT->eError =
53557 +               PVRSRVGetDCInfoKM(pvDispClassInfo,
53558 +                                                 &psGetDispClassInfoOUT->sDisplayInfo);
53559 +
53560 +       return 0;
53561 +}
53562 +
53563 +static IMG_INT
53564 +PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID,
53565 +                                                 PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN,
53566 +                                                 PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT,
53567 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53568 +{
53569 +       IMG_VOID *pvDispClassInfo;
53570 +       IMG_HANDLE hSwapChainInt;
53571 +       IMG_UINT32      ui32SwapChainID;
53572 +
53573 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
53574 +
53575 +       NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1);
53576 +
53577 +       psCreateDispClassSwapChainOUT->eError =
53578 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53579 +                                                  &pvDispClassInfo,
53580 +                                                  psCreateDispClassSwapChainIN->hDeviceKM,
53581 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53582 +
53583 +       if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
53584 +       {
53585 +               return 0;
53586 +       }
53587 +
53588 +       
53589 +       ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
53590 +
53591 +       psCreateDispClassSwapChainOUT->eError = 
53592 +               PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo, 
53593 +                                                                 psCreateDispClassSwapChainIN->ui32Flags,
53594 +                                                                 &psCreateDispClassSwapChainIN->sDstSurfAttrib,
53595 +                                                                 &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
53596 +                                                                 psCreateDispClassSwapChainIN->ui32BufferCount,
53597 +                                                                 psCreateDispClassSwapChainIN->ui32OEMFlags,
53598 +                                                                 &hSwapChainInt,
53599 +                                                                 &ui32SwapChainID);
53600 +
53601 +       if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
53602 +       {
53603 +               return 0;
53604 +       }
53605 +
53606 +       
53607 +       psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
53608 +
53609 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, 
53610 +                                         &psCreateDispClassSwapChainOUT->hSwapChain, 
53611 +                                         hSwapChainInt,
53612 +                                         PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
53613 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE,
53614 +                                         psCreateDispClassSwapChainIN->hDeviceKM);
53615 +
53616 +       COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc);
53617 +
53618 +       return 0;
53619 +}
53620 +
53621 +static IMG_INT
53622 +PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID,
53623 +                                                  PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN,
53624 +                                                  PVRSRV_BRIDGE_RETURN *psRetOUT,
53625 +                                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
53626 +{
53627 +       IMG_VOID *pvSwapChain;
53628 +
53629 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
53630 +
53631 +       psRetOUT->eError =
53632 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
53633 +                                                  psDestroyDispClassSwapChainIN->hSwapChain,
53634 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53635 +       if(psRetOUT->eError != PVRSRV_OK)
53636 +       {
53637 +               return 0;
53638 +       }
53639 +
53640 +       psRetOUT->eError =
53641 +               PVRSRVDestroyDCSwapChainKM(pvSwapChain);
53642 +
53643 +       if(psRetOUT->eError != PVRSRV_OK)
53644 +       {
53645 +               return 0;
53646 +       }
53647 +
53648 +       psRetOUT->eError =
53649 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
53650 +                                                       psDestroyDispClassSwapChainIN->hSwapChain,
53651 +                                                       PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53652 +
53653 +       return 0;
53654 +}
53655 +
53656 +static IMG_INT
53657 +PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID,
53658 +                                        PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
53659 +                                        PVRSRV_BRIDGE_RETURN *psRetOUT,
53660 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53661 +{
53662 +       IMG_VOID *pvDispClassInfo;
53663 +       IMG_VOID *pvSwapChain;
53664 +
53665 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
53666 +
53667 +       psRetOUT->eError =
53668 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53669 +                                                  &pvDispClassInfo,
53670 +                                                  psSetDispClassDstRectIN->hDeviceKM,
53671 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53672 +       if(psRetOUT->eError != PVRSRV_OK)
53673 +       {
53674 +               return 0;
53675 +       }
53676 +
53677 +       psRetOUT->eError =
53678 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53679 +                                                  &pvSwapChain,
53680 +                                                  psSetDispClassDstRectIN->hSwapChain,
53681 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53682 +
53683 +       if(psRetOUT->eError != PVRSRV_OK)
53684 +       {
53685 +               return 0;
53686 +       }
53687 +
53688 +       psRetOUT->eError =
53689 +               PVRSRVSetDCDstRectKM(pvDispClassInfo,
53690 +                                                        pvSwapChain,
53691 +                                                        &psSetDispClassDstRectIN->sRect);
53692 +
53693 +       return 0;
53694 +}
53695 +
53696 +static IMG_INT
53697 +PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID,
53698 +                                        PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
53699 +                                        PVRSRV_BRIDGE_RETURN *psRetOUT,
53700 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53701 +{
53702 +       IMG_VOID *pvDispClassInfo;
53703 +       IMG_VOID *pvSwapChain;
53704 +
53705 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
53706 +
53707 +       psRetOUT->eError =
53708 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53709 +                                                  &pvDispClassInfo,
53710 +                                                  psSetDispClassSrcRectIN->hDeviceKM,
53711 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53712 +       if(psRetOUT->eError != PVRSRV_OK)
53713 +       {
53714 +               return 0;
53715 +       }
53716 +
53717 +       psRetOUT->eError =
53718 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53719 +                                                  &pvSwapChain,
53720 +                                                  psSetDispClassSrcRectIN->hSwapChain,
53721 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53722 +       if(psRetOUT->eError != PVRSRV_OK)
53723 +       {
53724 +               return 0;
53725 +       }
53726 +
53727 +       psRetOUT->eError =
53728 +               PVRSRVSetDCSrcRectKM(pvDispClassInfo,
53729 +                                                        pvSwapChain,
53730 +                                                        &psSetDispClassSrcRectIN->sRect);
53731 +
53732 +       return 0;
53733 +}
53734 +
53735 +static IMG_INT
53736 +PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID,
53737 +                                                 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
53738 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
53739 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53740 +{
53741 +       IMG_VOID *pvDispClassInfo;
53742 +       IMG_VOID *pvSwapChain;
53743 +
53744 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
53745 +
53746 +       psRetOUT->eError =
53747 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53748 +                                                  &pvDispClassInfo,
53749 +                                                  psSetDispClassColKeyIN->hDeviceKM,
53750 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53751 +       if(psRetOUT->eError != PVRSRV_OK)
53752 +       {
53753 +               return 0;
53754 +       }
53755 +
53756 +       psRetOUT->eError =
53757 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53758 +                                                  &pvSwapChain,
53759 +                                                  psSetDispClassColKeyIN->hSwapChain,
53760 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53761 +       if(psRetOUT->eError != PVRSRV_OK)
53762 +       {
53763 +               return 0;
53764 +       }
53765 +
53766 +       psRetOUT->eError =
53767 +               PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
53768 +                                                                 pvSwapChain,
53769 +                                                                 psSetDispClassColKeyIN->ui32CKColour);
53770 +
53771 +       return 0;
53772 +}
53773 +
53774 +static IMG_INT
53775 +PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID,
53776 +                                                 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
53777 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
53778 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
53779 +{
53780 +       IMG_VOID *pvDispClassInfo;
53781 +       IMG_VOID *pvSwapChain;
53782 +
53783 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
53784 +
53785 +       psRetOUT->eError =
53786 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53787 +                                                  &pvDispClassInfo,
53788 +                                                  psSetDispClassColKeyIN->hDeviceKM,
53789 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53790 +       if(psRetOUT->eError != PVRSRV_OK)
53791 +       {
53792 +               return 0;
53793 +       }
53794 +
53795 +       psRetOUT->eError =
53796 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53797 +                                                  &pvSwapChain,
53798 +                                                  psSetDispClassColKeyIN->hSwapChain,
53799 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53800 +       if(psRetOUT->eError != PVRSRV_OK)
53801 +       {
53802 +               return 0;
53803 +       }
53804 +
53805 +       psRetOUT->eError =
53806 +               PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
53807 +                                                                 pvSwapChain,
53808 +                                                                 psSetDispClassColKeyIN->ui32CKColour);
53809 +
53810 +       return 0;
53811 +}
53812 +
53813 +static IMG_INT
53814 +PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID,
53815 +                                        PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
53816 +                                        PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
53817 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53818 +{
53819 +       IMG_VOID *pvDispClassInfo;
53820 +       IMG_VOID *pvSwapChain;
53821 +       IMG_UINT32 i;
53822 +
53823 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
53824 +
53825 +       NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
53826 +
53827 +       psGetDispClassBuffersOUT->eError =
53828 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53829 +                                                  &pvDispClassInfo,
53830 +                                                  psGetDispClassBuffersIN->hDeviceKM,
53831 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53832 +       if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
53833 +       {
53834 +               return 0;
53835 +       }
53836 +
53837 +       psGetDispClassBuffersOUT->eError =
53838 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53839 +                                                  &pvSwapChain,
53840 +                                                  psGetDispClassBuffersIN->hSwapChain,
53841 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
53842 +       if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
53843 +       {
53844 +               return 0;
53845 +       }
53846 +
53847 +       psGetDispClassBuffersOUT->eError =
53848 +               PVRSRVGetDCBuffersKM(pvDispClassInfo,
53849 +                                                        pvSwapChain,
53850 +                                                        &psGetDispClassBuffersOUT->ui32BufferCount,
53851 +                                                        psGetDispClassBuffersOUT->ahBuffer);
53852 +       if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
53853 +       {
53854 +               return 0;
53855 +       }
53856 +
53857 +       PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
53858 +
53859 +       for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
53860 +       {
53861 +               IMG_HANDLE hBufferExt;
53862 +
53863 +               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
53864 +                                                        &hBufferExt,
53865 +                                                        psGetDispClassBuffersOUT->ahBuffer[i],
53866 +                                                        PVRSRV_HANDLE_TYPE_DISP_BUFFER,
53867 +                                                        (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
53868 +                                                        psGetDispClassBuffersIN->hSwapChain);
53869 +
53870 +               psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
53871 +       }
53872 +
53873 +       COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc);
53874 +
53875 +       return 0;
53876 +}
53877 +
53878 +static IMG_INT
53879 +PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID,
53880 +                                          PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
53881 +                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
53882 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
53883 +{
53884 +       IMG_VOID *pvDispClassInfo;
53885 +       IMG_VOID *pvSwapChainBuf;
53886 +
53887 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
53888 +
53889 +       psRetOUT->eError =
53890 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53891 +                                                  &pvDispClassInfo,
53892 +                                                  psSwapDispClassBufferIN->hDeviceKM,
53893 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53894 +       if(psRetOUT->eError != PVRSRV_OK)
53895 +       {
53896 +               return 0;
53897 +       }
53898 +
53899 +       psRetOUT->eError =
53900 +               PVRSRVLookupSubHandle(psPerProc->psHandleBase,
53901 +                                                  &pvSwapChainBuf,
53902 +                                                  psSwapDispClassBufferIN->hBuffer,
53903 +                                                  PVRSRV_HANDLE_TYPE_DISP_BUFFER,
53904 +                                                  psSwapDispClassBufferIN->hDeviceKM);
53905 +       if(psRetOUT->eError != PVRSRV_OK)
53906 +       {
53907 +               return 0;
53908 +       }
53909 +
53910 +       psRetOUT->eError =
53911 +               PVRSRVSwapToDCBufferKM(pvDispClassInfo,
53912 +                                                          pvSwapChainBuf,
53913 +                                                          psSwapDispClassBufferIN->ui32SwapInterval,
53914 +                                                          psSwapDispClassBufferIN->hPrivateTag,
53915 +                                                          psSwapDispClassBufferIN->ui32ClipRectCount,
53916 +                                                          psSwapDispClassBufferIN->sClipRect);
53917 +
53918 +       return 0;
53919 +}
53920 +
53921 +static IMG_INT
53922 +PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID,
53923 +                                          PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
53924 +                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
53925 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
53926 +{
53927 +       IMG_VOID *pvDispClassInfo;
53928 +       IMG_VOID *pvSwapChain;
53929 +
53930 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
53931 +
53932 +       psRetOUT->eError =
53933 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53934 +                                                  &pvDispClassInfo,
53935 +                                                  psSwapDispClassSystemIN->hDeviceKM,
53936 +                                                  PVRSRV_HANDLE_TYPE_DISP_INFO);
53937 +       if(psRetOUT->eError != PVRSRV_OK)
53938 +       {
53939 +               return 0;
53940 +       }
53941 +
53942 +       psRetOUT->eError =
53943 +               PVRSRVLookupSubHandle(psPerProc->psHandleBase,
53944 +                                                  &pvSwapChain,
53945 +                                                  psSwapDispClassSystemIN->hSwapChain,
53946 +                                                  PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
53947 +                                                  psSwapDispClassSystemIN->hDeviceKM);
53948 +       if(psRetOUT->eError != PVRSRV_OK)
53949 +       {
53950 +               return 0;
53951 +       }
53952 +       psRetOUT->eError =
53953 +               PVRSRVSwapToDCSystemKM(pvDispClassInfo,
53954 +                                                          pvSwapChain);
53955 +
53956 +       return 0;
53957 +}
53958 +
53959 +static IMG_INT
53960 +PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID,
53961 +                                        PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
53962 +                                        PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
53963 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
53964 +{
53965 +       IMG_HANDLE hDevCookieInt;
53966 +       IMG_HANDLE hBufClassInfo;
53967 +
53968 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
53969 +
53970 +       NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1);
53971 +
53972 +       psOpenBufferClassDeviceOUT->eError =
53973 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
53974 +                                                  &hDevCookieInt,
53975 +                                                  psOpenBufferClassDeviceIN->hDevCookie,
53976 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
53977 +       if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
53978 +       {
53979 +               return 0;
53980 +       }
53981 +
53982 +       psOpenBufferClassDeviceOUT->eError =
53983 +               PVRSRVOpenBCDeviceKM(psPerProc,
53984 +                                                        psOpenBufferClassDeviceIN->ui32DeviceID,
53985 +                                                        hDevCookieInt,
53986 +                                                        &hBufClassInfo);
53987 +       if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
53988 +       {
53989 +               return 0;
53990 +       }
53991 +
53992 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
53993 +                                         &psOpenBufferClassDeviceOUT->hDeviceKM,
53994 +                                         hBufClassInfo,
53995 +                                         PVRSRV_HANDLE_TYPE_BUF_INFO,
53996 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
53997 +
53998 +       COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc);
53999 +
54000 +       return 0;
54001 +}
54002 +
54003 +static IMG_INT
54004 +PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID,
54005 +                                         PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
54006 +                                         PVRSRV_BRIDGE_RETURN *psRetOUT,
54007 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
54008 +{
54009 +       IMG_VOID *pvBufClassInfo;
54010 +
54011 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
54012 +
54013 +       psRetOUT->eError =
54014 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54015 +                                                  &pvBufClassInfo,
54016 +                                                  psCloseBufferClassDeviceIN->hDeviceKM,
54017 +                                                  PVRSRV_HANDLE_TYPE_BUF_INFO);
54018 +       if(psRetOUT->eError != PVRSRV_OK)
54019 +       {
54020 +               return 0;
54021 +       }
54022 +
54023 +       psRetOUT->eError =
54024 +               PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
54025 +
54026 +       if(psRetOUT->eError != PVRSRV_OK)
54027 +       {
54028 +               return 0;
54029 +       }
54030 +
54031 +       psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
54032 +                                                                                  psCloseBufferClassDeviceIN->hDeviceKM,
54033 +                                                                                  PVRSRV_HANDLE_TYPE_BUF_INFO);
54034 +
54035 +       return 0;
54036 +}
54037 +
54038 +static IMG_INT
54039 +PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID,
54040 +                                 PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
54041 +                                 PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
54042 +                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
54043 +{
54044 +       IMG_VOID *pvBufClassInfo;
54045 +
54046 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
54047 +
54048 +       psGetBufferClassInfoOUT->eError =
54049 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54050 +                                                  &pvBufClassInfo,
54051 +                                                  psGetBufferClassInfoIN->hDeviceKM,
54052 +                                                  PVRSRV_HANDLE_TYPE_BUF_INFO);
54053 +       if(psGetBufferClassInfoOUT->eError != PVRSRV_OK)
54054 +       {
54055 +               return 0;
54056 +       }
54057 +
54058 +       psGetBufferClassInfoOUT->eError =
54059 +               PVRSRVGetBCInfoKM(pvBufClassInfo,
54060 +                                                 &psGetBufferClassInfoOUT->sBufferInfo);
54061 +       return 0;
54062 +}
54063 +
54064 +static IMG_INT
54065 +PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID,
54066 +                                       PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
54067 +                                       PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
54068 +                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
54069 +{
54070 +       IMG_VOID *pvBufClassInfo;
54071 +       IMG_HANDLE hBufferInt;
54072 +
54073 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
54074 +
54075 +       NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1);
54076 +
54077 +       psGetBufferClassBufferOUT->eError =
54078 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54079 +                                                  &pvBufClassInfo,
54080 +                                                  psGetBufferClassBufferIN->hDeviceKM,
54081 +                                                  PVRSRV_HANDLE_TYPE_BUF_INFO);
54082 +       if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
54083 +       {
54084 +               return 0;
54085 +       }
54086 +
54087 +       psGetBufferClassBufferOUT->eError =
54088 +               PVRSRVGetBCBufferKM(pvBufClassInfo,
54089 +                                                       psGetBufferClassBufferIN->ui32BufferIndex,
54090 +                                                       &hBufferInt);
54091 +
54092 +       if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
54093 +       {
54094 +               return 0;
54095 +       }
54096 +
54097 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
54098 +                                                &psGetBufferClassBufferOUT->hBuffer,
54099 +                                                hBufferInt,
54100 +                                                PVRSRV_HANDLE_TYPE_BUF_BUFFER,
54101 +                                                (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |  PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
54102 +                                                psGetBufferClassBufferIN->hDeviceKM);
54103 +
54104 +       COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc);
54105 +
54106 +       return 0;
54107 +}
54108 +
54109 +
54110 +static IMG_INT
54111 +PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
54112 +                                                        PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
54113 +                                                        PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
54114 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
54115 +{
54116 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
54117 +
54118 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
54119 +
54120 +       NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1);
54121 +
54122 +       psAllocSharedSysMemOUT->eError =
54123 +               PVRSRVAllocSharedSysMemoryKM(psPerProc,
54124 +                                                                        psAllocSharedSysMemIN->ui32Flags,
54125 +                                                                        psAllocSharedSysMemIN->ui32Size,
54126 +                                                                        &psKernelMemInfo);
54127 +       if(psAllocSharedSysMemOUT->eError != PVRSRV_OK)
54128 +       {
54129 +               return 0;
54130 +       }
54131 +
54132 +       OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
54133 +                        0,
54134 +                        sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
54135 +
54136 +       psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
54137 +                       psKernelMemInfo->pvLinAddrKM;
54138 +
54139 +       psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0;
54140 +       psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
54141 +               psKernelMemInfo->ui32Flags;
54142 +       psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize =
54143 +               psKernelMemInfo->ui32AllocSize;
54144 +       psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
54145 +
54146 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
54147 +                                         &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
54148 +                                         psKernelMemInfo,
54149 +                                         PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
54150 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
54151 +
54152 +       COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc);
54153 +
54154 +       return 0;
54155 +}
54156 +
54157 +static IMG_INT
54158 +PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
54159 +                                                       PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
54160 +                                                       PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
54161 +                                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
54162 +{
54163 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
54164 +
54165 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
54166 +
54167 +       psFreeSharedSysMemOUT->eError =
54168 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54169 +                                                  (IMG_VOID **)&psKernelMemInfo,
54170 +                                                  psFreeSharedSysMemIN->psKernelMemInfo,
54171 +                                                                                                                                  PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
54172 +
54173 +       if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
54174 +               return 0;
54175 +
54176 +       psFreeSharedSysMemOUT->eError =
54177 +               PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
54178 +       if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
54179 +               return 0;
54180 +
54181 +       psFreeSharedSysMemOUT->eError =
54182 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
54183 +                                                       psFreeSharedSysMemIN->psKernelMemInfo,
54184 +                                                       PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
54185 +       return 0;
54186 +}
54187 +
54188 +static IMG_INT
54189 +PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
54190 +                                         PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
54191 +                                         PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
54192 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
54193 +{
54194 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
54195 +       PVRSRV_HANDLE_TYPE eHandleType;
54196 +       IMG_HANDLE      hParent;
54197 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
54198 +
54199 +       NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2);
54200 +
54201 +       psMapMemInfoMemOUT->eError =
54202 +               PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
54203 +                                                  (IMG_VOID **)&psKernelMemInfo,
54204 +                                                  &eHandleType,
54205 +                                                  psMapMemInfoMemIN->hKernelMemInfo);
54206 +       if(psMapMemInfoMemOUT->eError != PVRSRV_OK)
54207 +       {
54208 +               return 0;
54209 +       }
54210 +
54211 +       switch (eHandleType)
54212 +       {
54213 +#if defined(PVR_SECURE_HANDLES)
54214 +               case PVRSRV_HANDLE_TYPE_MEM_INFO:
54215 +               case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
54216 +               case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
54217 +#else
54218 +               case PVRSRV_HANDLE_TYPE_NONE:
54219 +#endif
54220 +                       break;
54221 +               default:
54222 +                       psMapMemInfoMemOUT->eError = PVRSRV_ERROR_GENERIC;
54223 +                       return 0;
54224 +       }
54225 +
54226 +
54227 +       psMapMemInfoMemOUT->eError =
54228 +               PVRSRVGetParentHandle(psPerProc->psHandleBase,
54229 +                                       &hParent,
54230 +                                       psMapMemInfoMemIN->hKernelMemInfo,
54231 +                                       eHandleType);
54232 +       if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
54233 +       {
54234 +               return 0;
54235 +       }
54236 +       if (hParent == IMG_NULL)
54237 +       {
54238 +               hParent = psMapMemInfoMemIN->hKernelMemInfo;
54239 +       }
54240 +
54241 +       OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
54242 +                        0,
54243 +                        sizeof(psMapMemInfoMemOUT->sClientMemInfo));
54244 +
54245 +       psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
54246 +                       psKernelMemInfo->pvLinAddrKM;
54247 +
54248 +       psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0;
54249 +       psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
54250 +               psKernelMemInfo->sDevVAddr;
54251 +       psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
54252 +               psKernelMemInfo->ui32Flags;
54253 +       psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize =
54254 +               psKernelMemInfo->ui32AllocSize;
54255 +       psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
54256 +
54257 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
54258 +                                         &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
54259 +                                         psKernelMemInfo,
54260 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
54261 +                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
54262 +                                         hParent);
54263 +
54264 +       if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
54265 +       {
54266 +
54267 +               OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
54268 +                                0,
54269 +                                sizeof (PVRSRV_CLIENT_SYNC_INFO));
54270 +               psMapMemInfoMemOUT->psKernelSyncInfo = IMG_NULL;
54271 +       }
54272 +       else
54273 +       {
54274 +
54275 +               psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
54276 +                       psKernelMemInfo->psKernelSyncInfo->psSyncData;
54277 +               psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
54278 +                       psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
54279 +               psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
54280 +                       psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
54281 +
54282 +               psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
54283 +                       psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
54284 +
54285 +               psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo;
54286 +
54287 +               PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
54288 +                                                        &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
54289 +                                                        psKernelMemInfo->psKernelSyncInfo,
54290 +                                                        PVRSRV_HANDLE_TYPE_SYNC_INFO,
54291 +                                                        PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
54292 +                                                        psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
54293 +       }
54294 +
54295 +       COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc);
54296 +
54297 +       return 0;
54298 +}
54299 +
54300 +
54301 +
54302 +static IMG_INT
54303 +MMU_GetPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
54304 +                                       PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN,
54305 +                                       PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT,
54306 +                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
54307 +{
54308 +       IMG_HANDLE hDevMemContextInt;
54309 +
54310 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR);
54311 +
54312 +       psGetMmuPDDevPAddrOUT->eError =
54313 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
54314 +                                                  psGetMmuPDDevPAddrIN->hDevMemContext,
54315 +                                                  PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
54316 +       if(psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK)
54317 +       {
54318 +               return 0;
54319 +       }
54320 +
54321 +       psGetMmuPDDevPAddrOUT->sPDDevPAddr =
54322 +               BM_GetDeviceNode(hDevMemContextInt)->pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext(hDevMemContextInt));
54323 +       if(psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr)
54324 +       {
54325 +               psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK;
54326 +       }
54327 +       else
54328 +       {
54329 +               psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_GENERIC;
54330 +       }
54331 +       return 0;
54332 +}
54333 +
54334 +
54335 +
54336 +IMG_INT
54337 +DummyBW(IMG_UINT32 ui32BridgeID,
54338 +               IMG_VOID *psBridgeIn,
54339 +               IMG_VOID *psBridgeOut,
54340 +               PVRSRV_PER_PROCESS_DATA *psPerProc)
54341 +{
54342 +#if !defined(DEBUG)
54343 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
54344 +#endif
54345 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
54346 +       PVR_UNREFERENCED_PARAMETER(psBridgeOut);
54347 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
54348 +
54349 +#if defined(DEBUG_BRIDGE_KM)
54350 +       PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu (%s) mapped to "
54351 +                        "Dummy Wrapper (probably not what you want!)",
54352 +                        __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
54353 +#else
54354 +       PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu mapped to "
54355 +                        "Dummy Wrapper (probably not what you want!)",
54356 +                        __FUNCTION__, ui32BridgeID));
54357 +#endif
54358 +       return -ENOTTY;
54359 +}
54360 +
54361 +
54362 +IMG_VOID
54363 +_SetDispatchTableEntry(IMG_UINT32 ui32Index,
54364 +                                          const IMG_CHAR *pszIOCName,
54365 +                                          BridgeWrapperFunction pfFunction,
54366 +                                          const IMG_CHAR *pszFunctionName)
54367 +{
54368 +       static IMG_UINT32 ui32PrevIndex = ~0UL;
54369 +#if !defined(DEBUG)
54370 +       PVR_UNREFERENCED_PARAMETER(pszIOCName);
54371 +#endif
54372 +#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
54373 +       PVR_UNREFERENCED_PARAMETER(pszFunctionName);
54374 +#endif
54375 +
54376 +#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
54377 +
54378 +       PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
54379 +#endif
54380 +
54381 +
54382 +       if(g_BridgeDispatchTable[ui32Index].pfFunction)
54383 +       {
54384 +#if defined(DEBUG_BRIDGE_KM)
54385 +               PVR_DPF((PVR_DBG_ERROR,
54386 +                                "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s",
54387 +                                __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName));
54388 +#else
54389 +               PVR_DPF((PVR_DBG_ERROR,
54390 +                                "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%lu)",
54391 +                                __FUNCTION__, pszIOCName, ui32Index));
54392 +#endif
54393 +               PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.",
54394 +                               __FUNCTION__));
54395 +       }
54396 +
54397 +
54398 +       if((ui32PrevIndex != ~0UL) &&
54399 +          ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
54400 +               (ui32Index <= ui32PrevIndex)))
54401 +       {
54402 +#if defined(DEBUG_BRIDGE_KM)
54403 +               PVR_DPF((PVR_DBG_WARNING,
54404 +                                "%s: There is a gap in the dispatch table between indices %lu (%s) and %lu (%s)",
54405 +                                __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
54406 +                                ui32Index, pszIOCName));
54407 +#else
54408 +               PVR_DPF((PVR_DBG_WARNING,
54409 +                                "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
54410 +                                __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
54411 +#endif
54412 +               PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.",
54413 +                               __FUNCTION__));
54414 +       }
54415 +
54416 +       g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
54417 +#if defined(DEBUG_BRIDGE_KM)
54418 +       g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
54419 +       g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
54420 +       g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
54421 +       g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
54422 +#endif
54423 +
54424 +       ui32PrevIndex = ui32Index;
54425 +}
54426 +
54427 +static IMG_INT
54428 +PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID,
54429 +                                          IMG_VOID *psBridgeIn,
54430 +                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
54431 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
54432 +{
54433 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
54434 +
54435 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
54436 +       PVR_UNREFERENCED_PARAMETER(psBridgeIn);
54437 +
54438 +       if(!OSProcHasPrivSrvInit() || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
54439 +       {
54440 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
54441 +               return 0;
54442 +       }
54443 +
54444 +#if defined (__linux__)
54445 +       PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
54446 +#endif
54447 +       psPerProc->bInitProcess = IMG_TRUE;
54448 +
54449 +       psRetOUT->eError = PVRSRV_OK;
54450 +
54451 +       return 0;
54452 +}
54453 +
54454 +
54455 +static IMG_INT
54456 +PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID,
54457 +                                                 PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
54458 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
54459 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
54460 +{
54461 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT);
54462 +
54463 +       if(!psPerProc->bInitProcess)
54464 +       {
54465 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
54466 +               return 0;
54467 +       }
54468 +
54469 +       psPerProc->bInitProcess = IMG_FALSE;
54470 +
54471 +       PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
54472 +       PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
54473 +
54474 +       psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
54475 +
54476 +       PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL,
54477 +                               (((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful)))
54478 +                               ? IMG_TRUE : IMG_FALSE);
54479 +
54480 +       return 0;
54481 +}
54482 +
54483 +
54484 +static IMG_INT
54485 +PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID,
54486 +                                                 PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
54487 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
54488 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
54489 +{
54490 +       IMG_HANDLE hOSEventKM;
54491 +
54492 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
54493 +
54494 +       psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
54495 +                                                  &hOSEventKM,
54496 +                                                  psEventObjectWaitIN->hOSEventKM,
54497 +                                                  PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
54498 +
54499 +       if(psRetOUT->eError != PVRSRV_OK)
54500 +       {
54501 +               return 0;
54502 +       }
54503 +
54504 +       psRetOUT->eError = OSEventObjectWait(hOSEventKM);
54505 +
54506 +       return 0;
54507 +}
54508 +
54509 +
54510 +static IMG_INT
54511 +PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID,
54512 +                                                 PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
54513 +                                                 PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
54514 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
54515 +{
54516 +
54517 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
54518 +
54519 +       NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1);
54520 +
54521 +       psEventObjectOpenOUT->eError =
54522 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54523 +                                                  &psEventObjectOpenIN->sEventObject.hOSEventKM,
54524 +                                                  psEventObjectOpenIN->sEventObject.hOSEventKM,
54525 +                                                  PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
54526 +
54527 +       if(psEventObjectOpenOUT->eError != PVRSRV_OK)
54528 +       {
54529 +               return 0;
54530 +       }
54531 +
54532 +       psEventObjectOpenOUT->eError = OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
54533 +
54534 +       if(psEventObjectOpenOUT->eError != PVRSRV_OK)
54535 +       {
54536 +               return 0;
54537 +       }
54538 +
54539 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
54540 +                                         &psEventObjectOpenOUT->hOSEvent,
54541 +                                         psEventObjectOpenOUT->hOSEvent,
54542 +                                         PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
54543 +                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
54544 +
54545 +       COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc);
54546 +
54547 +       return 0;
54548 +}
54549 +
54550 +
54551 +static IMG_INT
54552 +PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID,
54553 +                                                 PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
54554 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
54555 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
54556 +{
54557 +       IMG_HANDLE hOSEventKM;
54558 +
54559 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
54560 +
54561 +       psRetOUT->eError =
54562 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
54563 +                                                  &psEventObjectCloseIN->sEventObject.hOSEventKM,
54564 +                                                  psEventObjectCloseIN->sEventObject.hOSEventKM,
54565 +                                                  PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
54566 +       if(psRetOUT->eError != PVRSRV_OK)
54567 +       {
54568 +               return 0;
54569 +       }
54570 +
54571 +       psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
54572 +                                                  &hOSEventKM,
54573 +                                                  psEventObjectCloseIN->hOSEventKM,
54574 +                                                  PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
54575 +
54576 +       if(psRetOUT->eError != PVRSRV_OK)
54577 +       {
54578 +               return 0;
54579 +       }
54580 +
54581 +       psRetOUT->eError = OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM);
54582 +
54583 +       return 0;
54584 +}
54585 +
54586 +
54587 +typedef struct _MODIFY_SYNC_OP_INFO
54588 +{
54589 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
54590 +       IMG_UINT32      ui32ModifyFlags;
54591 +       IMG_UINT32      ui32ReadOpsPendingSnapShot;
54592 +       IMG_UINT32      ui32WriteOpsPendingSnapShot;
54593 +} MODIFY_SYNC_OP_INFO;
54594 +
54595 +
54596 +static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID            pvParam,
54597 +                                                                                                       IMG_UINT32      ui32Param)
54598 +{
54599 +       MODIFY_SYNC_OP_INFO             *psModSyncOpInfo;
54600 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
54601 +
54602 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
54603 +
54604 +       if (!pvParam)
54605 +       {
54606 +               PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
54607 +               return PVRSRV_ERROR_INVALID_PARAMS;
54608 +       }
54609 +
54610 +       psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
54611 +       psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
54612 +
54613 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
54614 +       {
54615 +               if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
54616 +               && (psModSyncOpInfo->ui32ReadOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
54617 +               {
54618 +                       goto OpFlushedComplete;
54619 +               }
54620 +               PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: waiting for old Ops to flush"));
54621 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
54622 +       } END_LOOP_UNTIL_TIMEOUT();
54623 +
54624 +       PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: waiting for old Ops to flush timed out"));
54625 +
54626 +       return PVRSRV_ERROR_TIMEOUT;
54627 +
54628 +OpFlushedComplete:
54629 +
54630 +
54631 +       if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
54632 +       {
54633 +               psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
54634 +       }
54635 +
54636 +
54637 +       if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
54638 +       {
54639 +               psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
54640 +       }
54641 +
54642 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,      sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
54643 +
54644 +
54645 +
54646 +       PVRSRVCommandCompleteCallbacks();
54647 +
54648 +       return PVRSRV_OK;
54649 +}
54650 +
54651 +
54652 +static IMG_INT
54653 +PVRSRVModifyPendingSyncOpsBW(IMG_UINT32                                                                        ui32BridgeID,
54654 +                                                     PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS  *psModifySyncOpsIN,
54655 +                                                         PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS     *psModifySyncOpsOUT,
54656 +                                                         PVRSRV_PER_PROCESS_DATA                                       *psPerProc)
54657 +{
54658 +       IMG_HANDLE                              hKernelSyncInfo;
54659 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
54660 +       MODIFY_SYNC_OP_INFO             *psModSyncOpInfo;
54661 +
54662 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
54663 +
54664 +       psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
54665 +                                                                                                       &hKernelSyncInfo,
54666 +                                                                                                       psModifySyncOpsIN->hKernelSyncInfo,
54667 +                                                                                                       PVRSRV_HANDLE_TYPE_SYNC_INFO);
54668 +       if (psModifySyncOpsOUT->eError != PVRSRV_OK)
54669 +       {
54670 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
54671 +               return 0;
54672 +       }
54673 +
54674 +       psKernelSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo;
54675 +
54676 +       if(psKernelSyncInfo->hResItem != IMG_NULL)
54677 +       {
54678 +
54679 +               psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
54680 +               return 0;
54681 +       }
54682 +
54683 +       ASSIGN_AND_EXIT_ON_ERROR(psModifySyncOpsOUT->eError,
54684 +                         OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
54685 +                         sizeof(MODIFY_SYNC_OP_INFO),
54686 +                         (IMG_VOID **)&psModSyncOpInfo, 0,
54687 +                         "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
54688 +
54689 +
54690 +       psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
54691 +       psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
54692 +       psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
54693 +       psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
54694 +
54695 +
54696 +
54697 +       psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
54698 +       psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
54699 +
54700 +       if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
54701 +       {
54702 +               psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
54703 +       }
54704 +
54705 +       if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
54706 +       {
54707 +               psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
54708 +       }
54709 +
54710 +       psKernelSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
54711 +                                                                                                       RESMAN_TYPE_MODIFY_SYNC_OPS,
54712 +                                                                                                       psModSyncOpInfo,
54713 +                                                                                                       0,
54714 +                                                                                                       ModifyCompleteSyncOpsCallBack);
54715 +       return 0;
54716 +}
54717 +
54718 +
54719 +static IMG_INT
54720 +PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32                                                       ui32BridgeID,
54721 +                                     PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS         *psModifySyncOpsIN,
54722 +                                         PVRSRV_BRIDGE_RETURN                                                  *psModifySyncOpsOUT,
54723 +                                         PVRSRV_PER_PROCESS_DATA                                               *psPerProc)
54724 +{
54725 +       PVRSRV_ERROR eError;
54726 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
54727 +
54728 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
54729 +
54730 +       psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
54731 +                                                                                                       (IMG_VOID**)&psKernelSyncInfo,
54732 +                                                                                                       psModifySyncOpsIN->hKernelSyncInfo,
54733 +                                                                                                       PVRSRV_HANDLE_TYPE_SYNC_INFO);
54734 +       if (psModifySyncOpsOUT->eError != PVRSRV_OK)
54735 +       {
54736 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
54737 +               return 0;
54738 +       }
54739 +
54740 +       if(psKernelSyncInfo->hResItem == IMG_NULL)
54741 +       {
54742 +
54743 +               psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
54744 +               return 0;
54745 +       }
54746 +
54747 +
54748 +
54749 +
54750 +
54751 +
54752 +
54753 +
54754 +
54755 +
54756 +       eError = ResManFreeResByPtr(psKernelSyncInfo->hResItem);
54757 +       if (eError != PVRSRV_OK)
54758 +       {
54759 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: ResManFreeResByPtr failed"));
54760 +               return 0;
54761 +       }
54762 +
54763 +       psKernelSyncInfo->hResItem = IMG_NULL;
54764 +
54765 +       return 0;
54766 +}
54767 +
54768 +
54769 +PVRSRV_ERROR
54770 +CommonBridgeInit(IMG_VOID)
54771 +{
54772 +       IMG_UINT32 i;
54773 +
54774 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW);
54775 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW);
54776 +       SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
54777 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW);
54778 +       SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW);
54779 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW);
54780 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW);
54781 +       SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW);
54782 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW);
54783 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
54784 +       SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
54785 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW);
54786 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
54787 +       SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW);
54788 +       SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
54789 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
54790 +       SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW);
54791 +       SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
54792 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
54793 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
54794 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW);
54795 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW);
54796 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW);
54797 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW);
54798 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
54799 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
54800 +       SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW);
54801 +       SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW);
54802 +
54803 +
54804 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
54805 +       SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
54806 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
54807 +
54808 +
54809 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
54810 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
54811 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
54812 +
54813 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
54814 +
54815 +
54816 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
54817 +       SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
54818 +
54819 +
54820 +#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
54821 +       SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW);
54822 +       SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW);
54823 +#endif
54824 +
54825 +
54826 +
54827 +#if defined(PDUMP)
54828 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
54829 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
54830 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
54831 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
54832 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
54833 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
54834 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
54835 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW);
54836 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
54837 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW);
54838 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
54839 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
54840 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW);
54841 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_PDREG, PDumpPDRegBW);
54842 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW);
54843 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW);
54844 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW);
54845 +       SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW);
54846 +#endif
54847 +
54848 +
54849 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
54850 +
54851 +
54852 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
54853 +
54854 +
54855 +       SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW);
54856 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW);
54857 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW);
54858 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW);
54859 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
54860 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW);
54861 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW);
54862 +       SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW);
54863 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW);
54864 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW);
54865 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW);
54866 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW);
54867 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW);
54868 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW);
54869 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
54870 +
54871 +
54872 +       SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW);
54873 +       SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW);
54874 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW);
54875 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW);
54876 +
54877 +
54878 +       SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
54879 +       SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
54880 +
54881 +
54882 +       SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
54883 +       SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
54884 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
54885 +
54886 +
54887 +       SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR, MMU_GetPDDevPAddrBW);
54888 +
54889 +
54890 +       SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT,    PVRSRVInitSrvConnectBW);
54891 +       SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, PVRSRVInitSrvDisconnectBW);
54892 +
54893 +
54894 +       SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT,  PVRSRVEventObjectWaitBW);
54895 +       SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN,  PVRSRVEventObjectOpenBW);
54896 +       SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW);
54897 +
54898 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
54899 +       SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
54900 +
54901 +#if defined (SUPPORT_SGX)
54902 +       SetSGXDispatchTableEntry();
54903 +#endif
54904 +#if defined (SUPPORT_VGX)
54905 +       SetVGXDispatchTableEntry();
54906 +#endif
54907 +#if defined (SUPPORT_MSVDX)
54908 +       SetMSVDXDispatchTableEntry();
54909 +#endif
54910 +
54911 +
54912 +
54913 +
54914 +       for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
54915 +       {
54916 +               if(!g_BridgeDispatchTable[i].pfFunction)
54917 +               {
54918 +                       g_BridgeDispatchTable[i].pfFunction = DummyBW;
54919 +#if defined(DEBUG_BRIDGE_KM)
54920 +                       g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
54921 +                       g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
54922 +                       g_BridgeDispatchTable[i].ui32CallCount = 0;
54923 +                       g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
54924 +                       g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
54925 +#endif
54926 +               }
54927 +       }
54928 +
54929 +       return PVRSRV_OK;
54930 +}
54931 +
54932 +
54933 +IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
54934 +                                         PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM)
54935 +{
54936 +
54937 +       IMG_VOID   * psBridgeIn;
54938 +       IMG_VOID   * psBridgeOut;
54939 +       BridgeWrapperFunction pfBridgeHandler;
54940 +       IMG_UINT32   ui32BridgeID = psBridgePackageKM->ui32BridgeID;
54941 +       IMG_INT      err          = -EFAULT;
54942 +
54943 +#if defined(DEBUG_TRACE_BRIDGE_KM)
54944 +       PVR_DPF((PVR_DBG_ERROR, "%s: %s",
54945 +                        __FUNCTION__,
54946 +                        g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
54947 +#endif
54948 +
54949 +#if defined(DEBUG_BRIDGE_KM)
54950 +       g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++;
54951 +       g_BridgeGlobalStats.ui32IOCTLCount++;
54952 +#endif
54953 +
54954 +       if(!psPerProc->bInitProcess)
54955 +       {
54956 +               if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
54957 +               {
54958 +                       if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
54959 +                       {
54960 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed.  Driver unusable.",
54961 +                                                __FUNCTION__));
54962 +                               goto return_fault;
54963 +                       }
54964 +               }
54965 +               else
54966 +               {
54967 +                       if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
54968 +                       {
54969 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
54970 +                                                __FUNCTION__));
54971 +                               goto return_fault;
54972 +                       }
54973 +                       else
54974 +                       {
54975 +
54976 +                               switch(ui32BridgeID)
54977 +                               {
54978 +                                       case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES):
54979 +                                       case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
54980 +                                       case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT):
54981 +                                       case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT):
54982 +                                               break;
54983 +                                       default:
54984 +                                               PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
54985 +                                                                __FUNCTION__));
54986 +                                               goto return_fault;
54987 +                               }
54988 +                       }
54989 +               }
54990 +       }
54991 +
54992 +
54993 +
54994 +#if defined(__linux__)
54995 +       {
54996 +
54997 +               SYS_DATA *psSysData;
54998 +
54999 +               SysAcquireData(&psSysData);
55000 +
55001 +
55002 +               psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
55003 +               psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
55004 +
55005 +               if(psBridgePackageKM->ui32InBufferSize > 0)
55006 +               {
55007 +                       if(!OSAccessOK(PVR_VERIFY_READ,
55008 +                                                       psBridgePackageKM->pvParamIn,
55009 +                                                       psBridgePackageKM->ui32InBufferSize))
55010 +                       {
55011 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__));
55012 +                       }
55013 +
55014 +                       if(CopyFromUserWrapper(psPerProc,
55015 +                                                      ui32BridgeID,
55016 +                                                                  psBridgeIn,
55017 +                                                                  psBridgePackageKM->pvParamIn,
55018 +                                                                  psBridgePackageKM->ui32InBufferSize)
55019 +                         != PVRSRV_OK)
55020 +                       {
55021 +                               goto return_fault;
55022 +                       }
55023 +               }
55024 +       }
55025 +#else
55026 +       psBridgeIn  = psBridgePackageKM->pvParamIn;
55027 +       psBridgeOut = psBridgePackageKM->pvParamOut;
55028 +#endif
55029 +
55030 +       if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
55031 +       {
55032 +               PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!",
55033 +                                __FUNCTION__, ui32BridgeID));
55034 +               goto return_fault;
55035 +       }
55036 +       pfBridgeHandler =
55037 +               (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction;
55038 +       err = pfBridgeHandler(ui32BridgeID,
55039 +                                                 psBridgeIn,
55040 +                                                 psBridgeOut,
55041 +                                                 psPerProc);
55042 +       if(err < 0)
55043 +       {
55044 +               goto return_fault;
55045 +       }
55046 +
55047 +
55048 +#if defined(__linux__)
55049 +
55050 +       if(CopyToUserWrapper(psPerProc,
55051 +                                                ui32BridgeID,
55052 +                                                psBridgePackageKM->pvParamOut,
55053 +                                                psBridgeOut,
55054 +                                                psBridgePackageKM->ui32OutBufferSize)
55055 +          != PVRSRV_OK)
55056 +       {
55057 +               goto return_fault;
55058 +       }
55059 +#endif
55060 +
55061 +       err = 0;
55062 +return_fault:
55063 +       ReleaseHandleBatch(psPerProc);
55064 +       return err;
55065 +}
55066 +
55067 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h
55068 new file mode 100644
55069 index 0000000..95a6377
55070 --- /dev/null
55071 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_pvr_bridge.h
55072 @@ -0,0 +1,231 @@
55073 +/**********************************************************************
55074 + *
55075 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
55076 + *
55077 + * This program is free software; you can redistribute it and/or modify it
55078 + * under the terms and conditions of the GNU General Public License,
55079 + * version 2, as published by the Free Software Foundation.
55080 + *
55081 + * This program is distributed in the hope it will be useful but, except
55082 + * as otherwise stated in writing, without any warranty; without even the
55083 + * implied warranty of merchantability or fitness for a particular purpose.
55084 + * See the GNU General Public License for more details.
55085 + *
55086 + * You should have received a copy of the GNU General Public License along with
55087 + * this program; if not, write to the Free Software Foundation, Inc.,
55088 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
55089 + *
55090 + * The full GNU General Public License is included in this distribution in
55091 + * the file called "COPYING".
55092 + *
55093 + * Contact Information:
55094 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
55095 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
55096 + *
55097 + ******************************************************************************/
55098 +
55099 +#ifndef __BRIDGED_PVR_BRIDGE_H__
55100 +#define __BRIDGED_PVR_BRIDGE_H__
55101 +
55102 +#include "pvr_bridge.h"
55103 +
55104 +#if defined(__cplusplus)
55105 +extern "C" {
55106 +#endif
55107 +
55108 +#if defined(__linux__)
55109 +#define PVRSRV_GET_BRIDGE_ID(X)        _IOC_NR(X)
55110 +#else
55111 +#define PVRSRV_GET_BRIDGE_ID(X)        (X - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST))
55112 +#endif
55113 +
55114 +#ifndef ENOMEM
55115 +#define ENOMEM 12
55116 +#endif
55117 +#ifndef EFAULT
55118 +#define EFAULT 14
55119 +#endif
55120 +#ifndef ENOTTY
55121 +#define ENOTTY 25
55122 +#endif
55123 +
55124 +#if defined(DEBUG_BRIDGE_KM)
55125 +PVRSRV_ERROR
55126 +CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
55127 +                                       IMG_UINT32 ui32BridgeID,
55128 +                                       IMG_VOID *pvDest,
55129 +                                       IMG_VOID *pvSrc,
55130 +                                       IMG_UINT32 ui32Size);
55131 +PVRSRV_ERROR
55132 +CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
55133 +                                 IMG_UINT32 ui32BridgeID,
55134 +                                 IMG_VOID *pvDest,
55135 +                                 IMG_VOID *pvSrc,
55136 +                                 IMG_UINT32 ui32Size);
55137 +#else
55138 +#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
55139 +       OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size)
55140 +#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \
55141 +       OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size)
55142 +#endif
55143 +
55144 +
55145 +#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res)            \
55146 +       do                                                      \
55147 +       {                                                       \
55148 +               (error) = (src);                                \
55149 +               if ((error) != PVRSRV_OK)                       \
55150 +               {                                               \
55151 +                       return (res);                           \
55152 +               }                                               \
55153 +       } while (error != PVRSRV_OK)
55154 +
55155 +#define ASSIGN_AND_EXIT_ON_ERROR(error, src)           \
55156 +       ASSIGN_AND_RETURN_ON_ERROR(error, src, 0)
55157 +
55158 +#if defined (PVR_SECURE_HANDLES)
55159 +#ifdef INLINE_IS_PRAGMA
55160 +#pragma inline(NewHandleBatch)
55161 +#endif
55162 +static INLINE PVRSRV_ERROR
55163 +NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc,
55164 +                                       IMG_UINT32 ui32BatchSize)
55165 +{
55166 +       PVRSRV_ERROR eError;
55167 +
55168 +       PVR_ASSERT(!psPerProc->bHandlesBatched);
55169 +
55170 +       eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize);
55171 +
55172 +       if (eError == PVRSRV_OK)
55173 +       {
55174 +               psPerProc->bHandlesBatched = IMG_TRUE;
55175 +       }
55176 +
55177 +       return eError;
55178 +}
55179 +
55180 +#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)     \
55181 +       ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize))
55182 +
55183 +#ifdef INLINE_IS_PRAGMA
55184 +#pragma inline(CommitHandleBatch)
55185 +#endif
55186 +static INLINE PVRSRV_ERROR
55187 +CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
55188 +{
55189 +       PVR_ASSERT(psPerProc->bHandlesBatched);
55190 +
55191 +       psPerProc->bHandlesBatched = IMG_FALSE;
55192 +
55193 +       return PVRSRVCommitHandleBatch(psPerProc->psHandleBase);
55194 +}
55195 +
55196 +
55197 +#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)                         \
55198 +       ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc))
55199 +
55200 +#ifdef INLINE_IS_PRAGMA
55201 +#pragma inline(ReleaseHandleBatch)
55202 +#endif
55203 +static INLINE IMG_VOID
55204 +ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc)
55205 +{
55206 +       if (psPerProc->bHandlesBatched)
55207 +       {
55208 +               psPerProc->bHandlesBatched = IMG_FALSE;
55209 +
55210 +               PVRSRVReleaseHandleBatch(psPerProc->psHandleBase);
55211 +       }
55212 +}
55213 +#else
55214 +#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)
55215 +#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)
55216 +#define ReleaseHandleBatch(psPerProc)
55217 +#endif
55218 +
55219 +IMG_INT
55220 +DummyBW(IMG_UINT32 ui32BridgeID,
55221 +               IMG_VOID *psBridgeIn,
55222 +               IMG_VOID *psBridgeOut,
55223 +               PVRSRV_PER_PROCESS_DATA *psPerProc);
55224 +
55225 +typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID,
55226 +                                                                        IMG_VOID *psBridgeIn,
55227 +                                                                        IMG_VOID *psBridgeOut,
55228 +                                                                        PVRSRV_PER_PROCESS_DATA *psPerProc);
55229 +
55230 +typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
55231 +{
55232 +       BridgeWrapperFunction pfFunction;
55233 +#if defined(DEBUG_BRIDGE_KM)
55234 +       const IMG_CHAR *pszIOCName;
55235 +       const IMG_CHAR *pszFunctionName;
55236 +       IMG_UINT32 ui32CallCount;
55237 +       IMG_UINT32 ui32CopyFromUserTotalBytes;
55238 +       IMG_UINT32 ui32CopyToUserTotalBytes;
55239 +#endif
55240 +}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
55241 +
55242 +#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX)
55243 +       #if defined(SUPPORT_VGX)
55244 +               #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1)
55245 +               #define PVRSRV_BRIDGE_LAST_DEVICE_CMD      PVRSRV_BRIDGE_LAST_VGX_CMD
55246 +       #else
55247 +               #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1)
55248 +               #define PVRSRV_BRIDGE_LAST_DEVICE_CMD      PVRSRV_BRIDGE_LAST_MSVDX_CMD
55249 +       #endif
55250 +#else
55251 +       #if defined(SUPPORT_SGX)
55252 +               #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1)
55253 +               #define PVRSRV_BRIDGE_LAST_DEVICE_CMD      PVRSRV_BRIDGE_LAST_SGX_CMD
55254 +       #else
55255 +               #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1)
55256 +               #define PVRSRV_BRIDGE_LAST_DEVICE_CMD      PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD
55257 +       #endif
55258 +#endif
55259 +
55260 +extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
55261 +
55262 +IMG_VOID
55263 +_SetDispatchTableEntry(IMG_UINT32 ui32Index,
55264 +                                          const IMG_CHAR *pszIOCName,
55265 +                                          BridgeWrapperFunction pfFunction,
55266 +                                          const IMG_CHAR *pszFunctionName);
55267 +
55268 +
55269 +#define SetDispatchTableEntry(ui32Index, pfFunction) \
55270 +       _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction)
55271 +
55272 +#define DISPATCH_TABLE_GAP_THRESHOLD 5
55273 +
55274 +#if defined(DEBUG)
55275 +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y))
55276 +#else
55277 +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X)
55278 +#endif
55279 +
55280 +
55281 +#if defined(DEBUG_BRIDGE_KM)
55282 +typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS
55283 +{
55284 +       IMG_UINT32 ui32IOCTLCount;
55285 +       IMG_UINT32 ui32TotalCopyFromUserBytes;
55286 +       IMG_UINT32 ui32TotalCopyToUserBytes;
55287 +}PVRSRV_BRIDGE_GLOBAL_STATS;
55288 +
55289 +extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
55290 +#endif
55291 +
55292 +
55293 +PVRSRV_ERROR CommonBridgeInit(IMG_VOID);
55294 +
55295 +IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
55296 +                                         PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM);
55297 +
55298 +#if defined (__cplusplus)
55299 +}
55300 +#endif
55301 +
55302 +#endif
55303 +
55304 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.c
55305 new file mode 100644
55306 index 0000000..adc9610
55307 --- /dev/null
55308 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.c
55309 @@ -0,0 +1,85 @@
55310 +/**********************************************************************
55311 + *
55312 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
55313 + *
55314 + * This program is free software; you can redistribute it and/or modify it
55315 + * under the terms and conditions of the GNU General Public License,
55316 + * version 2, as published by the Free Software Foundation.
55317 + *
55318 + * This program is distributed in the hope it will be useful but, except
55319 + * as otherwise stated in writing, without any warranty; without even the
55320 + * implied warranty of merchantability or fitness for a particular purpose.
55321 + * See the GNU General Public License for more details.
55322 + *
55323 + * You should have received a copy of the GNU General Public License along with
55324 + * this program; if not, write to the Free Software Foundation, Inc.,
55325 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
55326 + *
55327 + * The full GNU General Public License is included in this distribution in
55328 + * the file called "COPYING".
55329 + *
55330 + * Contact Information:
55331 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
55332 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
55333 + *
55334 + ******************************************************************************/
55335 +
55336 +#include "img_defs.h"
55337 +#include "servicesint.h"
55338 +#include "bridged_support.h"
55339 +
55340 +
55341 +PVRSRV_ERROR
55342 +PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle)
55343 +{
55344 +       IMG_HANDLE hMHandleInt;
55345 +       PVRSRV_HANDLE_TYPE eHandleType;
55346 +       PVRSRV_ERROR eError;
55347 +
55348 +
55349 +       eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt,
55350 +                                                         &eHandleType,
55351 +                                                         hMHandle);
55352 +       if(eError != PVRSRV_OK)
55353 +       {
55354 +               return eError;
55355 +       }
55356 +
55357 +       switch(eHandleType)
55358 +       {
55359 +#if defined(PVR_SECURE_HANDLES)
55360 +               case PVRSRV_HANDLE_TYPE_MEM_INFO:
55361 +               case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
55362 +               case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
55363 +               {
55364 +                       PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt;
55365 +
55366 +                       *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
55367 +
55368 +                       break;
55369 +               }
55370 +               case PVRSRV_HANDLE_TYPE_SYNC_INFO:
55371 +               {
55372 +                       PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt;
55373 +                       PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM;
55374 +
55375 +                       *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle;
55376 +
55377 +                       break;
55378 +               }
55379 +               case  PVRSRV_HANDLE_TYPE_SOC_TIMER:
55380 +               {
55381 +                       *phOSMemHandle = (IMG_VOID *)hMHandleInt;
55382 +                       break;
55383 +               }
55384 +#else
55385 +               case  PVRSRV_HANDLE_TYPE_NONE:
55386 +                       *phOSMemHandle = (IMG_VOID *)hMHandleInt;
55387 +                       break;
55388 +#endif
55389 +               default:
55390 +                       return PVRSRV_ERROR_BAD_MAPPING;
55391 +       }
55392 +
55393 +       return PVRSRV_OK;
55394 +}
55395 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.h
55396 new file mode 100644
55397 index 0000000..9785d37
55398 --- /dev/null
55399 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/bridged_support.h
55400 @@ -0,0 +1,43 @@
55401 +/**********************************************************************
55402 + *
55403 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
55404 + *
55405 + * This program is free software; you can redistribute it and/or modify it
55406 + * under the terms and conditions of the GNU General Public License,
55407 + * version 2, as published by the Free Software Foundation.
55408 + *
55409 + * This program is distributed in the hope it will be useful but, except
55410 + * as otherwise stated in writing, without any warranty; without even the
55411 + * implied warranty of merchantability or fitness for a particular purpose.
55412 + * See the GNU General Public License for more details.
55413 + *
55414 + * You should have received a copy of the GNU General Public License along with
55415 + * this program; if not, write to the Free Software Foundation, Inc.,
55416 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
55417 + *
55418 + * The full GNU General Public License is included in this distribution in
55419 + * the file called "COPYING".
55420 + *
55421 + * Contact Information:
55422 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
55423 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
55424 + *
55425 + ******************************************************************************/
55426 +
55427 +#ifndef __BRIDGED_SUPPORT_H__
55428 +#define __BRIDGED_SUPPORT_H__
55429 +
55430 +#include "handle.h"
55431 +
55432 +#if defined(__cplusplus)
55433 +extern "C" {
55434 +#endif
55435 +
55436 +PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle);
55437 +
55438 +#if defined (__cplusplus)
55439 +}
55440 +#endif
55441 +
55442 +#endif
55443 +
55444 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
55445 new file mode 100644
55446 index 0000000..be7e23d
55447 --- /dev/null
55448 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
55449 @@ -0,0 +1,2511 @@
55450 +/**********************************************************************
55451 + *
55452 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
55453 + *
55454 + * This program is free software; you can redistribute it and/or modify it
55455 + * under the terms and conditions of the GNU General Public License,
55456 + * version 2, as published by the Free Software Foundation.
55457 + *
55458 + * This program is distributed in the hope it will be useful but, except
55459 + * as otherwise stated in writing, without any warranty; without even the
55460 + * implied warranty of merchantability or fitness for a particular purpose.
55461 + * See the GNU General Public License for more details.
55462 + *
55463 + * You should have received a copy of the GNU General Public License along with
55464 + * this program; if not, write to the Free Software Foundation, Inc.,
55465 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
55466 + *
55467 + * The full GNU General Public License is included in this distribution in
55468 + * the file called "COPYING".
55469 + *
55470 + * Contact Information:
55471 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
55472 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
55473 + *
55474 + ******************************************************************************/
55475 +
55476 +
55477 +
55478 +#include <stddef.h>
55479 +
55480 +#include "img_defs.h"
55481 +
55482 +#if defined(SUPPORT_SGX)
55483 +
55484 +#include "services.h"
55485 +#include "pvr_debug.h"
55486 +#include "pvr_bridge.h"
55487 +#include "sgx_bridge.h"
55488 +#include "perproc.h"
55489 +#include "power.h"
55490 +#include "pvr_bridge_km.h"
55491 +#include "sgx_bridge_km.h"
55492 +
55493 +#if defined(SUPPORT_MSVDX)
55494 +       #include "msvdx_bridge.h"
55495 +#endif
55496 +
55497 +#include "bridged_pvr_bridge.h"
55498 +#include "bridged_sgx_bridge.h"
55499 +#include "sgxutils.h"
55500 +#include "pdump_km.h"
55501 +
55502 +static IMG_INT
55503 +SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID,
55504 +                                  PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN,
55505 +                                  PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT,
55506 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
55507 +{
55508 +       IMG_HANDLE hDevCookieInt;
55509 +
55510 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO);
55511 +
55512 +       psGetClientInfoOUT->eError =
55513 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
55514 +                                                  psGetClientInfoIN->hDevCookie,
55515 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55516 +       if(psGetClientInfoOUT->eError != PVRSRV_OK)
55517 +       {
55518 +               return 0;
55519 +       }
55520 +
55521 +       psGetClientInfoOUT->eError =
55522 +               SGXGetClientInfoKM(hDevCookieInt,
55523 +                                                  &psGetClientInfoOUT->sClientInfo);
55524 +       return 0;
55525 +}
55526 +
55527 +static IMG_INT
55528 +SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID,
55529 +                                          PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN,
55530 +                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
55531 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
55532 +{
55533 +       PVRSRV_SGXDEV_INFO *psDevInfo;
55534 +       IMG_HANDLE hDevCookieInt;
55535 +
55536 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO);
55537 +
55538 +       psRetOUT->eError =
55539 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
55540 +                                                  psReleaseClientInfoIN->hDevCookie,
55541 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55542 +       if(psRetOUT->eError != PVRSRV_OK)
55543 +       {
55544 +               return 0;
55545 +       }
55546 +
55547 +       psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
55548 +
55549 +       PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0);
55550 +
55551 +       psDevInfo->ui32ClientRefCount--;
55552 +
55553 +       psRetOUT->eError = PVRSRV_OK;
55554 +
55555 +       return 0;
55556 +}
55557 +
55558 +
55559 +static IMG_INT
55560 +SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID,
55561 +                                               PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN,
55562 +                                               PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT,
55563 +                                               PVRSRV_PER_PROCESS_DATA *psPerProc)
55564 +{
55565 +       IMG_HANDLE hDevCookieInt;
55566 +
55567 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO);
55568 +
55569 +       psSGXGetInternalDevInfoOUT->eError =
55570 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
55571 +                                                  psSGXGetInternalDevInfoIN->hDevCookie,
55572 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55573 +       if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK)
55574 +       {
55575 +               return 0;
55576 +       }
55577 +
55578 +       psSGXGetInternalDevInfoOUT->eError =
55579 +               SGXGetInternalDevInfoKM(hDevCookieInt,
55580 +                                                               &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
55581 +
55582 +
55583 +       psSGXGetInternalDevInfoOUT->eError =
55584 +               PVRSRVAllocHandle(psPerProc->psHandleBase,
55585 +                                                 &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
55586 +                                                 psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
55587 +                                                 PVRSRV_HANDLE_TYPE_MEM_INFO,
55588 +                                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
55589 +
55590 +       return 0;
55591 +}
55592 +
55593 +
55594 +static IMG_INT
55595 +SGXDoKickBW(IMG_UINT32 ui32BridgeID,
55596 +                       PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN,
55597 +                       PVRSRV_BRIDGE_RETURN *psRetOUT,
55598 +                       PVRSRV_PER_PROCESS_DATA *psPerProc)
55599 +{
55600 +       IMG_HANDLE hDevCookieInt;
55601 +       IMG_UINT32 i;
55602 +       IMG_INT ret = 0;
55603 +       IMG_UINT32 ui32NumDstSyncs;
55604 +       IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL;
55605 +
55606 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK);
55607 +
55608 +       psRetOUT->eError =
55609 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
55610 +                                                  &hDevCookieInt,
55611 +                                                  psDoKickIN->hDevCookie,
55612 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55613 +
55614 +       if(psRetOUT->eError != PVRSRV_OK)
55615 +       {
55616 +               return 0;
55617 +       }
55618 +
55619 +       psRetOUT->eError =
55620 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
55621 +                                                  &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
55622 +                                                  psDoKickIN->sCCBKick.hCCBKernelMemInfo,
55623 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
55624 +
55625 +       if(psRetOUT->eError != PVRSRV_OK)
55626 +       {
55627 +               return 0;
55628 +       }
55629 +
55630 +       if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL)
55631 +       {
55632 +               psRetOUT->eError =
55633 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55634 +                                                          &psDoKickIN->sCCBKick.hTA3DSyncInfo,
55635 +                                                          psDoKickIN->sCCBKick.hTA3DSyncInfo,
55636 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55637 +
55638 +               if(psRetOUT->eError != PVRSRV_OK)
55639 +               {
55640 +                       return 0;
55641 +               }
55642 +       }
55643 +
55644 +       if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL)
55645 +       {
55646 +               psRetOUT->eError =
55647 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55648 +                                                          &psDoKickIN->sCCBKick.hTASyncInfo,
55649 +                                                          psDoKickIN->sCCBKick.hTASyncInfo,
55650 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55651 +
55652 +               if(psRetOUT->eError != PVRSRV_OK)
55653 +               {
55654 +                       return 0;
55655 +               }
55656 +       }
55657 +
55658 +       if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL)
55659 +       {
55660 +               psRetOUT->eError =
55661 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55662 +                                                          &psDoKickIN->sCCBKick.h3DSyncInfo,
55663 +                                                          psDoKickIN->sCCBKick.h3DSyncInfo,
55664 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55665 +
55666 +               if(psRetOUT->eError != PVRSRV_OK)
55667 +               {
55668 +                       return 0;
55669 +               }
55670 +       }
55671 +
55672 +
55673 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
55674 +
55675 +       if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS)
55676 +       {
55677 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55678 +               return 0;
55679 +       }
55680 +
55681 +       for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++)
55682 +       {
55683 +               psRetOUT->eError =
55684 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55685 +                                                          &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
55686 +                                                          psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
55687 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55688 +
55689 +               if(psRetOUT->eError != PVRSRV_OK)
55690 +               {
55691 +                       return 0;
55692 +               }
55693 +       }
55694 +
55695 +       if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS)
55696 +       {
55697 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55698 +               return 0;
55699 +       }
55700 +
55701 +       for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++)
55702 +       {
55703 +               psRetOUT->eError =
55704 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55705 +                                                          &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
55706 +                                                          psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
55707 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55708 +
55709 +               if(psRetOUT->eError != PVRSRV_OK)
55710 +               {
55711 +                       return 0;
55712 +               }
55713 +       }
55714 +
55715 +       if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS)
55716 +       {
55717 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55718 +               return 0;
55719 +       }
55720 +
55721 +       for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++)
55722 +       {
55723 +               psRetOUT->eError =
55724 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55725 +                                                          &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
55726 +                                                          psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
55727 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55728 +
55729 +               if(psRetOUT->eError != PVRSRV_OK)
55730 +               {
55731 +                       return 0;
55732 +               }
55733 +       }
55734 +#else
55735 +
55736 +       if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS)
55737 +       {
55738 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55739 +               return 0;
55740 +       }
55741 +       for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++)
55742 +       {
55743 +               psRetOUT->eError =
55744 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55745 +                                                          &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
55746 +                                                          psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
55747 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55748 +
55749 +               if(psRetOUT->eError != PVRSRV_OK)
55750 +               {
55751 +                       return 0;
55752 +               }
55753 +       }
55754 +#endif
55755 +
55756 +       if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS)
55757 +       {
55758 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55759 +               return 0;
55760 +       }
55761 +       for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++)
55762 +       {
55763 +               psRetOUT->eError =
55764 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
55765 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55766 +                                                          &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
55767 +                                                          psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
55768 +                                                          PVRSRV_HANDLE_TYPE_MEM_INFO);
55769 +#else
55770 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55771 +                                                          &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
55772 +                                                          psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
55773 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55774 +#endif
55775 +               if(psRetOUT->eError != PVRSRV_OK)
55776 +               {
55777 +                       return 0;
55778 +               }
55779 +       }
55780 +
55781 +       if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS)
55782 +       {
55783 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55784 +               return 0;
55785 +       }
55786 +       for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++)
55787 +       {
55788 +               psRetOUT->eError =
55789 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
55790 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55791 +                                                          &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
55792 +                                                          psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
55793 +                                                          PVRSRV_HANDLE_TYPE_MEM_INFO);
55794 +#else
55795 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55796 +                                                          &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
55797 +                                                          psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
55798 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55799 +#endif
55800 +
55801 +               if(psRetOUT->eError != PVRSRV_OK)
55802 +               {
55803 +                       return 0;
55804 +               }
55805 +       }
55806 +
55807 +       ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
55808 +
55809 +       if(ui32NumDstSyncs > 0)
55810 +       {
55811 +               if(!OSAccessOK(PVR_VERIFY_READ,
55812 +                                               psDoKickIN->sCCBKick.pahDstSyncHandles,
55813 +                                               ui32NumDstSyncs * sizeof(IMG_HANDLE)))
55814 +               {
55815 +                       PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:"
55816 +                                       " Invalid pasDstSyncHandles pointer", __FUNCTION__));
55817 +                       return -EFAULT;
55818 +               }
55819 +
55820 +               psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
55821 +                                                                               ui32NumDstSyncs * sizeof(IMG_HANDLE),
55822 +                                                                               (IMG_VOID **)&phKernelSyncInfoHandles,
55823 +                                                                               0,
55824 +                                                                               "Array of Synchronization Info Handles");
55825 +               if (psRetOUT->eError != PVRSRV_OK)
55826 +               {
55827 +                       return 0;
55828 +               }
55829 +
55830 +               if(CopyFromUserWrapper(psPerProc,
55831 +                                                       ui32BridgeID,
55832 +                                                       phKernelSyncInfoHandles,
55833 +                                                       psDoKickIN->sCCBKick.pahDstSyncHandles,
55834 +                                                       ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK)
55835 +               {
55836 +                       ret = -EFAULT;
55837 +                       goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
55838 +               }
55839 +
55840 +
55841 +               psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles;
55842 +
55843 +               for( i = 0; i < ui32NumDstSyncs; i++)
55844 +               {
55845 +                       psRetOUT->eError =
55846 +                               PVRSRVLookupHandle(psPerProc->psHandleBase,
55847 +                                                                       &psDoKickIN->sCCBKick.pahDstSyncHandles[i],
55848 +                                                                       psDoKickIN->sCCBKick.pahDstSyncHandles[i],
55849 +                                                                       PVRSRV_HANDLE_TYPE_SYNC_INFO);
55850 +
55851 +                       if(psRetOUT->eError != PVRSRV_OK)
55852 +                       {
55853 +                               goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
55854 +                       }
55855 +
55856 +               }
55857 +
55858 +               psRetOUT->eError =
55859 +                                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55860 +                                                                          &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
55861 +                                                                          psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
55862 +                                                                          PVRSRV_HANDLE_TYPE_MEM_INFO);
55863 +
55864 +               if(psRetOUT->eError != PVRSRV_OK)
55865 +               {
55866 +                       goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
55867 +               }
55868 +       }
55869 +
55870 +       psRetOUT->eError =
55871 +               SGXDoKickKM(hDevCookieInt,
55872 +                                       &psDoKickIN->sCCBKick);
55873 +
55874 +PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT:
55875 +
55876 +       if(phKernelSyncInfoHandles)
55877 +       {
55878 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
55879 +                                 ui32NumDstSyncs * sizeof(IMG_HANDLE),
55880 +                                 (IMG_VOID *)phKernelSyncInfoHandles,
55881 +                                 0);
55882 +
55883 +       }
55884 +
55885 +       return ret;
55886 +}
55887 +
55888 +
55889 +static IMG_INT
55890 +SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID,
55891 +                       PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN,
55892 +                       PVRSRV_BRIDGE_RETURN *psRetOUT,
55893 +                       PVRSRV_PER_PROCESS_DATA *psPerProc)
55894 +{
55895 +       IMG_HANDLE hDevCookieInt;
55896 +
55897 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES);
55898 +
55899 +       psRetOUT->eError =
55900 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
55901 +                                                  &hDevCookieInt,
55902 +                                                  psScheduleProcQIN->hDevCookie,
55903 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55904 +
55905 +       if(psRetOUT->eError != PVRSRV_OK)
55906 +       {
55907 +               return 0;
55908 +       }
55909 +
55910 +       psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt);
55911 +
55912 +       return 0;
55913 +}
55914 +
55915 +
55916 +#if defined(TRANSFER_QUEUE)
55917 +static IMG_INT
55918 +SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID,
55919 +                       PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN,
55920 +                       PVRSRV_BRIDGE_RETURN *psRetOUT,
55921 +                       PVRSRV_PER_PROCESS_DATA *psPerProc)
55922 +{
55923 +       IMG_HANDLE hDevCookieInt;
55924 +       PVRSRV_TRANSFER_SGX_KICK *psKick;
55925 +       IMG_UINT32 i;
55926 +
55927 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
55928 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
55929 +
55930 +       psKick = &psSubmitTransferIN->sKick;
55931 +
55932 +       psRetOUT->eError =
55933 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
55934 +                                                  &hDevCookieInt,
55935 +                                                  psSubmitTransferIN->hDevCookie,
55936 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
55937 +       if(psRetOUT->eError != PVRSRV_OK)
55938 +       {
55939 +               return 0;
55940 +       }
55941 +
55942 +       psRetOUT->eError =
55943 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
55944 +                                                  &psKick->hCCBMemInfo,
55945 +                                                  psKick->hCCBMemInfo,
55946 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
55947 +       if(psRetOUT->eError != PVRSRV_OK)
55948 +       {
55949 +               return 0;
55950 +       }
55951 +
55952 +       if (psKick->hTASyncInfo != IMG_NULL)
55953 +       {
55954 +               psRetOUT->eError =
55955 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55956 +                                                          &psKick->hTASyncInfo,
55957 +                                                          psKick->hTASyncInfo,
55958 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55959 +               if(psRetOUT->eError != PVRSRV_OK)
55960 +               {
55961 +                       return 0;
55962 +               }
55963 +       }
55964 +
55965 +       if (psKick->h3DSyncInfo != IMG_NULL)
55966 +       {
55967 +               psRetOUT->eError =
55968 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55969 +                                                          &psKick->h3DSyncInfo,
55970 +                                                          psKick->h3DSyncInfo,
55971 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55972 +               if(psRetOUT->eError != PVRSRV_OK)
55973 +               {
55974 +                       return 0;
55975 +               }
55976 +       }
55977 +
55978 +       if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS)
55979 +       {
55980 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55981 +               return 0;
55982 +       }
55983 +       for (i = 0; i < psKick->ui32NumSrcSync; i++)
55984 +       {
55985 +               psRetOUT->eError =
55986 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
55987 +                                                          &psKick->ahSrcSyncInfo[i],
55988 +                                                          psKick->ahSrcSyncInfo[i],
55989 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
55990 +               if(psRetOUT->eError != PVRSRV_OK)
55991 +               {
55992 +                       return 0;
55993 +               }
55994 +       }
55995 +
55996 +       if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS)
55997 +       {
55998 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
55999 +               return 0;
56000 +       }
56001 +       for (i = 0; i < psKick->ui32NumDstSync; i++)
56002 +       {
56003 +               psRetOUT->eError =
56004 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
56005 +                                                          &psKick->ahDstSyncInfo[i],
56006 +                                                          psKick->ahDstSyncInfo[i],
56007 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
56008 +               if(psRetOUT->eError != PVRSRV_OK)
56009 +               {
56010 +                       return 0;
56011 +               }
56012 +       }
56013 +
56014 +       psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick);
56015 +
56016 +       return 0;
56017 +}
56018 +
56019 +
56020 +#if defined(SGX_FEATURE_2D_HARDWARE)
56021 +static IMG_INT
56022 +SGXSubmit2DBW(IMG_UINT32 ui32BridgeID,
56023 +                       PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN,
56024 +                       PVRSRV_BRIDGE_RETURN *psRetOUT,
56025 +                       PVRSRV_PER_PROCESS_DATA *psPerProc)
56026 +{
56027 +       IMG_HANDLE hDevCookieInt;
56028 +       PVRSRV_2D_SGX_KICK *psKick;
56029 +       IMG_UINT32 i;
56030 +
56031 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D);
56032 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
56033 +
56034 +       psRetOUT->eError =
56035 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56036 +                                                  &hDevCookieInt,
56037 +                                                  psSubmit2DIN->hDevCookie,
56038 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56039 +
56040 +       if(psRetOUT->eError != PVRSRV_OK)
56041 +       {
56042 +               return 0;
56043 +       }
56044 +
56045 +       psKick = &psSubmit2DIN->sKick;
56046 +
56047 +       psRetOUT->eError =
56048 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56049 +                                                  &psKick->hCCBMemInfo,
56050 +                                                  psKick->hCCBMemInfo,
56051 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56052 +       if(psRetOUT->eError != PVRSRV_OK)
56053 +       {
56054 +               return 0;
56055 +       }
56056 +
56057 +       if (psKick->hTASyncInfo != IMG_NULL)
56058 +       {
56059 +               psRetOUT->eError =
56060 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
56061 +                                                          &psKick->hTASyncInfo,
56062 +                                                          psKick->hTASyncInfo,
56063 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
56064 +               if(psRetOUT->eError != PVRSRV_OK)
56065 +               {
56066 +                       return 0;
56067 +               }
56068 +       }
56069 +
56070 +       if (psKick->h3DSyncInfo != IMG_NULL)
56071 +       {
56072 +               psRetOUT->eError =
56073 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
56074 +                                                          &psKick->h3DSyncInfo,
56075 +                                                          psKick->h3DSyncInfo,
56076 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
56077 +               if(psRetOUT->eError != PVRSRV_OK)
56078 +               {
56079 +                       return 0;
56080 +               }
56081 +       }
56082 +
56083 +       if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS)
56084 +       {
56085 +               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
56086 +               return 0;
56087 +       }
56088 +       for (i = 0; i < psKick->ui32NumSrcSync; i++)
56089 +       {
56090 +               psRetOUT->eError =
56091 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
56092 +                                                          &psKick->ahSrcSyncInfo[i],
56093 +                                                          psKick->ahSrcSyncInfo[i],
56094 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
56095 +               if(psRetOUT->eError != PVRSRV_OK)
56096 +               {
56097 +                       return 0;
56098 +               }
56099 +       }
56100 +
56101 +       if (psKick->hDstSyncInfo != IMG_NULL)
56102 +       {
56103 +               psRetOUT->eError =
56104 +                       PVRSRVLookupHandle(psPerProc->psHandleBase,
56105 +                                                          &psKick->hDstSyncInfo,
56106 +                                                          psKick->hDstSyncInfo,
56107 +                                                          PVRSRV_HANDLE_TYPE_SYNC_INFO);
56108 +               if(psRetOUT->eError != PVRSRV_OK)
56109 +               {
56110 +                       return 0;
56111 +               }
56112 +       }
56113 +
56114 +       psRetOUT->eError =
56115 +               SGXSubmit2DKM(hDevCookieInt, psKick);
56116 +
56117 +       return 0;
56118 +}
56119 +#endif
56120 +#endif
56121 +
56122 +
56123 +static IMG_INT
56124 +SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
56125 +                                PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
56126 +                                PVRSRV_BRIDGE_RETURN *psRetOUT,
56127 +                                PVRSRV_PER_PROCESS_DATA *psPerProc)
56128 +{
56129 +       IMG_HANDLE hDevCookieInt;
56130 +       IMG_HANDLE hDevMemContextInt = 0;
56131 +       PVRSRV_SGXDEV_INFO *psDevInfo;
56132 +       SGX_MISC_INFO        sMiscInfo;
56133 +       PVRSRV_DEVICE_NODE *psDeviceNode;
56134 +
56135 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
56136 +                                                       PVRSRV_BRIDGE_SGX_GETMISCINFO);
56137 +
56138 +       psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56139 +                                                       &hDevCookieInt,
56140 +                                                       psSGXGetMiscInfoIN->hDevCookie,
56141 +                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
56142 +
56143 +       if(psRetOUT->eError != PVRSRV_OK)
56144 +       {
56145 +               return 0;
56146 +       }
56147 +
56148 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
56149 +
56150 +       if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD)
56151 +       {
56152 +               psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56153 +                                                               &hDevMemContextInt,
56154 +                                                               psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext,
56155 +                                                               PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
56156 +
56157 +               if(psRetOUT->eError != PVRSRV_OK)
56158 +               {
56159 +                       return 0;
56160 +               }
56161 +       }
56162 +#endif
56163 +
56164 +       psDeviceNode = hDevCookieInt;
56165 +       PVR_ASSERT(psDeviceNode != IMG_NULL);
56166 +       if (psDeviceNode == IMG_NULL)
56167 +       {
56168 +               return -EFAULT;
56169 +       }
56170 +
56171 +       psDevInfo = psDeviceNode->pvDevice;
56172 +
56173 +
56174 +       psRetOUT->eError = CopyFromUserWrapper(psPerProc,
56175 +                                                      ui32BridgeID,
56176 +                                                      &sMiscInfo,
56177 +                                                      psSGXGetMiscInfoIN->psMiscInfo,
56178 +                                                      sizeof(SGX_MISC_INFO));
56179 +       if (psRetOUT->eError != PVRSRV_OK)
56180 +       {
56181 +               return -EFAULT;
56182 +       }
56183 +
56184 +#ifdef SUPPORT_SGX_HWPERF
56185 +       if (sMiscInfo.eRequest == SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB)
56186 +       {
56187 +
56188 +               IMG_VOID           * pAllocated;
56189 +               IMG_HANDLE           hAllocatedHandle;
56190 +               IMG_VOID           * psTmpUserData;
56191 +               IMG_UINT32           allocatedSize;
56192 +
56193 +               allocatedSize = (IMG_UINT32)(sMiscInfo.uData.sRetrieveCB.ui32ArraySize * sizeof(PVRSRV_SGX_HWPERF_CBDATA));
56194 +
56195 +               ASSIGN_AND_EXIT_ON_ERROR(psRetOUT->eError,
56196 +                                   OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
56197 +                                   allocatedSize,
56198 +                                   &pAllocated,
56199 +                                   &hAllocatedHandle,
56200 +                                                       "Array of Hardware Performance Circular Buffer Data"));
56201 +
56202 +
56203 +               psTmpUserData = sMiscInfo.uData.sRetrieveCB.psHWPerfData;
56204 +               sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated;
56205 +
56206 +               psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, 0);
56207 +               if (psRetOUT->eError != PVRSRV_OK)
56208 +               {
56209 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
56210 +                                         allocatedSize,
56211 +                                         pAllocated,
56212 +                                         hAllocatedHandle);
56213 +
56214 +                       return 0;
56215 +               }
56216 +
56217 +
56218 +               psRetOUT->eError = CopyToUserWrapper(psPerProc,
56219 +                                                                ui32BridgeID,
56220 +                                                                psTmpUserData,
56221 +                                                                sMiscInfo.uData.sRetrieveCB.psHWPerfData,
56222 +                                                                allocatedSize);
56223 +
56224 +               sMiscInfo.uData.sRetrieveCB.psHWPerfData = psTmpUserData;
56225 +
56226 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
56227 +                                 allocatedSize,
56228 +                                 pAllocated,
56229 +                             hAllocatedHandle);
56230 +
56231 +               if (psRetOUT->eError != PVRSRV_OK)
56232 +               {
56233 +                       return -EFAULT;
56234 +               }
56235 +       }
56236 +       else
56237 +#endif
56238 +       {
56239 +               psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt);
56240 +
56241 +               if (psRetOUT->eError != PVRSRV_OK)
56242 +               {
56243 +                       return 0;
56244 +               }
56245 +       }
56246 +
56247 +
56248 +       psRetOUT->eError = CopyToUserWrapper(psPerProc,
56249 +                                            ui32BridgeID,
56250 +                                            psSGXGetMiscInfoIN->psMiscInfo,
56251 +                                            &sMiscInfo,
56252 +                                            sizeof(SGX_MISC_INFO));
56253 +       if (psRetOUT->eError != PVRSRV_OK)
56254 +       {
56255 +               return -EFAULT;
56256 +       }
56257 +       return 0;
56258 +}
56259 +
56260 +
56261 +#if defined(SUPPORT_SGX_HWPERF)
56262 +static IMG_INT
56263 +SGXReadDiffCountersBW(IMG_UINT32                                                                       ui32BridgeID,
56264 +                                               PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS         *psSGXReadDiffCountersIN,
56265 +                                               PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS        *psSGXReadDiffCountersOUT,
56266 +                                               PVRSRV_PER_PROCESS_DATA                                         *psPerProc)
56267 +{
56268 +       IMG_HANDLE                      hDevCookieInt;
56269 +
56270 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS);
56271 +
56272 +       psSGXReadDiffCountersOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56273 +                                                       &hDevCookieInt,
56274 +                                                       psSGXReadDiffCountersIN->hDevCookie,
56275 +                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
56276 +
56277 +       if(psSGXReadDiffCountersOUT->eError != PVRSRV_OK)
56278 +       {
56279 +               return 0;
56280 +       }
56281 +
56282 +       psSGXReadDiffCountersOUT->eError = SGXReadDiffCountersKM(hDevCookieInt,
56283 +                                                       psSGXReadDiffCountersIN->ui32Reg,
56284 +                                                       &psSGXReadDiffCountersOUT->ui32Old,
56285 +                                                       psSGXReadDiffCountersIN->bNew,
56286 +                                                       psSGXReadDiffCountersIN->ui32New,
56287 +                                                       psSGXReadDiffCountersIN->ui32NewReset,
56288 +                                                       psSGXReadDiffCountersIN->ui32CountersReg,
56289 +                                                       psSGXReadDiffCountersIN->ui32Reg2,
56290 +                                                       &psSGXReadDiffCountersOUT->bActive,
56291 +                                                       &psSGXReadDiffCountersOUT->sDiffs);
56292 +
56293 +       return 0;
56294 +}
56295 +
56296 +
56297 +static IMG_INT
56298 +SGXReadHWPerfCBBW(IMG_UINT32                                                   ui32BridgeID,
56299 +                                 PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB   *psSGXReadHWPerfCBIN,
56300 +                                 PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB  *psSGXReadHWPerfCBOUT,
56301 +                                 PVRSRV_PER_PROCESS_DATA                               *psPerProc)
56302 +{
56303 +       IMG_HANDLE                                      hDevCookieInt;
56304 +       PVRSRV_SGX_HWPERF_CB_ENTRY      *psAllocated;
56305 +       IMG_HANDLE                                      hAllocatedHandle;
56306 +       IMG_UINT32                                      ui32AllocatedSize;
56307 +
56308 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB);
56309 +
56310 +       psSGXReadHWPerfCBOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56311 +                                                       &hDevCookieInt,
56312 +                                                       psSGXReadHWPerfCBIN->hDevCookie,
56313 +                                                       PVRSRV_HANDLE_TYPE_DEV_NODE);
56314 +
56315 +       if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK)
56316 +       {
56317 +               return 0;
56318 +       }
56319 +
56320 +       ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize *
56321 +                                                       sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]);
56322 +       ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError,
56323 +                           OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
56324 +                           ui32AllocatedSize,
56325 +                           (IMG_VOID **)&psAllocated,
56326 +                           &hAllocatedHandle,
56327 +                                               "Array of Hardware Performance Circular Buffer Data"));
56328 +
56329 +       psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt,
56330 +                                                                                                        psSGXReadHWPerfCBIN->ui32ArraySize,
56331 +                                                                                                        psAllocated,
56332 +                                                                                                        &psSGXReadHWPerfCBOUT->ui32DataCount,
56333 +                                                                                                        &psSGXReadHWPerfCBOUT->ui32ClockSpeed,
56334 +                                                                                                        &psSGXReadHWPerfCBOUT->ui32HostTimeStamp);
56335 +       if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK)
56336 +       {
56337 +               psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc,
56338 +                                                                ui32BridgeID,
56339 +                                                                psSGXReadHWPerfCBIN->psHWPerfCBData,
56340 +                                                                psAllocated,
56341 +                                                                ui32AllocatedSize);
56342 +       }
56343 +
56344 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
56345 +                         ui32AllocatedSize,
56346 +                         psAllocated,
56347 +                         hAllocatedHandle);
56348 +
56349 +
56350 +       return 0;
56351 +}
56352 +#endif
56353 +
56354 +
56355 +static IMG_INT
56356 +SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
56357 +                                 PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
56358 +                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
56359 +                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
56360 +{
56361 +       IMG_HANDLE hDevCookieInt;
56362 +       PVRSRV_ERROR eError;
56363 +       IMG_BOOL bDissociateFailed = IMG_FALSE;
56364 +       IMG_BOOL bLookupFailed = IMG_FALSE;
56365 +       IMG_BOOL bReleaseFailed = IMG_FALSE;
56366 +       IMG_HANDLE hDummy;
56367 +       IMG_UINT32 i;
56368 +
56369 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
56370 +
56371 +       if(!psPerProc->bInitProcess)
56372 +       {
56373 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
56374 +               return 0;
56375 +       }
56376 +
56377 +       psRetOUT->eError =
56378 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56379 +                                                  &hDevCookieInt,
56380 +                                                  psSGXDevInitPart2IN->hDevCookie,
56381 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56382 +       if(psRetOUT->eError != PVRSRV_OK)
56383 +       {
56384 +               return 0;
56385 +       }
56386 +
56387 +
56388 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56389 +                                                  &hDummy,
56390 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
56391 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56392 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56393 +
56394 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56395 +                                                  &hDummy,
56396 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
56397 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56398 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56399 +
56400 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56401 +                                                  &hDummy,
56402 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
56403 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56404 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56405 +
56406 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56407 +                                                  &hDummy,
56408 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
56409 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56410 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56411 +
56412 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56413 +                                                  &hDummy,
56414 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
56415 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56416 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56417 +
56418 +
56419 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56420 +                                                  &hDummy,
56421 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
56422 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56423 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56424 +
56425 +#if defined(SGX_SUPPORT_HWPROFILING)
56426 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56427 +                                                  &hDummy,
56428 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
56429 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56430 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56431 +#endif
56432 +
56433 +#if defined(SUPPORT_SGX_HWPERF)
56434 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56435 +                                                  &hDummy,
56436 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
56437 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56438 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56439 +#endif
56440 +
56441 +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
56442 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56443 +                                                  &hDummy,
56444 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
56445 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56446 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56447 +#endif
56448 +
56449 +#if defined(SGX_FEATURE_SPM_MODE_0)
56450 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56451 +                                                  &hDummy,
56452 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
56453 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56454 +       bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56455 +#endif
56456 +
56457 +       for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
56458 +       {
56459 +               IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
56460 +
56461 +               if (hHandle == IMG_NULL)
56462 +               {
56463 +                       continue;
56464 +               }
56465 +
56466 +               eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
56467 +                                                          &hDummy,
56468 +                                                          hHandle,
56469 +                                                          PVRSRV_HANDLE_TYPE_MEM_INFO);
56470 +               bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56471 +       }
56472 +
56473 +       if (bLookupFailed)
56474 +       {
56475 +               PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle lookup failed"));
56476 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
56477 +               return 0;
56478 +       }
56479 +
56480 +
56481 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56482 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
56483 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
56484 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56485 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56486 +
56487 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56488 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
56489 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
56490 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56491 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56492 +
56493 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56494 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
56495 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
56496 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56497 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56498 +
56499 +
56500 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56501 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
56502 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
56503 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56504 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56505 +
56506 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56507 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
56508 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
56509 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56510 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56511 +
56512 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56513 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
56514 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
56515 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56516 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56517 +
56518 +
56519 +       #if defined(SGX_SUPPORT_HWPROFILING)
56520 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56521 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
56522 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
56523 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56524 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56525 +#endif
56526 +
56527 +#if defined(SUPPORT_SGX_HWPERF)
56528 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56529 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
56530 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
56531 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56532 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56533 +#endif
56534 +
56535 +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
56536 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56537 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
56538 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
56539 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56540 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56541 +#endif
56542 +
56543 +#if defined(SGX_FEATURE_SPM_MODE_0)
56544 +       eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56545 +                                                  &psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
56546 +                                                  psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo,
56547 +                                                  PVRSRV_HANDLE_TYPE_MEM_INFO);
56548 +       bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56549 +#endif
56550 +
56551 +
56552 +       for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
56553 +       {
56554 +               IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
56555 +
56556 +               if (*phHandle == IMG_NULL)
56557 +                       continue;
56558 +
56559 +               eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
56560 +                                                          phHandle,
56561 +                                                          *phHandle,
56562 +                                                          PVRSRV_HANDLE_TYPE_MEM_INFO);
56563 +               bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56564 +       }
56565 +
56566 +       if (bReleaseFailed)
56567 +       {
56568 +               PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle release failed"));
56569 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
56570 +
56571 +               PVR_DBG_BREAK;
56572 +               return 0;
56573 +       }
56574 +
56575 +
56576 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
56577 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56578 +
56579 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
56580 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56581 +
56582 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo);
56583 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56584 +
56585 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
56586 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56587 +
56588 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
56589 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56590 +
56591 +
56592 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
56593 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56594 +
56595 +
56596 +#if defined(SGX_SUPPORT_HWPROFILING)
56597 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo);
56598 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56599 +#endif
56600 +
56601 +#if defined(SUPPORT_SGX_HWPERF)
56602 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo);
56603 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56604 +#endif
56605 +
56606 +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
56607 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo);
56608 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56609 +#endif
56610 +
56611 +#if defined(SGX_FEATURE_SPM_MODE_0)
56612 +       eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo);
56613 +       bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56614 +#endif
56615 +
56616 +       for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
56617 +       {
56618 +               IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
56619 +
56620 +               if (hHandle == IMG_NULL)
56621 +                       continue;
56622 +
56623 +               eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
56624 +               bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
56625 +       }
56626 +
56627 +
56628 +       if(bDissociateFailed)
56629 +       {
56630 +               PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
56631 +               PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
56632 +               PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
56633 +               PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
56634 +               PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
56635 +
56636 +               for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
56637 +               {
56638 +                       IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
56639 +
56640 +                       if (hHandle == IMG_NULL)
56641 +                               continue;
56642 +
56643 +                       PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle);
56644 +
56645 +               }
56646 +
56647 +               PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A dissociate failed"));
56648 +
56649 +               psRetOUT->eError = PVRSRV_ERROR_GENERIC;
56650 +
56651 +
56652 +               PVR_DBG_BREAK;
56653 +               return 0;
56654 +       }
56655 +
56656 +       psRetOUT->eError =
56657 +               DevInitSGXPart2KM(psPerProc,
56658 +                                                 hDevCookieInt,
56659 +                                                 &psSGXDevInitPart2IN->sInitInfo);
56660 +
56661 +       return 0;
56662 +}
56663 +
56664 +
56665 +static IMG_INT
56666 +SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
56667 +                                                        PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN,
56668 +                                                        PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT,
56669 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
56670 +{
56671 +       IMG_HANDLE hDevCookieInt;
56672 +       IMG_HANDLE hHWRenderContextInt;
56673 +
56674 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT);
56675 +
56676 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1);
56677 +
56678 +       psSGXRegHWRenderContextOUT->eError =
56679 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56680 +                                                  &hDevCookieInt,
56681 +                                                  psSGXRegHWRenderContextIN->hDevCookie,
56682 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56683 +       if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK)
56684 +       {
56685 +               return 0;
56686 +       }
56687 +
56688 +       hHWRenderContextInt =
56689 +               SGXRegisterHWRenderContextKM(hDevCookieInt,
56690 +                                                                        &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr,
56691 +                                                                        psPerProc);
56692 +
56693 +       if (hHWRenderContextInt == IMG_NULL)
56694 +       {
56695 +               psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_GENERIC;
56696 +               return 0;
56697 +       }
56698 +
56699 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
56700 +                                         &psSGXRegHWRenderContextOUT->hHWRenderContext,
56701 +                                         hHWRenderContextInt,
56702 +                                         PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
56703 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
56704 +
56705 +       COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc);
56706 +
56707 +       return 0;
56708 +}
56709 +
56710 +
56711 +static IMG_INT
56712 +SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
56713 +                                                          PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN,
56714 +                                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
56715 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
56716 +{
56717 +       IMG_HANDLE hHWRenderContextInt;
56718 +
56719 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT);
56720 +
56721 +       psRetOUT->eError =
56722 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56723 +                                                  &hHWRenderContextInt,
56724 +                                                  psSGXUnregHWRenderContextIN->hHWRenderContext,
56725 +                                                  PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
56726 +       if(psRetOUT->eError != PVRSRV_OK)
56727 +       {
56728 +               return 0;
56729 +       }
56730 +
56731 +       psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt);
56732 +       if(psRetOUT->eError != PVRSRV_OK)
56733 +       {
56734 +               return 0;
56735 +       }
56736 +
56737 +       psRetOUT->eError =
56738 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
56739 +                                                       psSGXUnregHWRenderContextIN->hHWRenderContext,
56740 +                                                       PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
56741 +
56742 +       return 0;
56743 +}
56744 +
56745 +
56746 +static IMG_INT
56747 +SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
56748 +                                                        PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN,
56749 +                                                        PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT,
56750 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
56751 +{
56752 +       IMG_HANDLE hDevCookieInt;
56753 +       IMG_HANDLE hHWTransferContextInt;
56754 +
56755 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT);
56756 +
56757 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1);
56758 +
56759 +       psSGXRegHWTransferContextOUT->eError =
56760 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56761 +                                                  &hDevCookieInt,
56762 +                                                  psSGXRegHWTransferContextIN->hDevCookie,
56763 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56764 +       if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK)
56765 +       {
56766 +               return 0;
56767 +       }
56768 +
56769 +       hHWTransferContextInt =
56770 +               SGXRegisterHWTransferContextKM(hDevCookieInt,
56771 +                                                                          &psSGXRegHWTransferContextIN->sHWTransferContextDevVAddr,
56772 +                                                                          psPerProc);
56773 +
56774 +       if (hHWTransferContextInt == IMG_NULL)
56775 +       {
56776 +               psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC;
56777 +               return 0;
56778 +       }
56779 +
56780 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
56781 +                                         &psSGXRegHWTransferContextOUT->hHWTransferContext,
56782 +                                         hHWTransferContextInt,
56783 +                                         PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
56784 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
56785 +
56786 +       COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc);
56787 +
56788 +       return 0;
56789 +}
56790 +
56791 +
56792 +static IMG_INT
56793 +SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
56794 +                                                          PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN,
56795 +                                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
56796 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
56797 +{
56798 +       IMG_HANDLE hHWTransferContextInt;
56799 +
56800 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT);
56801 +
56802 +       psRetOUT->eError =
56803 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56804 +                                                  &hHWTransferContextInt,
56805 +                                                  psSGXUnregHWTransferContextIN->hHWTransferContext,
56806 +                                                  PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
56807 +       if(psRetOUT->eError != PVRSRV_OK)
56808 +       {
56809 +               return 0;
56810 +       }
56811 +
56812 +       psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt);
56813 +       if(psRetOUT->eError != PVRSRV_OK)
56814 +       {
56815 +               return 0;
56816 +       }
56817 +
56818 +       psRetOUT->eError =
56819 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
56820 +                                                       psSGXUnregHWTransferContextIN->hHWTransferContext,
56821 +                                                       PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
56822 +
56823 +       return 0;
56824 +}
56825 +
56826 +
56827 +#if defined(SGX_FEATURE_2D_HARDWARE)
56828 +static IMG_INT
56829 +SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
56830 +                                                        PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN,
56831 +                                                        PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT,
56832 +                                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
56833 +{
56834 +       IMG_HANDLE hDevCookieInt;
56835 +       IMG_HANDLE hHW2DContextInt;
56836 +
56837 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT);
56838 +
56839 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1);
56840 +
56841 +       psSGXRegHW2DContextOUT->eError =
56842 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56843 +                                                  &hDevCookieInt,
56844 +                                                  psSGXRegHW2DContextIN->hDevCookie,
56845 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56846 +       if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK)
56847 +       {
56848 +               return 0;
56849 +       }
56850 +
56851 +       hHW2DContextInt =
56852 +               SGXRegisterHW2DContextKM(hDevCookieInt,
56853 +                                                                &psSGXRegHW2DContextIN->sHW2DContextDevVAddr,
56854 +                                                                psPerProc);
56855 +
56856 +       if (hHW2DContextInt == IMG_NULL)
56857 +       {
56858 +               psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_GENERIC;
56859 +               return 0;
56860 +       }
56861 +
56862 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
56863 +                                         &psSGXRegHW2DContextOUT->hHW2DContext,
56864 +                                         hHW2DContextInt,
56865 +                                         PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
56866 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
56867 +
56868 +       COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc);
56869 +
56870 +       return 0;
56871 +}
56872 +
56873 +
56874 +static IMG_INT
56875 +SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
56876 +                                                          PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN,
56877 +                                                          PVRSRV_BRIDGE_RETURN *psRetOUT,
56878 +                                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
56879 +{
56880 +       IMG_HANDLE hHW2DContextInt;
56881 +
56882 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT);
56883 +
56884 +       psRetOUT->eError =
56885 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56886 +                                                  &hHW2DContextInt,
56887 +                                                  psSGXUnregHW2DContextIN->hHW2DContext,
56888 +                                                  PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
56889 +       if(psRetOUT->eError != PVRSRV_OK)
56890 +       {
56891 +               return 0;
56892 +       }
56893 +
56894 +       psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt);
56895 +       if(psRetOUT->eError != PVRSRV_OK)
56896 +       {
56897 +               return 0;
56898 +       }
56899 +
56900 +       psRetOUT->eError =
56901 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
56902 +                                                       psSGXUnregHW2DContextIN->hHW2DContext,
56903 +                                                       PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
56904 +
56905 +       return 0;
56906 +}
56907 +#endif
56908 +
56909 +static IMG_INT
56910 +SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID,
56911 +                                                 PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN,
56912 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
56913 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
56914 +{
56915 +       IMG_HANDLE hDevCookieInt;
56916 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET);
56917 +
56918 +       psRetOUT->eError =
56919 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56920 +                                                  &hDevCookieInt,
56921 +                                                  psSGXFlushHWRenderTargetIN->hDevCookie,
56922 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56923 +       if(psRetOUT->eError != PVRSRV_OK)
56924 +       {
56925 +               return 0;
56926 +       }
56927 +
56928 +       SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr);
56929 +
56930 +       return 0;
56931 +}
56932 +
56933 +
56934 +static IMG_INT
56935 +SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID,
56936 +                                                 PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN,
56937 +                                                 PVRSRV_BRIDGE_RETURN *psRetOUT,
56938 +                                                 PVRSRV_PER_PROCESS_DATA *psPerProc)
56939 +{
56940 +       IMG_HANDLE hDevCookieInt;
56941 +       IMG_VOID *pvSyncInfo;
56942 +       PVRSRV_SGXDEV_INFO *psDevInfo;
56943 +
56944 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE);
56945 +
56946 +       psRetOUT->eError =
56947 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
56948 +                                                  ps2DQueryBltsCompleteIN->hDevCookie,
56949 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
56950 +       if(psRetOUT->eError != PVRSRV_OK)
56951 +       {
56952 +               return 0;
56953 +       }
56954 +
56955 +       psRetOUT->eError =
56956 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
56957 +                                                  ps2DQueryBltsCompleteIN->hKernSyncInfo,
56958 +                                                  PVRSRV_HANDLE_TYPE_SYNC_INFO);
56959 +       if(psRetOUT->eError != PVRSRV_OK)
56960 +       {
56961 +               return 0;
56962 +       }
56963 +
56964 +       psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
56965 +
56966 +       psRetOUT->eError =
56967 +               SGX2DQueryBlitsCompleteKM(psDevInfo,
56968 +                                                                 (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo,
56969 +                                                                 ps2DQueryBltsCompleteIN->bWaitForComplete);
56970 +
56971 +       return 0;
56972 +}
56973 +
56974 +
56975 +static IMG_INT
56976 +SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID,
56977 +                                         PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN,
56978 +                                         PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT,
56979 +                                         PVRSRV_PER_PROCESS_DATA *psPerProc)
56980 +{
56981 +       IMG_HANDLE hDevCookieInt;
56982 +       PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
56983 +       PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
56984 +       PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
56985 +       PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
56986 +       PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL;
56987 +       IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0;
56988 +       IMG_UINT32 i;
56989 +       IMG_HANDLE hSharedPBDesc = IMG_NULL;
56990 +
56991 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC);
56992 +
56993 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4);
56994 +
56995 +       psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
56996 +
56997 +       psSGXFindSharedPBDescOUT->eError =
56998 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
56999 +                                                  &hDevCookieInt,
57000 +                                                  psSGXFindSharedPBDescIN->hDevCookie,
57001 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
57002 +       if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
57003 +               goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
57004 +
57005 +       psSGXFindSharedPBDescOUT->eError =
57006 +               SGXFindSharedPBDescKM(psPerProc, hDevCookieInt,
57007 +                                                         psSGXFindSharedPBDescIN->bLockOnFailure,
57008 +                                                         psSGXFindSharedPBDescIN->ui32TotalPBSize,
57009 +                                                         &hSharedPBDesc,
57010 +                                                         &psSharedPBDescKernelMemInfo,
57011 +                                                         &psHWPBDescKernelMemInfo,
57012 +                                                         &psBlockKernelMemInfo,
57013 +                                                         &psHWBlockKernelMemInfo,
57014 +                                                         &ppsSharedPBDescSubKernelMemInfos,
57015 +                                                         &ui32SharedPBDescSubKernelMemInfosCount);
57016 +       if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
57017 +               goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
57018 +
57019 +       PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount
57020 +                          <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
57021 +
57022 +       psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount =
57023 +               ui32SharedPBDescSubKernelMemInfosCount;
57024 +
57025 +       if(hSharedPBDesc == IMG_NULL)
57026 +       {
57027 +               psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0;
57028 +
57029 +               goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
57030 +       }
57031 +
57032 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
57033 +                                         &psSGXFindSharedPBDescOUT->hSharedPBDesc,
57034 +                                         hSharedPBDesc,
57035 +                                         PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
57036 +                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE);
57037 +
57038 +
57039 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
57040 +                                         &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle,
57041 +                                         psSharedPBDescKernelMemInfo,
57042 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57043 +                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
57044 +                                         psSGXFindSharedPBDescOUT->hSharedPBDesc);
57045 +
57046 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
57047 +                                         &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle,
57048 +                                         psHWPBDescKernelMemInfo,
57049 +                                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57050 +                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
57051 +                                         psSGXFindSharedPBDescOUT->hSharedPBDesc);
57052 +
57053 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
57054 +                                 &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle,
57055 +                                 psBlockKernelMemInfo,
57056 +                                 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57057 +                                 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
57058 +                                 psSGXFindSharedPBDescOUT->hSharedPBDesc);
57059 +
57060 +       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
57061 +                                 &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle,
57062 +                                 psHWBlockKernelMemInfo,
57063 +                                 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57064 +                                 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
57065 +                                 psSGXFindSharedPBDescOUT->hSharedPBDesc);
57066 +
57067 +
57068 +       for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
57069 +       {
57070 +               PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut =
57071 +                       psSGXFindSharedPBDescOUT;
57072 +
57073 +                       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
57074 +                                                         &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i],
57075 +                                                         ppsSharedPBDescSubKernelMemInfos[i],
57076 +                                                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
57077 +                                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
57078 +                                                         psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle);
57079 +       }
57080 +
57081 +PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT:
57082 +       if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL)
57083 +       {
57084 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
57085 +                                 sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
57086 +                                 ppsSharedPBDescSubKernelMemInfos,
57087 +                                 IMG_NULL);
57088 +       }
57089 +
57090 +       if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
57091 +       {
57092 +               if(hSharedPBDesc != IMG_NULL)
57093 +               {
57094 +                       SGXUnrefSharedPBDescKM(hSharedPBDesc);
57095 +               }
57096 +       }
57097 +       else
57098 +       {
57099 +               COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc);
57100 +       }
57101 +
57102 +       return 0;
57103 +}
57104 +
57105 +
57106 +static IMG_INT
57107 +SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID,
57108 +                                          PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN,
57109 +                                          PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT,
57110 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
57111 +{
57112 +       IMG_HANDLE hSharedPBDesc;
57113 +
57114 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC);
57115 +
57116 +       psSGXUnrefSharedPBDescOUT->eError =
57117 +               PVRSRVLookupHandle(psPerProc->psHandleBase,
57118 +                                                  &hSharedPBDesc,
57119 +                                                  psSGXUnrefSharedPBDescIN->hSharedPBDesc,
57120 +                                                  PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
57121 +       if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
57122 +       {
57123 +               return 0;
57124 +       }
57125 +
57126 +       psSGXUnrefSharedPBDescOUT->eError =
57127 +               SGXUnrefSharedPBDescKM(hSharedPBDesc);
57128 +
57129 +       if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
57130 +       {
57131 +               return 0;
57132 +       }
57133 +
57134 +       psSGXUnrefSharedPBDescOUT->eError =
57135 +               PVRSRVReleaseHandle(psPerProc->psHandleBase,
57136 +                                                  psSGXUnrefSharedPBDescIN->hSharedPBDesc,
57137 +                                                  PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
57138 +
57139 +       return 0;
57140 +}
57141 +
57142 +
57143 +static IMG_INT
57144 +SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID,
57145 +                                        PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN,
57146 +                                        PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT,
57147 +                                        PVRSRV_PER_PROCESS_DATA *psPerProc)
57148 +{
57149 +       IMG_HANDLE hDevCookieInt;
57150 +       PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
57151 +       PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
57152 +       PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
57153 +       PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
57154 +       IMG_UINT32 ui32KernelMemInfoHandlesCount =
57155 +               psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
57156 +       IMG_INT ret = 0;
57157 +       IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL;
57158 +       PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL;
57159 +       IMG_UINT32 i;
57160 +       PVRSRV_ERROR eError;
57161 +       IMG_HANDLE hSharedPBDesc = IMG_NULL;
57162 +
57163 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC);
57164 +
57165 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1);
57166 +
57167 +       psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL;
57168 +
57169 +       PVR_ASSERT(ui32KernelMemInfoHandlesCount
57170 +                          <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
57171 +
57172 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57173 +                                                               &hDevCookieInt,
57174 +                                                               psSGXAddSharedPBDescIN->hDevCookie,
57175 +                                                               PVRSRV_HANDLE_TYPE_DEV_NODE);
57176 +       if(eError != PVRSRV_OK)
57177 +       {
57178 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57179 +       }
57180 +
57181 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57182 +                                                               (IMG_VOID **)&psSharedPBDescKernelMemInfo,
57183 +                                                               psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
57184 +                                                               PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
57185 +       if(eError != PVRSRV_OK)
57186 +       {
57187 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57188 +       }
57189 +
57190 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57191 +                                                               (IMG_VOID **)&psHWPBDescKernelMemInfo,
57192 +                                                               psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
57193 +                                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
57194 +       if(eError != PVRSRV_OK)
57195 +       {
57196 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57197 +       }
57198 +
57199 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57200 +                                                               (IMG_VOID **)&psBlockKernelMemInfo,
57201 +                                                               psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
57202 +                                                               PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
57203 +       if(eError != PVRSRV_OK)
57204 +       {
57205 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57206 +       }
57207 +
57208 +       eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57209 +                                                               (IMG_VOID **)&psHWBlockKernelMemInfo,
57210 +                                                               psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
57211 +                                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
57212 +       if(eError != PVRSRV_OK)
57213 +       {
57214 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57215 +       }
57216 +
57217 +
57218 +       if(!OSAccessOK(PVR_VERIFY_READ,
57219 +                                  psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
57220 +                                  ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)))
57221 +       {
57222 +               PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:"
57223 +                                " Invalid phKernelMemInfos pointer", __FUNCTION__));
57224 +               ret = -EFAULT;
57225 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57226 +       }
57227 +
57228 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57229 +                                 ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
57230 +                                 (IMG_VOID **)&phKernelMemInfoHandles,
57231 +                                 0,
57232 +                                 "Array of Handles");
57233 +       if (eError != PVRSRV_OK)
57234 +       {
57235 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57236 +       }
57237 +
57238 +       if(CopyFromUserWrapper(psPerProc,
57239 +                                      ui32BridgeID,
57240 +                                      phKernelMemInfoHandles,
57241 +                                                  psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
57242 +                                                  ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))
57243 +          != PVRSRV_OK)
57244 +       {
57245 +               ret = -EFAULT;
57246 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57247 +       }
57248 +
57249 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57250 +                                 ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
57251 +                                 (IMG_VOID **)&ppsKernelMemInfos,
57252 +                                 0,
57253 +                                 "Array of pointers to Kernel Memory Info");
57254 +       if (eError != PVRSRV_OK)
57255 +       {
57256 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57257 +       }
57258 +
57259 +       for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
57260 +       {
57261 +               eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57262 +                                                                       (IMG_VOID **)&ppsKernelMemInfos[i],
57263 +                                                                       phKernelMemInfoHandles[i],
57264 +                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
57265 +               if(eError != PVRSRV_OK)
57266 +               {
57267 +                       goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57268 +               }
57269 +       }
57270 +
57271 +
57272 +
57273 +       eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
57274 +                                                               psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
57275 +                                                               PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
57276 +       PVR_ASSERT(eError == PVRSRV_OK);
57277 +
57278 +
57279 +       eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
57280 +                                                               psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
57281 +                                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
57282 +       PVR_ASSERT(eError == PVRSRV_OK);
57283 +
57284 +
57285 +       eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
57286 +                                                               psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
57287 +                                                               PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
57288 +       PVR_ASSERT(eError == PVRSRV_OK);
57289 +
57290 +
57291 +       eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
57292 +                                                               psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
57293 +                                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
57294 +       PVR_ASSERT(eError == PVRSRV_OK);
57295 +
57296 +       for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
57297 +       {
57298 +
57299 +               eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
57300 +                                                                       phKernelMemInfoHandles[i],
57301 +                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
57302 +               PVR_ASSERT(eError == PVRSRV_OK);
57303 +       }
57304 +
57305 +       eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
57306 +                                                                 psSharedPBDescKernelMemInfo,
57307 +                                                                 psHWPBDescKernelMemInfo,
57308 +                                                                 psBlockKernelMemInfo,
57309 +                                                                 psHWBlockKernelMemInfo,
57310 +                                                                 psSGXAddSharedPBDescIN->ui32TotalPBSize,
57311 +                                                                 &hSharedPBDesc,
57312 +                                                                 ppsKernelMemInfos,
57313 +                                                                 ui32KernelMemInfoHandlesCount);
57314 +
57315 +
57316 +       if (eError != PVRSRV_OK)
57317 +       {
57318 +               goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
57319 +       }
57320 +
57321 +       PVRSRVAllocHandleNR(psPerProc->psHandleBase,
57322 +                                 &psSGXAddSharedPBDescOUT->hSharedPBDesc,
57323 +                                 hSharedPBDesc,
57324 +                                 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
57325 +                                 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
57326 +
57327 +PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT:
57328 +
57329 +       if(phKernelMemInfoHandles)
57330 +       {
57331 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
57332 +                                 psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE),
57333 +                                 (IMG_VOID *)phKernelMemInfoHandles,
57334 +                                 0);
57335 +       }
57336 +       if(ppsKernelMemInfos)
57337 +       {
57338 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
57339 +                                 psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *),
57340 +                                 (IMG_VOID *)ppsKernelMemInfos,
57341 +                                 0);
57342 +       }
57343 +
57344 +       if(ret == 0 && eError == PVRSRV_OK)
57345 +       {
57346 +               COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc);
57347 +       }
57348 +
57349 +       psSGXAddSharedPBDescOUT->eError = eError;
57350 +
57351 +       return ret;
57352 +}
57353 +
57354 +static IMG_INT
57355 +SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID,
57356 +                                          PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN,
57357 +                                          PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT,
57358 +                                          PVRSRV_PER_PROCESS_DATA *psPerProc)
57359 +{
57360 +       IMG_HANDLE hDevCookieInt;
57361 +       IMG_UINT32 i;
57362 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT);
57363 +
57364 +       NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS);
57365 +
57366 +       if(!psPerProc->bInitProcess)
57367 +       {
57368 +               psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_GENERIC;
57369 +               return 0;
57370 +       }
57371 +
57372 +       psSGXInfoForSrvinitOUT->eError =
57373 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
57374 +                                                  psSGXInfoForSrvinitIN->hDevCookie,
57375 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
57376 +
57377 +       if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
57378 +       {
57379 +               return 0;
57380 +       }
57381 +
57382 +       psSGXInfoForSrvinitOUT->eError =
57383 +               SGXGetInfoForSrvinitKM(hDevCookieInt,
57384 +                                                          &psSGXInfoForSrvinitOUT->sInitInfo);
57385 +
57386 +       if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
57387 +       {
57388 +               return 0;
57389 +       }
57390 +
57391 +       for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
57392 +       {
57393 +               PVRSRV_HEAP_INFO *psHeapInfo;
57394 +
57395 +               psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i];
57396 +
57397 +               if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID)
57398 +               {
57399 +                       IMG_HANDLE hDevMemHeapExt;
57400 +
57401 +                       if (psHeapInfo->hDevMemHeap != IMG_NULL)
57402 +                       {
57403 +
57404 +                               PVRSRVAllocHandleNR(psPerProc->psHandleBase,
57405 +                                                                 &hDevMemHeapExt,
57406 +                                                                 psHeapInfo->hDevMemHeap,
57407 +                                                                 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
57408 +                                                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
57409 +                               psHeapInfo->hDevMemHeap = hDevMemHeapExt;
57410 +                       }
57411 +               }
57412 +       }
57413 +
57414 +       COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
57415 +
57416 +       return 0;
57417 +}
57418 +
57419 +#if defined(PDUMP)
57420 +static IMG_VOID
57421 +DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc,
57422 +                               PSGX_KICKTA_DUMP_BUFFER psBufferArray,
57423 +                               IMG_UINT32                                              ui32BufferArrayLength,
57424 +                               IMG_BOOL                                                bDumpPolls)
57425 +{
57426 +       IMG_UINT32      i;
57427 +
57428 +       for (i=0; i<ui32BufferArrayLength; i++)
57429 +       {
57430 +               PSGX_KICKTA_DUMP_BUFFER psBuffer;
57431 +               PVRSRV_KERNEL_MEM_INFO  *psCtrlMemInfoKM;
57432 +               IMG_CHAR * pszName;
57433 +               IMG_HANDLE hUniqueTag;
57434 +               IMG_UINT32      ui32Offset;
57435 +
57436 +               psBuffer = &psBufferArray[i];
57437 +               pszName = psBuffer->pszName;
57438 +               if (!pszName)
57439 +               {
57440 +                       pszName = "Nameless buffer";
57441 +               }
57442 +
57443 +               hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo);
57444 +
57445 +       #if defined(SUPPORT_SGX_NEW_STATUS_VALS)
57446 +               psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo);
57447 +               ui32Offset =  psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr;
57448 +       #else
57449 +               psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM;
57450 +               ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
57451 +       #endif
57452 +
57453 +               if (psBuffer->ui32Start <= psBuffer->ui32End)
57454 +               {
57455 +                       if (bDumpPolls)
57456 +                       {
57457 +                               PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
57458 +                               PDUMPCBP(psCtrlMemInfoKM,
57459 +                                                ui32Offset,
57460 +                                                psBuffer->ui32Start,
57461 +                                                psBuffer->ui32SpaceUsed,
57462 +                                                psBuffer->ui32BufferSize,
57463 +                                                0,
57464 +                                                MAKEUNIQUETAG(psCtrlMemInfoKM));
57465 +                       }
57466 +
57467 +                       PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName);
57468 +                       PDUMPMEMUM(psPerProc,
57469 +                                        IMG_NULL,
57470 +                                        psBuffer->pvLinAddr,
57471 +                                        (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
57472 +                                        psBuffer->ui32Start,
57473 +                                        psBuffer->ui32End - psBuffer->ui32Start,
57474 +                                        0,
57475 +                                        hUniqueTag);
57476 +               }
57477 +               else
57478 +               {
57479 +
57480 +
57481 +                       if (bDumpPolls)
57482 +                       {
57483 +                               PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
57484 +                               PDUMPCBP(psCtrlMemInfoKM,
57485 +                                                ui32Offset,
57486 +                                                psBuffer->ui32Start,
57487 +                                                psBuffer->ui32BackEndLength,
57488 +                                                psBuffer->ui32BufferSize,
57489 +                                                0,
57490 +                                                MAKEUNIQUETAG(psCtrlMemInfoKM));
57491 +                       }
57492 +                       PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
57493 +                       PDUMPMEMUM(psPerProc,
57494 +                                        IMG_NULL,
57495 +                                        psBuffer->pvLinAddr,
57496 +                                        (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
57497 +                                        psBuffer->ui32Start,
57498 +                                        psBuffer->ui32BackEndLength,
57499 +                                        0,
57500 +                                        hUniqueTag);
57501 +
57502 +                       if (bDumpPolls)
57503 +                       {
57504 +                               PDUMPMEMPOL(psCtrlMemInfoKM,
57505 +                                                       ui32Offset,
57506 +                                                       0,
57507 +                                                       0xFFFFFFFF,
57508 +                                                       PDUMP_POLL_OPERATOR_NOTEQUAL,
57509 +                                                       0,
57510 +                                                       MAKEUNIQUETAG(psCtrlMemInfoKM));
57511 +
57512 +                               PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName);
57513 +                               PDUMPCBP(psCtrlMemInfoKM,
57514 +                                                ui32Offset,
57515 +                                                0,
57516 +                                                psBuffer->ui32End,
57517 +                                                psBuffer->ui32BufferSize,
57518 +                                                0,
57519 +                                                MAKEUNIQUETAG(psCtrlMemInfoKM));
57520 +                       }
57521 +                       PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
57522 +                       PDUMPMEMUM(psPerProc,
57523 +                                        IMG_NULL,
57524 +                                        psBuffer->pvLinAddr,
57525 +                                        (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo,
57526 +                                        0,
57527 +                                        psBuffer->ui32End,
57528 +                                        0,
57529 +                                        hUniqueTag);
57530 +               }
57531 +       }
57532 +}
57533 +static IMG_INT
57534 +SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID,
57535 +                                  PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
57536 +                                  IMG_VOID *psBridgeOut,
57537 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
57538 +{
57539 +       IMG_UINT32 i;
57540 +       SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
57541 +       IMG_UINT32 ui32BufferArrayLength =
57542 +               psPDumpBufferArrayIN->ui32BufferArrayLength;
57543 +       IMG_UINT32 ui32BufferArraySize =
57544 +               ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER);
57545 +       PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC;
57546 +
57547 +       PVR_UNREFERENCED_PARAMETER(psBridgeOut);
57548 +
57549 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
57550 +
57551 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57552 +                                 ui32BufferArraySize,
57553 +                                 (IMG_PVOID *)&psKickTADumpBuffer, 0,
57554 +                                 "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
57555 +       {
57556 +               return -ENOMEM;
57557 +       }
57558 +
57559 +       if(CopyFromUserWrapper(psPerProc,
57560 +                                      ui32BridgeID,
57561 +                                                  psKickTADumpBuffer,
57562 +                                                  psPDumpBufferArrayIN->psBufferArray,
57563 +                                                  ui32BufferArraySize) != PVRSRV_OK)
57564 +       {
57565 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
57566 +
57567 +               return -EFAULT;
57568 +       }
57569 +
57570 +       for(i = 0; i < ui32BufferArrayLength; i++)
57571 +       {
57572 +               IMG_VOID *pvMemInfo;
57573 +
57574 +               eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57575 +                                                                       &pvMemInfo,
57576 +                                                                       psKickTADumpBuffer[i].hKernelMemInfo,
57577 +                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
57578 +
57579 +               if(eError != PVRSRV_OK)
57580 +               {
57581 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
57582 +                                        "PVRSRVLookupHandle failed (%d)", eError));
57583 +                       break;
57584 +               }
57585 +               psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
57586 +
57587 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
57588 +               eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
57589 +                                                                       &pvMemInfo,
57590 +                                                                       psKickTADumpBuffer[i].hCtrlKernelMemInfo,
57591 +                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
57592 +
57593 +               if(eError != PVRSRV_OK)
57594 +               {
57595 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
57596 +                                        "PVRSRVLookupHandle failed (%d)", eError));
57597 +                       break;
57598 +               }
57599 +               psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo;
57600 +#endif
57601 +       }
57602 +
57603 +       if(eError == PVRSRV_OK)
57604 +       {
57605 +               DumpBufferArray(psPerProc,
57606 +                                               psKickTADumpBuffer,
57607 +                                               ui32BufferArrayLength,
57608 +                                               psPDumpBufferArrayIN->bDumpPolls);
57609 +       }
57610 +
57611 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
57612 +
57613 +
57614 +       return 0;
57615 +}
57616 +
57617 +static IMG_INT
57618 +SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID,
57619 +                                  PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN,
57620 +                                  PVRSRV_BRIDGE_RETURN *psRetOUT,
57621 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
57622 +{
57623 +       IMG_UINT32 ui32RegisterArraySize =  psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
57624 +       IMG_UINT32 *pui32Registers = IMG_NULL;
57625 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57626 +       PVRSRV_SGXDEV_INFO      *psDevInfo = IMG_NULL;
57627 +       IMG_HANDLE      hDevCookieInt;
57628 +       IMG_UINT32      ui32RegVal = 0;
57629 +#endif
57630 +       IMG_INT ret = -EFAULT;
57631 +
57632 +       PVR_UNREFERENCED_PARAMETER(psRetOUT);
57633 +
57634 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
57635 +
57636 +       if (ui32RegisterArraySize == 0)
57637 +       {
57638 +               goto ExitNoError;
57639 +       }
57640 +
57641 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57642 +       psRetOUT->eError =
57643 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
57644 +                                                  psPDump3DSignatureRegistersIN->hDevCookie,
57645 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
57646 +       if(psRetOUT->eError != PVRSRV_OK)
57647 +       {
57648 +               PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
57649 +               goto Exit;
57650 +       }
57651 +
57652 +       psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
57653 +
57654 +
57655 +       ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
57656 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
57657 +#if defined(PDUMP)
57658 +       PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
57659 +                                               psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
57660 +#endif
57661 +#endif
57662 +
57663 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57664 +                                 ui32RegisterArraySize,
57665 +                                 (IMG_PVOID *)&pui32Registers, 0,
57666 +                                 "Array of Registers") != PVRSRV_OK)
57667 +       {
57668 +               PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed"));
57669 +               goto Exit;
57670 +       }
57671 +
57672 +       if(CopyFromUserWrapper(psPerProc,
57673 +                                       ui32BridgeID,
57674 +                                       pui32Registers,
57675 +                                       psPDump3DSignatureRegistersIN->pui32Registers,
57676 +                                       ui32RegisterArraySize) != PVRSRV_OK)
57677 +       {
57678 +               PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed"));
57679 +               goto Exit;
57680 +       }
57681 +
57682 +       PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN->ui32DumpFrameNum,
57683 +                                       psPDump3DSignatureRegistersIN->bLastFrame,
57684 +                                       pui32Registers,
57685 +                                       psPDump3DSignatureRegistersIN->ui32NumRegisters);
57686 +
57687 +ExitNoError:
57688 +       psRetOUT->eError = PVRSRV_OK;
57689 +       ret = 0;
57690 +Exit:
57691 +       if (pui32Registers != IMG_NULL)
57692 +       {
57693 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
57694 +       }
57695 +
57696 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57697 +       if (psDevInfo != IMG_NULL)
57698 +       {
57699 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
57700 +#if defined(PDUMP)
57701 +               PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, ui32RegVal,
57702 +                                                       psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
57703 +#endif
57704 +       }
57705 +#endif
57706 +
57707 +       return ret;
57708 +}
57709 +
57710 +static IMG_INT
57711 +SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID,
57712 +                                  PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN,
57713 +                                  IMG_VOID *psBridgeOut,
57714 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
57715 +{
57716 +       IMG_UINT32 ui32RegisterArraySize =  psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
57717 +       IMG_UINT32 *pui32Registers = IMG_NULL;
57718 +       IMG_INT ret = -EFAULT;
57719 +
57720 +       PVR_UNREFERENCED_PARAMETER(psBridgeOut);
57721 +
57722 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
57723 +
57724 +       if (ui32RegisterArraySize == 0)
57725 +       {
57726 +               goto ExitNoError;
57727 +       }
57728 +
57729 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57730 +                                 ui32RegisterArraySize,
57731 +                                 (IMG_PVOID *)&pui32Registers, 0,
57732 +                                 "Array of Registers") != PVRSRV_OK)
57733 +       {
57734 +               PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed"));
57735 +               ret = -ENOMEM;
57736 +               goto Exit;
57737 +       }
57738 +
57739 +       if(CopyFromUserWrapper(psPerProc,
57740 +                                       ui32BridgeID,
57741 +                                       pui32Registers,
57742 +                                       psPDumpCounterRegistersIN->pui32Registers,
57743 +                                       ui32RegisterArraySize) != PVRSRV_OK)
57744 +       {
57745 +               PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed"));
57746 +               goto Exit;
57747 +       }
57748 +
57749 +       PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum,
57750 +                                       psPDumpCounterRegistersIN->bLastFrame,
57751 +                                       pui32Registers,
57752 +                                       psPDumpCounterRegistersIN->ui32NumRegisters);
57753 +
57754 +ExitNoError:
57755 +       ret = 0;
57756 +Exit:
57757 +       if (pui32Registers != IMG_NULL)
57758 +       {
57759 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
57760 +       }
57761 +
57762 +       return ret;
57763 +}
57764 +
57765 +static IMG_INT
57766 +SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID,
57767 +                                  PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN,
57768 +                                  PVRSRV_BRIDGE_RETURN *psRetOUT,
57769 +                                  PVRSRV_PER_PROCESS_DATA *psPerProc)
57770 +{
57771 +       IMG_UINT32 ui32RegisterArraySize =  psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
57772 +       IMG_UINT32 *pui32Registers = IMG_NULL;
57773 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57774 +       PVRSRV_SGXDEV_INFO      *psDevInfo = IMG_NULL;
57775 +       IMG_HANDLE hDevCookieInt;
57776 +       IMG_UINT32      ui32RegVal = 0;
57777 +#endif
57778 +       IMG_INT ret = -EFAULT;
57779 +
57780 +       PVR_UNREFERENCED_PARAMETER(psRetOUT);
57781 +
57782 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
57783 +
57784 +       if (ui32RegisterArraySize == 0)
57785 +       {
57786 +               goto ExitNoError;
57787 +       }
57788 +
57789 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57790 +       psRetOUT->eError =
57791 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
57792 +                                                  psPDumpTASignatureRegistersIN->hDevCookie,
57793 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
57794 +       if(psRetOUT->eError != PVRSRV_OK)
57795 +       {
57796 +               PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
57797 +               goto Exit;
57798 +       }
57799 +
57800 +       psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
57801 +
57802 +
57803 +       ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
57804 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
57805 +#if defined(PDUMP)
57806 +       PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
57807 +                                               psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
57808 +#endif
57809 +#endif
57810 +
57811 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
57812 +                                 ui32RegisterArraySize,
57813 +                                 (IMG_PVOID *)&pui32Registers, 0,
57814 +                                 "Array of Registers") != PVRSRV_OK)
57815 +       {
57816 +               PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed"));
57817 +               ret = -ENOMEM;
57818 +               goto Exit;
57819 +       }
57820 +
57821 +       if(CopyFromUserWrapper(psPerProc,
57822 +                                       ui32BridgeID,
57823 +                                       pui32Registers,
57824 +                                       psPDumpTASignatureRegistersIN->pui32Registers,
57825 +                                       ui32RegisterArraySize) != PVRSRV_OK)
57826 +       {
57827 +               PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed"));
57828 +               goto Exit;
57829 +       }
57830 +
57831 +       PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN->ui32DumpFrameNum,
57832 +                                       psPDumpTASignatureRegistersIN->ui32TAKickCount,
57833 +                                       psPDumpTASignatureRegistersIN->bLastFrame,
57834 +                                       pui32Registers,
57835 +                                       psPDumpTASignatureRegistersIN->ui32NumRegisters);
57836 +
57837 +ExitNoError:
57838 +       psRetOUT->eError = PVRSRV_OK;
57839 +       ret = 0;
57840 +Exit:
57841 +       if (pui32Registers != IMG_NULL)
57842 +       {
57843 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
57844 +       }
57845 +
57846 +#if defined(SGX_FEATURE_MP)    && defined(FIX_HW_BRN_27270)
57847 +       if (psDevInfo != IMG_NULL)
57848 +       {
57849 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
57850 +#if defined(PDUMP)
57851 +               PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, ui32RegVal,
57852 +                                                       psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
57853 +#endif
57854 +       }
57855 +#endif
57856 +
57857 +       return ret;
57858 +}
57859 +static IMG_INT
57860 +SGXPDumpHWPerfCBBW(IMG_UINT32                                          ui32BridgeID,
57861 +                                  PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB      *psPDumpHWPerfCBIN,
57862 +                                  PVRSRV_BRIDGE_RETURN                         *psRetOUT,
57863 +                                  PVRSRV_PER_PROCESS_DATA                      *psPerProc)
57864 +{
57865 +#if defined(SUPPORT_SGX_HWPERF)
57866 +#if defined(__linux__)
57867 +       PVRSRV_SGXDEV_INFO      *psDevInfo;
57868 +       IMG_HANDLE                      hDevCookieInt;
57869 +
57870 +       PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
57871 +
57872 +       psRetOUT->eError =
57873 +               PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
57874 +                                                  psPDumpHWPerfCBIN->hDevCookie,
57875 +                                                  PVRSRV_HANDLE_TYPE_DEV_NODE);
57876 +       if(psRetOUT->eError != PVRSRV_OK)
57877 +       {
57878 +               return 0;
57879 +       }
57880 +
57881 +       psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
57882 +
57883 +       PDumpHWPerfCBKM(&psPDumpHWPerfCBIN->szFileName[0],
57884 +                                       psPDumpHWPerfCBIN->ui32FileOffset,
57885 +                                       psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
57886 +                                       psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize,
57887 +                                       psPDumpHWPerfCBIN->ui32PDumpFlags);
57888 +
57889 +       return 0;
57890 +#else
57891 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
57892 +       PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
57893 +       PVR_UNREFERENCED_PARAMETER(psRetOUT);
57894 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
57895 +       return 0;
57896 +#endif
57897 +#else
57898 +       PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
57899 +       PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN);
57900 +       PVR_UNREFERENCED_PARAMETER(psRetOUT);
57901 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
57902 +       return -EFAULT;
57903 +#endif
57904 +}
57905 +
57906 +#endif
57907 +
57908 +
57909 +IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
57910 +{
57911 +
57912 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, SGXGetClientInfoBW);
57913 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW);
57914 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW);
57915 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW);
57916 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW);
57917 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW);
57918 +
57919 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW);
57920 +
57921 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW);
57922 +
57923 +#if defined(TRANSFER_QUEUE)
57924 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW);
57925 +#endif
57926 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW);
57927 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT , SGXGetInfoForSrvinitBW);
57928 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, SGXDevInitPart2BW);
57929 +
57930 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW);
57931 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW);
57932 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW);
57933 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW);
57934 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW);
57935 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW);
57936 +#if defined(SGX_FEATURE_2D_HARDWARE)
57937 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW);
57938 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW);
57939 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW);
57940 +#endif
57941 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW);
57942 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW);
57943 +
57944 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
57945 +
57946 +#if defined(SUPPORT_SGX_HWPERF)
57947 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS, SGXReadDiffCountersBW);
57948 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
57949 +#endif
57950 +
57951 +#if defined(PDUMP)
57952 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW);
57953 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW);
57954 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW);
57955 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW);
57956 +       SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW);
57957 +#endif
57958 +}
57959 +
57960 +#endif
57961 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
57962 new file mode 100644
57963 index 0000000..23f3600
57964 --- /dev/null
57965 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
57966 @@ -0,0 +1,42 @@
57967 +/**********************************************************************
57968 + *
57969 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
57970 + *
57971 + * This program is free software; you can redistribute it and/or modify it
57972 + * under the terms and conditions of the GNU General Public License,
57973 + * version 2, as published by the Free Software Foundation.
57974 + *
57975 + * This program is distributed in the hope it will be useful but, except
57976 + * as otherwise stated in writing, without any warranty; without even the
57977 + * implied warranty of merchantability or fitness for a particular purpose.
57978 + * See the GNU General Public License for more details.
57979 + *
57980 + * You should have received a copy of the GNU General Public License along with
57981 + * this program; if not, write to the Free Software Foundation, Inc.,
57982 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
57983 + *
57984 + * The full GNU General Public License is included in this distribution in
57985 + * the file called "COPYING".
57986 + *
57987 + * Contact Information:
57988 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
57989 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
57990 + *
57991 + ******************************************************************************/
57992 +
57993 +#ifndef __BRIDGED_SGX_BRIDGE_H__
57994 +#define __BRIDGED_SGX_BRIDGE_H__
57995 +
57996 +#if defined (__cplusplus)
57997 +extern "C" {
57998 +#endif
57999 +
58000 +
58001 +IMG_VOID SetSGXDispatchTableEntry(IMG_VOID);
58002 +
58003 +#if defined (__cplusplus)
58004 +}
58005 +#endif
58006 +
58007 +#endif
58008 +
58009 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/.gitignore
58010 new file mode 100644
58011 index 0000000..2f89523
58012 --- /dev/null
58013 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/.gitignore
58014 @@ -0,0 +1,5 @@
58015 +bin_pc_i686*
58016 +tmp_pc_i686*
58017 +host_pc_i686*
58018 +*.o
58019 +*.o.cmd
58020 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/buffer_manager.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/buffer_manager.c
58021 new file mode 100644
58022 index 0000000..946fe79
58023 --- /dev/null
58024 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/buffer_manager.c
58025 @@ -0,0 +1,2036 @@
58026 +/**********************************************************************
58027 + *
58028 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
58029 + *
58030 + * This program is free software; you can redistribute it and/or modify it
58031 + * under the terms and conditions of the GNU General Public License,
58032 + * version 2, as published by the Free Software Foundation.
58033 + *
58034 + * This program is distributed in the hope it will be useful but, except
58035 + * as otherwise stated in writing, without any warranty; without even the
58036 + * implied warranty of merchantability or fitness for a particular purpose.
58037 + * See the GNU General Public License for more details.
58038 + *
58039 + * You should have received a copy of the GNU General Public License along with
58040 + * this program; if not, write to the Free Software Foundation, Inc.,
58041 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
58042 + *
58043 + * The full GNU General Public License is included in this distribution in
58044 + * the file called "COPYING".
58045 + *
58046 + * Contact Information:
58047 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
58048 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
58049 + *
58050 + ******************************************************************************/
58051 +
58052 +#include "services_headers.h"
58053 +
58054 +#include "sysconfig.h"
58055 +#include "hash.h"
58056 +#include "ra.h"
58057 +#include "pdump_km.h"
58058 +
58059 +#define MIN(a,b)       (a > b ? b : a)
58060 +
58061 +
58062 +#include "lists.h"
58063 +
58064 +DECLARE_LIST_ANY_VA(BM_HEAP);
58065 +DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
58066 +DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
58067 +DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
58068 +DECLARE_LIST_INSERT(BM_HEAP);
58069 +DECLARE_LIST_REMOVE(BM_HEAP);
58070 +
58071 +DECLARE_LIST_FOR_EACH(BM_CONTEXT);
58072 +DECLARE_LIST_ANY_VA(BM_CONTEXT);
58073 +DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL);
58074 +DECLARE_LIST_INSERT(BM_CONTEXT);
58075 +DECLARE_LIST_REMOVE(BM_CONTEXT);
58076 +
58077 +
58078 +static IMG_BOOL
58079 +ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
58080 +static IMG_VOID
58081 +BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
58082 +static IMG_BOOL
58083 +BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
58084 +                                       IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
58085 +                                       IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase);
58086 +
58087 +static IMG_BOOL
58088 +DevMemoryAlloc (BM_CONTEXT *pBMContext,
58089 +                               BM_MAPPING *pMapping,
58090 +                               IMG_SIZE_T *pActualSize,
58091 +                               IMG_UINT32 uFlags,
58092 +                               IMG_UINT32 dev_vaddr_alignment,
58093 +                               IMG_DEV_VIRTADDR *pDevVAddr);
58094 +static IMG_VOID
58095 +DevMemoryFree (BM_MAPPING *pMapping);
58096 +
58097 +static IMG_BOOL
58098 +AllocMemory (BM_CONTEXT                                *pBMContext,
58099 +                               BM_HEAP                         *psBMHeap,
58100 +                               IMG_DEV_VIRTADDR        *psDevVAddr,
58101 +                               IMG_SIZE_T                      uSize,
58102 +                               IMG_UINT32                      uFlags,
58103 +                               IMG_UINT32                      uDevVAddrAlignment,
58104 +                               BM_BUF                          *pBuf)
58105 +{
58106 +       BM_MAPPING                      *pMapping;
58107 +       IMG_UINTPTR_T           uOffset;
58108 +       RA_ARENA                        *pArena = IMG_NULL;
58109 +
58110 +       PVR_DPF ((PVR_DBG_MESSAGE,
58111 +                         "AllocMemory (pBMContext=%08X, uSize=0x%x, uFlags=0x%x, align=0x%x, pBuf=%08X)",
58112 +                         pBMContext, uSize, uFlags, uDevVAddrAlignment, pBuf));
58113 +
58114 +
58115 +
58116 +
58117 +       if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
58118 +       {
58119 +               if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
58120 +               {
58121 +
58122 +                       PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
58123 +                       return IMG_FALSE;
58124 +               }
58125 +
58126 +
58127 +
58128 +
58129 +               if(psBMHeap->ui32Attribs
58130 +                  &    (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
58131 +                  |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
58132 +               {
58133 +
58134 +                       pArena = psBMHeap->pImportArena;
58135 +               }
58136 +               else
58137 +               {
58138 +                       PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
58139 +                       return IMG_FALSE;
58140 +               }
58141 +
58142 +
58143 +               if (!RA_Alloc(pArena,
58144 +                                         uSize,
58145 +                                         IMG_NULL,
58146 +                                         (IMG_VOID*) &pMapping,
58147 +                                         uFlags,
58148 +                                         uDevVAddrAlignment,
58149 +                                         0,
58150 +                                         (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
58151 +               {
58152 +                       PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize));
58153 +                       return IMG_FALSE;
58154 +               }
58155 +
58156 +               uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
58157 +               if(pMapping->CpuVAddr)
58158 +               {
58159 +                       pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
58160 +               }
58161 +               else
58162 +               {
58163 +                       pBuf->CpuVAddr = IMG_NULL;
58164 +               }
58165 +
58166 +               if(uSize == pMapping->uSize)
58167 +               {
58168 +                       pBuf->hOSMemHandle = pMapping->hOSMemHandle;
58169 +               }
58170 +               else
58171 +               {
58172 +                       if(OSGetSubMemHandle(pMapping->hOSMemHandle,
58173 +                                                                uOffset,
58174 +                                                                uSize,
58175 +                                                                psBMHeap->ui32Attribs,
58176 +                                                                &pBuf->hOSMemHandle)!=PVRSRV_OK)
58177 +                       {
58178 +                               PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
58179 +                               return IMG_FALSE;
58180 +                       }
58181 +               }
58182 +
58183 +
58184 +               pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
58185 +
58186 +               if(uFlags & PVRSRV_MEM_ZERO)
58187 +               {
58188 +                       if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
58189 +                       {
58190 +                               return IMG_FALSE;
58191 +                       }
58192 +               }
58193 +       }
58194 +       else
58195 +       {
58196 +               if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
58197 +               {
58198 +
58199 +                       PVR_ASSERT(psDevVAddr != IMG_NULL);
58200 +
58201 +                       if (psDevVAddr == IMG_NULL)
58202 +                       {
58203 +                               PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
58204 +                               return IMG_FALSE;
58205 +                       }
58206 +
58207 +
58208 +                       pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
58209 +                                                                                                       uSize,
58210 +                                                                                                       IMG_NULL,
58211 +                                                                                                       PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
58212 +                                                                                                       uDevVAddrAlignment,
58213 +                                                                                                       psDevVAddr);
58214 +
58215 +
58216 +                       pBuf->DevVAddr = *psDevVAddr;
58217 +               }
58218 +               else
58219 +               {
58220 +
58221 +
58222 +
58223 +                       pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
58224 +                                                                                                       uSize,
58225 +                                                                                                       IMG_NULL,
58226 +                                                                                                       0,
58227 +                                                                                                       uDevVAddrAlignment,
58228 +                                                                                                       &pBuf->DevVAddr);
58229 +               }
58230 +
58231 +
58232 +               if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
58233 +                                                       sizeof (struct _BM_MAPPING_),
58234 +                                                       (IMG_PVOID *)&pMapping, IMG_NULL,
58235 +                                                       "Buffer Manager Mapping") != PVRSRV_OK)
58236 +               {
58237 +                       PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED"));
58238 +                       return IMG_FALSE;
58239 +               }
58240 +
58241 +
58242 +               pBuf->CpuVAddr = IMG_NULL;
58243 +               pBuf->hOSMemHandle = 0;
58244 +               pBuf->CpuPAddr.uiAddr = 0;
58245 +
58246 +
58247 +               pMapping->CpuVAddr = IMG_NULL;
58248 +               pMapping->CpuPAddr.uiAddr = 0;
58249 +               pMapping->DevVAddr = pBuf->DevVAddr;
58250 +               pMapping->psSysAddr = IMG_NULL;
58251 +               pMapping->uSize = uSize;
58252 +               pMapping->hOSMemHandle = 0;
58253 +       }
58254 +
58255 +
58256 +       pMapping->pArena = pArena;
58257 +
58258 +
58259 +       pMapping->pBMHeap = psBMHeap;
58260 +       pBuf->pMapping = pMapping;
58261 +
58262 +
58263 +       PVR_DPF ((PVR_DBG_MESSAGE,
58264 +                               "AllocMemory: pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x",
58265 +                               pMapping,
58266 +                               pMapping->DevVAddr.uiAddr,
58267 +                               pMapping->CpuVAddr,
58268 +                               pMapping->CpuPAddr.uiAddr,
58269 +                               pMapping->uSize));
58270 +
58271 +       PVR_DPF ((PVR_DBG_MESSAGE,
58272 +                               "AllocMemory: pBuf=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x",
58273 +                               pBuf,
58274 +                               pBuf->DevVAddr.uiAddr,
58275 +                               pBuf->CpuVAddr,
58276 +                               pBuf->CpuPAddr.uiAddr,
58277 +                               uSize));
58278 +
58279 +
58280 +       PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
58281 +
58282 +       return IMG_TRUE;
58283 +}
58284 +
58285 +
58286 +static IMG_BOOL
58287 +WrapMemory (BM_HEAP *psBMHeap,
58288 +                       IMG_SIZE_T uSize,
58289 +                       IMG_SIZE_T ui32BaseOffset,
58290 +                       IMG_BOOL bPhysContig,
58291 +                       IMG_SYS_PHYADDR *psAddr,
58292 +                       IMG_VOID *pvCPUVAddr,
58293 +                       IMG_UINT32 uFlags,
58294 +                       BM_BUF *pBuf)
58295 +{
58296 +       IMG_DEV_VIRTADDR DevVAddr = {0};
58297 +       BM_MAPPING *pMapping;
58298 +       IMG_BOOL bResult;
58299 +       IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
58300 +
58301 +       PVR_DPF ((PVR_DBG_MESSAGE,
58302 +                         "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%x, flags=0x%x, pBuf=%08X)",
58303 +                         psBMHeap, uSize, ui32BaseOffset, bPhysContig, pvCPUVAddr, uFlags, pBuf));
58304 +
58305 +       PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
58306 +
58307 +       PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
58308 +
58309 +       uSize += ui32BaseOffset;
58310 +       uSize = HOST_PAGEALIGN (uSize);
58311 +
58312 +
58313 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
58314 +                                               sizeof(*pMapping),
58315 +                                               (IMG_PVOID *)&pMapping, IMG_NULL,
58316 +                                               "Mocked-up mapping") != PVRSRV_OK)
58317 +       {
58318 +               PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
58319 +               return IMG_FALSE;
58320 +       }
58321 +
58322 +       OSMemSet(pMapping, 0, sizeof (*pMapping));
58323 +
58324 +       pMapping->uSize = uSize;
58325 +       pMapping->pBMHeap = psBMHeap;
58326 +
58327 +       if(pvCPUVAddr)
58328 +       {
58329 +               pMapping->CpuVAddr = pvCPUVAddr;
58330 +
58331 +               if (bPhysContig)
58332 +               {
58333 +                       pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
58334 +                       pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
58335 +
58336 +                       if(OSRegisterMem(pMapping->CpuPAddr,
58337 +                                                       pMapping->CpuVAddr,
58338 +                                                       pMapping->uSize,
58339 +                                                       uFlags,
58340 +                                                       &pMapping->hOSMemHandle) != PVRSRV_OK)
58341 +                       {
58342 +                               PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, CpuVAddr = 0x%08X, Size=%d) failed",
58343 +                                       pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize));
58344 +                               goto fail_cleanup;
58345 +                       }
58346 +               }
58347 +               else
58348 +               {
58349 +                       pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
58350 +                       pMapping->psSysAddr = psAddr;
58351 +
58352 +                       if(OSRegisterDiscontigMem(pMapping->psSysAddr,
58353 +                                                       pMapping->CpuVAddr,
58354 +                                                       pMapping->uSize,
58355 +                                                       uFlags,
58356 +                                                       &pMapping->hOSMemHandle) != PVRSRV_OK)
58357 +                       {
58358 +                               PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem CpuVAddr = 0x%08X, Size=%d) failed",
58359 +                                       pMapping->CpuVAddr, pMapping->uSize));
58360 +                               goto fail_cleanup;
58361 +                       }
58362 +               }
58363 +       }
58364 +       else
58365 +       {
58366 +               if (bPhysContig)
58367 +               {
58368 +                       pMapping->eCpuMemoryOrigin = hm_wrapped;
58369 +                       pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
58370 +
58371 +                       if(OSReservePhys(pMapping->CpuPAddr,
58372 +                                                        pMapping->uSize,
58373 +                                                        uFlags,
58374 +                                                        &pMapping->CpuVAddr,
58375 +                                                        &pMapping->hOSMemHandle) != PVRSRV_OK)
58376 +                       {
58377 +                               PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
58378 +                                       pMapping->CpuPAddr, pMapping->uSize));
58379 +                               goto fail_cleanup;
58380 +                       }
58381 +               }
58382 +               else
58383 +               {
58384 +                       pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
58385 +                       pMapping->psSysAddr = psAddr;
58386 +
58387 +                       if(OSReserveDiscontigPhys(pMapping->psSysAddr,
58388 +                                                        pMapping->uSize,
58389 +                                                        uFlags,
58390 +                                                        &pMapping->CpuVAddr,
58391 +                                                        &pMapping->hOSMemHandle) != PVRSRV_OK)
58392 +                       {
58393 +                               PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
58394 +                                       pMapping->uSize));
58395 +                               goto fail_cleanup;
58396 +                       }
58397 +               }
58398 +       }
58399 +
58400 +
58401 +       bResult = DevMemoryAlloc(psBMHeap->pBMContext,
58402 +                                                        pMapping,
58403 +                                                        IMG_NULL,
58404 +                                                        uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
58405 +                                                        IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
58406 +                                                        &DevVAddr);
58407 +       if (!bResult)
58408 +       {
58409 +               PVR_DPF((PVR_DBG_ERROR,
58410 +                               "WrapMemory: DevMemoryAlloc(0x%x) failed",
58411 +                               pMapping->uSize));
58412 +               goto fail_cleanup;
58413 +       }
58414 +
58415 +
58416 +       pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
58417 +       if(!ui32BaseOffset)
58418 +       {
58419 +               pBuf->hOSMemHandle = pMapping->hOSMemHandle;
58420 +       }
58421 +       else
58422 +       {
58423 +               if(OSGetSubMemHandle(pMapping->hOSMemHandle,
58424 +                                                        ui32BaseOffset,
58425 +                                                        (pMapping->uSize-ui32BaseOffset),
58426 +                                                        uFlags,
58427 +                                                        &pBuf->hOSMemHandle)!=PVRSRV_OK)
58428 +               {
58429 +                       PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
58430 +                       goto fail_cleanup;
58431 +               }
58432 +       }
58433 +       if(pMapping->CpuVAddr)
58434 +       {
58435 +               pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
58436 +       }
58437 +       pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
58438 +
58439 +       if(uFlags & PVRSRV_MEM_ZERO)
58440 +       {
58441 +               if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
58442 +               {
58443 +                       return IMG_FALSE;
58444 +               }
58445 +       }
58446 +
58447 +       PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
58448 +       PVR_DPF ((PVR_DBG_MESSAGE,
58449 +                               "WrapMemory: pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x",
58450 +                               pMapping, pMapping->DevVAddr.uiAddr,
58451 +                               pMapping->CpuVAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
58452 +       PVR_DPF ((PVR_DBG_MESSAGE,
58453 +                               "WrapMemory: pBuf=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x",
58454 +                               pBuf, pBuf->DevVAddr.uiAddr,
58455 +                               pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr, uSize));
58456 +
58457 +       pBuf->pMapping = pMapping;
58458 +       return IMG_TRUE;
58459 +
58460 +fail_cleanup:
58461 +       if(ui32BaseOffset && pBuf->hOSMemHandle)
58462 +       {
58463 +               OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
58464 +       }
58465 +
58466 +       if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
58467 +       {
58468 +               switch(pMapping->eCpuMemoryOrigin)
58469 +               {
58470 +                       case hm_wrapped:
58471 +                               OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
58472 +                               break;
58473 +                       case hm_wrapped_virtaddr:
58474 +                               OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
58475 +                               break;
58476 +                       case hm_wrapped_scatter:
58477 +                               OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
58478 +                               break;
58479 +                       case hm_wrapped_scatter_virtaddr:
58480 +                               OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
58481 +                               break;
58482 +                       default:
58483 +                               break;
58484 +               }
58485 +
58486 +       }
58487 +
58488 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
58489 +
58490 +
58491 +       return IMG_FALSE;
58492 +}
58493 +
58494 +
58495 +static IMG_BOOL
58496 +ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
58497 +{
58498 +       IMG_VOID *pvCpuVAddr;
58499 +
58500 +       if(pBuf->CpuVAddr)
58501 +       {
58502 +               OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
58503 +       }
58504 +       else if(pMapping->eCpuMemoryOrigin == hm_contiguous
58505 +                       || pMapping->eCpuMemoryOrigin == hm_wrapped)
58506 +       {
58507 +               pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
58508 +                                                                       ui32Bytes,
58509 +                                                                       PVRSRV_HAP_KERNEL_ONLY
58510 +                                                                       | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
58511 +                                                                       IMG_NULL);
58512 +               if(!pvCpuVAddr)
58513 +               {
58514 +                       PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
58515 +                       return IMG_FALSE;
58516 +               }
58517 +               OSMemSet(pvCpuVAddr, 0, ui32Bytes);
58518 +               OSUnMapPhysToLin(pvCpuVAddr,
58519 +                                                ui32Bytes,
58520 +                                                PVRSRV_HAP_KERNEL_ONLY
58521 +                                                | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
58522 +                                                IMG_NULL);
58523 +       }
58524 +       else
58525 +       {
58526 +               IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
58527 +               IMG_SIZE_T ui32CurrentOffset = 0;
58528 +               IMG_CPU_PHYADDR CpuPAddr;
58529 +
58530 +
58531 +               PVR_ASSERT(pBuf->hOSMemHandle);
58532 +
58533 +               while(ui32BytesRemaining > 0)
58534 +               {
58535 +                       IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
58536 +                       CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
58537 +
58538 +                       if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
58539 +                       {
58540 +                               ui32BlockBytes =
58541 +                                       MIN(ui32BytesRemaining, HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr);
58542 +                       }
58543 +
58544 +                       pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
58545 +                                                                               ui32BlockBytes,
58546 +                                                                               PVRSRV_HAP_KERNEL_ONLY
58547 +                                                                               | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
58548 +                                                                               IMG_NULL);
58549 +                       if(!pvCpuVAddr)
58550 +                       {
58551 +                               PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
58552 +                               return IMG_FALSE;
58553 +                       }
58554 +                       OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
58555 +                       OSUnMapPhysToLin(pvCpuVAddr,
58556 +                                                        ui32BlockBytes,
58557 +                                                        PVRSRV_HAP_KERNEL_ONLY
58558 +                                                        | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
58559 +                                                        IMG_NULL);
58560 +
58561 +                       ui32BytesRemaining -= ui32BlockBytes;
58562 +                       ui32CurrentOffset += ui32BlockBytes;
58563 +               }
58564 +       }
58565 +
58566 +       return IMG_TRUE;
58567 +}
58568 +
58569 +static IMG_VOID
58570 +FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags)
58571 +{
58572 +       BM_MAPPING *pMapping;
58573 +
58574 +       PVR_DPF ((PVR_DBG_MESSAGE,
58575 +                       "FreeBuf: pBuf=%08X: DevVAddr=%08X CpuVAddr=%08X CpuPAddr=%08X",
58576 +                       pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
58577 +
58578 +
58579 +       pMapping = pBuf->pMapping;
58580 +
58581 +       if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
58582 +       {
58583 +
58584 +               if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
58585 +               {
58586 +
58587 +                       PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
58588 +               }
58589 +               else
58590 +               {
58591 +
58592 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
58593 +                       pBuf->pMapping = IMG_NULL;
58594 +               }
58595 +       }
58596 +       else
58597 +       {
58598 +
58599 +               if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
58600 +               {
58601 +                       OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
58602 +               }
58603 +               if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
58604 +               {
58605 +
58606 +
58607 +
58608 +                       RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
58609 +               }
58610 +               else
58611 +               {
58612 +                       switch (pMapping->eCpuMemoryOrigin)
58613 +                       {
58614 +                               case hm_wrapped:
58615 +                                       OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
58616 +                                       break;
58617 +                               case hm_wrapped_virtaddr:
58618 +                                       OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
58619 +                                       break;
58620 +                               case hm_wrapped_scatter:
58621 +                                       OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
58622 +                                       break;
58623 +                               case hm_wrapped_scatter_virtaddr:
58624 +                                       OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
58625 +                                       break;
58626 +                               default:
58627 +                                       break;
58628 +                       }
58629 +
58630 +                       DevMemoryFree (pMapping);
58631 +
58632 +
58633 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
58634 +                       pBuf->pMapping = IMG_NULL;
58635 +               }
58636 +       }
58637 +
58638 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
58639 +
58640 +}
58641 +
58642 +PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
58643 +{
58644 +       if(psBMHeap->ui32Attribs
58645 +       &       (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
58646 +               |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
58647 +       {
58648 +               if (psBMHeap->pImportArena)
58649 +               {
58650 +                       IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
58651 +                       if (!bTestDelete)
58652 +                       {
58653 +                               PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
58654 +                               return PVRSRV_ERROR_GENERIC;
58655 +                       }
58656 +               }
58657 +       }
58658 +       return PVRSRV_OK;
58659 +}
58660 +
58661 +
58662 +PVRSRV_ERROR
58663 +BM_DestroyContext(IMG_HANDLE   hBMContext,
58664 +                                 IMG_BOOL              *pbDestroyed)
58665 +{
58666 +       PVRSRV_ERROR eError;
58667 +       BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
58668 +
58669 +       PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
58670 +
58671 +       if (pbDestroyed != IMG_NULL)
58672 +       {
58673 +               *pbDestroyed = IMG_FALSE;
58674 +       }
58675 +
58676 +
58677 +
58678 +       if (pBMContext == IMG_NULL)
58679 +       {
58680 +               PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
58681 +               return PVRSRV_ERROR_INVALID_PARAMS;
58682 +       }
58683 +
58684 +       pBMContext->ui32RefCount--;
58685 +
58686 +       if (pBMContext->ui32RefCount > 0)
58687 +       {
58688 +
58689 +               return PVRSRV_OK;
58690 +       }
58691 +
58692 +
58693 +
58694 +
58695 +       eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, BM_DestroyContext_AnyCb);
58696 +       if(eError != PVRSRV_OK)
58697 +       {
58698 +               PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
58699 +#if 0
58700 +
58701 +
58702 +
58703 +
58704 +               PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Cleaning up with ResManFreeSpecial"));
58705 +               if(ResManFreeSpecial() != PVRSRV_OK)
58706 +               {
58707 +                       PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeSpecial failed %d",eError));
58708 +               }
58709 +
58710 +#endif
58711 +               return eError;
58712 +       }
58713 +       else
58714 +       {
58715 +
58716 +               eError = ResManFreeResByPtr(pBMContext->hResItem);
58717 +               if(eError != PVRSRV_OK)
58718 +               {
58719 +                       PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
58720 +                       return eError;
58721 +               }
58722 +
58723 +
58724 +               if (pbDestroyed != IMG_NULL)
58725 +               {
58726 +                       *pbDestroyed = IMG_TRUE;
58727 +               }
58728 +       }
58729 +
58730 +       return PVRSRV_OK;
58731 +}
58732 +
58733 +
58734 +PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
58735 +{
58736 +       PVRSRV_DEVICE_NODE *psDeviceNode;
58737 +       psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
58738 +
58739 +
58740 +       if(psBMHeap->ui32Attribs
58741 +       &       (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
58742 +               |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
58743 +       {
58744 +               if (psBMHeap->pImportArena)
58745 +               {
58746 +                       RA_Delete (psBMHeap->pImportArena);
58747 +               }
58748 +       }
58749 +       else
58750 +       {
58751 +               PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
58752 +               return PVRSRV_ERROR_GENERIC;
58753 +       }
58754 +
58755 +
58756 +       psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
58757 +
58758 +
58759 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
58760 +
58761 +
58762 +       return PVRSRV_OK;
58763 +}
58764 +
58765 +
58766 +static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID                pvParam,
58767 +                                                                                         IMG_UINT32    ui32Param)
58768 +{
58769 +       BM_CONTEXT *pBMContext = pvParam;
58770 +       PVRSRV_DEVICE_NODE *psDeviceNode;
58771 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
58772 +
58773 +
58774 +
58775 +       psDeviceNode = pBMContext->psDeviceNode;
58776 +
58777 +
58778 +
58779 +       if(List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
58780 +                                                                               BM_DestroyContextCallBack_AnyVaCb,
58781 +                                                                               psDeviceNode) != PVRSRV_OK)
58782 +       {
58783 +               return PVRSRV_ERROR_GENERIC;
58784 +       }
58785 +
58786 +
58787 +       if (pBMContext->psMMUContext)
58788 +       {
58789 +               psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
58790 +       }
58791 +
58792 +
58793 +
58794 +       if (pBMContext->pBufferHash)
58795 +       {
58796 +               HASH_Delete(pBMContext->pBufferHash);
58797 +       }
58798 +
58799 +       if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
58800 +       {
58801 +
58802 +               psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
58803 +       }
58804 +       else
58805 +       {
58806 +
58807 +               List_BM_CONTEXT_Remove(pBMContext);
58808 +       }
58809 +
58810 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
58811 +
58812 +
58813 +       return PVRSRV_OK;
58814 +}
58815 +
58816 +
58817 +IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
58818 +{
58819 +       PRESMAN_CONTEXT hResManContext;
58820 +       hResManContext = va_arg(va, PRESMAN_CONTEXT);
58821 +       if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
58822 +       {
58823 +
58824 +               pBMContext->ui32RefCount++;
58825 +               return pBMContext;
58826 +       }
58827 +       return IMG_NULL;
58828 +}
58829 +
58830 +IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
58831 +{
58832 +       PVRSRV_DEVICE_NODE *psDeviceNode;
58833 +       BM_CONTEXT *pBMContext;
58834 +       psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
58835 +       pBMContext = va_arg(va, BM_CONTEXT*);
58836 +       switch(psBMHeap->sDevArena.DevMemHeapType)
58837 +       {
58838 +               case DEVICE_MEMORY_HEAP_SHARED:
58839 +               case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
58840 +               {
58841 +
58842 +                       psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
58843 +                       break;
58844 +               }
58845 +       }
58846 +}
58847 +
58848 +IMG_HANDLE
58849 +BM_CreateContext(PVRSRV_DEVICE_NODE                    *psDeviceNode,
58850 +                                IMG_DEV_PHYADDR                        *psPDDevPAddr,
58851 +                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
58852 +                                IMG_BOOL                                       *pbCreated)
58853 +{
58854 +       BM_CONTEXT                      *pBMContext;
58855 +       DEVICE_MEMORY_INFO      *psDevMemoryInfo;
58856 +       IMG_BOOL                        bKernelContext;
58857 +       PRESMAN_CONTEXT         hResManContext;
58858 +
58859 +       PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
58860 +
58861 +       if (psPerProc == IMG_NULL)
58862 +       {
58863 +               bKernelContext = IMG_TRUE;
58864 +               hResManContext = psDeviceNode->hResManContext;
58865 +       }
58866 +       else
58867 +       {
58868 +               bKernelContext = IMG_FALSE;
58869 +               hResManContext = psPerProc->hResManContext;
58870 +       }
58871 +
58872 +       if (pbCreated != IMG_NULL)
58873 +       {
58874 +               *pbCreated = IMG_FALSE;
58875 +       }
58876 +
58877 +
58878 +       psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
58879 +
58880 +       if (bKernelContext == IMG_FALSE)
58881 +       {
58882 +               IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
58883 +                                                                                                                       BM_CreateContext_IncRefCount_AnyVaCb,
58884 +                                                                                                                       hResManContext);
58885 +               if (res)
58886 +               {
58887 +                       return res;
58888 +               }
58889 +       }
58890 +
58891 +
58892 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
58893 +                                        sizeof (struct _BM_CONTEXT_),
58894 +                                        (IMG_PVOID *)&pBMContext, IMG_NULL,
58895 +                                        "Buffer Manager Context") != PVRSRV_OK)
58896 +       {
58897 +               PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
58898 +               return IMG_NULL;
58899 +       }
58900 +       OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
58901 +
58902 +
58903 +       pBMContext->psDeviceNode = psDeviceNode;
58904 +
58905 +
58906 +
58907 +       pBMContext->pBufferHash = HASH_Create(32);
58908 +       if (pBMContext->pBufferHash==IMG_NULL)
58909 +       {
58910 +               PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
58911 +               goto cleanup;
58912 +       }
58913 +
58914 +       if(psDeviceNode->pfnMMUInitialise(psDeviceNode,
58915 +                                                                               &pBMContext->psMMUContext,
58916 +                                                                               psPDDevPAddr) != PVRSRV_OK)
58917 +       {
58918 +               PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
58919 +               goto cleanup;
58920 +       }
58921 +
58922 +       if(bKernelContext)
58923 +       {
58924 +
58925 +               PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
58926 +               psDevMemoryInfo->pBMKernelContext = pBMContext;
58927 +       }
58928 +       else
58929 +       {
58930 +
58931 +
58932 +
58933 +
58934 +
58935 +               PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
58936 +
58937 +               if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
58938 +               {
58939 +                       PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
58940 +                       goto cleanup;
58941 +               }
58942 +
58943 +               PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
58944 +
58945 +
58946 +
58947 +
58948 +
58949 +               pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
58950 +
58951 +
58952 +
58953 +
58954 +               List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
58955 +                                                               BM_CreateContext_InsertHeap_ForEachVaCb,
58956 +                                                               psDeviceNode,
58957 +                                                               pBMContext);
58958 +
58959 +
58960 +               List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
58961 +       }
58962 +
58963 +
58964 +       pBMContext->ui32RefCount++;
58965 +
58966 +
58967 +       pBMContext->hResItem = ResManRegisterRes(hResManContext,
58968 +                                                                                       RESMAN_TYPE_DEVICEMEM_CONTEXT,
58969 +                                                                                       pBMContext,
58970 +                                                                                       0,
58971 +                                                                                       BM_DestroyContextCallBack);
58972 +       if (pBMContext->hResItem == IMG_NULL)
58973 +       {
58974 +               PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
58975 +               goto cleanup;
58976 +       }
58977 +
58978 +       if (pbCreated != IMG_NULL)
58979 +       {
58980 +               *pbCreated = IMG_TRUE;
58981 +       }
58982 +       return (IMG_HANDLE)pBMContext;
58983 +
58984 +cleanup:
58985 +       (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0);
58986 +
58987 +       return IMG_NULL;
58988 +}
58989 +
58990 +
58991 +IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
58992 +{
58993 +       DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
58994 +       psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
58995 +       if (psBMHeap->sDevArena.ui32HeapID ==  psDevMemHeapInfo->ui32HeapID)
58996 +       {
58997 +
58998 +               return psBMHeap;
58999 +       }
59000 +       else
59001 +       {
59002 +               return IMG_NULL;
59003 +       }
59004 +}
59005 +
59006 +IMG_HANDLE
59007 +BM_CreateHeap (IMG_HANDLE hBMContext,
59008 +                          DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
59009 +{
59010 +       BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
59011 +       PVRSRV_DEVICE_NODE *psDeviceNode;
59012 +       BM_HEAP *psBMHeap;
59013 +
59014 +       PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
59015 +
59016 +       if(!pBMContext)
59017 +       {
59018 +               return IMG_NULL;
59019 +       }
59020 +
59021 +       psDeviceNode = pBMContext->psDeviceNode;
59022 +
59023 +       
59024 +
59025 +
59026 +
59027 +
59028 +       if(pBMContext->ui32RefCount > 0)
59029 +       {
59030 +               psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
59031 +                                                                                                BM_CreateHeap_AnyVaCb,
59032 +                                                                                                psDevMemHeapInfo);
59033 +
59034 +               if (psBMHeap)
59035 +               {
59036 +                       return psBMHeap;
59037 +               }
59038 +       }
59039 +
59040 +
59041 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
59042 +                                               sizeof (BM_HEAP),
59043 +                                               (IMG_PVOID *)&psBMHeap, IMG_NULL,
59044 +                                               "Buffer Manager Heap") != PVRSRV_OK)
59045 +       {
59046 +               PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
59047 +               return IMG_NULL;
59048 +       }
59049 +
59050 +       OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
59051 +
59052 +       psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
59053 +       psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
59054 +       psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
59055 +       psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
59056 +       psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
59057 +       psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
59058 +       psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
59059 +       psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
59060 +
59061 +
59062 +       psBMHeap->pBMContext = pBMContext;
59063 +
59064 +       psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
59065 +                                                                                                       &psBMHeap->sDevArena,
59066 +                                                                                                       &psBMHeap->pVMArena);
59067 +       if (!psBMHeap->pMMUHeap)
59068 +       {
59069 +               PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
59070 +               goto ErrorExit;
59071 +       }
59072 +
59073 +
59074 +       psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
59075 +                                                                               0, 0, IMG_NULL,
59076 +                                                                               psBMHeap->sDevArena.ui32DataPageSize,
59077 +                                                                               BM_ImportMemory,
59078 +                                                                               BM_FreeMemory,
59079 +                                                                               IMG_NULL,
59080 +                                                                               psBMHeap);
59081 +       if(psBMHeap->pImportArena == IMG_NULL)
59082 +       {
59083 +               PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
59084 +               goto ErrorExit;
59085 +       }
59086 +
59087 +       if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
59088 +       {
59089 +
59090 +
59091 +
59092 +
59093 +               psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
59094 +               if(psBMHeap->pLocalDevMemArena == IMG_NULL)
59095 +               {
59096 +                       PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
59097 +                       goto ErrorExit;
59098 +               }
59099 +       }
59100 +
59101 +
59102 +       List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
59103 +
59104 +       return (IMG_HANDLE)psBMHeap;
59105 +
59106 +
59107 +ErrorExit:
59108 +
59109 +
59110 +       if (psBMHeap->pMMUHeap != IMG_NULL)
59111 +       {
59112 +               psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
59113 +               psDeviceNode->pfnMMUFinalise (pBMContext->psMMUContext);
59114 +       }
59115 +
59116 +
59117 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
59118 +
59119 +
59120 +       return IMG_NULL;
59121 +}
59122 +
59123 +IMG_VOID
59124 +BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
59125 +{
59126 +       BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
59127 +       PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
59128 +
59129 +       PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
59130 +
59131 +       if(psBMHeap)
59132 +       {
59133 +
59134 +               if(psBMHeap->ui32Attribs
59135 +               &       (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
59136 +                       |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
59137 +               {
59138 +                       if (psBMHeap->pImportArena)
59139 +                       {
59140 +                               RA_Delete (psBMHeap->pImportArena);
59141 +                       }
59142 +               }
59143 +               else
59144 +               {
59145 +                       PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
59146 +                       return;
59147 +               }
59148 +
59149 +
59150 +               psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
59151 +
59152 +
59153 +               List_BM_HEAP_Remove(psBMHeap);
59154 +
59155 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
59156 +
59157 +       }
59158 +       else
59159 +       {
59160 +               PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
59161 +       }
59162 +}
59163 +
59164 +
59165 +IMG_BOOL
59166 +BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
59167 +{
59168 +
59169 +       PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
59170 +       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
59171 +
59172 +
59173 +       return IMG_TRUE;
59174 +}
59175 +
59176 +IMG_BOOL
59177 +BM_Alloc (  IMG_HANDLE                 hDevMemHeap,
59178 +                       IMG_DEV_VIRTADDR        *psDevVAddr,
59179 +                       IMG_SIZE_T                      uSize,
59180 +                       IMG_UINT32                      *pui32Flags,
59181 +                       IMG_UINT32                      uDevVAddrAlignment,
59182 +                       BM_HANDLE                       *phBuf)
59183 +{
59184 +       BM_BUF *pBuf;
59185 +       BM_CONTEXT *pBMContext;
59186 +       BM_HEAP *psBMHeap;
59187 +       SYS_DATA *psSysData;
59188 +       IMG_UINT32 uFlags;
59189 +
59190 +       if (pui32Flags == IMG_NULL)
59191 +       {
59192 +               PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
59193 +               PVR_DBG_BREAK;
59194 +               return IMG_FALSE;
59195 +       }
59196 +
59197 +       uFlags = *pui32Flags;
59198 +
59199 +       PVR_DPF ((PVR_DBG_MESSAGE,
59200 +                 "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
59201 +                       uSize, uFlags, uDevVAddrAlignment));
59202 +
59203 +       SysAcquireData(&psSysData);
59204 +
59205 +       psBMHeap = (BM_HEAP*)hDevMemHeap;
59206 +       pBMContext = psBMHeap->pBMContext;
59207 +
59208 +       if(uDevVAddrAlignment == 0)
59209 +       {
59210 +               uDevVAddrAlignment = 1;
59211 +       }
59212 +
59213 +
59214 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
59215 +                                  sizeof (BM_BUF),
59216 +                                  (IMG_PVOID *)&pBuf, IMG_NULL,
59217 +                                  "Buffer Manager buffer") != PVRSRV_OK)
59218 +       {
59219 +               PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
59220 +               return IMG_FALSE;
59221 +       }
59222 +       OSMemSet(pBuf, 0, sizeof (BM_BUF));
59223 +
59224 +
59225 +       if (AllocMemory(pBMContext,
59226 +                                       psBMHeap,
59227 +                                       psDevVAddr,
59228 +                                       uSize,
59229 +                                       uFlags,
59230 +                                       uDevVAddrAlignment,
59231 +                                       pBuf) != IMG_TRUE)
59232 +       {
59233 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
59234 +
59235 +               PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
59236 +               return IMG_FALSE;
59237 +       }
59238 +
59239 +       PVR_DPF ((PVR_DBG_MESSAGE,
59240 +                 "BM_Alloc (uSize=0x%x, uFlags=0x%x)=%08X",
59241 +                 uSize, uFlags, pBuf));
59242 +
59243 +
59244 +       pBuf->ui32RefCount = 1;
59245 +       *phBuf = (BM_HANDLE)pBuf;
59246 +       *pui32Flags = uFlags | psBMHeap->ui32Attribs;
59247 +
59248 +
59249 +       if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
59250 +       {
59251 +               *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
59252 +               *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
59253 +       }
59254 +
59255 +       return IMG_TRUE;
59256 +}
59257 +
59258 +
59259 +
59260 +#if defined(PVR_LMA)
59261 +static IMG_BOOL
59262 +ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
59263 +{
59264 +       IMG_UINT32 i;
59265 +
59266 +       for (i = 0; i < ui32PageCount; i++)
59267 +       {
59268 +               IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
59269 +               IMG_SYS_PHYADDR sEndSysPAddr;
59270 +
59271 +               if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
59272 +               {
59273 +                       return IMG_FALSE;
59274 +               }
59275 +
59276 +               sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
59277 +
59278 +               if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
59279 +               {
59280 +                       return IMG_FALSE;
59281 +               }
59282 +       }
59283 +
59284 +       return IMG_TRUE;
59285 +}
59286 +
59287 +static IMG_BOOL
59288 +ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
59289 +{
59290 +       IMG_SYS_PHYADDR sEndSysPAddr;
59291 +
59292 +       if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
59293 +       {
59294 +               return IMG_FALSE;
59295 +       }
59296 +
59297 +       sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
59298 +
59299 +       if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
59300 +       {
59301 +               return IMG_FALSE;
59302 +       }
59303 +
59304 +       return IMG_TRUE;
59305 +}
59306 +
59307 +#define        WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
59308 +
59309 +#define        WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
59310 +
59311 +#endif
59312 +
59313 +
59314 +IMG_BOOL
59315 +BM_Wrap (      IMG_HANDLE hDevMemHeap,
59316 +                       IMG_SIZE_T ui32Size,
59317 +                       IMG_SIZE_T ui32Offset,
59318 +                       IMG_BOOL bPhysContig,
59319 +                       IMG_SYS_PHYADDR *psSysAddr,
59320 +                       IMG_VOID *pvCPUVAddr,
59321 +                       IMG_UINT32 *pui32Flags,
59322 +                       BM_HANDLE *phBuf)
59323 +{
59324 +       BM_BUF *pBuf;
59325 +       BM_CONTEXT *psBMContext;
59326 +       BM_HEAP *psBMHeap;
59327 +       SYS_DATA *psSysData;
59328 +       IMG_SYS_PHYADDR sHashAddress;
59329 +       IMG_UINT32 uFlags;
59330 +
59331 +       psBMHeap = (BM_HEAP*)hDevMemHeap;
59332 +       psBMContext = psBMHeap->pBMContext;
59333 +
59334 +       uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);
59335 +
59336 +       if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
59337 +       {
59338 +               uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
59339 +               uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
59340 +       }
59341 +
59342 +       PVR_DPF ((PVR_DBG_MESSAGE,
59343 +                 "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
59344 +                       ui32Size, ui32Offset, bPhysContig, pvCPUVAddr, uFlags));
59345 +
59346 +       SysAcquireData(&psSysData);
59347 +
59348 +#if defined(PVR_LMA)
59349 +       if (bPhysContig)
59350 +       {
59351 +               if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
59352 +               {
59353 +                       PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
59354 +                       return IMG_FALSE;
59355 +               }
59356 +       }
59357 +       else
59358 +       {
59359 +               IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
59360 +
59361 +               if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
59362 +               {
59363 +                       PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
59364 +                       return IMG_FALSE;
59365 +               }
59366 +       }
59367 +#endif
59368 +
59369 +       sHashAddress = psSysAddr[0];
59370 +
59371 +
59372 +       sHashAddress.uiAddr += ui32Offset;
59373 +
59374 +
59375 +       pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, (IMG_UINTPTR_T) sHashAddress.uiAddr);
59376 +
59377 +       if(pBuf)
59378 +       {
59379 +               IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
59380 +
59381 +
59382 +               if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
59383 +                                                                                                               pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
59384 +               {
59385 +                       PVR_DPF((PVR_DBG_MESSAGE,
59386 +                                       "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
59387 +                                       ui32Size, ui32Offset, sHashAddress.uiAddr));
59388 +
59389 +                       pBuf->ui32RefCount++;
59390 +                       *phBuf = (BM_HANDLE)pBuf;
59391 +                       if(pui32Flags)
59392 +                               *pui32Flags = uFlags;
59393 +
59394 +                       return IMG_TRUE;
59395 +               }
59396 +       }
59397 +
59398 +
59399 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
59400 +                                               sizeof (BM_BUF),
59401 +                                               (IMG_PVOID *)&pBuf, IMG_NULL,
59402 +                                               "Buffer Manager buffer") != PVRSRV_OK)
59403 +       {
59404 +               PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
59405 +               return IMG_FALSE;
59406 +       }
59407 +       OSMemSet(pBuf, 0, sizeof (BM_BUF));
59408 +
59409 +
59410 +       if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
59411 +       {
59412 +               PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
59413 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
59414 +
59415 +               return IMG_FALSE;
59416 +       }
59417 +
59418 +
59419 +       if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
59420 +       {
59421 +
59422 +               PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
59423 +
59424 +               if (!HASH_Insert (psBMContext->pBufferHash, (IMG_UINTPTR_T) sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
59425 +               {
59426 +                       FreeBuf (pBuf, uFlags);
59427 +                       PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
59428 +                       return IMG_FALSE;
59429 +               }
59430 +       }
59431 +
59432 +       PVR_DPF ((PVR_DBG_MESSAGE,
59433 +                       "BM_Wrap (uSize=0x%x, uFlags=0x%x)=%08X(devVAddr=%08X)",
59434 +                       ui32Size, uFlags, pBuf, pBuf->DevVAddr.uiAddr));
59435 +
59436 +
59437 +       pBuf->ui32RefCount = 1;
59438 +       *phBuf = (BM_HANDLE)pBuf;
59439 +       if(pui32Flags)
59440 +       {
59441 +
59442 +               *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
59443 +       }
59444 +
59445 +       return IMG_TRUE;
59446 +}
59447 +
59448 +
59449 +IMG_VOID
59450 +BM_Free (BM_HANDLE hBuf,
59451 +               IMG_UINT32 ui32Flags)
59452 +{
59453 +       BM_BUF *pBuf = (BM_BUF *)hBuf;
59454 +       SYS_DATA *psSysData;
59455 +       IMG_SYS_PHYADDR sHashAddr;
59456 +
59457 +       PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=%08X)", hBuf));
59458 +       PVR_ASSERT (pBuf!=IMG_NULL);
59459 +
59460 +       if (pBuf == IMG_NULL)
59461 +       {
59462 +               PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
59463 +               return;
59464 +       }
59465 +
59466 +       SysAcquireData(&psSysData);
59467 +
59468 +       pBuf->ui32RefCount--;
59469 +
59470 +       if(pBuf->ui32RefCount == 0)
59471 +       {
59472 +               if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
59473 +               {
59474 +                       sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
59475 +
59476 +                       HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash,  (IMG_UINTPTR_T)sHashAddr.uiAddr);
59477 +               }
59478 +               FreeBuf (pBuf, ui32Flags);
59479 +       }
59480 +}
59481 +
59482 +
59483 +IMG_CPU_VIRTADDR
59484 +BM_HandleToCpuVaddr (BM_HANDLE hBuf)
59485 +{
59486 +       BM_BUF *pBuf = (BM_BUF *)hBuf;
59487 +
59488 +       PVR_ASSERT (pBuf != IMG_NULL);
59489 +       if (pBuf == IMG_NULL)
59490 +       {
59491 +               PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
59492 +               return IMG_NULL;
59493 +       }
59494 +
59495 +       PVR_DPF ((PVR_DBG_MESSAGE,
59496 +                               "BM_HandleToCpuVaddr(h=%08X)=%08X",
59497 +                               hBuf, pBuf->CpuVAddr));
59498 +       return pBuf->CpuVAddr;
59499 +}
59500 +
59501 +
59502 +IMG_DEV_VIRTADDR
59503 +BM_HandleToDevVaddr (BM_HANDLE hBuf)
59504 +{
59505 +       BM_BUF *pBuf = (BM_BUF *)hBuf;
59506 +
59507 +       PVR_ASSERT (pBuf != IMG_NULL);
59508 +       if (pBuf == IMG_NULL)
59509 +       {
59510 +               IMG_DEV_VIRTADDR        DevVAddr = {0};
59511 +               PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
59512 +               return DevVAddr;
59513 +       }
59514 +
59515 +       PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=%08X)=%08X", hBuf, pBuf->DevVAddr));
59516 +       return pBuf->DevVAddr;
59517 +}
59518 +
59519 +
59520 +IMG_SYS_PHYADDR
59521 +BM_HandleToSysPaddr (BM_HANDLE hBuf)
59522 +{
59523 +       BM_BUF *pBuf = (BM_BUF *)hBuf;
59524 +
59525 +       PVR_ASSERT (pBuf != IMG_NULL);
59526 +
59527 +       if (pBuf == IMG_NULL)
59528 +       {
59529 +               IMG_SYS_PHYADDR PhysAddr = {0};
59530 +               PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
59531 +               return PhysAddr;
59532 +       }
59533 +
59534 +       PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=%08X)=%08X", hBuf, pBuf->CpuPAddr.uiAddr));
59535 +       return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
59536 +}
59537 +
59538 +IMG_HANDLE
59539 +BM_HandleToOSMemHandle(BM_HANDLE hBuf)
59540 +{
59541 +       BM_BUF *pBuf = (BM_BUF *)hBuf;
59542 +
59543 +       PVR_ASSERT (pBuf != IMG_NULL);
59544 +
59545 +       if (pBuf == IMG_NULL)
59546 +       {
59547 +               PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
59548 +               return IMG_NULL;
59549 +       }
59550 +
59551 +       PVR_DPF ((PVR_DBG_MESSAGE,
59552 +                               "BM_HandleToOSMemHandle(h=%08X)=%08X",
59553 +                               hBuf, pBuf->hOSMemHandle));
59554 +       return pBuf->hOSMemHandle;
59555 +}
59556 +
59557 +IMG_BOOL
59558 +BM_ContiguousStatistics (IMG_UINT32 uFlags,
59559 +                                                IMG_UINT32 *pTotalBytes,
59560 +                                                IMG_UINT32 *pAvailableBytes)
59561 +{
59562 +       if (pAvailableBytes || pTotalBytes || uFlags);
59563 +       return IMG_FALSE;
59564 +}
59565 +
59566 +
59567 +static IMG_BOOL
59568 +DevMemoryAlloc (BM_CONTEXT *pBMContext,
59569 +                               BM_MAPPING *pMapping,
59570 +                               IMG_SIZE_T *pActualSize,
59571 +                               IMG_UINT32 uFlags,
59572 +                               IMG_UINT32 dev_vaddr_alignment,
59573 +                               IMG_DEV_VIRTADDR *pDevVAddr)
59574 +{
59575 +       PVRSRV_DEVICE_NODE *psDeviceNode;
59576 +#ifdef PDUMP
59577 +       IMG_UINT32 ui32PDumpSize = pMapping->uSize;
59578 +#endif
59579 +
59580 +       psDeviceNode = pBMContext->psDeviceNode;
59581 +
59582 +       if(uFlags & PVRSRV_MEM_INTERLEAVED)
59583 +       {
59584 +
59585 +               pMapping->uSize *= 2;
59586 +       }
59587 +
59588 +#ifdef PDUMP
59589 +       if(uFlags & PVRSRV_MEM_DUMMY)
59590 +       {
59591 +
59592 +               ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
59593 +       }
59594 +#endif
59595 +
59596 +
59597 +       if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
59598 +                                                                       pMapping->uSize,
59599 +                                                                       pActualSize,
59600 +                                                                       0,
59601 +                                                                       dev_vaddr_alignment,
59602 +                                                                       &(pMapping->DevVAddr)))
59603 +       {
59604 +               PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
59605 +               return IMG_FALSE;
59606 +       }
59607 +
59608 +#ifdef SUPPORT_SGX_MMU_BYPASS
59609 +       EnableHostAccess(pBMContext->psMMUContext);
59610 +#endif
59611 +
59612 +
59613 +
59614 +       PDUMPMALLOCPAGES(psDeviceNode->sDevId.eDeviceType, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, (IMG_HANDLE)pMapping);
59615 +
59616 +       switch (pMapping->eCpuMemoryOrigin)
59617 +       {
59618 +               case hm_wrapped:
59619 +               case hm_wrapped_virtaddr:
59620 +               case hm_contiguous:
59621 +               {
59622 +                       psDeviceNode->pfnMMUMapPages (  pMapping->pBMHeap->pMMUHeap,
59623 +                                                       pMapping->DevVAddr,
59624 +                                                       SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
59625 +                                                       pMapping->uSize,
59626 +                                                       uFlags,
59627 +                                                       (IMG_HANDLE)pMapping);
59628 +
59629 +                       *pDevVAddr = pMapping->DevVAddr;
59630 +                       break;
59631 +               }
59632 +               case hm_env:
59633 +               {
59634 +                       psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap,
59635 +                                                       pMapping->DevVAddr,
59636 +                                                       pMapping->uSize,
59637 +                                                       pMapping->CpuVAddr,
59638 +                                                       pMapping->hOSMemHandle,
59639 +                                                       pDevVAddr,
59640 +                                                       uFlags,
59641 +                                                       (IMG_HANDLE)pMapping);
59642 +                       break;
59643 +               }
59644 +               case hm_wrapped_scatter:
59645 +               case hm_wrapped_scatter_virtaddr:
59646 +               {
59647 +                       psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
59648 +                                                       pMapping->DevVAddr,
59649 +                                                       pMapping->psSysAddr,
59650 +                                                       pMapping->uSize,
59651 +                                                       uFlags,
59652 +                                                       (IMG_HANDLE)pMapping);
59653 +
59654 +                       *pDevVAddr = pMapping->DevVAddr;
59655 +                       break;
59656 +               }
59657 +               default:
59658 +                       PVR_DPF((PVR_DBG_ERROR,
59659 +                               "Illegal value %d for pMapping->eCpuMemoryOrigin",
59660 +                               pMapping->eCpuMemoryOrigin));
59661 +                       return IMG_FALSE;
59662 +       }
59663 +
59664 +#ifdef SUPPORT_SGX_MMU_BYPASS
59665 +       DisableHostAccess(pBMContext->psMMUContext);
59666 +#endif
59667 +
59668 +       return IMG_TRUE;
59669 +}
59670 +
59671 +static IMG_VOID
59672 +DevMemoryFree (BM_MAPPING *pMapping)
59673 +{
59674 +       PVRSRV_DEVICE_NODE *psDeviceNode;
59675 +#ifdef PDUMP
59676 +       IMG_UINT32 ui32PSize;
59677 +#endif
59678 +
59679 +#ifdef PDUMP
59680 +
59681 +       if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
59682 +       {
59683 +
59684 +               ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
59685 +       }
59686 +       else
59687 +       {
59688 +               ui32PSize = pMapping->uSize;
59689 +       }
59690 +
59691 +       PDUMPFREEPAGES(pMapping->pBMHeap,
59692 +                    pMapping->DevVAddr,
59693 +                    ui32PSize,
59694 +                    pMapping->pBMHeap->sDevArena.ui32DataPageSize,
59695 +                    (IMG_HANDLE)pMapping,
59696 +                    (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE);
59697 +#endif
59698 +
59699 +       psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
59700 +
59701 +       psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize));
59702 +}
59703 +
59704 +static IMG_BOOL
59705 +BM_ImportMemory (IMG_VOID *pH,
59706 +                         IMG_SIZE_T uRequestSize,
59707 +                         IMG_SIZE_T *pActualSize,
59708 +                         BM_MAPPING **ppsMapping,
59709 +                         IMG_UINT32 uFlags,
59710 +                         IMG_UINTPTR_T *pBase)
59711 +{
59712 +       BM_MAPPING *pMapping;
59713 +       BM_HEAP *pBMHeap = pH;
59714 +       BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
59715 +       IMG_BOOL bResult;
59716 +       IMG_SIZE_T uSize;
59717 +       IMG_SIZE_T uPSize;
59718 +       IMG_UINT32 uDevVAddrAlignment = 0;
59719 +
59720 +       PVR_DPF ((PVR_DBG_MESSAGE,
59721 +                         "BM_ImportMemory (pBMContext=%08X, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
59722 +                         pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
59723 +
59724 +       PVR_ASSERT (ppsMapping != IMG_NULL);
59725 +       PVR_ASSERT (pBMContext != IMG_NULL);
59726 +
59727 +       if (ppsMapping == IMG_NULL)
59728 +       {
59729 +               PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
59730 +               goto fail_exit;
59731 +       }
59732 +
59733 +       uSize = HOST_PAGEALIGN (uRequestSize);
59734 +       PVR_ASSERT (uSize >= uRequestSize);
59735 +
59736 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
59737 +                                               sizeof (BM_MAPPING),
59738 +                                               (IMG_PVOID *)&pMapping, IMG_NULL,
59739 +                                               "Buffer Manager Mapping") != PVRSRV_OK)
59740 +       {
59741 +               PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
59742 +               goto fail_exit;
59743 +       }
59744 +
59745 +       pMapping->hOSMemHandle = 0;
59746 +       pMapping->CpuVAddr = 0;
59747 +       pMapping->DevVAddr.uiAddr = 0;
59748 +       pMapping->CpuPAddr.uiAddr = 0;
59749 +       pMapping->uSize = uSize;
59750 +       pMapping->pBMHeap = pBMHeap;
59751 +       pMapping->ui32Flags = uFlags;
59752 +
59753 +
59754 +       if (pActualSize)
59755 +       {
59756 +               *pActualSize = uSize;
59757 +       }
59758 +
59759 +
59760 +       if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
59761 +       {
59762 +               uPSize = pBMHeap->sDevArena.ui32DataPageSize;
59763 +       }
59764 +       else
59765 +       {
59766 +               uPSize = pMapping->uSize;
59767 +       }
59768 +
59769 +
59770 +
59771 +       if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
59772 +       {
59773 +               IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
59774 +
59775 +
59776 +               if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
59777 +               {
59778 +                       ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
59779 +                       ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
59780 +               }
59781 +
59782 +
59783 +               if (OSAllocPages(ui32Attribs,
59784 +                                                uPSize,
59785 +                                                pBMHeap->sDevArena.ui32DataPageSize,
59786 +                                                (IMG_VOID **)&pMapping->CpuVAddr,
59787 +                                                &pMapping->hOSMemHandle) != PVRSRV_OK)
59788 +               {
59789 +                       PVR_DPF((PVR_DBG_ERROR,
59790 +                                       "BM_ImportMemory: OSAllocPages(0x%x) failed",
59791 +                                       uPSize));
59792 +                       goto fail_mapping_alloc;
59793 +               }
59794 +
59795 +
59796 +               pMapping->eCpuMemoryOrigin = hm_env;
59797 +       }
59798 +       else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
59799 +       {
59800 +               IMG_SYS_PHYADDR sSysPAddr;
59801 +               IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
59802 +
59803 +
59804 +               if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
59805 +               {
59806 +                       ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
59807 +                       ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
59808 +               }
59809 +
59810 +
59811 +               PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
59812 +
59813 +               if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
59814 +                                          uPSize,
59815 +                                          IMG_NULL,
59816 +                                          IMG_NULL,
59817 +                                          0,
59818 +                                          pBMHeap->sDevArena.ui32DataPageSize,
59819 +                                          0,
59820 +                                          (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
59821 +               {
59822 +                       PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
59823 +                       goto fail_mapping_alloc;
59824 +               }
59825 +
59826 +
59827 +               pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
59828 +               if(OSReservePhys(pMapping->CpuPAddr,
59829 +                                                uPSize,
59830 +                                                ui32Attribs,
59831 +                                                &pMapping->CpuVAddr,
59832 +                                                &pMapping->hOSMemHandle) != PVRSRV_OK)
59833 +               {
59834 +                       PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
59835 +                       goto fail_dev_mem_alloc;
59836 +               }
59837 +
59838 +
59839 +               pMapping->eCpuMemoryOrigin = hm_contiguous;
59840 +       }
59841 +       else
59842 +       {
59843 +               PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
59844 +               goto fail_mapping_alloc;
59845 +       }
59846 +
59847 +
59848 +       bResult = DevMemoryAlloc (pBMContext,
59849 +                                                               pMapping,
59850 +                                                               IMG_NULL,
59851 +                                                               uFlags,
59852 +                                                               uDevVAddrAlignment,
59853 +                                                               &pMapping->DevVAddr);
59854 +       if (!bResult)
59855 +       {
59856 +               PVR_DPF((PVR_DBG_ERROR,
59857 +                               "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
59858 +                               pMapping->uSize));
59859 +               goto fail_dev_mem_alloc;
59860 +       }
59861 +
59862 +
59863 +
59864 +       PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
59865 +
59866 +       *pBase = pMapping->DevVAddr.uiAddr;
59867 +       *ppsMapping = pMapping;
59868 +
59869 +       PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
59870 +       return IMG_TRUE;
59871 +
59872 +fail_dev_mem_alloc:
59873 +       if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
59874 +       {
59875 +
59876 +               if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
59877 +               {
59878 +                       pMapping->uSize /= 2;
59879 +               }
59880 +
59881 +               if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
59882 +               {
59883 +                       uPSize = pBMHeap->sDevArena.ui32DataPageSize;
59884 +               }
59885 +               else
59886 +               {
59887 +                       uPSize = pMapping->uSize;
59888 +               }
59889 +
59890 +               if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
59891 +               {
59892 +                       OSFreePages(pBMHeap->ui32Attribs,
59893 +                                                 uPSize,
59894 +                                                 (IMG_VOID *)pMapping->CpuVAddr,
59895 +                                                 pMapping->hOSMemHandle);
59896 +               }
59897 +               else
59898 +               {
59899 +                       IMG_SYS_PHYADDR sSysPAddr;
59900 +
59901 +                       if(pMapping->CpuVAddr)
59902 +                       {
59903 +                               OSUnReservePhys(pMapping->CpuVAddr,
59904 +                                                               uPSize,
59905 +                                                               pBMHeap->ui32Attribs,
59906 +                                                               pMapping->hOSMemHandle);
59907 +                       }
59908 +                       sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
59909 +                       RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
59910 +               }
59911 +       }
59912 +fail_mapping_alloc:
59913 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
59914 +
59915 +fail_exit:
59916 +       return IMG_FALSE;
59917 +}
59918 +
59919 +
59920 +static IMG_VOID
59921 +BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
59922 +{
59923 +       BM_HEAP *pBMHeap = h;
59924 +       IMG_SIZE_T uPSize;
59925 +
59926 +       PVR_UNREFERENCED_PARAMETER (_base);
59927 +
59928 +       PVR_DPF ((PVR_DBG_MESSAGE,
59929 +                         "BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)", h, _base, psMapping));
59930 +
59931 +       PVR_ASSERT (psMapping != IMG_NULL);
59932 +
59933 +       if (psMapping == IMG_NULL)
59934 +       {
59935 +               PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
59936 +               return;
59937 +       }
59938 +
59939 +       DevMemoryFree (psMapping);
59940 +
59941 +
59942 +       if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
59943 +       {
59944 +               psMapping->uSize /= 2;
59945 +       }
59946 +
59947 +       if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
59948 +       {
59949 +               uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
59950 +       }
59951 +       else
59952 +       {
59953 +               uPSize = psMapping->uSize;
59954 +       }
59955 +
59956 +       if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
59957 +       {
59958 +               OSFreePages(pBMHeap->ui32Attribs,
59959 +                                               uPSize,
59960 +                                               (IMG_VOID *) psMapping->CpuVAddr,
59961 +                                               psMapping->hOSMemHandle);
59962 +       }
59963 +       else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
59964 +       {
59965 +               IMG_SYS_PHYADDR sSysPAddr;
59966 +
59967 +               OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
59968 +
59969 +               sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
59970 +
59971 +               RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
59972 +       }
59973 +       else
59974 +       {
59975 +               PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"));
59976 +       }
59977 +
59978 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
59979 +
59980 +
59981 +       PVR_DPF((PVR_DBG_MESSAGE,
59982 +                       "..BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)",
59983 +                       h, _base, psMapping));
59984 +}
59985 +
59986 +IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
59987 +                                                               IMG_DEV_VIRTADDR sDevVPageAddr,
59988 +                                                               IMG_DEV_PHYADDR *psDevPAddr)
59989 +{
59990 +       PVRSRV_DEVICE_NODE *psDeviceNode;
59991 +
59992 +       PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
59993 +
59994 +       PVR_ASSERT (psMemInfo && psDevPAddr)
59995 +
59996 +
59997 +       PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
59998 +
59999 +       psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
60000 +
60001 +       *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
60002 +                                                                                               sDevVPageAddr);
60003 +}
60004 +
60005 +
60006 +PVRSRV_ERROR BM_GetHeapInfo(IMG_HANDLE hDevMemHeap, PVRSRV_HEAP_INFO *psHeapInfo)
60007 +{
60008 +       BM_HEAP *psBMHeap = (BM_HEAP *)hDevMemHeap;
60009 +
60010 +       PVR_DPF((PVR_DBG_VERBOSE, "BM_GetHeapInfo"));
60011 +
60012 +       psHeapInfo->hDevMemHeap = hDevMemHeap;
60013 +       psHeapInfo->sDevVAddrBase = psBMHeap->sDevArena.BaseDevVAddr;
60014 +       psHeapInfo->ui32HeapByteSize = psBMHeap->sDevArena.ui32Size;
60015 +       psHeapInfo->ui32Attribs = psBMHeap->ui32Attribs;
60016 +
60017 +       return PVRSRV_OK;
60018 +}
60019 +
60020 +
60021 +MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
60022 +{
60023 +       BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
60024 +
60025 +       PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
60026 +
60027 +       return pBMHeap->pBMContext->psMMUContext;
60028 +}
60029 +
60030 +MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
60031 +{
60032 +       BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
60033 +
60034 +       PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
60035 +
60036 +       return pBMContext->psMMUContext;
60037 +}
60038 +
60039 +IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
60040 +{
60041 +       PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
60042 +
60043 +       return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
60044 +}
60045 +
60046 +
60047 +PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
60048 +{
60049 +       PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
60050 +
60051 +       return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
60052 +}
60053 +
60054 +
60055 +IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
60056 +{
60057 +       PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
60058 +
60059 +       return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
60060 +}
60061 +
60062 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/deviceclass.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/deviceclass.c
60063 new file mode 100644
60064 index 0000000..3340dd8
60065 --- /dev/null
60066 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/deviceclass.c
60067 @@ -0,0 +1,1937 @@
60068 +/**********************************************************************
60069 + *
60070 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
60071 + *
60072 + * This program is free software; you can redistribute it and/or modify it
60073 + * under the terms and conditions of the GNU General Public License,
60074 + * version 2, as published by the Free Software Foundation.
60075 + *
60076 + * This program is distributed in the hope it will be useful but, except
60077 + * as otherwise stated in writing, without any warranty; without even the
60078 + * implied warranty of merchantability or fitness for a particular purpose.
60079 + * See the GNU General Public License for more details.
60080 + *
60081 + * You should have received a copy of the GNU General Public License along with
60082 + * this program; if not, write to the Free Software Foundation, Inc.,
60083 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
60084 + *
60085 + * The full GNU General Public License is included in this distribution in
60086 + * the file called "COPYING".
60087 + *
60088 + * Contact Information:
60089 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
60090 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
60091 + *
60092 + ******************************************************************************/
60093 +
60094 +#include "services_headers.h"
60095 +#include "buffer_manager.h"
60096 +#include "kernelbuffer.h"
60097 +#include "pvr_bridge_km.h"
60098 +
60099 +#include "lists.h"
60100 +DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
60101 +DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
60102 +DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
60103 +DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
60104 +
60105 +IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
60106 +
60107 +PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
60108 +PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
60109 +
60110 +#if defined(SUPPORT_MISR_IN_THREAD)
60111 +void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
60112 +#endif
60113 +
60114 +
60115 +typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
60116 +
60117 +typedef struct PVRSRV_DC_BUFFER_TAG
60118 +{
60119 +
60120 +       PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
60121 +
60122 +       struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
60123 +       struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
60124 +} PVRSRV_DC_BUFFER;
60125 +
60126 +typedef struct PVRSRV_DC_SWAPCHAIN_TAG
60127 +{
60128 +       IMG_HANDLE                                                      hExtSwapChain;
60129 +       IMG_UINT32                                                      ui32SwapChainID;
60130 +       IMG_UINT32                                                      ui32Flags;
60131 +       IMG_UINT32                                                      ui32RefCount;
60132 +       PVRSRV_QUEUE_INFO                                       *psQueue;
60133 +       PVRSRV_DC_BUFFER                                        asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
60134 +       IMG_UINT32                                                      ui32BufferCount;
60135 +       PVRSRV_DC_BUFFER                                        *psLastFlipBuffer;
60136 +       struct PVRSRV_DC_SWAPCHAIN_TAG          *psNext;
60137 +       struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
60138 +       //IMG_HANDLE                                                    hResItem;
60139 +} PVRSRV_DC_SWAPCHAIN;
60140 +
60141 +typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
60142 +{
60143 +       struct PVRSRV_DC_SWAPCHAIN_TAG          *psSwapChain;
60144 +       IMG_HANDLE                                                      hResItem;       
60145 +} PVRSRV_DC_SWAPCHAIN_REF;
60146 +
60147 +
60148 +typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG
60149 +{
60150 +       IMG_UINT32                                                      ui32RefCount;
60151 +       IMG_UINT32                                                      ui32DeviceID;
60152 +       IMG_HANDLE                                                      hExtDevice;
60153 +       PPVRSRV_DC_SRV2DISP_KMJTABLE            psFuncTable;
60154 +       IMG_HANDLE                                                      hDevMemContext;
60155 +       PVRSRV_DC_BUFFER                                        sSystemBuffer;
60156 +       struct PVRSRV_DC_SWAPCHAIN_TAG          *psDCSwapChainShared;
60157 +} PVRSRV_DISPLAYCLASS_INFO;
60158 +
60159 +
60160 +typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
60161 +{
60162 +       PVRSRV_DISPLAYCLASS_INFO                        *psDCInfo;
60163 +       PRESMAN_ITEM                                            hResItem;
60164 +} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
60165 +
60166 +
60167 +typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
60168 +
60169 +typedef struct PVRSRV_BC_BUFFER_TAG
60170 +{
60171 +
60172 +       PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
60173 +
60174 +       struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
60175 +} PVRSRV_BC_BUFFER;
60176 +
60177 +
60178 +typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
60179 +{
60180 +       IMG_UINT32                                                      ui32RefCount;
60181 +       IMG_UINT32                                                      ui32DeviceID;
60182 +       IMG_HANDLE                                                      hExtDevice;
60183 +       PPVRSRV_BC_SRV2BUFFER_KMJTABLE          psFuncTable;
60184 +       IMG_HANDLE                                                      hDevMemContext;
60185 +
60186 +       IMG_UINT32                                                      ui32BufferCount;
60187 +       PVRSRV_BC_BUFFER                                        *psBuffer;
60188 +
60189 +} PVRSRV_BUFFERCLASS_INFO;
60190 +
60191 +
60192 +typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
60193 +{
60194 +       PVRSRV_BUFFERCLASS_INFO                         *psBCInfo;
60195 +       IMG_HANDLE                                                      hResItem;
60196 +} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
60197 +
60198 +
60199 +static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
60200 +{
60201 +       PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
60202 +
60203 +       psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
60204 +
60205 +       return psDCPerContextInfo->psDCInfo;
60206 +}
60207 +
60208 +
60209 +static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
60210 +{
60211 +       PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
60212 +
60213 +       psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
60214 +
60215 +       return psBCPerContextInfo->psBCInfo;
60216 +}
60217 +
60218 +IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
60219 +{
60220 +       IMG_UINT *pui32DevCount;
60221 +       IMG_UINT32 **ppui32DevID;
60222 +       PVRSRV_DEVICE_CLASS peDeviceClass;
60223 +
60224 +       pui32DevCount = va_arg(va, IMG_UINT*);
60225 +       ppui32DevID = va_arg(va, IMG_UINT32**);
60226 +       peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
60227 +
60228 +       if      ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
60229 +       &&      (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
60230 +       {
60231 +               (*pui32DevCount)++;
60232 +               if(*ppui32DevID)
60233 +               {
60234 +                       *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
60235 +               }
60236 +       }
60237 +}
60238 +
60239 +
60240 +IMG_EXPORT
60241 +PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass,
60242 +                                                                 IMG_UINT32 *pui32DevCount,
60243 +                                                                 IMG_UINT32 *pui32DevID )
60244 +{
60245 +
60246 +       IMG_UINT                        ui32DevCount = 0;
60247 +       SYS_DATA                        *psSysData;
60248 +
60249 +       SysAcquireData(&psSysData);
60250 +
60251 +
60252 +       List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
60253 +                                                                               PVRSRVEnumerateDCKM_ForEachVaCb,
60254 +                                                                               &ui32DevCount,
60255 +                                                                               &pui32DevID,
60256 +                                                                               DeviceClass);
60257 +
60258 +       if(pui32DevCount)
60259 +       {
60260 +               *pui32DevCount = ui32DevCount;
60261 +       }
60262 +       else if(pui32DevID == IMG_NULL)
60263 +       {
60264 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters"));
60265 +               return (PVRSRV_ERROR_INVALID_PARAMS);
60266 +       }
60267 +
60268 +       return PVRSRV_OK;
60269 +}
60270 +
60271 +
60272 +PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
60273 +                                                                          IMG_UINT32 *pui32DeviceID)
60274 +{
60275 +       PVRSRV_DISPLAYCLASS_INFO        *psDCInfo = IMG_NULL;
60276 +       PVRSRV_DEVICE_NODE                      *psDeviceNode;
60277 +       SYS_DATA                                        *psSysData;
60278 +
60279 +
60280 +
60281 +
60282 +
60283 +
60284 +
60285 +
60286 +
60287 +
60288 +
60289 +
60290 +
60291 +
60292 +
60293 +
60294 +       SysAcquireData(&psSysData);
60295 +
60296 +
60297 +
60298 +
60299 +
60300 +
60301 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60302 +                                        sizeof(*psDCInfo),
60303 +                                        (IMG_VOID **)&psDCInfo, IMG_NULL,
60304 +                                        "Display Class Info") != PVRSRV_OK)
60305 +       {
60306 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
60307 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
60308 +       }
60309 +       OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
60310 +
60311 +
60312 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60313 +                                        sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
60314 +                                        (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
60315 +                                        "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
60316 +       {
60317 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
60318 +               goto ErrorExit;
60319 +       }
60320 +       OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
60321 +
60322 +
60323 +       *psDCInfo->psFuncTable = *psFuncTable;
60324 +
60325 +
60326 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60327 +                                        sizeof(PVRSRV_DEVICE_NODE),
60328 +                                        (IMG_VOID **)&psDeviceNode, IMG_NULL,
60329 +                                        "Device Node") != PVRSRV_OK)
60330 +       {
60331 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
60332 +               goto ErrorExit;
60333 +       }
60334 +       OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
60335 +
60336 +       psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo;
60337 +       psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
60338 +       psDeviceNode->ui32RefCount = 1;
60339 +       psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
60340 +       psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
60341 +       psDeviceNode->psSysData = psSysData;
60342 +
60343 +
60344 +       if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
60345 +       {
60346 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
60347 +               goto ErrorExit;
60348 +       }
60349 +       psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
60350 +       if (pui32DeviceID)
60351 +       {
60352 +               *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
60353 +       }
60354 +
60355 +
60356 +       SysRegisterExternalDevice(psDeviceNode);
60357 +
60358 +
60359 +       List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
60360 +
60361 +       return PVRSRV_OK;
60362 +
60363 +ErrorExit:
60364 +
60365 +       if(psDCInfo->psFuncTable)
60366 +       {
60367 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
60368 +               psDCInfo->psFuncTable = IMG_NULL;
60369 +       }
60370 +
60371 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
60372 +
60373 +
60374 +       return PVRSRV_ERROR_OUT_OF_MEMORY;
60375 +}
60376 +
60377 +PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
60378 +{
60379 +       SYS_DATA                                        *psSysData;
60380 +       PVRSRV_DEVICE_NODE                      *psDeviceNode;
60381 +       PVRSRV_DISPLAYCLASS_INFO        *psDCInfo;
60382 +
60383 +       SysAcquireData(&psSysData);
60384 +
60385 +
60386 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)
60387 +               List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
60388 +                                                                          MatchDeviceKM_AnyVaCb,
60389 +                                                                          ui32DevIndex,
60390 +                                                                          IMG_FALSE,
60391 +                                                                          PVRSRV_DEVICE_CLASS_DISPLAY);
60392 +       if (!psDeviceNode)
60393 +       {
60394 +
60395 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
60396 +               return PVRSRV_ERROR_GENERIC;
60397 +       }
60398 +
60399 +
60400 +       psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
60401 +
60402 +
60403 +
60404 +
60405 +       if(psDCInfo->ui32RefCount == 0)
60406 +       {
60407 +
60408 +
60409 +               List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
60410 +
60411 +
60412 +               SysRemoveExternalDevice(psDeviceNode);
60413 +
60414 +
60415 +
60416 +
60417 +               PVR_ASSERT(psDCInfo->ui32RefCount == 0);
60418 +               (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
60419 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
60420 +               psDCInfo->psFuncTable = IMG_NULL;
60421 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
60422 +
60423 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
60424 +
60425 +       }
60426 +       else
60427 +       {
60428 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
60429 +               return PVRSRV_ERROR_GENERIC;
60430 +       }
60431 +
60432 +       return PVRSRV_OK;
60433 +}
60434 +
60435 +
60436 +PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
60437 +                                                                          IMG_UINT32   *pui32DeviceID)
60438 +{
60439 +       PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
60440 +       PVRSRV_DEVICE_NODE              *psDeviceNode;
60441 +       SYS_DATA                                *psSysData;
60442 +
60443 +
60444 +
60445 +
60446 +
60447 +
60448 +
60449 +
60450 +
60451 +
60452 +
60453 +
60454 +
60455 +
60456 +       SysAcquireData(&psSysData);
60457 +
60458 +
60459 +
60460 +
60461 +
60462 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60463 +                                        sizeof(*psBCInfo),
60464 +                                        (IMG_VOID **)&psBCInfo, IMG_NULL,
60465 +                                        "Buffer Class Info") != PVRSRV_OK)
60466 +       {
60467 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
60468 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
60469 +       }
60470 +       OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
60471 +
60472 +
60473 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60474 +                                        sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
60475 +                                        (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
60476 +                                        "Function table for SRVKM->BUFFER") != PVRSRV_OK)
60477 +       {
60478 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
60479 +               goto ErrorExit;
60480 +       }
60481 +       OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
60482 +
60483 +
60484 +       *psBCInfo->psFuncTable = *psFuncTable;
60485 +
60486 +
60487 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60488 +                                        sizeof(PVRSRV_DEVICE_NODE),
60489 +                                        (IMG_VOID **)&psDeviceNode, IMG_NULL,
60490 +                                        "Device Node") != PVRSRV_OK)
60491 +       {
60492 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
60493 +               goto ErrorExit;
60494 +       }
60495 +       OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
60496 +
60497 +       psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo;
60498 +       psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
60499 +       psDeviceNode->ui32RefCount = 1;
60500 +       psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
60501 +       psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
60502 +       psDeviceNode->psSysData = psSysData;
60503 +
60504 +
60505 +       if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
60506 +       {
60507 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
60508 +               goto ErrorExit;
60509 +       }
60510 +       psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
60511 +       if (pui32DeviceID)
60512 +       {
60513 +               *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
60514 +       }
60515 +
60516 +
60517 +       List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
60518 +
60519 +       return PVRSRV_OK;
60520 +
60521 +ErrorExit:
60522 +
60523 +       if(psBCInfo->psFuncTable)
60524 +       {
60525 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
60526 +               psBCInfo->psFuncTable = IMG_NULL;
60527 +       }
60528 +
60529 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
60530 +
60531 +
60532 +       return PVRSRV_ERROR_OUT_OF_MEMORY;
60533 +}
60534 +
60535 +
60536 +PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
60537 +{
60538 +       SYS_DATA                                        *psSysData;
60539 +       PVRSRV_DEVICE_NODE                      *psDevNode;
60540 +       PVRSRV_BUFFERCLASS_INFO         *psBCInfo;
60541 +
60542 +       SysAcquireData(&psSysData);
60543 +
60544 +
60545 +       psDevNode = (PVRSRV_DEVICE_NODE*)
60546 +               List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
60547 +                                                                          MatchDeviceKM_AnyVaCb,
60548 +                                                                          ui32DevIndex,
60549 +                                                                          IMG_FALSE,
60550 +                                                                          PVRSRV_DEVICE_CLASS_BUFFER);
60551 +
60552 +       if (!psDevNode)
60553 +       {
60554 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
60555 +               return PVRSRV_ERROR_GENERIC;
60556 +       }
60557 +
60558 +
60559 +
60560 +       psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
60561 +
60562 +
60563 +
60564 +
60565 +       if(psBCInfo->ui32RefCount == 0)
60566 +       {
60567 +
60568 +
60569 +               List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
60570 +
60571 +
60572 +
60573 +
60574 +               (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
60575 +
60576 +
60577 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
60578 +               psBCInfo->psFuncTable = IMG_NULL;
60579 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
60580 +
60581 +               (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
60582 +
60583 +       }
60584 +       else
60585 +       {
60586 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
60587 +               return PVRSRV_ERROR_GENERIC;
60588 +       }
60589 +
60590 +       return PVRSRV_OK;
60591 +}
60592 +
60593 +
60594 +
60595 +IMG_EXPORT
60596 +PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM,
60597 +                                                                       IMG_BOOL        bResManCallback)
60598 +{
60599 +       PVRSRV_ERROR eError;
60600 +       PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
60601 +
60602 +       PVR_UNREFERENCED_PARAMETER(bResManCallback);
60603 +
60604 +       psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
60605 +
60606 +
60607 +       eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem);
60608 +
60609 +       return eError;
60610 +}
60611 +
60612 +
60613 +static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID            pvParam,
60614 +                                                                                 IMG_UINT32    ui32Param)
60615 +{
60616 +       PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
60617 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60618 +
60619 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
60620 +
60621 +       psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
60622 +       psDCInfo = psDCPerContextInfo->psDCInfo;
60623 +
60624 +       psDCInfo->ui32RefCount--;
60625 +       if(psDCInfo->ui32RefCount == 0)
60626 +       {
60627 +
60628 +               psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
60629 +
60630 +               if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
60631 +               {
60632 +                       PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
60633 +               }
60634 +               
60635 +               psDCInfo->hDevMemContext = IMG_NULL;
60636 +               psDCInfo->hExtDevice = IMG_NULL;
60637 +       }
60638 +
60639 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
60640 +
60641 +
60642 +       return PVRSRV_OK;
60643 +}
60644 +
60645 +
60646 +IMG_EXPORT
60647 +PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA     *psPerProc,
60648 +                                                                  IMG_UINT32                           ui32DeviceID,
60649 +                                                                  IMG_HANDLE                           hDevCookie,
60650 +                                                                  IMG_HANDLE                           *phDeviceKM)
60651 +{
60652 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60653 +       PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
60654 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
60655 +       SYS_DATA                        *psSysData;
60656 +       PVRSRV_ERROR eError;
60657 +
60658 +       if(!phDeviceKM || !hDevCookie)
60659 +       {
60660 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
60661 +               return PVRSRV_ERROR_GENERIC;
60662 +       }
60663 +
60664 +       SysAcquireData(&psSysData);
60665 +
60666 +
60667 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)
60668 +                       List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
60669 +                                                                                  MatchDeviceKM_AnyVaCb,
60670 +                                                                                  ui32DeviceID,
60671 +                                                                                  IMG_FALSE,
60672 +                                                                                  PVRSRV_DEVICE_CLASS_DISPLAY);
60673 +       if (!psDeviceNode)
60674 +       {
60675 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
60676 +               return PVRSRV_ERROR_GENERIC;
60677 +       }
60678 +       psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
60679 +
60680 +
60681 +
60682 +
60683 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
60684 +                                 sizeof(*psDCPerContextInfo),
60685 +                                 (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
60686 +                                 "Display Class per Context Info") != PVRSRV_OK)
60687 +       {
60688 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
60689 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
60690 +       }
60691 +       OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
60692 +
60693 +       if(psDCInfo->ui32RefCount++ == 0)
60694 +       {
60695 +
60696 +               psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
60697 +
60698 +
60699 +               psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
60700 +
60701 +
60702 +               eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
60703 +                                                                       (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
60704 +                                                                       &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
60705 +               if(eError != PVRSRV_OK)
60706 +               {
60707 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
60708 +                       psDCInfo->ui32RefCount--;
60709 +                       return eError;
60710 +               }
60711 +
60712 +
60713 +               eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
60714 +                                                               &psDCInfo->hExtDevice,
60715 +                                                               (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
60716 +               if(eError != PVRSRV_OK)
60717 +               {
60718 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
60719 +                       psDCInfo->ui32RefCount--;
60720 +                       PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
60721 +                       return eError;
60722 +               }
60723 +
60724 +               psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
60725 +       }
60726 +
60727 +       psDCPerContextInfo->psDCInfo = psDCInfo;
60728 +       psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
60729 +                                                                                                        RESMAN_TYPE_DISPLAYCLASS_DEVICE,
60730 +                                                                                                        psDCPerContextInfo,
60731 +                                                                                                        0,
60732 +                                                                                                        CloseDCDeviceCallBack);
60733 +
60734 +
60735 +       *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
60736 +
60737 +       return PVRSRV_OK;
60738 +}
60739 +
60740 +
60741 +IMG_EXPORT
60742 +PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
60743 +                                                                       IMG_UINT32 *pui32Count,
60744 +                                                                       DISPLAY_FORMAT *psFormat)
60745 +{
60746 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60747 +
60748 +       if(!hDeviceKM || !pui32Count || !psFormat)
60749 +       {
60750 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
60751 +               return PVRSRV_ERROR_INVALID_PARAMS;
60752 +       }
60753 +
60754 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
60755 +
60756 +
60757 +       return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
60758 +}
60759 +
60760 +
60761 +
60762 +IMG_EXPORT
60763 +PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM,
60764 +                                                                DISPLAY_FORMAT *psFormat,
60765 +                                                                IMG_UINT32 *pui32Count,
60766 +                                                                DISPLAY_DIMS *psDim)
60767 +{
60768 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60769 +
60770 +       if(!hDeviceKM || !pui32Count || !psFormat)
60771 +       {
60772 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
60773 +               return PVRSRV_ERROR_INVALID_PARAMS;
60774 +       }
60775 +
60776 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
60777 +
60778 +
60779 +       return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
60780 +}
60781 +
60782 +
60783 +IMG_EXPORT
60784 +PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
60785 +                                                                               IMG_HANDLE *phBuffer)
60786 +{
60787 +       PVRSRV_ERROR eError;
60788 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60789 +       IMG_HANDLE hExtBuffer;
60790 +
60791 +       if(!hDeviceKM || !phBuffer)
60792 +       {
60793 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
60794 +               return PVRSRV_ERROR_INVALID_PARAMS;
60795 +       }
60796 +
60797 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
60798 +
60799 +
60800 +       eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer);
60801 +       if(eError != PVRSRV_OK)
60802 +       {
60803 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
60804 +               return eError;
60805 +       }
60806 +
60807 +
60808 +       psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
60809 +       psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
60810 +       psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
60811 +       psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
60812 +
60813 +       psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
60814 +
60815 +
60816 +       *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
60817 +
60818 +       return PVRSRV_OK;
60819 +}
60820 +
60821 +
60822 +IMG_EXPORT
60823 +PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM,
60824 +                                                               DISPLAY_INFO *psDisplayInfo)
60825 +{
60826 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
60827 +       PVRSRV_ERROR eError;
60828 +
60829 +       if(!hDeviceKM || !psDisplayInfo)
60830 +       {
60831 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters"));
60832 +               return PVRSRV_ERROR_INVALID_PARAMS;
60833 +       }
60834 +
60835 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
60836 +
60837 +
60838 +       eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo);
60839 +       if (eError != PVRSRV_OK)
60840 +       {
60841 +               return eError;
60842 +       }
60843 +
60844 +       if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
60845 +       {
60846 +               psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
60847 +       }
60848 +
60849 +       return PVRSRV_OK;
60850 +}
60851 +
60852 +
60853 +IMG_EXPORT
60854 +PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef)
60855 +{
60856 +       PVRSRV_ERROR eError;
60857 +       PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
60858 +
60859 +       if(!hSwapChainRef)
60860 +       {
60861 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
60862 +               return PVRSRV_ERROR_INVALID_PARAMS;
60863 +       }
60864 +
60865 +       psSwapChainRef = hSwapChainRef;
60866 +
60867 +       eError = ResManFreeResByPtr(psSwapChainRef->hResItem);
60868 +
60869 +       return eError;
60870 +}
60871 +
60872 +
60873 +static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
60874 +{
60875 +       PVRSRV_ERROR                            eError;
60876 +       PVRSRV_DISPLAYCLASS_INFO        *psDCInfo = psSwapChain->psDCInfo;
60877 +       IMG_UINT32 i;
60878 +
60879 +
60880 +       
60881 +       if( psDCInfo->psDCSwapChainShared )
60882 +       {
60883 +               if( psDCInfo->psDCSwapChainShared == psSwapChain )
60884 +               {
60885 +                       psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
60886 +               }
60887 +               else 
60888 +               {
60889 +                       PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
60890 +                       psCurrentSwapChain = psDCInfo->psDCSwapChainShared;             
60891 +                       while( psCurrentSwapChain->psNext )
60892 +                       {
60893 +                               if( psCurrentSwapChain->psNext != psSwapChain ) 
60894 +                               {
60895 +                                       psCurrentSwapChain = psCurrentSwapChain->psNext;
60896 +                                       continue;
60897 +                               }
60898 +                               psCurrentSwapChain->psNext = psSwapChain->psNext;
60899 +                               break;                          
60900 +                       }
60901 +               }
60902 +       }
60903 +
60904 +       
60905 +       PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
60906 +
60907 +
60908 +       eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
60909 +                                                                                                                       psSwapChain->hExtSwapChain);
60910 +
60911 +       if (eError != PVRSRV_OK)
60912 +       {
60913 +               PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
60914 +               return eError;
60915 +       }
60916 +
60917 +
60918 +       for(i=0; i<psSwapChain->ui32BufferCount; i++)
60919 +       {
60920 +               if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
60921 +               {
60922 +                       if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
60923 +                       {
60924 +                               PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
60925 +                       }
60926 +               }
60927 +       }
60928 +
60929 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
60930 +
60931 +
60932 +       return eError;
60933 +}
60934 +
60935 +
60936 +static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
60937 +{
60938 +       PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
60939 +       PVRSRV_ERROR eError = PVRSRV_OK;
60940 +
60941 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
60942 +
60943 +       if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) 
60944 +       {
60945 +               eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
60946 +       }
60947 +
60948 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
60949 +       return eError;
60950 +}
60951 +
60952 +static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
60953 +                                                                                                                IMG_UINT32 ui32SwapChainID)
60954 +{
60955 +       PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
60956 +
60957 +       for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; 
60958 +               psCurrentSwapChain; 
60959 +               psCurrentSwapChain = psCurrentSwapChain->psNext) 
60960 +       {
60961 +               if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
60962 +                       return psCurrentSwapChain;
60963 +       }
60964 +       return IMG_NULL;
60965 +}
60966 +
60967 +static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA       *psPerProc,
60968 +                                                                                                PVRSRV_DC_SWAPCHAIN            *psSwapChain, 
60969 +                                                                                                PVRSRV_DC_SWAPCHAIN_REF        **ppsSwapChainRef)
60970 +{
60971 +       PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
60972 +
60973 +       
60974 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
60975 +                                        sizeof(PVRSRV_DC_SWAPCHAIN_REF),
60976 +                                        (IMG_VOID **)&psSwapChainRef, IMG_NULL,
60977 +                                        "Display Class Swapchain Reference") != PVRSRV_OK)
60978 +       {
60979 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
60980 +               return  PVRSRV_ERROR_OUT_OF_MEMORY;
60981 +       }
60982 +       OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
60983 +
60984 +       
60985 +       psSwapChain->ui32RefCount++;
60986 +
60987 +       
60988 +       psSwapChainRef->psSwapChain = psSwapChain;
60989 +       psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
60990 +                                                                                                 RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
60991 +                                                                                                 psSwapChainRef,
60992 +                                                                                                 0,
60993 +                                                                                                 &DestroyDCSwapChainRefCallBack);
60994 +       *ppsSwapChainRef = psSwapChainRef;
60995 +
60996 +       return PVRSRV_OK;
60997 +}
60998 +
60999 +IMG_EXPORT
61000 +PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA        *psPerProc,
61001 +                                                                               IMG_HANDLE                              hDeviceKM,
61002 +                                                                               IMG_UINT32                              ui32Flags,
61003 +                                                                               DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
61004 +                                                                               DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
61005 +                                                                               IMG_UINT32                              ui32BufferCount,
61006 +                                                                               IMG_UINT32                              ui32OEMFlags,
61007 +                                                                               IMG_HANDLE                              *phSwapChainRef,
61008 +                                                                               IMG_UINT32                              *pui32SwapChainID)
61009 +{
61010 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61011 +       PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
61012 +       PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
61013 +       PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
61014 +       PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
61015 +       PVRSRV_ERROR eError;
61016 +       IMG_UINT32 i;
61017 +       DISPLAY_INFO sDisplayInfo;
61018 +
61019 +
61020 +       if(!hDeviceKM
61021 +       || !psDstSurfAttrib
61022 +       || !psSrcSurfAttrib
61023 +       || !phSwapChainRef
61024 +       || !pui32SwapChainID)
61025 +       {
61026 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters"));
61027 +               return PVRSRV_ERROR_INVALID_PARAMS;
61028 +       }
61029 +
61030 +       if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
61031 +       {
61032 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers"));
61033 +               return PVRSRV_ERROR_TOOMANYBUFFERS;
61034 +       }
61035 +
61036 +       if (ui32BufferCount < 2)
61037 +       {
61038 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers"));
61039 +               return PVRSRV_ERROR_TOO_FEW_BUFFERS;
61040 +       }
61041 +
61042 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61043 +
61044 +       if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
61045 +       {
61046 +               
61047 +               psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
61048 +               if( psSwapChain  ) 
61049 +               {       
61050 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: found query"));
61051 +                                          
61052 +                       eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
61053 +                                                                                                 psSwapChain, 
61054 +                                                                                                 &psSwapChainRef);
61055 +                       if( eError != PVRSRV_OK ) 
61056 +                       {
61057 +                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
61058 +                               return eError;
61059 +                       }
61060 +
61061 +                       *phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
61062 +                       return PVRSRV_OK;
61063 +               }
61064 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
61065 +               return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;          
61066 +       }
61067 +
61068 +       
61069 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
61070 +                                        sizeof(PVRSRV_DC_SWAPCHAIN),
61071 +                                        (IMG_VOID **)&psSwapChain, IMG_NULL,
61072 +                                        "Display Class Swapchain") != PVRSRV_OK)
61073 +       {
61074 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
61075 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
61076 +               goto ErrorExit;
61077 +       }
61078 +       OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
61079 +
61080 +
61081 +       eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
61082 +       if(eError != PVRSRV_OK)
61083 +       {
61084 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
61085 +               goto ErrorExit;
61086 +       }
61087 +
61088 +
61089 +       psSwapChain->psQueue = psQueue;
61090 +
61091 +
61092 +       for(i=0; i<ui32BufferCount; i++)
61093 +       {
61094 +               eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
61095 +                                                                               psDCInfo->hDevMemContext,
61096 +                                                                               &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
61097 +               if(eError != PVRSRV_OK)
61098 +               {
61099 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
61100 +                       goto ErrorExit;
61101 +               }
61102 +
61103 +               psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
61104 +
61105 +               
61106 +               psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
61107 +               psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
61108 +               psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
61109 +
61110 +
61111 +               psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
61112 +               psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
61113 +
61114 +
61115 +               apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
61116 +       }
61117 +
61118 +       psSwapChain->ui32BufferCount = ui32BufferCount;
61119 +       psSwapChain->psDCInfo = psDCInfo;
61120 +
61121 +       eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
61122 +       if (eError != PVRSRV_OK)
61123 +       {
61124 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
61125 +               return eError;
61126 +       }
61127 +       
61128 +       
61129 +       eError =  psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
61130 +                                                                                                               ui32Flags,
61131 +                                                                                                               psDstSurfAttrib,
61132 +                                                                                                               psSrcSurfAttrib,
61133 +                                                                                                               ui32BufferCount,
61134 +                                                                                                               apsSyncData,
61135 +                                                                                                               ui32OEMFlags,
61136 +                                                                                                               &psSwapChain->hExtSwapChain,
61137 +                                                                                                               &psSwapChain->ui32SwapChainID);
61138 +       if(eError != PVRSRV_OK)
61139 +       {
61140 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
61141 +               goto ErrorExit;
61142 +       }
61143 +
61144 +                          
61145 +       eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
61146 +                                                                                 psSwapChain, 
61147 +                                                                                 &psSwapChainRef);
61148 +       if( eError != PVRSRV_OK ) 
61149 +       {
61150 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
61151 +               goto ErrorExit;
61152 +       }
61153 +
61154 +       psSwapChain->ui32RefCount = 1;
61155 +       psSwapChain->ui32Flags = ui32Flags;
61156 +
61157 +       
61158 +       if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
61159 +       {
61160 +               if(! psDCInfo->psDCSwapChainShared ) 
61161 +               {
61162 +                       psDCInfo->psDCSwapChainShared = psSwapChain;
61163 +               } 
61164 +               else 
61165 +               {       
61166 +                       PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
61167 +                       psDCInfo->psDCSwapChainShared = psSwapChain;
61168 +                       psSwapChain->psNext = psOldHead;
61169 +               }
61170 +       }
61171 +
61172 +       
61173 +       *pui32SwapChainID = psSwapChain->ui32SwapChainID;
61174 +
61175 +       
61176 +       *phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
61177 +
61178 +       return eError;
61179 +
61180 +ErrorExit:
61181 +
61182 +       for(i=0; i<ui32BufferCount; i++)
61183 +       {
61184 +               if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
61185 +               {
61186 +                       if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
61187 +                       {
61188 +                               PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
61189 +                       }
61190 +               }
61191 +       }
61192 +
61193 +       if(psQueue)
61194 +       {
61195 +               PVRSRVDestroyCommandQueueKM(psQueue);
61196 +       }
61197 +
61198 +       if(psSwapChain)
61199 +       {
61200 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
61201 +
61202 +       }
61203 +
61204 +       return eError;
61205 +}
61206 +
61207 +IMG_EXPORT
61208 +PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE   hDeviceKM,
61209 +                                                                 IMG_HANDLE    hSwapChainRef,
61210 +                                                                 IMG_RECT              *psRect)
61211 +{
61212 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61213 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61214 +
61215 +       if(!hDeviceKM || !hSwapChainRef)
61216 +       {
61217 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
61218 +               return PVRSRV_ERROR_INVALID_PARAMS;
61219 +       }
61220 +
61221 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61222 +       psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
61223 +
61224 +       return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
61225 +                                                                                                       psSwapChain->hExtSwapChain,
61226 +                                                                                                       psRect);
61227 +}
61228 +
61229 +
61230 +IMG_EXPORT
61231 +PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE   hDeviceKM,
61232 +                                                                 IMG_HANDLE    hSwapChainRef,
61233 +                                                                 IMG_RECT              *psRect)
61234 +{
61235 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61236 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61237 +
61238 +       if(!hDeviceKM || !hSwapChainRef)
61239 +       {
61240 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
61241 +               return PVRSRV_ERROR_INVALID_PARAMS;
61242 +       }
61243 +
61244 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61245 +       psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
61246 +
61247 +       return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
61248 +                                                                                                       psSwapChain->hExtSwapChain,
61249 +                                                                                                       psRect);
61250 +}
61251 +
61252 +
61253 +IMG_EXPORT
61254 +PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE      hDeviceKM,
61255 +                                                                          IMG_HANDLE   hSwapChainRef,
61256 +                                                                          IMG_UINT32   ui32CKColour)
61257 +{
61258 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61259 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61260 +
61261 +       if(!hDeviceKM || !hSwapChainRef)
61262 +       {
61263 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
61264 +               return PVRSRV_ERROR_INVALID_PARAMS;
61265 +       }
61266 +
61267 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61268 +       psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
61269 +
61270 +       return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
61271 +                                                                                                               psSwapChain->hExtSwapChain,
61272 +                                                                                                               ui32CKColour);
61273 +}
61274 +
61275 +
61276 +IMG_EXPORT
61277 +PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE      hDeviceKM,
61278 +                                                                          IMG_HANDLE   hSwapChainRef,
61279 +                                                                          IMG_UINT32   ui32CKColour)
61280 +{
61281 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61282 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61283 +
61284 +       if(!hDeviceKM || !hSwapChainRef)
61285 +       {
61286 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
61287 +               return PVRSRV_ERROR_INVALID_PARAMS;
61288 +       }
61289 +
61290 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61291 +       psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
61292 +
61293 +       return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
61294 +                                                                                                               psSwapChain->hExtSwapChain,
61295 +                                                                                                               ui32CKColour);
61296 +}
61297 +
61298 +
61299 +IMG_EXPORT
61300 +PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE   hDeviceKM,
61301 +                                                                 IMG_HANDLE    hSwapChainRef,
61302 +                                                                 IMG_UINT32    *pui32BufferCount,
61303 +                                                                 IMG_HANDLE    *phBuffer)
61304 +{
61305 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61306 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61307 +       IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
61308 +       PVRSRV_ERROR eError;
61309 +       IMG_UINT32 i;
61310 +
61311 +       if(!hDeviceKM || !hSwapChainRef || !phBuffer)
61312 +       {
61313 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
61314 +               return PVRSRV_ERROR_INVALID_PARAMS;
61315 +       }
61316 +
61317 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61318 +       psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
61319 +
61320 +
61321 +       eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
61322 +                                                                                                       psSwapChain->hExtSwapChain,
61323 +                                                                                                       pui32BufferCount,
61324 +                                                                                                       ahExtBuffer);
61325 +
61326 +       PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
61327 +
61328 +
61329 +
61330 +
61331 +       for(i=0; i<*pui32BufferCount; i++)
61332 +       {
61333 +               psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
61334 +               phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
61335 +       }
61336 +
61337 +       return eError;
61338 +}
61339 +
61340 +IMG_EXPORT
61341 +PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
61342 +                                                                       IMG_HANDLE      hBuffer,
61343 +                                                                       IMG_UINT32      ui32SwapInterval,
61344 +                                                                       IMG_HANDLE      hPrivateTag,
61345 +                                                                       IMG_UINT32      ui32ClipRectCount,
61346 +                                                                       IMG_RECT        *psClipRect)
61347 +{
61348 +       PVRSRV_ERROR eError;
61349 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61350 +       PVRSRV_DC_BUFFER *psBuffer;
61351 +       PVRSRV_QUEUE_INFO *psQueue;
61352 +       DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
61353 +       IMG_UINT32 i;
61354 +       IMG_UINT32 ui32NumSrcSyncs = 1;
61355 +       PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
61356 +       PVRSRV_COMMAND *psCommand;
61357 +
61358 +       if(!hDeviceKM || !hBuffer || !psClipRect)
61359 +       {
61360 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
61361 +               return PVRSRV_ERROR_INVALID_PARAMS;
61362 +       }
61363 +
61364 +#if defined(SUPPORT_LMA)
61365 +       eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
61366 +       if(eError != PVRSRV_OK)
61367 +       {
61368 +               return eError;
61369 +       }
61370 +#endif
61371 +
61372 +       psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
61373 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61374 +
61375 +
61376 +       psQueue = psBuffer->psSwapChain->psQueue;
61377 +
61378 +
61379 +       apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
61380 +       
61381 +
61382 +
61383 +       if(psBuffer->psSwapChain->psLastFlipBuffer &&
61384 +               psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
61385 +       {
61386 +               apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
61387 +               
61388 +
61389 +
61390 +               ui32NumSrcSyncs++;
61391 +       }
61392 +
61393 +
61394 +       eError = PVRSRVInsertCommandKM (psQueue,
61395 +                                                                       &psCommand,
61396 +                                                                       psDCInfo->ui32DeviceID,
61397 +                                                                       DC_FLIP_COMMAND,
61398 +                                                                       0,
61399 +                                                                       IMG_NULL,
61400 +                                                                       ui32NumSrcSyncs,
61401 +                                                                       apsSrcSync,
61402 +                                                                       sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount));
61403 +       if(eError != PVRSRV_OK)
61404 +       {
61405 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
61406 +               goto Exit;
61407 +       }
61408 +
61409 +
61410 +       psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
61411 +
61412 +
61413 +       psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
61414 +
61415 +
61416 +       psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
61417 +
61418 +
61419 +       psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
61420 +
61421 +
61422 +       psFlipCmd->hPrivateTag = hPrivateTag;
61423 +
61424 +
61425 +       psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
61426 +
61427 +       psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND));
61428 +
61429 +       for(i=0; i<ui32ClipRectCount; i++)
61430 +       {
61431 +               psFlipCmd->psClipRect[i] = psClipRect[i];
61432 +       }
61433 +
61434 +
61435 +       psFlipCmd->ui32SwapInterval = ui32SwapInterval;
61436 +
61437 +
61438 +       eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
61439 +       if (eError != PVRSRV_OK)
61440 +       {
61441 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
61442 +               goto Exit;
61443 +       }
61444 +
61445 +
61446 +
61447 +
61448 +
61449 +
61450 +
61451 +
61452 +
61453 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
61454 +       {
61455 +               if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED)
61456 +               {
61457 +                       goto ProcessedQueues;
61458 +               }
61459 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
61460 +       } END_LOOP_UNTIL_TIMEOUT();
61461 +
61462 +       PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to process queues"));
61463 +
61464 +       eError = PVRSRV_ERROR_GENERIC;
61465 +       goto Exit;
61466 +
61467 +ProcessedQueues:
61468 +
61469 +       psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
61470 +
61471 +Exit:
61472 +
61473 +       if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
61474 +       {
61475 +               eError = PVRSRV_ERROR_RETRY;
61476 +       }
61477 +
61478 +#if defined(SUPPORT_LMA)
61479 +       PVRSRVPowerUnlock(KERNEL_ID);
61480 +#endif
61481 +       return eError;
61482 +}
61483 +
61484 +
61485 +IMG_EXPORT
61486 +PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
61487 +                                                                       IMG_HANDLE      hSwapChainRef)
61488 +{
61489 +       PVRSRV_ERROR eError;
61490 +       PVRSRV_QUEUE_INFO *psQueue;
61491 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61492 +       PVRSRV_DC_SWAPCHAIN *psSwapChain;
61493 +       PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
61494 +       DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
61495 +       IMG_UINT32 ui32NumSrcSyncs = 1;
61496 +       PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
61497 +       PVRSRV_COMMAND *psCommand;
61498 +
61499 +       if(!hDeviceKM || !hSwapChainRef)
61500 +       {
61501 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
61502 +               return PVRSRV_ERROR_INVALID_PARAMS;
61503 +       }
61504 +
61505 +#if defined(SUPPORT_LMA)
61506 +       eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
61507 +       if(eError != PVRSRV_OK)
61508 +       {
61509 +               return eError;
61510 +       }
61511 +#endif
61512 +
61513 +       psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
61514 +       psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
61515 +       psSwapChain = psSwapChainRef->psSwapChain;
61516 +
61517 +       
61518 +       psQueue = psSwapChain->psQueue;
61519 +
61520 +
61521 +       apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
61522 +       
61523 +
61524 +
61525 +       if(psSwapChain->psLastFlipBuffer)
61526 +       {
61527 +
61528 +               if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
61529 +               {
61530 +                       apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
61531 +                       
61532 +
61533 +
61534 +                       ui32NumSrcSyncs++;
61535 +               }
61536 +       }
61537 +
61538 +
61539 +       eError = PVRSRVInsertCommandKM (psQueue,
61540 +                                                                       &psCommand,
61541 +                                                                       psDCInfo->ui32DeviceID,
61542 +                                                                       DC_FLIP_COMMAND,
61543 +                                                                       0,
61544 +                                                                       IMG_NULL,
61545 +                                                                       ui32NumSrcSyncs,
61546 +                                                                       apsSrcSync,
61547 +                                                                       sizeof(DISPLAYCLASS_FLIP_COMMAND));
61548 +       if(eError != PVRSRV_OK)
61549 +       {
61550 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
61551 +               goto Exit;
61552 +       }
61553 +
61554 +
61555 +       psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
61556 +
61557 +
61558 +       psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
61559 +
61560 +
61561 +       psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
61562 +
61563 +
61564 +       psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
61565 +
61566 +
61567 +       psFlipCmd->hPrivateTag = IMG_NULL;
61568 +
61569 +
61570 +       psFlipCmd->ui32ClipRectCount = 0;
61571 +
61572 +       psFlipCmd->ui32SwapInterval = 1;
61573 +
61574 +
61575 +       eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
61576 +       if (eError != PVRSRV_OK)
61577 +       {
61578 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
61579 +               goto Exit;
61580 +       }
61581 +
61582 +
61583 +
61584 +
61585 +
61586 +
61587 +
61588 +
61589 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
61590 +       {
61591 +               if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED)
61592 +               {
61593 +                       goto ProcessedQueues;
61594 +               }
61595 +
61596 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
61597 +       } END_LOOP_UNTIL_TIMEOUT();
61598 +
61599 +       PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues"));
61600 +       eError = PVRSRV_ERROR_GENERIC;
61601 +       goto Exit;
61602 +
61603 +ProcessedQueues:
61604 +
61605 +       psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
61606 +
61607 +       eError = PVRSRV_OK;
61608 +
61609 +Exit:
61610 +
61611 +       if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
61612 +       {
61613 +               eError = PVRSRV_ERROR_RETRY;
61614 +       }
61615 +
61616 +#if defined(SUPPORT_LMA)
61617 +       PVRSRVPowerUnlock(KERNEL_ID);
61618 +#endif
61619 +       return eError;
61620 +}
61621 +
61622 +
61623 +PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER   pfnISRHandler,
61624 +                                                                                        IMG_VOID                       *pvISRHandlerData,
61625 +                                                                                        IMG_UINT32                     ui32ISRSourceMask,
61626 +                                                                                        IMG_UINT32                     ui32DeviceID)
61627 +{
61628 +       SYS_DATA                        *psSysData;
61629 +       PVRSRV_DEVICE_NODE      *psDevNode;
61630 +
61631 +       PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
61632 +
61633 +       SysAcquireData(&psSysData);
61634 +
61635 +
61636 +       psDevNode = (PVRSRV_DEVICE_NODE*)
61637 +                               List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
61638 +                                                                                               MatchDeviceKM_AnyVaCb,
61639 +                                                                                               ui32DeviceID,
61640 +                                                                                               IMG_TRUE);
61641 +
61642 +       if (psDevNode == IMG_NULL)
61643 +       {
61644 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
61645 +               PVR_DBG_BREAK;
61646 +               return PVRSRV_ERROR_GENERIC;
61647 +       }
61648 +
61649 +
61650 +       psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
61651 +
61652 +
61653 +       psDevNode->pfnDeviceISR = pfnISRHandler;
61654 +
61655 +       return PVRSRV_OK;
61656 +}
61657 +
61658 +IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
61659 +{
61660 +       PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
61661 +       IMG_UINT32 ui32State;
61662 +       ui32State = va_arg(va, IMG_UINT32);
61663 +
61664 +       if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
61665 +       {
61666 +               psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
61667 +               if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice)
61668 +               {
61669 +                       psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State);
61670 +               }
61671 +       }
61672 +}
61673 +
61674 +
61675 +IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
61676 +{
61677 +       SYS_DATA                                        *psSysData;
61678 +
61679 +       SysAcquireData(&psSysData);
61680 +
61681 +       List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
61682 +                                                                               PVRSRVSetDCState_ForEachVaCb,
61683 +                                                                               ui32State);
61684 +}
61685 +
61686 +
61687 +IMG_EXPORT
61688 +IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
61689 +{
61690 +       psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
61691 +       psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM;
61692 +       psJTable->pfnPVRSRVRemoveDCDevice = PVRSRVRemoveDCDeviceKM;
61693 +       psJTable->pfnPVRSRVOEMFunction = SysOEMFunction;
61694 +       psJTable->pfnPVRSRVRegisterCmdProcList = PVRSRVRegisterCmdProcListKM;
61695 +       psJTable->pfnPVRSRVRemoveCmdProcList = PVRSRVRemoveCmdProcListKM;
61696 +#if defined(SUPPORT_MISR_IN_THREAD)
61697 +        psJTable->pfnPVRSRVCmdComplete = OSVSyncMISR;
61698 +#else
61699 +        psJTable->pfnPVRSRVCmdComplete = PVRSRVCommandCompleteKM;
61700 +#endif
61701 +       psJTable->pfnPVRSRVRegisterSystemISRHandler = PVRSRVRegisterSystemISRHandler;
61702 +       psJTable->pfnPVRSRVRegisterPowerDevice = PVRSRVRegisterPowerDevice;
61703 +
61704 +       return IMG_TRUE;
61705 +}
61706 +
61707 +
61708 +
61709 +IMG_EXPORT
61710 +PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM,
61711 +                                                                       IMG_BOOL        bResManCallback)
61712 +{
61713 +       PVRSRV_ERROR eError;
61714 +       PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
61715 +
61716 +       PVR_UNREFERENCED_PARAMETER(bResManCallback);
61717 +
61718 +       psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
61719 +
61720 +
61721 +       eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem);
61722 +
61723 +       return eError;
61724 +}
61725 +
61726 +
61727 +static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID            pvParam,
61728 +                                                                                 IMG_UINT32    ui32Param)
61729 +{
61730 +       PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
61731 +       PVRSRV_BUFFERCLASS_INFO *psBCInfo;
61732 +
61733 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
61734 +
61735 +       psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
61736 +       psBCInfo = psBCPerContextInfo->psBCInfo;
61737 +
61738 +       psBCInfo->ui32RefCount--;
61739 +       if(psBCInfo->ui32RefCount == 0)
61740 +       {
61741 +               IMG_UINT32 i;
61742 +
61743 +
61744 +               psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice);
61745 +
61746 +
61747 +               for(i=0; i<psBCInfo->ui32BufferCount; i++)
61748 +               {
61749 +                       if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
61750 +                       {
61751 +                               if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
61752 +                               {
61753 +                                       PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
61754 +                               }
61755 +                       }
61756 +               }
61757 +
61758 +
61759 +               if(psBCInfo->psBuffer)
61760 +               {
61761 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
61762 +                       psBCInfo->psBuffer = IMG_NULL;
61763 +               }
61764 +       }
61765 +
61766 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
61767 +
61768 +
61769 +       return PVRSRV_OK;
61770 +}
61771 +
61772 +
61773 +IMG_EXPORT
61774 +PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA     *psPerProc,
61775 +                                                                  IMG_UINT32                           ui32DeviceID,
61776 +                                                                  IMG_HANDLE                           hDevCookie,
61777 +                                                                  IMG_HANDLE                           *phDeviceKM)
61778 +{
61779 +       PVRSRV_BUFFERCLASS_INFO *psBCInfo;
61780 +       PVRSRV_BUFFERCLASS_PERCONTEXT_INFO      *psBCPerContextInfo;
61781 +       PVRSRV_DEVICE_NODE              *psDeviceNode;
61782 +       SYS_DATA                                *psSysData;
61783 +       IMG_UINT32                              i;
61784 +       PVRSRV_ERROR                    eError;
61785 +
61786 +       if(!phDeviceKM || !hDevCookie)
61787 +       {
61788 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
61789 +               return PVRSRV_ERROR_GENERIC;
61790 +       }
61791 +
61792 +       SysAcquireData(&psSysData);
61793 +
61794 +
61795 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)
61796 +                       List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
61797 +                                                                                  MatchDeviceKM_AnyVaCb,
61798 +                                                                                  ui32DeviceID,
61799 +                                                                                  IMG_FALSE,
61800 +                                                                                  PVRSRV_DEVICE_CLASS_BUFFER);
61801 +       if (!psDeviceNode)
61802 +       {
61803 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
61804 +               return PVRSRV_ERROR_GENERIC;
61805 +       }
61806 +       psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
61807 +
61808 +
61809 +
61810 +
61811 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
61812 +                                 sizeof(*psBCPerContextInfo),
61813 +                                 (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
61814 +                                 "Buffer Class per Context Info") != PVRSRV_OK)
61815 +       {
61816 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
61817 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
61818 +       }
61819 +       OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
61820 +
61821 +       if(psBCInfo->ui32RefCount++ == 0)
61822 +       {
61823 +               BUFFER_INFO sBufferInfo;
61824 +
61825 +               psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
61826 +
61827 +
61828 +               psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
61829 +
61830 +
61831 +               eError = psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->hExtDevice);
61832 +               if(eError != PVRSRV_OK)
61833 +               {
61834 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
61835 +                       return eError;
61836 +               }
61837 +
61838 +
61839 +               eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
61840 +               if(eError != PVRSRV_OK)
61841 +               {
61842 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
61843 +                       return eError;
61844 +               }
61845 +
61846 +
61847 +               psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
61848 +
61849 +
61850 +
61851 +               eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
61852 +                                                         sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
61853 +                                                         (IMG_VOID **)&psBCInfo->psBuffer,
61854 +                                                         IMG_NULL,
61855 +                                                         "Array of Buffer Class Buffer");
61856 +               if(eError != PVRSRV_OK)
61857 +               {
61858 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
61859 +                       return eError;
61860 +               }
61861 +               OSMemSet (psBCInfo->psBuffer,
61862 +                                       0,
61863 +                                       sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
61864 +
61865 +               for(i=0; i<psBCInfo->ui32BufferCount; i++)
61866 +               {
61867 +
61868 +                       eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
61869 +                                                                               psBCInfo->hDevMemContext,
61870 +                                                                               &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
61871 +                       if(eError != PVRSRV_OK)
61872 +                       {
61873 +                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
61874 +                               goto ErrorExit;
61875 +                       }
61876 +                       
61877 +                       psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
61878 +                       
61879 +                       
61880 +
61881 +
61882 +                       eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
61883 +                                                                                                                       i,
61884 +                                                                                                                       psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
61885 +                                                                                                                       &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
61886 +                       if(eError != PVRSRV_OK)
61887 +                       {
61888 +                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
61889 +                               goto ErrorExit;
61890 +                       }
61891 +
61892 +
61893 +                       psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
61894 +                       psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
61895 +                       psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
61896 +               }
61897 +       }
61898 +
61899 +       psBCPerContextInfo->psBCInfo = psBCInfo;
61900 +       psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
61901 +                                                                                                        RESMAN_TYPE_BUFFERCLASS_DEVICE,
61902 +                                                                                                        psBCPerContextInfo,
61903 +                                                                                                        0,
61904 +                                                                                                        CloseBCDeviceCallBack);
61905 +
61906 +
61907 +       *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
61908 +
61909 +       return PVRSRV_OK;
61910 +
61911 +ErrorExit:
61912 +
61913 +
61914 +       for(i=0; i<psBCInfo->ui32BufferCount; i++)
61915 +       {
61916 +               if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
61917 +               {
61918 +                       if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
61919 +                       {
61920 +                               PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
61921 +                       }
61922 +               }
61923 +       }
61924 +
61925 +
61926 +       if(psBCInfo->psBuffer)
61927 +       {
61928 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
61929 +               psBCInfo->psBuffer = IMG_NULL;
61930 +       }
61931 +
61932 +       return eError;
61933 +}
61934 +
61935 +
61936 +
61937 +
61938 +IMG_EXPORT
61939 +PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM,
61940 +                                                               BUFFER_INFO *psBufferInfo)
61941 +{
61942 +       PVRSRV_BUFFERCLASS_INFO *psBCInfo;
61943 +       PVRSRV_ERROR                    eError;
61944 +
61945 +       if(!hDeviceKM || !psBufferInfo)
61946 +       {
61947 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters"));
61948 +               return PVRSRV_ERROR_INVALID_PARAMS;
61949 +       }
61950 +
61951 +       psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
61952 +
61953 +       eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo);
61954 +
61955 +       if(eError != PVRSRV_OK)
61956 +       {
61957 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info"));
61958 +               return eError;
61959 +       }
61960 +
61961 +       return PVRSRV_OK;
61962 +}
61963 +
61964 +
61965 +IMG_EXPORT
61966 +PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM,
61967 +                                                                 IMG_UINT32 ui32BufferIndex,
61968 +                                                                 IMG_HANDLE *phBuffer)
61969 +{
61970 +       PVRSRV_BUFFERCLASS_INFO *psBCInfo;
61971 +
61972 +       if(!hDeviceKM || !phBuffer)
61973 +       {
61974 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters"));
61975 +               return PVRSRV_ERROR_INVALID_PARAMS;
61976 +       }
61977 +
61978 +       psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
61979 +
61980 +       if(ui32BufferIndex < psBCInfo->ui32BufferCount)
61981 +       {
61982 +               *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex];
61983 +       }
61984 +       else
61985 +       {
61986 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount));
61987 +               return PVRSRV_ERROR_INVALID_PARAMS;
61988 +       }
61989 +
61990 +       return PVRSRV_OK;
61991 +}
61992 +
61993 +
61994 +IMG_EXPORT
61995 +IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
61996 +{
61997 +       psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
61998 +
61999 +       psJTable->pfnPVRSRVRegisterBCDevice = PVRSRVRegisterBCDeviceKM;
62000 +       psJTable->pfnPVRSRVRemoveBCDevice = PVRSRVRemoveBCDeviceKM;
62001 +
62002 +       return IMG_TRUE;
62003 +}
62004 +
62005 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/devicemem.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/devicemem.c
62006 new file mode 100644
62007 index 0000000..ed60870
62008 --- /dev/null
62009 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/devicemem.c
62010 @@ -0,0 +1,1448 @@
62011 +/**********************************************************************
62012 + *
62013 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
62014 + *
62015 + * This program is free software; you can redistribute it and/or modify it
62016 + * under the terms and conditions of the GNU General Public License,
62017 + * version 2, as published by the Free Software Foundation.
62018 + *
62019 + * This program is distributed in the hope it will be useful but, except
62020 + * as otherwise stated in writing, without any warranty; without even the
62021 + * implied warranty of merchantability or fitness for a particular purpose.
62022 + * See the GNU General Public License for more details.
62023 + *
62024 + * You should have received a copy of the GNU General Public License along with
62025 + * this program; if not, write to the Free Software Foundation, Inc.,
62026 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
62027 + *
62028 + * The full GNU General Public License is included in this distribution in
62029 + * the file called "COPYING".
62030 + *
62031 + * Contact Information:
62032 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
62033 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
62034 + *
62035 + ******************************************************************************/
62036 +
62037 +#include <stddef.h>
62038 +
62039 +#include "services_headers.h"
62040 +#include "buffer_manager.h"
62041 +#include "pdump_km.h"
62042 +#include "pvr_bridge_km.h"
62043 +
62044 +static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE          hDevCookie,
62045 +                                                                       IMG_HANDLE              hDevMemHeap,
62046 +                                                                       IMG_UINT32              ui32Flags,
62047 +                                                                       IMG_SIZE_T              ui32Size,
62048 +                                                                       IMG_SIZE_T              ui32Alignment,
62049 +                                                                       PVRSRV_KERNEL_MEM_INFO  **ppsMemInfo);
62050 +
62051 +typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
62052 +{
62053 +
62054 +       PVRSRV_KERNEL_MEM_INFO  *psMemInfo;
62055 +
62056 +       PVRSRV_KERNEL_MEM_INFO  *psSrcMemInfo;
62057 +} RESMAN_MAP_DEVICE_MEM_DATA;
62058 +
62059 +
62060 +IMG_EXPORT
62061 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
62062 +                                                                                                       PVRSRV_HEAP_INFO *psHeapInfo)
62063 +{
62064 +       PVRSRV_DEVICE_NODE *psDeviceNode;
62065 +       IMG_UINT32 ui32HeapCount;
62066 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
62067 +       IMG_UINT32 i;
62068 +
62069 +       if (hDevCookie == IMG_NULL)
62070 +       {
62071 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"));
62072 +               PVR_DBG_BREAK;
62073 +               return PVRSRV_ERROR_INVALID_PARAMS;
62074 +       }
62075 +
62076 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
62077 +
62078 +
62079 +       ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
62080 +       psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
62081 +
62082 +
62083 +       PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
62084 +
62085 +
62086 +       for(i=0; i<ui32HeapCount; i++)
62087 +       {
62088 +
62089 +               psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
62090 +               psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
62091 +               psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
62092 +               psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
62093 +               psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
62094 +       }
62095 +
62096 +       for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
62097 +       {
62098 +               OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
62099 +               psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
62100 +       }
62101 +
62102 +       return PVRSRV_OK;
62103 +}
62104 +
62105 +IMG_EXPORT
62106 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE                                    hDevCookie,
62107 +                                                                                                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
62108 +                                                                                                                IMG_HANDLE                             *phDevMemContext,
62109 +                                                                                                                IMG_UINT32                             *pui32ClientHeapCount,
62110 +                                                                                                                PVRSRV_HEAP_INFO                       *psHeapInfo,
62111 +                                                                                                                IMG_BOOL                                       *pbCreated,
62112 +                                                                                                                IMG_BOOL                                       *pbShared)
62113 +{
62114 +       PVRSRV_DEVICE_NODE *psDeviceNode;
62115 +       IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
62116 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
62117 +       IMG_HANDLE hDevMemContext;
62118 +       IMG_HANDLE hDevMemHeap;
62119 +       IMG_DEV_PHYADDR sPDDevPAddr;
62120 +       IMG_UINT32 i;
62121 +
62122 +#if !defined(PVR_SECURE_HANDLES)
62123 +       PVR_UNREFERENCED_PARAMETER(pbShared);
62124 +#endif
62125 +
62126 +       if (hDevCookie == IMG_NULL)
62127 +       {
62128 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"));
62129 +               PVR_DBG_BREAK;
62130 +               return PVRSRV_ERROR_INVALID_PARAMS;
62131 +       }
62132 +
62133 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
62134 +
62135 +
62136 +
62137 +       ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
62138 +       psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
62139 +
62140 +
62141 +
62142 +       PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
62143 +
62144 +
62145 +
62146 +       hDevMemContext = BM_CreateContext(psDeviceNode,
62147 +                                                                         &sPDDevPAddr,
62148 +                                                                         psPerProc,
62149 +                                                                         pbCreated);
62150 +       if (hDevMemContext == IMG_NULL)
62151 +       {
62152 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"));
62153 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
62154 +       }
62155 +
62156 +
62157 +       for(i=0; i<ui32HeapCount; i++)
62158 +       {
62159 +               switch(psDeviceMemoryHeap[i].DevMemHeapType)
62160 +               {
62161 +                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
62162 +                       {
62163 +
62164 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
62165 +                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
62166 +                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
62167 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
62168 +                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
62169 +#if defined(PVR_SECURE_HANDLES)
62170 +                               pbShared[ui32ClientHeapCount] = IMG_TRUE;
62171 +#endif
62172 +                               ui32ClientHeapCount++;
62173 +                               break;
62174 +                       }
62175 +                       case DEVICE_MEMORY_HEAP_PERCONTEXT:
62176 +                       {
62177 +                               hDevMemHeap = BM_CreateHeap(hDevMemContext,
62178 +                                                                                       &psDeviceMemoryHeap[i]);
62179 +
62180 +
62181 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
62182 +                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
62183 +                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
62184 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
62185 +                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
62186 +#if defined(PVR_SECURE_HANDLES)
62187 +                               pbShared[ui32ClientHeapCount] = IMG_FALSE;
62188 +#endif
62189 +
62190 +                               ui32ClientHeapCount++;
62191 +                               break;
62192 +                       }
62193 +               }
62194 +       }
62195 +
62196 +
62197 +       *pui32ClientHeapCount = ui32ClientHeapCount;
62198 +       *phDevMemContext = hDevMemContext;
62199 +
62200 +       return PVRSRV_OK;
62201 +}
62202 +
62203 +IMG_EXPORT
62204 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
62205 +                                                                                                                 IMG_HANDLE hDevMemContext,
62206 +                                                                                                                 IMG_BOOL *pbDestroyed)
62207 +{
62208 +       PVR_UNREFERENCED_PARAMETER(hDevCookie);
62209 +
62210 +       return BM_DestroyContext(hDevMemContext, pbDestroyed);
62211 +}
62212 +
62213 +
62214 +
62215 +
62216 +IMG_EXPORT
62217 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE                                      hDevCookie,
62218 +                                                                                                                IMG_HANDLE                             hDevMemContext,
62219 +                                                                                                                IMG_UINT32                             *pui32ClientHeapCount,
62220 +                                                                                                                PVRSRV_HEAP_INFO                       *psHeapInfo,
62221 +                                                                                                                IMG_BOOL                                       *pbShared)
62222 +{
62223 +       PVRSRV_DEVICE_NODE *psDeviceNode;
62224 +       IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
62225 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
62226 +       IMG_HANDLE hDevMemHeap;
62227 +       IMG_UINT32 i;
62228 +
62229 +#if !defined(PVR_SECURE_HANDLES)
62230 +       PVR_UNREFERENCED_PARAMETER(pbShared);
62231 +#endif
62232 +
62233 +       if (hDevCookie == IMG_NULL)
62234 +       {
62235 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"));
62236 +               PVR_DBG_BREAK;
62237 +               return PVRSRV_ERROR_INVALID_PARAMS;
62238 +       }
62239 +
62240 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
62241 +
62242 +
62243 +
62244 +       ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
62245 +       psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
62246 +
62247 +
62248 +
62249 +       PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
62250 +
62251 +
62252 +       for(i=0; i<ui32HeapCount; i++)
62253 +       {
62254 +               switch(psDeviceMemoryHeap[i].DevMemHeapType)
62255 +               {
62256 +                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
62257 +                       {
62258 +
62259 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
62260 +                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
62261 +                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
62262 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
62263 +                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
62264 +#if defined(PVR_SECURE_HANDLES)
62265 +                               pbShared[ui32ClientHeapCount] = IMG_TRUE;
62266 +#endif
62267 +                               ui32ClientHeapCount++;
62268 +                               break;
62269 +                       }
62270 +                       case DEVICE_MEMORY_HEAP_PERCONTEXT:
62271 +                       {
62272 +                               hDevMemHeap = BM_CreateHeap(hDevMemContext,
62273 +                                                                                       &psDeviceMemoryHeap[i]);
62274 +
62275 +
62276 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
62277 +                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
62278 +                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
62279 +                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
62280 +                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
62281 +#if defined(PVR_SECURE_HANDLES)
62282 +                               pbShared[ui32ClientHeapCount] = IMG_FALSE;
62283 +#endif
62284 +
62285 +                               ui32ClientHeapCount++;
62286 +                               break;
62287 +                       }
62288 +               }
62289 +       }
62290 +
62291 +
62292 +       *pui32ClientHeapCount = ui32ClientHeapCount;
62293 +
62294 +       return PVRSRV_OK;
62295 +}
62296 +
62297 +
62298 +static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE          hDevCookie,
62299 +                                                                       IMG_HANDLE              hDevMemHeap,
62300 +                                                                       IMG_UINT32              ui32Flags,
62301 +                                                                       IMG_SIZE_T              ui32Size,
62302 +                                                                       IMG_SIZE_T              ui32Alignment,
62303 +                                                                       PVRSRV_KERNEL_MEM_INFO  **ppsMemInfo)
62304 +{
62305 +       PVRSRV_KERNEL_MEM_INFO  *psMemInfo;
62306 +       BM_HANDLE               hBuffer;
62307 +
62308 +       PVRSRV_MEMBLK   *psMemBlock;
62309 +       IMG_BOOL                bBMError;
62310 +
62311 +       PVR_UNREFERENCED_PARAMETER(hDevCookie);
62312 +
62313 +       *ppsMemInfo = IMG_NULL;
62314 +
62315 +       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
62316 +                                       sizeof(PVRSRV_KERNEL_MEM_INFO),
62317 +                                       (IMG_VOID **)&psMemInfo, IMG_NULL,
62318 +                                       "Kernel Memory Info") != PVRSRV_OK)
62319 +       {
62320 +               PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
62321 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
62322 +       }
62323 +
62324 +       OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
62325 +
62326 +       psMemBlock = &(psMemInfo->sMemBlk);
62327 +
62328 +
62329 +       psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
62330 +
62331 +       bBMError = BM_Alloc (hDevMemHeap,
62332 +                                                       IMG_NULL,
62333 +                                                       ui32Size,
62334 +                                                       &psMemInfo->ui32Flags,
62335 +                                                       IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
62336 +                                                       &hBuffer);
62337 +
62338 +       if (!bBMError)
62339 +       {
62340 +               PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
62341 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
62342 +
62343 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
62344 +       }
62345 +
62346 +
62347 +       psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
62348 +       psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
62349 +
62350 +
62351 +       psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
62352 +
62353 +
62354 +
62355 +       psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
62356 +
62357 +       psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
62358 +
62359 +       psMemInfo->ui32AllocSize = ui32Size;
62360 +
62361 +
62362 +       psMemInfo->pvSysBackupBuffer = IMG_NULL;
62363 +
62364 +
62365 +       *ppsMemInfo = psMemInfo;
62366 +
62367 +
62368 +       return (PVRSRV_OK);
62369 +}
62370 +
62371 +
62372 +static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
62373 +{
62374 +       BM_HANDLE               hBuffer;
62375 +
62376 +       if (!psMemInfo)
62377 +       {
62378 +               return PVRSRV_ERROR_INVALID_PARAMS;
62379 +       }
62380 +
62381 +       hBuffer = psMemInfo->sMemBlk.hBuffer;
62382 +
62383 +
62384 +       BM_Free(hBuffer, psMemInfo->ui32Flags);
62385 +
62386 +       if(psMemInfo->pvSysBackupBuffer)
62387 +       {
62388 +
62389 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
62390 +               psMemInfo->pvSysBackupBuffer = IMG_NULL;
62391 +       }
62392 +
62393 +       OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
62394 +
62395 +
62396 +       return(PVRSRV_OK);
62397 +}
62398 +
62399 +
62400 +IMG_EXPORT
62401 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE                                     hDevCookie,
62402 +                                                                                               IMG_HANDLE                                      hDevMemContext,
62403 +                                                                                               PVRSRV_KERNEL_SYNC_INFO         **ppsKernelSyncInfo)
62404 +{
62405 +       IMG_HANDLE hSyncDevMemHeap;
62406 +       DEVICE_MEMORY_INFO *psDevMemoryInfo;
62407 +       BM_CONTEXT *pBMContext;
62408 +       PVRSRV_ERROR eError;
62409 +       PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
62410 +       PVRSRV_SYNC_DATA *psSyncData;
62411 +
62412 +       eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
62413 +                                               sizeof(PVRSRV_KERNEL_SYNC_INFO),
62414 +                                               (IMG_VOID **)&psKernelSyncInfo, IMG_NULL,
62415 +                                               "Kernel Synchronization Info");
62416 +       if (eError != PVRSRV_OK)
62417 +       {
62418 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
62419 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
62420 +       }
62421 +
62422 +       psKernelSyncInfo->ui32RefCount = 0;
62423 +
62424 +       
62425 +       pBMContext = (BM_CONTEXT*)hDevMemContext;
62426 +       psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
62427 +
62428 +
62429 +       hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
62430 +
62431 +
62432 +
62433 +
62434 +       eError = AllocDeviceMem(hDevCookie,
62435 +                                                       hSyncDevMemHeap,
62436 +                                                       PVRSRV_MEM_CACHE_CONSISTENT,
62437 +                                                       sizeof(PVRSRV_SYNC_DATA),
62438 +                                                       sizeof(IMG_UINT32),
62439 +                                                       &psKernelSyncInfo->psSyncDataMemInfoKM);
62440 +
62441 +       if (eError != PVRSRV_OK)
62442 +       {
62443 +
62444 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
62445 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
62446 +
62447 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
62448 +       }
62449 +
62450 +
62451 +       psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
62452 +       psSyncData = psKernelSyncInfo->psSyncData;
62453 +
62454 +       psSyncData->ui32WriteOpsPending = 0;
62455 +       psSyncData->ui32WriteOpsComplete = 0;
62456 +       psSyncData->ui32ReadOpsPending = 0;
62457 +       psSyncData->ui32ReadOpsComplete = 0;
62458 +       psSyncData->ui32LastOpDumpVal = 0;
62459 +       psSyncData->ui32LastReadOpDumpVal = 0;
62460 +
62461 +#if defined(PDUMP)
62462 +       PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
62463 +                       psKernelSyncInfo->psSyncDataMemInfoKM,
62464 +                       0,
62465 +                       psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize,
62466 +                       PDUMP_FLAGS_CONTINUOUS,
62467 +                       MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
62468 +#endif
62469 +
62470 +       psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
62471 +       psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
62472 +
62473 +
62474 +       psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
62475 +
62476 +
62477 +       psKernelSyncInfo->hResItem = IMG_NULL;
62478 +
62479 +
62480 +       *ppsKernelSyncInfo = psKernelSyncInfo;
62481 +
62482 +       return PVRSRV_OK;
62483 +}
62484 +
62485 +
62486 +IMG_EXPORT
62487 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
62488 +{
62489 +       PVRSRV_ERROR eError;
62490 +       
62491 +       if (psKernelSyncInfo->ui32RefCount != 0)
62492 +       {
62493 +               PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
62494 +               
62495 +               return PVRSRV_ERROR_OUT_OF_MEMORY; 
62496 +       }
62497 +
62498 +       eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
62499 +       (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
62500 +
62501 +
62502 +       return eError;
62503 +}
62504 +
62505 +
62506 +static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID            pvParam,
62507 +                                                                                 IMG_UINT32    ui32Param)
62508 +{
62509 +       PVRSRV_ERROR eError = PVRSRV_OK;
62510 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
62511 +
62512 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
62513 +
62514 +
62515 +       psMemInfo->ui32RefCount--;
62516 +
62517 +
62518 +       if(psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED)
62519 +       {
62520 +               IMG_HANDLE hMemInfo = IMG_NULL;
62521 +
62522 +
62523 +               if (psMemInfo->ui32RefCount != 0)
62524 +               {
62525 +                       PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: mappings are open in other processes"));
62526 +                       return PVRSRV_ERROR_GENERIC;
62527 +               }
62528 +
62529 +
62530 +               eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
62531 +                                                                &hMemInfo,
62532 +                                                                psMemInfo,
62533 +                                                                PVRSRV_HANDLE_TYPE_MEM_INFO);
62534 +               if(eError != PVRSRV_OK)
62535 +               {
62536 +                       PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: can't find exported meminfo in the global handle list"));
62537 +                       return eError;
62538 +               }
62539 +
62540 +
62541 +               eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
62542 +                                                                       hMemInfo,
62543 +                                                                       PVRSRV_HANDLE_TYPE_MEM_INFO);
62544 +               if(eError != PVRSRV_OK)
62545 +               {
62546 +                       PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: PVRSRVReleaseHandle failed for exported meminfo"));
62547 +                       return eError;
62548 +               }
62549 +       }
62550 +
62551 +       PVR_ASSERT(psMemInfo->ui32RefCount == 0);
62552 +
62553 +       if (psMemInfo->psKernelSyncInfo)
62554 +       {
62555 +               psMemInfo->psKernelSyncInfo->ui32RefCount--;
62556 +
62557 +               if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
62558 +               {
62559 +                       eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
62560 +               }
62561 +       }
62562 +
62563 +       if (eError == PVRSRV_OK)
62564 +       {
62565 +               eError = FreeDeviceMem(psMemInfo);
62566 +       }
62567 +
62568 +       return eError;
62569 +}
62570 +
62571 +
62572 +IMG_EXPORT
62573 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE                             hDevCookie,
62574 +                                                                                               PVRSRV_KERNEL_MEM_INFO  *psMemInfo)
62575 +{
62576 +       PVRSRV_ERROR eError;
62577 +
62578 +       PVR_UNREFERENCED_PARAMETER(hDevCookie);
62579 +
62580 +       if (!psMemInfo)
62581 +       {
62582 +               return PVRSRV_ERROR_INVALID_PARAMS;
62583 +       }
62584 +
62585 +       if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
62586 +       {
62587 +               eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
62588 +       }
62589 +       else
62590 +       {
62591 +
62592 +               eError = FreeDeviceMemCallBack(psMemInfo, 0);
62593 +       }
62594 +
62595 +       return eError;
62596 +}
62597 +
62598 +
62599 +IMG_EXPORT
62600 +PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE                                   hDevCookie,
62601 +                                                                                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
62602 +                                                                                                IMG_HANDLE                                     hDevMemHeap,
62603 +                                                                                                IMG_UINT32                                     ui32Flags,
62604 +                                                                                                IMG_SIZE_T                                     ui32Size,
62605 +                                                                                                IMG_SIZE_T                                     ui32Alignment,
62606 +                                                                                                PVRSRV_KERNEL_MEM_INFO         **ppsMemInfo)
62607 +{
62608 +       PVRSRV_KERNEL_MEM_INFO  *psMemInfo;
62609 +       PVRSRV_ERROR                    eError;
62610 +       BM_HEAP                                 *psBMHeap;
62611 +       IMG_HANDLE                              hDevMemContext;
62612 +
62613 +       if (!hDevMemHeap ||
62614 +               (ui32Size == 0))
62615 +       {
62616 +               return PVRSRV_ERROR_INVALID_PARAMS;
62617 +       }
62618 +
62619 +
62620 +       if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
62621 +       {
62622 +               if (((ui32Size % HOST_PAGESIZE()) != 0) ||
62623 +                       ((ui32Alignment % HOST_PAGESIZE()) != 0))
62624 +               {
62625 +                       return PVRSRV_ERROR_INVALID_PARAMS;
62626 +               }
62627 +       }
62628 +
62629 +       eError = AllocDeviceMem(hDevCookie,
62630 +                                                       hDevMemHeap,
62631 +                                                       ui32Flags,
62632 +                                                       ui32Size,
62633 +                                                       ui32Alignment,
62634 +                                                       &psMemInfo);
62635 +
62636 +       if (eError != PVRSRV_OK)
62637 +       {
62638 +               return eError;
62639 +       }
62640 +
62641 +       if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
62642 +       {
62643 +               psMemInfo->psKernelSyncInfo = IMG_NULL;
62644 +       }
62645 +       else
62646 +       {
62647 +
62648 +
62649 +
62650 +               psBMHeap = (BM_HEAP*)hDevMemHeap;
62651 +               hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
62652 +               eError = PVRSRVAllocSyncInfoKM(hDevCookie,
62653 +                                                                          hDevMemContext,
62654 +                                                                          &psMemInfo->psKernelSyncInfo);
62655 +               if(eError != PVRSRV_OK)
62656 +               {
62657 +                       goto free_mainalloc;
62658 +               }
62659 +               psMemInfo->psKernelSyncInfo->ui32RefCount++;
62660 +       }
62661 +
62662 +       
62663 +       *ppsMemInfo = psMemInfo;
62664 +
62665 +       if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
62666 +       {
62667 +               psMemInfo->sMemBlk.hResItem = IMG_NULL;
62668 +       }
62669 +       else
62670 +       {
62671 +
62672 +               psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
62673 +                                                                                                               RESMAN_TYPE_DEVICEMEM_ALLOCATION,
62674 +                                                                                                               psMemInfo,
62675 +                                                                                                               0,
62676 +                                                                                                               FreeDeviceMemCallBack);
62677 +               if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
62678 +               {
62679 +
62680 +                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
62681 +                       goto free_mainalloc;
62682 +               }
62683 +       }
62684 +
62685 +
62686 +       psMemInfo->ui32RefCount++;
62687 +
62688 +
62689 +       return (PVRSRV_OK);
62690 +
62691 +free_mainalloc:
62692 +       FreeDeviceMem(psMemInfo);
62693 +
62694 +       return eError;
62695 +}
62696 +
62697 +
62698 +IMG_EXPORT
62699 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE              hDevCookie,
62700 +                                                                                                         PVRSRV_KERNEL_MEM_INFO *psMemInfo)
62701 +{
62702 +       PVRSRV_ERROR            eError;
62703 +       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevCookie;
62704 +
62705 +       PVR_UNREFERENCED_PARAMETER(hDevCookie);
62706 +
62707 +       if (!psMemInfo)
62708 +       {
62709 +               return PVRSRV_ERROR_INVALID_PARAMS;
62710 +       }
62711 +
62712 +       eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext);
62713 +
62714 +       PVR_ASSERT(eError == PVRSRV_OK);
62715 +
62716 +       return eError;
62717 +}
62718 +
62719 +
62720 +IMG_EXPORT
62721 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
62722 +                                                                                                  IMG_SIZE_T *pui32Total,
62723 +                                                                                                  IMG_SIZE_T *pui32Free,
62724 +                                                                                                  IMG_SIZE_T *pui32LargestBlock)
62725 +{
62726 +
62727 +
62728 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
62729 +       PVR_UNREFERENCED_PARAMETER(pui32Total);
62730 +       PVR_UNREFERENCED_PARAMETER(pui32Free);
62731 +       PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
62732 +
62733 +       return PVRSRV_OK;
62734 +}
62735 +
62736 +
62737 +
62738 +
62739 +IMG_EXPORT
62740 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO      *psMemInfo)
62741 +{
62742 +       if (!psMemInfo)
62743 +       {
62744 +               return PVRSRV_ERROR_INVALID_PARAMS;
62745 +       }
62746 +
62747 +       return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
62748 +}
62749 +
62750 +
62751 +static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID  pvParam,
62752 +                                                                                       IMG_UINT32      ui32Param)
62753 +{
62754 +       PVRSRV_ERROR eError = PVRSRV_OK;
62755 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
62756 +       IMG_HANDLE hOSWrapMem;
62757 +
62758 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
62759 +
62760 +       hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
62761 +
62762 +       if (psMemInfo->psKernelSyncInfo)
62763 +       {
62764 +               psMemInfo->psKernelSyncInfo->ui32RefCount--;
62765 +               if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
62766 +               {
62767 +                       eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
62768 +               }
62769 +       }
62770 +
62771 +       
62772 +       if(psMemInfo->sMemBlk.psIntSysPAddr)
62773 +       {
62774 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
62775 +               psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
62776 +       }
62777 +
62778 +       if (eError == PVRSRV_OK)
62779 +       {
62780 +
62781 +               psMemInfo->ui32RefCount--;
62782 +
62783 +               eError = FreeDeviceMem(psMemInfo);
62784 +       }
62785 +
62786 +       if(hOSWrapMem)
62787 +       {
62788 +               OSReleasePhysPageAddr(hOSWrapMem);
62789 +       }
62790 +
62791 +       return eError;
62792 +}
62793 +
62794 +
62795 +IMG_EXPORT
62796 +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE                             hDevCookie,
62797 +                                                                                               PVRSRV_PER_PROCESS_DATA *psPerProc,
62798 +                                                                                               IMG_HANDLE                              hDevMemContext,
62799 +                                                                                               IMG_SIZE_T                              ui32ByteSize,
62800 +                                                                                               IMG_SIZE_T                              ui32PageOffset,
62801 +                                                                                               IMG_BOOL                                bPhysContig,
62802 +                                                                                               IMG_SYS_PHYADDR                 *psExtSysPAddr,
62803 +                                                                                               IMG_VOID                                *pvLinAddr,
62804 +                                                                                               IMG_UINT32                              ui32Flags,
62805 +                                                                                               PVRSRV_KERNEL_MEM_INFO  **ppsMemInfo)
62806 +{
62807 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
62808 +       DEVICE_MEMORY_INFO  *psDevMemoryInfo;
62809 +       IMG_SIZE_T                      ui32HostPageSize = HOST_PAGESIZE();
62810 +       IMG_HANDLE                      hDevMemHeap = IMG_NULL;
62811 +       PVRSRV_DEVICE_NODE* psDeviceNode;
62812 +       BM_HANDLE                       hBuffer;
62813 +       PVRSRV_MEMBLK           *psMemBlock;
62814 +       IMG_BOOL                        bBMError;
62815 +       BM_HEAP                         *psBMHeap;
62816 +       PVRSRV_ERROR            eError;
62817 +       IMG_VOID                        *pvPageAlignedCPUVAddr;
62818 +       IMG_SYS_PHYADDR         *psIntSysPAddr = IMG_NULL;
62819 +       IMG_HANDLE                      hOSWrapMem = IMG_NULL;
62820 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
62821 +       IMG_SIZE_T              ui32PageCount = 0;
62822 +       IMG_UINT32              i;
62823 +
62824 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
62825 +       PVR_ASSERT(psDeviceNode != IMG_NULL);
62826 +
62827 +       if (psDeviceNode == IMG_NULL)
62828 +       {
62829 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
62830 +               return PVRSRV_ERROR_INVALID_PARAMS;
62831 +       }
62832 +
62833 +       if(pvLinAddr)
62834 +       {
62835 +
62836 +               ui32PageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
62837 +
62838 +
62839 +               ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize;
62840 +               pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - ui32PageOffset);
62841 +
62842 +
62843 +               if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
62844 +                                               ui32PageCount * sizeof(IMG_SYS_PHYADDR),
62845 +                                               (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
62846 +                                               "Array of Page Addresses") != PVRSRV_OK)
62847 +               {
62848 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
62849 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
62850 +               }
62851 +
62852 +               eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
62853 +                                                                               ui32PageCount * ui32HostPageSize,
62854 +                                                                               psIntSysPAddr,
62855 +                                                                               &hOSWrapMem,
62856 +                                                                               (ui32Flags != 0) ? IMG_TRUE : IMG_FALSE);
62857 +               if(eError != PVRSRV_OK)
62858 +               {
62859 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
62860 +                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
62861 +                       goto ErrorExitPhase1;
62862 +               }
62863 +
62864 +
62865 +               psExtSysPAddr = psIntSysPAddr;
62866 +
62867 +
62868 +
62869 +               bPhysContig = IMG_FALSE;
62870 +       }
62871 +       else
62872 +       {
62873 +
62874 +       }
62875 +
62876 +
62877 +       psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
62878 +       psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
62879 +       for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
62880 +       {
62881 +               if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
62882 +               {
62883 +                       if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
62884 +                       {
62885 +
62886 +                               hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
62887 +                       }
62888 +                       else
62889 +                       {
62890 +                               hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
62891 +                       }
62892 +                       break;
62893 +               }
62894 +       }
62895 +
62896 +       if(hDevMemHeap == IMG_NULL)
62897 +       {
62898 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
62899 +               eError = PVRSRV_ERROR_GENERIC;
62900 +               goto ErrorExitPhase2;
62901 +       }
62902 +
62903 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
62904 +                                       sizeof(PVRSRV_KERNEL_MEM_INFO),
62905 +                                       (IMG_VOID **)&psMemInfo, IMG_NULL,
62906 +                                       "Kernel Memory Info") != PVRSRV_OK)
62907 +       {
62908 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
62909 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
62910 +               goto ErrorExitPhase2;
62911 +       }
62912 +
62913 +       OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
62914 +       psMemInfo->ui32Flags = ui32Flags;
62915 +
62916 +       psMemBlock = &(psMemInfo->sMemBlk);
62917 +
62918 +       bBMError = BM_Wrap(hDevMemHeap,
62919 +                                          ui32ByteSize,
62920 +                                          ui32PageOffset,
62921 +                                          bPhysContig,
62922 +                                          psExtSysPAddr,
62923 +                                          IMG_NULL,
62924 +                                          &psMemInfo->ui32Flags,
62925 +                                          &hBuffer);
62926 +       if (!bBMError)
62927 +       {
62928 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
62929 +               eError = PVRSRV_ERROR_BAD_MAPPING;
62930 +               goto ErrorExitPhase3;
62931 +       }
62932 +
62933 +
62934 +       psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
62935 +       psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
62936 +       psMemBlock->hOSWrapMem = hOSWrapMem;
62937 +       psMemBlock->psIntSysPAddr = psIntSysPAddr;
62938 +
62939 +
62940 +       psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
62941 +
62942 +
62943 +       psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
62944 +       psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
62945 +       psMemInfo->ui32AllocSize = ui32ByteSize;
62946 +
62947 +
62948 +
62949 +       psMemInfo->pvSysBackupBuffer = IMG_NULL;
62950 +
62951 +
62952 +
62953 +
62954 +       psBMHeap = (BM_HEAP*)hDevMemHeap;
62955 +       hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
62956 +       eError = PVRSRVAllocSyncInfoKM(hDevCookie,
62957 +                                                                       hDevMemContext,
62958 +                                                                       &psMemInfo->psKernelSyncInfo);
62959 +       if(eError != PVRSRV_OK)
62960 +       {
62961 +               goto ErrorExitPhase4;
62962 +       }
62963 +
62964 +       psMemInfo->psKernelSyncInfo->ui32RefCount++;
62965 +
62966 +       
62967 +       psMemInfo->ui32RefCount++;
62968 +
62969 +
62970 +       psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
62971 +                                                                                                       RESMAN_TYPE_DEVICEMEM_WRAP,
62972 +                                                                                                       psMemInfo,
62973 +                                                                                                       0,
62974 +                                                                                                       UnwrapExtMemoryCallBack);
62975 +
62976 +
62977 +       *ppsMemInfo = psMemInfo;
62978 +
62979 +       return PVRSRV_OK;
62980 +
62981 +
62982 +
62983 +ErrorExitPhase4:
62984 +       if(psMemInfo)
62985 +       {
62986 +               FreeDeviceMem(psMemInfo);
62987 +
62988 +
62989 +
62990 +               psMemInfo = IMG_NULL;
62991 +       }
62992 +
62993 +ErrorExitPhase3:
62994 +       if(psMemInfo)
62995 +       {
62996 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
62997 +
62998 +       }
62999 +
63000 +ErrorExitPhase2:
63001 +       if(psIntSysPAddr)
63002 +       {
63003 +               OSReleasePhysPageAddr(hOSWrapMem);
63004 +       }
63005 +
63006 +ErrorExitPhase1:
63007 +       if(psIntSysPAddr)
63008 +       {
63009 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
63010 +
63011 +       }
63012 +
63013 +       return eError;
63014 +}
63015 +
63016 +
63017 +IMG_EXPORT
63018 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
63019 +{
63020 +       if (!psMemInfo)
63021 +       {
63022 +               return PVRSRV_ERROR_INVALID_PARAMS;
63023 +       }
63024 +
63025 +       return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
63026 +}
63027 +
63028 +
63029 +static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
63030 +                                                                                         IMG_UINT32 ui32Param)
63031 +{
63032 +       PVRSRV_ERROR                            eError;
63033 +       RESMAN_MAP_DEVICE_MEM_DATA      *psMapData = pvParam;
63034 +
63035 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
63036 +
63037 +       if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
63038 +       {
63039 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
63040 +               psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
63041 +       }
63042 +
63043 +       psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--;
63044 +       if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
63045 +       {
63046 +               eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
63047 +               if(eError != PVRSRV_OK)
63048 +               {
63049 +                       PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
63050 +                       return eError;
63051 +               }
63052 +       }
63053 +       
63054 +       eError = FreeDeviceMem(psMapData->psMemInfo);
63055 +       if(eError != PVRSRV_OK)
63056 +       {
63057 +               PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
63058 +               return eError;
63059 +       }
63060 +
63061 +
63062 +       psMapData->psSrcMemInfo->ui32RefCount--;
63063 +
63064 +       if (psMapData->psSrcMemInfo->ui32RefCount == 1 &&
63065 +                psMapData->psSrcMemInfo->bPendingFree == IMG_TRUE)
63066 +       {
63067 +
63068 +
63069 +
63070 +               if (psMapData->psSrcMemInfo->sMemBlk.hResItem != IMG_NULL)
63071 +               {
63072 +
63073 +
63074 +                       eError = ResManFreeResByPtr(psMapData->psSrcMemInfo->sMemBlk.hResItem);
63075 +                       if (eError != PVRSRV_OK)
63076 +                       {
63077 +                               PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free SRC meminfo"));
63078 +                               PVR_DBG_BREAK;
63079 +                       }
63080 +               }
63081 +               else
63082 +               {
63083 +
63084 +                       eError = FreeDeviceMemCallBack(psMapData->psSrcMemInfo, 0);
63085 +               }
63086 +       }
63087 +
63088 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
63089 +
63090 +
63091 +       return eError;
63092 +}
63093 +
63094 +
63095 +IMG_EXPORT
63096 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA      *psPerProc,
63097 +                                                                                                 PVRSRV_KERNEL_MEM_INFO        *psSrcMemInfo,
63098 +                                                                                                 IMG_HANDLE                            hDstDevMemHeap,
63099 +                                                                                                 PVRSRV_KERNEL_MEM_INFO        **ppsDstMemInfo)
63100 +{
63101 +       PVRSRV_ERROR                            eError;
63102 +       IMG_UINT32                                      i;
63103 +       IMG_SIZE_T                                      ui32PageCount, ui32PageOffset;
63104 +       IMG_SIZE_T                                      ui32HostPageSize = HOST_PAGESIZE();
63105 +       IMG_SYS_PHYADDR                         *psSysPAddr = IMG_NULL;
63106 +       IMG_DEV_PHYADDR                         sDevPAddr;
63107 +       BM_BUF                                          *psBuf;
63108 +       IMG_DEV_VIRTADDR                        sDevVAddr;
63109 +       PVRSRV_KERNEL_MEM_INFO          *psMemInfo = IMG_NULL;
63110 +       BM_HANDLE                                       hBuffer;
63111 +       PVRSRV_MEMBLK                           *psMemBlock;
63112 +       IMG_BOOL                                        bBMError;
63113 +       PVRSRV_DEVICE_NODE                      *psDeviceNode;
63114 +       IMG_VOID                                        *pvPageAlignedCPUVAddr;
63115 +       RESMAN_MAP_DEVICE_MEM_DATA      *psMapData = IMG_NULL;
63116 +
63117 +
63118 +       if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
63119 +       {
63120 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
63121 +               return PVRSRV_ERROR_INVALID_PARAMS;
63122 +       }
63123 +
63124 +
63125 +       *ppsDstMemInfo = IMG_NULL;
63126 +
63127 +       ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
63128 +       ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize;
63129 +       pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - ui32PageOffset);
63130 +
63131 +
63132 +
63133 +
63134 +
63135 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
63136 +                                       ui32PageCount*sizeof(IMG_SYS_PHYADDR),
63137 +                                       (IMG_VOID **)&psSysPAddr, IMG_NULL,
63138 +                                       "Array of Page Addresses") != PVRSRV_OK)
63139 +       {
63140 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
63141 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
63142 +       }
63143 +
63144 +       psBuf = psSrcMemInfo->sMemBlk.hBuffer;
63145 +
63146 +
63147 +       psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
63148 +
63149 +
63150 +       sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(ui32PageOffset);
63151 +       for(i=0; i<ui32PageCount; i++)
63152 +       {
63153 +               BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
63154 +
63155 +
63156 +               psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
63157 +
63158 +
63159 +               sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
63160 +       }
63161 +
63162 +
63163 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
63164 +                                       sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
63165 +                                       (IMG_VOID **)&psMapData, IMG_NULL,
63166 +                                       "Resource Manager Map Data") != PVRSRV_OK)
63167 +       {
63168 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
63169 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
63170 +               goto ErrorExit;
63171 +       }
63172 +
63173 +
63174 +       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
63175 +                                       sizeof(PVRSRV_KERNEL_MEM_INFO),
63176 +                                       (IMG_VOID **)&psMemInfo, IMG_NULL,
63177 +                                       "Kernel Memory Info") != PVRSRV_OK)
63178 +       {
63179 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
63180 +               eError = PVRSRV_ERROR_OUT_OF_MEMORY;
63181 +               goto ErrorExit;
63182 +       }
63183 +
63184 +       OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
63185 +       psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
63186 +
63187 +       psMemBlock = &(psMemInfo->sMemBlk);
63188 +
63189 +       bBMError = BM_Wrap(hDstDevMemHeap,
63190 +                                          psSrcMemInfo->ui32AllocSize,
63191 +                                          ui32PageOffset,
63192 +                                          IMG_FALSE,
63193 +                                          psSysPAddr,
63194 +                                          pvPageAlignedCPUVAddr,
63195 +                                          &psMemInfo->ui32Flags,
63196 +                                          &hBuffer);
63197 +
63198 +       if (!bBMError)
63199 +       {
63200 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
63201 +               eError = PVRSRV_ERROR_BAD_MAPPING;
63202 +               goto ErrorExit;
63203 +       }
63204 +
63205 +
63206 +       psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
63207 +       psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
63208 +
63209 +
63210 +       psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
63211 +
63212 +
63213 +       psMemBlock->psIntSysPAddr = psSysPAddr;
63214 +
63215 +
63216 +       psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
63217 +
63218 +
63219 +       psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
63220 +       psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
63221 +       psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
63222 +
63223 +       
63224 +       psMemInfo->psKernelSyncInfo->ui32RefCount++;
63225 +
63226 +       
63227 +
63228 +       psMemInfo->pvSysBackupBuffer = IMG_NULL;
63229 +
63230 +
63231 +       psSrcMemInfo->ui32RefCount++;
63232 +
63233 +
63234 +       psMapData->psMemInfo = psMemInfo;
63235 +       psMapData->psSrcMemInfo = psSrcMemInfo;
63236 +
63237 +
63238 +       psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
63239 +                                                                                                       RESMAN_TYPE_DEVICEMEM_MAPPING,
63240 +                                                                                                       psMapData,
63241 +                                                                                                       0,
63242 +                                                                                                       UnmapDeviceMemoryCallBack);
63243 +
63244 +       *ppsDstMemInfo = psMemInfo;
63245 +
63246 +       return PVRSRV_OK;
63247 +
63248 +
63249 +
63250 +ErrorExit:
63251 +
63252 +       if(psSysPAddr)
63253 +       {
63254 +
63255 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
63256 +
63257 +       }
63258 +
63259 +       if(psMemInfo)
63260 +       {
63261 +
63262 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
63263 +
63264 +       }
63265 +
63266 +       if(psMapData)
63267 +       {
63268 +
63269 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
63270 +
63271 +       }
63272 +
63273 +       return eError;
63274 +}
63275 +
63276 +
63277 +IMG_EXPORT
63278 +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
63279 +{
63280 +       if (!psMemInfo)
63281 +       {
63282 +               return PVRSRV_ERROR_INVALID_PARAMS;
63283 +       }
63284 +
63285 +       return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
63286 +}
63287 +
63288 +
63289 +static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID   pvParam,
63290 +                                                                                                  IMG_UINT32   ui32Param)
63291 +{
63292 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
63293 +
63294 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
63295 +
63296 +       return FreeDeviceMem(psMemInfo);
63297 +}
63298 +
63299 +
63300 +IMG_EXPORT
63301 +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
63302 +                                                                                                          IMG_HANDLE                           hDevMemContext,
63303 +                                                                                                          IMG_HANDLE                           hDeviceClassBuffer,
63304 +                                                                                                          PVRSRV_KERNEL_MEM_INFO       **ppsMemInfo,
63305 +                                                                                                          IMG_HANDLE                           *phOSMapInfo)
63306 +{
63307 +       PVRSRV_ERROR eError;
63308 +       PVRSRV_KERNEL_MEM_INFO *psMemInfo;
63309 +       PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
63310 +       IMG_SYS_PHYADDR *psSysPAddr;
63311 +       IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
63312 +       IMG_BOOL bPhysContig;
63313 +       BM_CONTEXT *psBMContext;
63314 +       DEVICE_MEMORY_INFO *psDevMemoryInfo;
63315 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
63316 +       IMG_HANDLE hDevMemHeap = IMG_NULL;
63317 +       IMG_SIZE_T ui32ByteSize;
63318 +       IMG_SIZE_T ui32Offset;
63319 +       IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
63320 +       BM_HANDLE               hBuffer;
63321 +       PVRSRV_MEMBLK   *psMemBlock;
63322 +       IMG_BOOL                bBMError;
63323 +       IMG_UINT32 i;
63324 +
63325 +       if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
63326 +       {
63327 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
63328 +               return PVRSRV_ERROR_INVALID_PARAMS;
63329 +       }
63330 +
63331 +       psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
63332 +
63333 +
63334 +
63335 +
63336 +
63337 +
63338 +
63339 +
63340 +
63341 +
63342 +
63343 +
63344 +
63345 +
63346 +
63347 +
63348 +
63349 +
63350 +
63351 +
63352 +       eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
63353 +                                                                                                  psDeviceClassBuffer->hExtBuffer,
63354 +                                                                                                  &psSysPAddr,
63355 +                                                                                                  &ui32ByteSize,
63356 +                                                                                                  &pvCPUVAddr,
63357 +                                                                                                  phOSMapInfo,
63358 +                                                                                                  &bPhysContig);
63359 +       if(eError != PVRSRV_OK)
63360 +       {
63361 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
63362 +               return PVRSRV_ERROR_GENERIC;
63363 +       }
63364 +
63365 +
63366 +       psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
63367 +       psDevMemoryInfo = &psBMContext->psDeviceNode->sDevMemoryInfo;
63368 +       psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
63369 +       for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
63370 +       {
63371 +               if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
63372 +               {
63373 +                       if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
63374 +                       {
63375 +
63376 +                               hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
63377 +                       }
63378 +                       else
63379 +                       {
63380 +                               hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
63381 +                       }
63382 +                       break;
63383 +               }
63384 +       }
63385 +
63386 +       if(hDevMemHeap == IMG_NULL)
63387 +       {
63388 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
63389 +               return PVRSRV_ERROR_GENERIC;
63390 +       }
63391 +
63392 +
63393 +       ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
63394 +       pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
63395 +
63396 +       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
63397 +                                       sizeof(PVRSRV_KERNEL_MEM_INFO),
63398 +                                       (IMG_VOID **)&psMemInfo, IMG_NULL,
63399 +                                       "Kernel Memory Info") != PVRSRV_OK)
63400 +       {
63401 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
63402 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
63403 +       }
63404 +
63405 +       OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
63406 +
63407 +       psMemBlock = &(psMemInfo->sMemBlk);
63408 +
63409 +       bBMError = BM_Wrap(hDevMemHeap,
63410 +                                          ui32ByteSize,
63411 +                                          ui32Offset,
63412 +                                          bPhysContig,
63413 +                                          psSysPAddr,
63414 +                                          pvPageAlignedCPUVAddr,
63415 +                                          &psMemInfo->ui32Flags,
63416 +                                          &hBuffer);
63417 +
63418 +       if (!bBMError)
63419 +       {
63420 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
63421 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
63422 +
63423 +               return PVRSRV_ERROR_BAD_MAPPING;
63424 +       }
63425 +
63426 +
63427 +       psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
63428 +       psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
63429 +
63430 +
63431 +       psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
63432 +
63433 +
63434 +
63435 +       psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
63436 +
63437 +
63438 +       psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
63439 +       psMemInfo->ui32AllocSize = ui32ByteSize;
63440 +       psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
63441 +
63442 +
63443 +
63444 +       psMemInfo->pvSysBackupBuffer = IMG_NULL;
63445 +
63446 +
63447 +       psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
63448 +                                                                                                       RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
63449 +                                                                                                       psMemInfo,
63450 +                                                                                                       0,
63451 +                                                                                                       UnmapDeviceClassMemoryCallBack);
63452 +
63453 +
63454 +       *ppsMemInfo = psMemInfo;
63455 +
63456 +       return PVRSRV_OK;
63457 +}
63458 +
63459 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/handle.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/handle.c
63460 new file mode 100644
63461 index 0000000..6ac016a
63462 --- /dev/null
63463 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/handle.c
63464 @@ -0,0 +1,1547 @@
63465 +/**********************************************************************
63466 + *
63467 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
63468 + *
63469 + * This program is free software; you can redistribute it and/or modify it
63470 + * under the terms and conditions of the GNU General Public License,
63471 + * version 2, as published by the Free Software Foundation.
63472 + *
63473 + * This program is distributed in the hope it will be useful but, except
63474 + * as otherwise stated in writing, without any warranty; without even the
63475 + * implied warranty of merchantability or fitness for a particular purpose.
63476 + * See the GNU General Public License for more details.
63477 + *
63478 + * You should have received a copy of the GNU General Public License along with
63479 + * this program; if not, write to the Free Software Foundation, Inc.,
63480 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
63481 + *
63482 + * The full GNU General Public License is included in this distribution in
63483 + * the file called "COPYING".
63484 + *
63485 + * Contact Information:
63486 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
63487 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
63488 + *
63489 + ******************************************************************************/
63490 +
63491 +#ifdef PVR_SECURE_HANDLES
63492 +#include <stddef.h>
63493 +
63494 +#include "services_headers.h"
63495 +#include "handle.h"
63496 +
63497 +#ifdef DEBUG
63498 +#define        HANDLE_BLOCK_SIZE       1
63499 +#else
63500 +#define        HANDLE_BLOCK_SIZE       256
63501 +#endif
63502 +
63503 +#define        HANDLE_HASH_TAB_INIT_SIZE       32
63504 +
63505 +#define        DEFAULT_MAX_INDEX_PLUS_ONE      0xfffffffful
63506 +#define        DEFAULT_MAX_HANDLE              DEFAULT_MAX_INDEX_PLUS_ONE
63507 +
63508 +#define        INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
63509 +
63510 +#define        INDEX_TO_HANDLE(psBase, idx) ((IMG_HANDLE)((idx) + 1))
63511 +#define        HANDLE_TO_INDEX(psBase, hand) ((IMG_UINT32)(hand) - 1)
63512 +
63513 +#define INDEX_TO_HANDLE_PTR(psBase, i) (((psBase)->psHandleArray) + (i))
63514 +#define        HANDLE_TO_HANDLE_PTR(psBase, h) (INDEX_TO_HANDLE_PTR(psBase, HANDLE_TO_INDEX(psBase, h)))
63515 +
63516 +#define        HANDLE_PTR_TO_INDEX(psBase, psHandle) (IMG_UINT32)((psHandle) - ((psBase)->psHandleArray))
63517 +#define        HANDLE_PTR_TO_HANDLE(psBase, psHandle) \
63518 +       INDEX_TO_HANDLE(psBase, HANDLE_PTR_TO_INDEX(psBase, psHandle))
63519 +
63520 +#define        ROUND_UP_TO_MULTIPLE(a, b) ((((a) + (b) - 1) / (b)) * (b))
63521 +
63522 +#define        HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
63523 +
63524 +#define        SET_FLAG(v, f) ((IMG_VOID)((v) |= (f)))
63525 +#define        CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f)))
63526 +#define        TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0))
63527 +
63528 +#define        TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f)
63529 +
63530 +#define        SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f)
63531 +#define        CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f)
63532 +#define        TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f)
63533 +
63534 +#define        BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
63535 +
63536 +#define        SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
63537 +
63538 +#define        SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
63539 +
63540 +#define        BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
63541 +
63542 +#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
63543 +
63544 +#define        HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE)
63545 +
63546 +#ifdef MIN
63547 +#undef MIN
63548 +#endif
63549 +
63550 +#define        MIN(x, y) (((x) < (y)) ? (x) : (y))
63551 +
63552 +struct sHandleList
63553 +{
63554 +       IMG_UINT32 ui32Prev;
63555 +       IMG_UINT32 ui32Next;
63556 +       IMG_HANDLE hParent;
63557 +};
63558 +
63559 +enum ePVRSRVInternalHandleFlag
63560 +{
63561 +       INTERNAL_HANDLE_FLAG_NONE = 0x00,
63562 +       INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
63563 +       INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
63564 +};
63565 +
63566 +struct sHandle
63567 +{
63568 +
63569 +       PVRSRV_HANDLE_TYPE eType;
63570 +
63571 +
63572 +       IMG_VOID *pvData;
63573 +
63574 +
63575 +       IMG_UINT32 ui32NextIndexPlusOne;
63576 +
63577 +
63578 +       enum ePVRSRVInternalHandleFlag eInternalFlag;
63579 +
63580 +
63581 +       PVRSRV_HANDLE_ALLOC_FLAG eFlag;
63582 +
63583 +
63584 +       IMG_UINT32 ui32Index;
63585 +
63586 +
63587 +       struct sHandleList sChildren;
63588 +
63589 +
63590 +       struct sHandleList sSiblings;
63591 +};
63592 +
63593 +struct _PVRSRV_HANDLE_BASE_
63594 +{
63595 +
63596 +       IMG_HANDLE hBaseBlockAlloc;
63597 +
63598 +
63599 +       IMG_HANDLE hHandBlockAlloc;
63600 +
63601 +
63602 +       struct sHandle *psHandleArray;
63603 +
63604 +
63605 +       HASH_TABLE *psHashTab;
63606 +
63607 +
63608 +       IMG_UINT32 ui32FreeHandCount;
63609 +
63610 +
63611 +       IMG_UINT32 ui32FirstFreeIndex;
63612 +
63613 +
63614 +       IMG_UINT32 ui32MaxIndexPlusOne;
63615 +
63616 +
63617 +       IMG_UINT32 ui32TotalHandCount;
63618 +
63619 +
63620 +       IMG_UINT32 ui32LastFreeIndexPlusOne;
63621 +
63622 +
63623 +       IMG_UINT32 ui32HandBatchSize;
63624 +
63625 +
63626 +       IMG_UINT32 ui32TotalHandCountPreBatch;
63627 +
63628 +
63629 +       IMG_UINT32 ui32FirstBatchIndexPlusOne;
63630 +
63631 +
63632 +       IMG_UINT32 ui32BatchHandAllocFailures;
63633 +
63634 +
63635 +       IMG_BOOL bPurgingEnabled;
63636 +};
63637 +
63638 +enum eHandKey {
63639 +       HAND_KEY_DATA = 0,
63640 +       HAND_KEY_TYPE,
63641 +       HAND_KEY_PARENT,
63642 +       HAND_KEY_LEN
63643 +};
63644 +
63645 +PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
63646 +
63647 +typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
63648 +
63649 +#ifdef INLINE_IS_PRAGMA
63650 +#pragma inline(HandleListInit)
63651 +#endif
63652 +static INLINE
63653 +IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
63654 +{
63655 +       psList->ui32Next = ui32Index;
63656 +       psList->ui32Prev = ui32Index;
63657 +       psList->hParent = hParent;
63658 +}
63659 +
63660 +#ifdef INLINE_IS_PRAGMA
63661 +#pragma inline(InitParentList)
63662 +#endif
63663 +static INLINE
63664 +IMG_VOID InitParentList(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63665 +{
63666 +       IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psBase, psHandle);
63667 +
63668 +       HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(psBase, ui32Parent));
63669 +}
63670 +
63671 +#ifdef INLINE_IS_PRAGMA
63672 +#pragma inline(InitChildEntry)
63673 +#endif
63674 +static INLINE
63675 +IMG_VOID InitChildEntry(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63676 +{
63677 +       HandleListInit(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings, IMG_NULL);
63678 +}
63679 +
63680 +#ifdef INLINE_IS_PRAGMA
63681 +#pragma inline(HandleListIsEmpty)
63682 +#endif
63683 +static INLINE
63684 +IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList)
63685 +{
63686 +       IMG_BOOL bIsEmpty;
63687 +
63688 +       bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index);
63689 +
63690 +#ifdef DEBUG
63691 +       {
63692 +               IMG_BOOL bIsEmpty2;
63693 +
63694 +               bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index);
63695 +               PVR_ASSERT(bIsEmpty == bIsEmpty2);
63696 +       }
63697 +#endif
63698 +
63699 +       return bIsEmpty;
63700 +}
63701 +
63702 +#ifdef DEBUG
63703 +#ifdef INLINE_IS_PRAGMA
63704 +#pragma inline(NoChildren)
63705 +#endif
63706 +static INLINE
63707 +IMG_BOOL NoChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63708 +{
63709 +       PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psBase, psHandle));
63710 +
63711 +       return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sChildren);
63712 +}
63713 +
63714 +#ifdef INLINE_IS_PRAGMA
63715 +#pragma inline(NoParent)
63716 +#endif
63717 +static INLINE
63718 +IMG_BOOL NoParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63719 +{
63720 +       if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings))
63721 +       {
63722 +               PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL);
63723 +
63724 +               return IMG_TRUE;
63725 +       }
63726 +       else
63727 +       {
63728 +               PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL);
63729 +       }
63730 +       return IMG_FALSE;
63731 +}
63732 +#endif
63733 +#ifdef INLINE_IS_PRAGMA
63734 +#pragma inline(ParentHandle)
63735 +#endif
63736 +static INLINE
63737 +IMG_HANDLE ParentHandle(struct sHandle *psHandle)
63738 +{
63739 +       return psHandle->sSiblings.hParent;
63740 +}
63741 +
63742 +#define        LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
63743 +               ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
63744 +
63745 +#ifdef INLINE_IS_PRAGMA
63746 +#pragma inline(HandleListInsertBefore)
63747 +#endif
63748 +static INLINE
63749 +IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex)
63750 +{
63751 +
63752 +       struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset);
63753 +
63754 +       PVR_ASSERT(psEntry->hParent == IMG_NULL);
63755 +       PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next);
63756 +       PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(psBase, ui32ParentIndex));
63757 +
63758 +       psEntry->ui32Prev = psIns->ui32Prev;
63759 +       psIns->ui32Prev = ui32EntryIndex;
63760 +       psEntry->ui32Next = ui32InsIndex;
63761 +       psPrevIns->ui32Next = ui32EntryIndex;
63762 +
63763 +       psEntry->hParent = INDEX_TO_HANDLE(psBase, ui32ParentIndex);
63764 +}
63765 +
63766 +#ifdef INLINE_IS_PRAGMA
63767 +#pragma inline(AdoptChild)
63768 +#endif
63769 +static INLINE
63770 +IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild)
63771 +{
63772 +       IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psBase, psParent->sChildren.hParent);
63773 +
63774 +       PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psBase, psParent));
63775 +
63776 +       HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psBase, psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
63777 +
63778 +}
63779 +
63780 +#ifdef INLINE_IS_PRAGMA
63781 +#pragma inline(HandleListRemove)
63782 +#endif
63783 +static INLINE
63784 +IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset)
63785 +{
63786 +       if (!HandleListIsEmpty(ui32EntryIndex, psEntry))
63787 +       {
63788 +
63789 +               struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psBase, psEntry->hParent), uiParentOffset, uiEntryOffset);
63790 +               struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psBase, psEntry->hParent), uiParentOffset, uiEntryOffset);
63791 +
63792 +
63793 +               PVR_ASSERT(psEntry->hParent != IMG_NULL);
63794 +
63795 +               psPrev->ui32Next = psEntry->ui32Next;
63796 +               psNext->ui32Prev = psEntry->ui32Prev;
63797 +
63798 +               HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
63799 +       }
63800 +}
63801 +
63802 +#ifdef INLINE_IS_PRAGMA
63803 +#pragma inline(UnlinkFromParent)
63804 +#endif
63805 +static INLINE
63806 +IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63807 +{
63808 +       HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
63809 +}
63810 +
63811 +#ifdef INLINE_IS_PRAGMA
63812 +#pragma inline(HandleListIterate)
63813 +#endif
63814 +static INLINE
63815 +PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
63816 +{
63817 +       IMG_UINT32 ui32Index;
63818 +       IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psBase, psHead->hParent);
63819 +
63820 +       PVR_ASSERT(psHead->hParent != IMG_NULL);
63821 +
63822 +
63823 +       for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
63824 +       {
63825 +               struct sHandle *psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32Index);
63826 +
63827 +               struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
63828 +               PVRSRV_ERROR eError;
63829 +
63830 +               PVR_ASSERT(psEntry->hParent == psHead->hParent);
63831 +
63832 +               ui32Index = psEntry->ui32Next;
63833 +
63834 +               eError = (*pfnIterFunc)(psBase, psHandle);
63835 +               if (eError != PVRSRV_OK)
63836 +               {
63837 +                       return eError;
63838 +               }
63839 +       }
63840 +
63841 +       return PVRSRV_OK;
63842 +}
63843 +
63844 +#ifdef INLINE_IS_PRAGMA
63845 +#pragma inline(IterateOverChildren)
63846 +#endif
63847 +static INLINE
63848 +PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
63849 +{
63850 +        return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc);
63851 +}
63852 +
63853 +#ifdef INLINE_IS_PRAGMA
63854 +#pragma inline(GetHandleStructure)
63855 +#endif
63856 +static INLINE
63857 +PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
63858 +{
63859 +       IMG_UINT32 ui32Index = HANDLE_TO_INDEX(psBase, hHandle);
63860 +       struct sHandle *psHandle;
63861 +
63862 +
63863 +       if (!INDEX_IS_VALID(psBase, ui32Index))
63864 +       {
63865 +               PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
63866 +               return PVRSRV_ERROR_GENERIC;
63867 +       }
63868 +
63869 +       psHandle =  INDEX_TO_HANDLE_PTR(psBase, ui32Index);
63870 +       if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
63871 +       {
63872 +               PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
63873 +               return PVRSRV_ERROR_GENERIC;
63874 +       }
63875 +
63876 +
63877 +       if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
63878 +       {
63879 +               PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
63880 +               return PVRSRV_ERROR_GENERIC;
63881 +       }
63882 +
63883 +
63884 +       *ppsHandle = psHandle;
63885 +
63886 +       return PVRSRV_OK;
63887 +}
63888 +
63889 +#ifdef INLINE_IS_PRAGMA
63890 +#pragma inline(ParentIfPrivate)
63891 +#endif
63892 +static INLINE
63893 +IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
63894 +{
63895 +       return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
63896 +                       ParentHandle(psHandle) : IMG_NULL;
63897 +}
63898 +
63899 +#ifdef INLINE_IS_PRAGMA
63900 +#pragma inline(InitKey)
63901 +#endif
63902 +static INLINE
63903 +IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
63904 +{
63905 +       PVR_UNREFERENCED_PARAMETER(psBase);
63906 +
63907 +       aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData;
63908 +       aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType;
63909 +       aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent;
63910 +}
63911 +
63912 +static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
63913 +{
63914 +       PVRSRV_ERROR eError = PVRSRV_OK;
63915 +
63916 +       if (psBase->psHandleArray != IMG_NULL)
63917 +       {
63918 +               eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
63919 +                       psBase->ui32TotalHandCount * sizeof(struct sHandle),
63920 +                       psBase->psHandleArray,
63921 +                       psBase->hHandBlockAlloc);
63922 +
63923 +               if (eError != PVRSRV_OK)
63924 +               {
63925 +                       PVR_DPF((PVR_DBG_ERROR, "FreeHandleArray: Error freeing memory (%d)", eError));
63926 +               }
63927 +               else
63928 +               {
63929 +                       psBase->psHandleArray = IMG_NULL;
63930 +               }
63931 +       }
63932 +
63933 +       return eError;
63934 +}
63935 +
63936 +static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
63937 +{
63938 +       HAND_KEY aKey;
63939 +       IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psBase, psHandle);
63940 +       PVRSRV_ERROR eError;
63941 +
63942 +
63943 +       InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
63944 +
63945 +       if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
63946 +       {
63947 +               IMG_HANDLE hHandle;
63948 +               hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
63949 +
63950 +               PVR_ASSERT(hHandle != IMG_NULL);
63951 +               PVR_ASSERT(hHandle == INDEX_TO_HANDLE(psBase, ui32Index));
63952 +               PVR_UNREFERENCED_PARAMETER(hHandle);
63953 +       }
63954 +
63955 +
63956 +       UnlinkFromParent(psBase, psHandle);
63957 +
63958 +
63959 +       eError = IterateOverChildren(psBase, psHandle, FreeHandle);
63960 +       if (eError != PVRSRV_OK)
63961 +       {
63962 +               PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
63963 +               return eError;
63964 +       }
63965 +
63966 +
63967 +       psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
63968 +
63969 +       if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
63970 +       {
63971 +               SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
63972 +
63973 +               return PVRSRV_OK;
63974 +       }
63975 +
63976 +
63977 +       if (!psBase->bPurgingEnabled)
63978 +       {
63979 +               if (psBase->ui32FreeHandCount == 0)
63980 +               {
63981 +                       PVR_ASSERT(psBase->ui32FirstFreeIndex == 0);
63982 +                       PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
63983 +
63984 +                       psBase->ui32FirstFreeIndex =  ui32Index;
63985 +               }
63986 +               else
63987 +               {
63988 +
63989 +                       PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
63990 +                       PVR_ASSERT(INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
63991 +                       INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne =  ui32Index + 1;
63992 +               }
63993 +
63994 +               PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0);
63995 +
63996 +
63997 +               psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
63998 +       }
63999 +
64000 +       psBase->ui32FreeHandCount++;
64001 +
64002 +       return PVRSRV_OK;
64003 +}
64004 +
64005 +static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase)
64006 +{
64007 +       IMG_UINT32 i;
64008 +       PVRSRV_ERROR eError = PVRSRV_OK;
64009 +
64010 +       if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
64011 +       {
64012 +               return eError;
64013 +       }
64014 +
64015 +       for (i = 0; i < psBase->ui32TotalHandCount; i++)
64016 +       {
64017 +               struct sHandle *psHandle;
64018 +
64019 +               psHandle = INDEX_TO_HANDLE_PTR(psBase, i);
64020 +
64021 +               if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE)
64022 +               {
64023 +                       eError = FreeHandle(psBase, psHandle);
64024 +                       if (eError != PVRSRV_OK)
64025 +                       {
64026 +                               PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError));
64027 +                               break;
64028 +                       }
64029 +
64030 +
64031 +                       if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
64032 +                       {
64033 +                               break;
64034 +                       }
64035 +               }
64036 +       }
64037 +
64038 +       return eError;
64039 +}
64040 +
64041 +static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
64042 +{
64043 +       PVRSRV_ERROR eError;
64044 +
64045 +       if (HANDLES_BATCHED(psBase))
64046 +       {
64047 +               PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch"));
64048 +               PVRSRVReleaseHandleBatch(psBase);
64049 +       }
64050 +
64051 +
64052 +       eError = FreeAllHandles(psBase);
64053 +       if (eError != PVRSRV_OK)
64054 +       {
64055 +               PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
64056 +               return eError;
64057 +       }
64058 +
64059 +
64060 +       eError = FreeHandleArray(psBase);
64061 +       if (eError != PVRSRV_OK)
64062 +       {
64063 +               PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError));
64064 +               return eError;
64065 +       }
64066 +
64067 +       if (psBase->psHashTab != IMG_NULL)
64068 +       {
64069 +
64070 +               HASH_Delete(psBase->psHashTab);
64071 +       }
64072 +
64073 +       eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
64074 +               sizeof(*psBase),
64075 +               psBase,
64076 +               psBase->hBaseBlockAlloc);
64077 +       if (eError != PVRSRV_OK)
64078 +       {
64079 +               PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError));
64080 +               return eError;
64081 +       }
64082 +
64083 +       return PVRSRV_OK;
64084 +}
64085 +
64086 +#ifdef INLINE_IS_PRAGMA
64087 +#pragma inline(FindHandle)
64088 +#endif
64089 +static INLINE
64090 +IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
64091 +{
64092 +       HAND_KEY aKey;
64093 +
64094 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64095 +
64096 +       InitKey(aKey, psBase, pvData, eType, hParent);
64097 +
64098 +       return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
64099 +}
64100 +
64101 +static PVRSRV_ERROR ReallocMem(IMG_PVOID *ppvMem, IMG_HANDLE *phBlockAlloc, IMG_UINT32 ui32NewSize, IMG_UINT32 ui32OldSize)
64102 +{
64103 +       IMG_VOID *pvOldMem = *ppvMem;
64104 +       IMG_HANDLE hOldBlockAlloc = *phBlockAlloc;
64105 +       IMG_UINT32 ui32CopySize = MIN(ui32NewSize, ui32OldSize);
64106 +       IMG_VOID *pvNewMem = IMG_NULL;
64107 +       IMG_HANDLE hNewBlockAlloc = IMG_NULL;
64108 +       PVRSRV_ERROR eError;
64109 +
64110 +       if (ui32NewSize == ui32OldSize)
64111 +       {
64112 +               return (PVRSRV_OK);
64113 +       }
64114 +
64115 +       if (ui32NewSize != 0)
64116 +       {
64117 +
64118 +               eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
64119 +                       ui32NewSize,
64120 +                       &pvNewMem,
64121 +                       &hNewBlockAlloc,
64122 +                       "Memory Area");
64123 +               if (eError != PVRSRV_OK)
64124 +               {
64125 +                       PVR_DPF((PVR_DBG_ERROR, "ReallocMem: Couldn't allocate new memory area (%d)", eError));
64126 +                       return eError;
64127 +               }
64128 +       }
64129 +
64130 +       if (ui32CopySize != 0)
64131 +       {
64132 +
64133 +               OSMemCopy(pvNewMem, pvOldMem, ui32CopySize);
64134 +       }
64135 +
64136 +       if (ui32OldSize != 0)
64137 +       {
64138 +
64139 +               eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
64140 +                               ui32OldSize,
64141 +                               pvOldMem,
64142 +                               hOldBlockAlloc);
64143 +               if (eError != PVRSRV_OK)
64144 +               {
64145 +                       PVR_DPF((PVR_DBG_ERROR, "ReallocMem: Couldn't free old memory area (%d)", eError));
64146 +               }
64147 +       }
64148 +
64149 +       *ppvMem = pvNewMem;
64150 +       *phBlockAlloc = hNewBlockAlloc;
64151 +
64152 +       return PVRSRV_OK;
64153 +}
64154 +
64155 +#ifdef INLINE_IS_PRAGMA
64156 +#pragma inline(ReallocHandleArray)
64157 +#endif
64158 +static INLINE
64159 +PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount, IMG_UINT32 ui32OldCount)
64160 +{
64161 +       return ReallocMem((IMG_PVOID *)&psBase->psHandleArray,
64162 +                               &psBase->hHandBlockAlloc,
64163 +                               ui32NewCount * sizeof(struct sHandle),
64164 +                               ui32OldCount * sizeof(struct sHandle));
64165 +}
64166 +
64167 +static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
64168 +{
64169 +       PVRSRV_ERROR eError;
64170 +       struct sHandle *psHandle;
64171 +       IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE(ui32Delta, HANDLE_BLOCK_SIZE);
64172 +       IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
64173 +;
64174 +
64175 +       PVR_ASSERT(ui32Delta != 0);
64176 +
64177 +
64178 +       if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount)
64179 +       {
64180 +               ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne;
64181 +
64182 +               ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount;
64183 +
64184 +               if (ui32DeltaAdjusted < ui32Delta)
64185 +               {
64186 +                       PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne));
64187 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
64188 +               }
64189 +       }
64190 +
64191 +       PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta);
64192 +
64193 +
64194 +       eError = ReallocHandleArray(psBase, ui32NewTotalHandCount, psBase->ui32TotalHandCount);
64195 +       if (eError != PVRSRV_OK)
64196 +       {
64197 +               PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
64198 +               return eError;
64199 +       }
64200 +
64201 +
64202 +       for(psHandle = psBase->psHandleArray + psBase->ui32TotalHandCount;
64203 +               psHandle < psBase->psHandleArray + ui32NewTotalHandCount;
64204 +               psHandle++)
64205 +       {
64206 +               psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
64207 +               psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
64208 +               psHandle->ui32NextIndexPlusOne  = 0;
64209 +       }
64210 +
64211 +
64212 +       psBase->ui32FreeHandCount += ui32DeltaAdjusted;
64213 +
64214 +       if (psBase->ui32FirstFreeIndex == 0)
64215 +       {
64216 +               PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
64217 +
64218 +               psBase->ui32FirstFreeIndex = psBase->ui32TotalHandCount;
64219 +       }
64220 +       else
64221 +       {
64222 +               if (!psBase->bPurgingEnabled)
64223 +               {
64224 +                       PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0)
64225 +                       PVR_ASSERT(INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
64226 +
64227 +                       INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = psBase->ui32TotalHandCount + 1;
64228 +               }
64229 +       }
64230 +
64231 +       if (!psBase->bPurgingEnabled)
64232 +       {
64233 +               psBase->ui32LastFreeIndexPlusOne = ui32NewTotalHandCount;
64234 +       }
64235 +
64236 +       psBase->ui32TotalHandCount = ui32NewTotalHandCount;
64237 +
64238 +       return PVRSRV_OK;
64239 +}
64240 +
64241 +static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free)
64242 +{
64243 +       PVRSRV_ERROR eError;
64244 +
64245 +       if (ui32Free > psBase->ui32FreeHandCount)
64246 +       {
64247 +               IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount;
64248 +               eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta);
64249 +               if (eError != PVRSRV_OK)
64250 +               {
64251 +                       PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError));
64252 +
64253 +                       return eError;
64254 +               }
64255 +       }
64256 +
64257 +       return PVRSRV_OK;
64258 +}
64259 +
64260 +static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
64261 +{
64262 +       IMG_UINT32 ui32NewIndex;
64263 +       struct sHandle *psNewHandle = IMG_NULL;
64264 +       IMG_HANDLE hHandle;
64265 +       HAND_KEY aKey;
64266 +       PVRSRV_ERROR eError;
64267 +
64268 +
64269 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64270 +
64271 +       PVR_ASSERT(psBase->psHashTab != IMG_NULL);
64272 +
64273 +       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
64274 +       {
64275 +
64276 +               PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL);
64277 +       }
64278 +
64279 +       if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase))
64280 +       {
64281 +                PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize));
64282 +       }
64283 +
64284 +
64285 +       eError = EnsureFreeHandles(psBase, 1);
64286 +       if (eError != PVRSRV_OK)
64287 +       {
64288 +               PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError));
64289 +               return eError;
64290 +       }
64291 +       PVR_ASSERT(psBase->ui32FreeHandCount != 0)
64292 +
64293 +       if (!psBase->bPurgingEnabled)
64294 +       {
64295 +
64296 +               ui32NewIndex = psBase->ui32FirstFreeIndex;
64297 +
64298 +
64299 +               psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex);
64300 +       }
64301 +       else
64302 +       {
64303 +
64304 +               for(ui32NewIndex = psBase->ui32FirstFreeIndex; ui32NewIndex < psBase->ui32TotalHandCount; ui32NewIndex++)
64305 +               {
64306 +                       psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex);
64307 +                       if (HANDLE_STRUCT_IS_FREE(psNewHandle))
64308 +                       {
64309 +                               break;
64310 +                       }
64311 +
64312 +               }
64313 +               psBase->ui32FirstFreeIndex = 0;
64314 +               PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount);
64315 +       }
64316 +       PVR_ASSERT(psNewHandle != IMG_NULL);
64317 +
64318 +
64319 +       hHandle = INDEX_TO_HANDLE(psBase, ui32NewIndex);
64320 +
64321 +
64322 +       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
64323 +       {
64324 +
64325 +               InitKey(aKey, psBase, pvData, eType, hParent);
64326 +
64327 +
64328 +               if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
64329 +               {
64330 +                       PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
64331 +
64332 +                       return PVRSRV_ERROR_GENERIC;
64333 +               }
64334 +       }
64335 +
64336 +       psBase->ui32FreeHandCount--;
64337 +
64338 +
64339 +       if (!psBase->bPurgingEnabled)
64340 +       {
64341 +
64342 +               if (psBase->ui32FreeHandCount == 0)
64343 +               {
64344 +                       PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex);
64345 +                       PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1));
64346 +
64347 +                       psBase->ui32LastFreeIndexPlusOne = 0;
64348 +                       psBase->ui32FirstFreeIndex = 0;
64349 +               }
64350 +               else
64351 +               {
64352 +
64353 +                       psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
64354 +                               ui32NewIndex + 1 :
64355 +                               psNewHandle->ui32NextIndexPlusOne - 1;
64356 +               }
64357 +       }
64358 +
64359 +
64360 +       psNewHandle->eType = eType;
64361 +       psNewHandle->pvData = pvData;
64362 +       psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
64363 +       psNewHandle->eFlag = eFlag;
64364 +       psNewHandle->ui32Index = ui32NewIndex;
64365 +
64366 +       InitParentList(psBase, psNewHandle);
64367 +#if defined(DEBUG)
64368 +       PVR_ASSERT(NoChildren(psBase, psNewHandle));
64369 +#endif
64370 +
64371 +       InitChildEntry(psBase, psNewHandle);
64372 +#if defined(DEBUG)
64373 +       PVR_ASSERT(NoParent(psBase, psNewHandle));
64374 +#endif
64375 +
64376 +       if (HANDLES_BATCHED(psBase))
64377 +       {
64378 +
64379 +               psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
64380 +
64381 +               psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
64382 +
64383 +               SET_BATCHED_HANDLE(psNewHandle);
64384 +       }
64385 +       else
64386 +       {
64387 +               psNewHandle->ui32NextIndexPlusOne = 0;
64388 +       }
64389 +
64390 +
64391 +       *phHandle = hHandle;
64392 +
64393 +       return PVRSRV_OK;
64394 +}
64395 +
64396 +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
64397 +{
64398 +       IMG_HANDLE hHandle;
64399 +       PVRSRV_ERROR eError;
64400 +
64401 +       *phHandle = IMG_NULL;
64402 +
64403 +       if (HANDLES_BATCHED(psBase))
64404 +       {
64405 +
64406 +               psBase->ui32BatchHandAllocFailures++;
64407 +       }
64408 +
64409 +
64410 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64411 +
64412 +       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
64413 +       {
64414 +
64415 +               hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
64416 +               if (hHandle != IMG_NULL)
64417 +               {
64418 +                       struct sHandle *psHandle;
64419 +
64420 +                       eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
64421 +                       if (eError != PVRSRV_OK)
64422 +                       {
64423 +                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed"));
64424 +                               return eError;
64425 +                       }
64426 +
64427 +
64428 +                       if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
64429 +                       {
64430 +                               *phHandle = hHandle;
64431 +                               eError = PVRSRV_OK;
64432 +                               goto exit_ok;
64433 +                       }
64434 +                       return PVRSRV_ERROR_GENERIC;
64435 +               }
64436 +       }
64437 +
64438 +       eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
64439 +
64440 +exit_ok:
64441 +       if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
64442 +       {
64443 +               psBase->ui32BatchHandAllocFailures--;
64444 +       }
64445 +
64446 +       return eError;
64447 +}
64448 +
64449 +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
64450 +{
64451 +       struct sHandle *psPHand;
64452 +       struct sHandle *psCHand;
64453 +       PVRSRV_ERROR eError;
64454 +       IMG_HANDLE hParentKey;
64455 +       IMG_HANDLE hHandle;
64456 +
64457 +       *phHandle = IMG_NULL;
64458 +
64459 +       if (HANDLES_BATCHED(psBase))
64460 +       {
64461 +
64462 +               psBase->ui32BatchHandAllocFailures++;
64463 +       }
64464 +
64465 +
64466 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64467 +
64468 +       hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
64469 +                       hParent : IMG_NULL;
64470 +
64471 +
64472 +       eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
64473 +       if (eError != PVRSRV_OK)
64474 +       {
64475 +               return PVRSRV_ERROR_GENERIC;
64476 +       }
64477 +
64478 +       if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
64479 +       {
64480 +
64481 +               hHandle = FindHandle(psBase, pvData, eType, hParentKey);
64482 +               if (hHandle != IMG_NULL)
64483 +               {
64484 +                       struct sHandle *psCHandle;
64485 +                       PVRSRV_ERROR eErr;
64486 +
64487 +                       eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType);
64488 +                       if (eErr != PVRSRV_OK)
64489 +                       {
64490 +                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
64491 +                               return eErr;
64492 +                       }
64493 +
64494 +                       PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_PTR(psBase, hHandle)) == hParent);
64495 +
64496 +
64497 +                       if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_PTR(psBase, hHandle)) == hParent)
64498 +                       {
64499 +                               *phHandle = hHandle;
64500 +                               goto exit_ok;
64501 +                       }
64502 +                       return PVRSRV_ERROR_GENERIC;
64503 +               }
64504 +       }
64505 +
64506 +       eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
64507 +       if (eError != PVRSRV_OK)
64508 +       {
64509 +               return eError;
64510 +       }
64511 +
64512 +
64513 +       psPHand = HANDLE_TO_HANDLE_PTR(psBase, hParent);
64514 +
64515 +       psCHand = HANDLE_TO_HANDLE_PTR(psBase, hHandle);
64516 +
64517 +       AdoptChild(psBase, psPHand, psCHand);
64518 +
64519 +       *phHandle = hHandle;
64520 +
64521 +exit_ok:
64522 +       if (HANDLES_BATCHED(psBase))
64523 +       {
64524 +               psBase->ui32BatchHandAllocFailures--;
64525 +       }
64526 +
64527 +       return PVRSRV_OK;
64528 +}
64529 +
64530 +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
64531 +{
64532 +       IMG_HANDLE hHandle;
64533 +
64534 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64535 +
64536 +
64537 +       hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
64538 +       if (hHandle == IMG_NULL)
64539 +       {
64540 +               return PVRSRV_ERROR_GENERIC;
64541 +       }
64542 +
64543 +       *phHandle = hHandle;
64544 +
64545 +       return PVRSRV_OK;
64546 +}
64547 +
64548 +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
64549 +{
64550 +       struct sHandle *psHandle;
64551 +       PVRSRV_ERROR eError;
64552 +
64553 +       eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE);
64554 +       if (eError != PVRSRV_OK)
64555 +       {
64556 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError));
64557 +               return eError;
64558 +       }
64559 +
64560 +       *ppvData = psHandle->pvData;
64561 +       *peType = psHandle->eType;
64562 +
64563 +       return PVRSRV_OK;
64564 +}
64565 +
64566 +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
64567 +{
64568 +       struct sHandle *psHandle;
64569 +       PVRSRV_ERROR eError;
64570 +
64571 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64572 +
64573 +       eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
64574 +       if (eError != PVRSRV_OK)
64575 +       {
64576 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
64577 +               return eError;
64578 +       }
64579 +
64580 +       *ppvData = psHandle->pvData;
64581 +
64582 +       return PVRSRV_OK;
64583 +}
64584 +
64585 +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
64586 +{
64587 +       struct sHandle *psPHand;
64588 +       struct sHandle *psCHand;
64589 +       PVRSRV_ERROR eError;
64590 +
64591 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64592 +
64593 +       eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
64594 +       if (eError != PVRSRV_OK)
64595 +       {
64596 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
64597 +               return eError;
64598 +       }
64599 +
64600 +
64601 +       for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; )
64602 +       {
64603 +               eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE);
64604 +               if (eError != PVRSRV_OK)
64605 +               {
64606 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
64607 +                       return PVRSRV_ERROR_GENERIC;
64608 +               }
64609 +       }
64610 +
64611 +       *ppvData = psCHand->pvData;
64612 +
64613 +       return PVRSRV_OK;
64614 +}
64615 +
64616 +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
64617 +{
64618 +       struct sHandle *psHandle;
64619 +       PVRSRV_ERROR eError;
64620 +
64621 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64622 +
64623 +       eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
64624 +       if (eError != PVRSRV_OK)
64625 +       {
64626 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError));
64627 +               return eError;
64628 +       }
64629 +
64630 +       *phParent = ParentHandle(psHandle);
64631 +
64632 +       return PVRSRV_OK;
64633 +}
64634 +
64635 +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
64636 +{
64637 +       struct sHandle *psHandle;
64638 +       PVRSRV_ERROR eError;
64639 +
64640 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64641 +
64642 +       eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
64643 +       if (eError != PVRSRV_OK)
64644 +       {
64645 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError));
64646 +               return eError;
64647 +       }
64648 +
64649 +       *ppvData = psHandle->pvData;
64650 +
64651 +       eError = FreeHandle(psBase, psHandle);
64652 +
64653 +       return eError;
64654 +}
64655 +
64656 +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
64657 +{
64658 +       struct sHandle *psHandle;
64659 +       PVRSRV_ERROR eError;
64660 +
64661 +       PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
64662 +
64663 +       eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
64664 +       if (eError != PVRSRV_OK)
64665 +       {
64666 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError));
64667 +               return eError;
64668 +       }
64669 +
64670 +       eError = FreeHandle(psBase, psHandle);
64671 +
64672 +       return eError;
64673 +}
64674 +
64675 +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
64676 +{
64677 +       PVRSRV_ERROR eError;
64678 +
64679 +       if (HANDLES_BATCHED(psBase))
64680 +       {
64681 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize));
64682 +               return  PVRSRV_ERROR_GENERIC;
64683 +       }
64684 +
64685 +       if (ui32BatchSize == 0)
64686 +       {
64687 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize));
64688 +               return  PVRSRV_ERROR_INVALID_PARAMS;
64689 +       }
64690 +
64691 +       eError = EnsureFreeHandles(psBase, ui32BatchSize);
64692 +       if (eError != PVRSRV_OK)
64693 +       {
64694 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError));
64695 +               return eError;
64696 +       }
64697 +
64698 +       psBase->ui32HandBatchSize = ui32BatchSize;
64699 +
64700 +
64701 +       psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
64702 +
64703 +       PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0);
64704 +
64705 +       PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0);
64706 +
64707 +       PVR_ASSERT(HANDLES_BATCHED(psBase));
64708 +
64709 +       return PVRSRV_OK;
64710 +}
64711 +
64712 +static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit)
64713 +{
64714 +
64715 +       IMG_UINT32 ui32IndexPlusOne;
64716 +       IMG_BOOL bCommitBatch = bCommit;
64717 +
64718 +       if (!HANDLES_BATCHED(psBase))
64719 +       {
64720 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch"));
64721 +               return PVRSRV_ERROR_INVALID_PARAMS;
64722 +
64723 +       }
64724 +
64725 +       if (psBase->ui32BatchHandAllocFailures != 0)
64726 +       {
64727 +               if (bCommit)
64728 +               {
64729 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures."));
64730 +               }
64731 +               bCommitBatch = IMG_FALSE;
64732 +       }
64733 +
64734 +       PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit);
64735 +
64736 +       ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
64737 +       while(ui32IndexPlusOne != 0)
64738 +       {
64739 +               struct sHandle *psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32IndexPlusOne - 1);
64740 +               IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne;
64741 +               PVR_ASSERT(BATCHED_HANDLE(psHandle));
64742 +
64743 +               psHandle->ui32NextIndexPlusOne = 0;
64744 +
64745 +               if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
64746 +               {
64747 +                       PVRSRV_ERROR eError;
64748 +
64749 +
64750 +                       if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
64751 +                       {
64752 +                               SET_UNBATCHED_HANDLE(psHandle);
64753 +                       }
64754 +
64755 +                       eError = FreeHandle(psBase, psHandle);
64756 +                       if (eError != PVRSRV_OK)
64757 +                       {
64758 +                                PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError));
64759 +                       }
64760 +                       PVR_ASSERT(eError == PVRSRV_OK);
64761 +               }
64762 +               else
64763 +               {
64764 +                       SET_UNBATCHED_HANDLE(psHandle);
64765 +               }
64766 +
64767 +               ui32IndexPlusOne = ui32NextIndexPlusOne;
64768 +       }
64769 +
64770 +#ifdef DEBUG
64771 +       if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount)
64772 +       {
64773 +               IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch;
64774 +
64775 +               PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch);
64776 +
64777 +               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));
64778 +
64779 +       }
64780 +#endif
64781 +
64782 +       psBase->ui32HandBatchSize = 0;
64783 +       psBase->ui32FirstBatchIndexPlusOne = 0;
64784 +       psBase->ui32TotalHandCountPreBatch = 0;
64785 +       psBase->ui32BatchHandAllocFailures = 0;
64786 +
64787 +       if (psBase->ui32BatchHandAllocFailures != 0 && bCommit)
64788 +       {
64789 +               PVR_ASSERT(!bCommitBatch);
64790 +
64791 +               return PVRSRV_ERROR_GENERIC;
64792 +       }
64793 +
64794 +       return PVRSRV_OK;
64795 +}
64796 +
64797 +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
64798 +{
64799 +       return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
64800 +}
64801 +
64802 +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
64803 +{
64804 +       (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
64805 +}
64806 +
64807 +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
64808 +{
64809 +       if (HANDLES_BATCHED(psBase))
64810 +       {
64811 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
64812 +               return PVRSRV_ERROR_INVALID_PARAMS;
64813 +       }
64814 +
64815 +
64816 +       if (ui32MaxHandle == 0 || ui32MaxHandle >= DEFAULT_MAX_HANDLE)
64817 +       {
64818 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE));
64819 +
64820 +               return PVRSRV_ERROR_INVALID_PARAMS;
64821 +       }
64822 +
64823 +
64824 +       if (psBase->ui32TotalHandCount != 0)
64825 +       {
64826 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set becuase handles have already been allocated"));
64827 +
64828 +               return PVRSRV_ERROR_INVALID_PARAMS;
64829 +       }
64830 +
64831 +       psBase->ui32MaxIndexPlusOne = ui32MaxHandle;
64832 +
64833 +       return PVRSRV_OK;
64834 +}
64835 +
64836 +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
64837 +{
64838 +       return psBase->ui32MaxIndexPlusOne;
64839 +}
64840 +
64841 +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
64842 +{
64843 +       if (psBase->bPurgingEnabled)
64844 +       {
64845 +               PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
64846 +               return PVRSRV_OK;
64847 +       }
64848 +
64849 +
64850 +       if (psBase->ui32TotalHandCount != 0)
64851 +       {
64852 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated"));
64853 +               return PVRSRV_ERROR_INVALID_PARAMS;
64854 +       }
64855 +
64856 +       psBase->bPurgingEnabled = IMG_TRUE;
64857 +
64858 +       return PVRSRV_OK;
64859 +}
64860 +
64861 +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
64862 +{
64863 +       IMG_UINT32 ui32Handle;
64864 +       IMG_UINT32 ui32NewHandCount;
64865 +
64866 +       if (!psBase->bPurgingEnabled)
64867 +       {
64868 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base"));
64869 +               return PVRSRV_ERROR_NOT_SUPPORTED;
64870 +       }
64871 +
64872 +       if (HANDLES_BATCHED(psBase))
64873 +       {
64874 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode"));
64875 +               return PVRSRV_ERROR_INVALID_PARAMS;
64876 +       }
64877 +
64878 +       for (ui32Handle = psBase->ui32TotalHandCount; ui32Handle != 0; ui32Handle--)
64879 +       {
64880 +               struct sHandle *psHandle = HANDLE_TO_HANDLE_PTR(psBase, ui32Handle);
64881 +               if (!HANDLE_STRUCT_IS_FREE(psHandle))
64882 +               {
64883 +                       break;
64884 +               }
64885 +       }
64886 +
64887 +       ui32NewHandCount = ROUND_UP_TO_MULTIPLE(ui32Handle, HANDLE_BLOCK_SIZE);
64888 +
64889 +
64890 +       if (ui32NewHandCount >= ui32Handle && ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
64891 +       {
64892 +               IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - ui32NewHandCount;
64893 +               PVRSRV_ERROR eError;
64894 +
64895 +
64896 +
64897 +               eError = ReallocHandleArray(psBase, ui32NewHandCount, psBase->ui32TotalHandCount);
64898 +               if (eError != PVRSRV_OK)
64899 +               {
64900 +                       return eError;
64901 +               }
64902 +
64903 +
64904 +               psBase->ui32TotalHandCount = ui32NewHandCount;
64905 +               psBase->ui32FreeHandCount -= ui32Delta;
64906 +               psBase->ui32FirstFreeIndex = 0;
64907 +       }
64908 +
64909 +       return PVRSRV_OK;
64910 +}
64911 +
64912 +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
64913 +{
64914 +       PVRSRV_HANDLE_BASE *psBase;
64915 +       IMG_HANDLE hBlockAlloc;
64916 +       PVRSRV_ERROR eError;
64917 +
64918 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
64919 +               sizeof(*psBase),
64920 +               (IMG_PVOID *)&psBase,
64921 +               &hBlockAlloc,
64922 +               "Handle Base");
64923 +       if (eError != PVRSRV_OK)
64924 +       {
64925 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
64926 +               return eError;
64927 +       }
64928 +       OSMemSet(psBase, 0, sizeof(*psBase));
64929 +
64930 +
64931 +       psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default);
64932 +       if (psBase->psHashTab == IMG_NULL)
64933 +       {
64934 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n"));
64935 +               goto failure;
64936 +       }
64937 +
64938 +       psBase->hBaseBlockAlloc = hBlockAlloc;
64939 +
64940 +       psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
64941 +
64942 +       *ppsBase = psBase;
64943 +
64944 +       return PVRSRV_OK;
64945 +failure:
64946 +       (IMG_VOID)PVRSRVFreeHandleBase(psBase);
64947 +       return PVRSRV_ERROR_GENERIC;
64948 +}
64949 +
64950 +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
64951 +{
64952 +       PVRSRV_ERROR eError;
64953 +
64954 +       PVR_ASSERT(psBase != gpsKernelHandleBase);
64955 +
64956 +       eError = FreeHandleBase(psBase);
64957 +       if (eError != PVRSRV_OK)
64958 +       {
64959 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError));
64960 +       }
64961 +
64962 +       return eError;
64963 +}
64964 +
64965 +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
64966 +{
64967 +       PVRSRV_ERROR eError;
64968 +
64969 +       PVR_ASSERT(gpsKernelHandleBase == IMG_NULL);
64970 +
64971 +       eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
64972 +       if (eError != PVRSRV_OK)
64973 +       {
64974 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError));
64975 +               goto error;
64976 +       }
64977 +
64978 +       eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase);
64979 +       if (eError != PVRSRV_OK)
64980 +       {
64981 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError));
64982 +               goto error;
64983 +       }
64984 +
64985 +       return PVRSRV_OK;
64986 +error:
64987 +       (IMG_VOID) PVRSRVHandleDeInit();
64988 +       return eError;
64989 +}
64990 +
64991 +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
64992 +{
64993 +       PVRSRV_ERROR eError = PVRSRV_OK;
64994 +
64995 +       if (gpsKernelHandleBase != IMG_NULL)
64996 +       {
64997 +               eError = FreeHandleBase(gpsKernelHandleBase);
64998 +               if (eError == PVRSRV_OK)
64999 +               {
65000 +                       gpsKernelHandleBase = IMG_NULL;
65001 +               }
65002 +               else
65003 +               {
65004 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError));
65005 +               }
65006 +       }
65007 +
65008 +       return eError;
65009 +}
65010 +#else
65011 +#endif
65012 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/hash.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/hash.c
65013 new file mode 100644
65014 index 0000000..489a9c5
65015 --- /dev/null
65016 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/hash.c
65017 @@ -0,0 +1,463 @@
65018 +/**********************************************************************
65019 + *
65020 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
65021 + *
65022 + * This program is free software; you can redistribute it and/or modify it
65023 + * under the terms and conditions of the GNU General Public License,
65024 + * version 2, as published by the Free Software Foundation.
65025 + *
65026 + * This program is distributed in the hope it will be useful but, except
65027 + * as otherwise stated in writing, without any warranty; without even the
65028 + * implied warranty of merchantability or fitness for a particular purpose.
65029 + * See the GNU General Public License for more details.
65030 + *
65031 + * You should have received a copy of the GNU General Public License along with
65032 + * this program; if not, write to the Free Software Foundation, Inc.,
65033 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
65034 + *
65035 + * The full GNU General Public License is included in this distribution in
65036 + * the file called "COPYING".
65037 + *
65038 + * Contact Information:
65039 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
65040 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
65041 + *
65042 + ******************************************************************************/
65043 +
65044 +#include "pvr_debug.h"
65045 +#include "img_defs.h"
65046 +#include "services.h"
65047 +#include "servicesint.h"
65048 +#include "hash.h"
65049 +#include "osfunc.h"
65050 +
65051 +#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b))
65052 +
65053 +#define        KEY_TO_INDEX(pHash, key, uSize) \
65054 +       ((pHash)->pfnHashFunc((pHash)->uKeySize, key, uSize) % uSize)
65055 +
65056 +#define        KEY_COMPARE(pHash, pKey1, pKey2) \
65057 +       ((pHash)->pfnKeyComp((pHash)->uKeySize, pKey1, pKey2))
65058 +
65059 +struct _BUCKET_
65060 +{
65061 +
65062 +       struct _BUCKET_ *pNext;
65063 +
65064 +
65065 +       IMG_UINTPTR_T v;
65066 +
65067 +
65068 +       IMG_UINTPTR_T k[];
65069 +};
65070 +typedef struct _BUCKET_ BUCKET;
65071 +
65072 +struct _HASH_TABLE_
65073 +{
65074 +
65075 +       BUCKET **ppBucketTable;
65076 +
65077 +
65078 +       IMG_UINT32 uSize;
65079 +
65080 +
65081 +       IMG_UINT32 uCount;
65082 +
65083 +
65084 +       IMG_UINT32 uMinimumSize;
65085 +
65086 +
65087 +       IMG_UINT32 uKeySize;
65088 +
65089 +
65090 +       HASH_FUNC *pfnHashFunc;
65091 +
65092 +
65093 +       HASH_KEY_COMP *pfnKeyComp;
65094 +};
65095 +
65096 +IMG_UINT32
65097 +HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen)
65098 +{
65099 +       IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey;
65100 +       IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T);
65101 +       IMG_UINT32 ui;
65102 +       IMG_UINT32 uHashKey = 0;
65103 +
65104 +       PVR_UNREFERENCED_PARAMETER(uHashTabLen);
65105 +
65106 +       PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
65107 +
65108 +       for (ui = 0; ui < uKeyLen; ui++)
65109 +       {
65110 +               IMG_UINT32 uHashPart = (IMG_UINT32)*p++;
65111 +
65112 +               uHashPart += (uHashPart << 12);
65113 +               uHashPart ^= (uHashPart >> 22);
65114 +               uHashPart += (uHashPart << 4);
65115 +               uHashPart ^= (uHashPart >> 9);
65116 +               uHashPart += (uHashPart << 10);
65117 +               uHashPart ^= (uHashPart >> 2);
65118 +               uHashPart += (uHashPart << 7);
65119 +               uHashPart ^= (uHashPart >> 12);
65120 +
65121 +               uHashKey += uHashPart;
65122 +       }
65123 +
65124 +       return uHashKey;
65125 +}
65126 +
65127 +IMG_BOOL
65128 +HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2)
65129 +{
65130 +       IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1;
65131 +       IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2;
65132 +       IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T);
65133 +       IMG_UINT32 ui;
65134 +
65135 +       PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0);
65136 +
65137 +       for (ui = 0; ui < uKeyLen; ui++)
65138 +       {
65139 +               if (*p1++ != *p2++)
65140 +                       return IMG_FALSE;
65141 +       }
65142 +
65143 +       return IMG_TRUE;
65144 +}
65145 +
65146 +static PVRSRV_ERROR
65147 +_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
65148 +{
65149 +       IMG_UINT32 uIndex;
65150 +
65151 +       PVR_ASSERT (pBucket != IMG_NULL);
65152 +       PVR_ASSERT (ppBucketTable != IMG_NULL);
65153 +       PVR_ASSERT (uSize != 0);
65154 +
65155 +       if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0))
65156 +       {
65157 +               PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter"));
65158 +               return PVRSRV_ERROR_INVALID_PARAMS;
65159 +       }
65160 +
65161 +       uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize);
65162 +       pBucket->pNext = ppBucketTable[uIndex];
65163 +       ppBucketTable[uIndex] = pBucket;
65164 +
65165 +       return PVRSRV_OK;
65166 +}
65167 +
65168 +static PVRSRV_ERROR
65169 +_Rehash (HASH_TABLE *pHash,
65170 +        BUCKET **ppOldTable, IMG_UINT32 uOldSize,
65171 +         BUCKET **ppNewTable, IMG_UINT32 uNewSize)
65172 +{
65173 +       IMG_UINT32 uIndex;
65174 +       for (uIndex=0; uIndex< uOldSize; uIndex++)
65175 +    {
65176 +               BUCKET *pBucket;
65177 +               pBucket = ppOldTable[uIndex];
65178 +               while (pBucket != IMG_NULL)
65179 +               {
65180 +                       BUCKET *pNextBucket = pBucket->pNext;
65181 +                       if (_ChainInsert (pHash, pBucket, ppNewTable, uNewSize) != PVRSRV_OK)
65182 +                       {
65183 +                               PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed"));
65184 +                               return PVRSRV_ERROR_GENERIC;
65185 +                       }
65186 +                       pBucket = pNextBucket;
65187 +               }
65188 +    }
65189 +       return PVRSRV_OK;
65190 +}
65191 +
65192 +static IMG_BOOL
65193 +_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize)
65194 +{
65195 +       if (uNewSize != pHash->uSize)
65196 +    {
65197 +               BUCKET **ppNewTable;
65198 +        IMG_UINT32 uIndex;
65199 +
65200 +               PVR_DPF ((PVR_DBG_MESSAGE,
65201 +                  "HASH_Resize: oldsize=0x%x  newsize=0x%x  count=0x%x",
65202 +                               pHash->uSize, uNewSize, pHash->uCount));
65203 +
65204 +               OSAllocMem(PVRSRV_PAGEABLE_SELECT,
65205 +                      sizeof (BUCKET *) * uNewSize,
65206 +                      (IMG_PVOID*)&ppNewTable, IMG_NULL,
65207 +                                         "Hash Table Buckets");
65208 +               if (ppNewTable == IMG_NULL)
65209 +            return IMG_FALSE;
65210 +
65211 +        for (uIndex=0; uIndex<uNewSize; uIndex++)
65212 +            ppNewTable[uIndex] = IMG_NULL;
65213 +
65214 +        if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK)
65215 +               {
65216 +                       return IMG_FALSE;
65217 +               }
65218 +
65219 +        OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
65220 +
65221 +        pHash->ppBucketTable = ppNewTable;
65222 +        pHash->uSize = uNewSize;
65223 +    }
65224 +    return IMG_TRUE;
65225 +}
65226 +
65227 +
65228 +HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp)
65229 +{
65230 +       HASH_TABLE *pHash;
65231 +       IMG_UINT32 uIndex;
65232 +
65233 +       PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen));
65234 +
65235 +       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
65236 +                                       sizeof(HASH_TABLE),
65237 +                                       (IMG_VOID **)&pHash, IMG_NULL,
65238 +                                       "Hash Table") != PVRSRV_OK)
65239 +       {
65240 +               return IMG_NULL;
65241 +       }
65242 +
65243 +       pHash->uCount = 0;
65244 +       pHash->uSize = uInitialLen;
65245 +       pHash->uMinimumSize = uInitialLen;
65246 +       pHash->uKeySize = uKeySize;
65247 +       pHash->pfnHashFunc = pfnHashFunc;
65248 +       pHash->pfnKeyComp = pfnKeyComp;
65249 +
65250 +       OSAllocMem(PVRSRV_PAGEABLE_SELECT,
65251 +                  sizeof (BUCKET *) * pHash->uSize,
65252 +                  (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL,
65253 +                                 "Hash Table Buckets");
65254 +
65255 +       if (pHash->ppBucketTable == IMG_NULL)
65256 +    {
65257 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
65258 +
65259 +               return IMG_NULL;
65260 +    }
65261 +
65262 +       for (uIndex=0; uIndex<pHash->uSize; uIndex++)
65263 +               pHash->ppBucketTable[uIndex] = IMG_NULL;
65264 +       return pHash;
65265 +}
65266 +
65267 +HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
65268 +{
65269 +       return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
65270 +               &HASH_Func_Default, &HASH_Key_Comp_Default);
65271 +}
65272 +
65273 +IMG_VOID
65274 +HASH_Delete (HASH_TABLE *pHash)
65275 +{
65276 +       if (pHash != IMG_NULL)
65277 +    {
65278 +               PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete"));
65279 +
65280 +               PVR_ASSERT (pHash->uCount==0);
65281 +               if(pHash->uCount != 0)
65282 +               {
65283 +                       PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
65284 +                       PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
65285 +               }
65286 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
65287 +               pHash->ppBucketTable = IMG_NULL;
65288 +               OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
65289 +
65290 +    }
65291 +}
65292 +
65293 +IMG_BOOL
65294 +HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v)
65295 +{
65296 +       BUCKET *pBucket;
65297 +
65298 +       PVR_DPF ((PVR_DBG_MESSAGE,
65299 +              "HASH_Insert_Extended: Hash=%08X, pKey=%08X, v=0x%x", pHash, pKey, v));
65300 +
65301 +       PVR_ASSERT (pHash != IMG_NULL);
65302 +
65303 +       if (pHash == IMG_NULL)
65304 +       {
65305 +               PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter"));
65306 +               return IMG_FALSE;
65307 +       }
65308 +
65309 +       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
65310 +                                       sizeof(BUCKET) + pHash->uKeySize,
65311 +                                       (IMG_VOID **)&pBucket, IMG_NULL,
65312 +                                       "Hash Table entry") != PVRSRV_OK)
65313 +       {
65314 +               return IMG_FALSE;
65315 +       }
65316 +
65317 +       pBucket->v = v;
65318 +
65319 +       OSMemCopy(pBucket->k, pKey, pHash->uKeySize);
65320 +       if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
65321 +       {
65322 +               return IMG_FALSE;
65323 +       }
65324 +
65325 +       pHash->uCount++;
65326 +
65327 +
65328 +       if (pHash->uCount << 1 > pHash->uSize)
65329 +    {
65330 +
65331 +
65332 +        _Resize (pHash, pHash->uSize << 1);
65333 +    }
65334 +
65335 +
65336 +       return IMG_TRUE;
65337 +}
65338 +
65339 +IMG_BOOL
65340 +HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
65341 +{
65342 +       PVR_DPF ((PVR_DBG_MESSAGE,
65343 +              "HASH_Insert: Hash=%08X, k=0x%x, v=0x%x", pHash, k, v));
65344 +
65345 +       return HASH_Insert_Extended(pHash, &k, v);
65346 +}
65347 +
65348 +IMG_UINTPTR_T
65349 +HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
65350 +{
65351 +       BUCKET **ppBucket;
65352 +       IMG_UINT32 uIndex;
65353 +
65354 +       PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=%08X, pKey=%08X", pHash, pKey));
65355 +
65356 +       PVR_ASSERT (pHash != IMG_NULL);
65357 +
65358 +       if (pHash == IMG_NULL)
65359 +       {
65360 +               PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table"));
65361 +               return 0;
65362 +       }
65363 +
65364 +       uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
65365 +
65366 +       for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
65367 +       {
65368 +
65369 +               if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
65370 +               {
65371 +                       BUCKET *pBucket = *ppBucket;
65372 +                       IMG_UINTPTR_T v = pBucket->v;
65373 +                       (*ppBucket) = pBucket->pNext;
65374 +
65375 +                       OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL);
65376 +
65377 +
65378 +                       pHash->uCount--;
65379 +
65380 +
65381 +                       if (pHash->uSize > (pHash->uCount << 2) &&
65382 +                pHash->uSize > pHash->uMinimumSize)
65383 +            {
65384 +
65385 +
65386 +                               _Resize (pHash,
65387 +                         PRIVATE_MAX (pHash->uSize >> 1,
65388 +                                      pHash->uMinimumSize));
65389 +            }
65390 +
65391 +                       PVR_DPF ((PVR_DBG_MESSAGE,
65392 +                      "HASH_Remove_Extended: Hash=%08X, pKey=%08X = 0x%x",
65393 +                      pHash, pKey, v));
65394 +                       return v;
65395 +               }
65396 +       }
65397 +       PVR_DPF ((PVR_DBG_MESSAGE,
65398 +              "HASH_Remove_Extended: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, pKey));
65399 +       return 0;
65400 +}
65401 +
65402 +IMG_UINTPTR_T
65403 +HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
65404 +{
65405 +       PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=%08X, k=0x%x", pHash, k));
65406 +
65407 +       return HASH_Remove_Extended(pHash, &k);
65408 +}
65409 +
65410 +IMG_UINTPTR_T
65411 +HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
65412 +{
65413 +       BUCKET **ppBucket;
65414 +       IMG_UINT32 uIndex;
65415 +
65416 +       PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=%08X, pKey=%08X", pHash,pKey));
65417 +
65418 +       PVR_ASSERT (pHash != IMG_NULL);
65419 +
65420 +       if (pHash == IMG_NULL)
65421 +       {
65422 +               PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table"));
65423 +               return 0;
65424 +       }
65425 +
65426 +       uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
65427 +
65428 +       for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
65429 +       {
65430 +
65431 +               if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
65432 +               {
65433 +                       BUCKET *pBucket = *ppBucket;
65434 +                       IMG_UINTPTR_T v = pBucket->v;
65435 +
65436 +                       PVR_DPF ((PVR_DBG_MESSAGE,
65437 +                      "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x%x",
65438 +                      pHash, pKey, v));
65439 +                       return v;
65440 +               }
65441 +       }
65442 +       PVR_DPF ((PVR_DBG_MESSAGE,
65443 +              "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, pKey));
65444 +       return 0;
65445 +}
65446 +
65447 +IMG_UINTPTR_T
65448 +HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
65449 +{
65450 +       PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=%08X, k=0x%x", pHash,k));
65451 +       return HASH_Retrieve_Extended(pHash, &k);
65452 +}
65453 +
65454 +#ifdef HASH_TRACE
65455 +IMG_VOID
65456 +HASH_Dump (HASH_TABLE *pHash)
65457 +{
65458 +       IMG_UINT32 uIndex;
65459 +       IMG_UINT32 uMaxLength=0;
65460 +       IMG_UINT32 uEmptyCount=0;
65461 +
65462 +       PVR_ASSERT (pHash != IMG_NULL);
65463 +       for (uIndex=0; uIndex<pHash->uSize; uIndex++)
65464 +       {
65465 +               BUCKET *pBucket;
65466 +               IMG_UINT32 uLength = 0;
65467 +               if (pHash->ppBucketTable[uIndex] == IMG_NULL)
65468 +                       uEmptyCount++;
65469 +               for (pBucket=pHash->ppBucketTable[uIndex];
65470 +                       pBucket != IMG_NULL;
65471 +                       pBucket = pBucket->pNext)
65472 +                               uLength++;
65473 +               uMaxLength = PRIVATE_MAX (uMaxLength, uLength);
65474 +       }
65475 +
65476 +       PVR_TRACE(("hash table: uMinimumSize=%d  size=%d  count=%d",
65477 +                       pHash->uMinimumSize, pHash->uSize, pHash->uCount));
65478 +       PVR_TRACE(("  empty=%d  max=%d", uEmptyCount, uMaxLength));
65479 +}
65480 +#endif
65481 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/lists.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/lists.c
65482 new file mode 100644
65483 index 0000000..cb54071
65484 --- /dev/null
65485 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/lists.c
65486 @@ -0,0 +1,99 @@
65487 +/**********************************************************************
65488 + *
65489 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
65490 + *
65491 + * This program is free software; you can redistribute it and/or modify it
65492 + * under the terms and conditions of the GNU General Public License,
65493 + * version 2, as published by the Free Software Foundation.
65494 + *
65495 + * This program is distributed in the hope it will be useful but, except
65496 + * as otherwise stated in writing, without any warranty; without even the
65497 + * implied warranty of merchantability or fitness for a particular purpose.
65498 + * See the GNU General Public License for more details.
65499 + *
65500 + * You should have received a copy of the GNU General Public License along with
65501 + * this program; if not, write to the Free Software Foundation, Inc.,
65502 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
65503 + *
65504 + * The full GNU General Public License is included in this distribution in
65505 + * the file called "COPYING".
65506 + *
65507 + * Contact Information:
65508 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
65509 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
65510 + *
65511 + ******************************************************************************/
65512 +
65513 +#include "lists.h"
65514 +#include "services_headers.h"
65515 +
65516 +IMPLEMENT_LIST_ANY_VA(BM_HEAP)
65517 +IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
65518 +IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
65519 +IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP)
65520 +IMPLEMENT_LIST_REMOVE(BM_HEAP)
65521 +IMPLEMENT_LIST_INSERT(BM_HEAP)
65522 +
65523 +IMPLEMENT_LIST_ANY_VA(BM_CONTEXT)
65524 +IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL)
65525 +IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK)
65526 +IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT)
65527 +IMPLEMENT_LIST_REMOVE(BM_CONTEXT)
65528 +IMPLEMENT_LIST_INSERT(BM_CONTEXT)
65529 +
65530 +IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
65531 +IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
65532 +IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
65533 +IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
65534 +IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
65535 +IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
65536 +IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
65537 +
65538 +IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
65539 +IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
65540 +IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
65541 +IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
65542 +
65543 +
65544 +IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
65545 +{
65546 +       IMG_UINT32 ui32DevIndex;
65547 +       IMG_BOOL bIgnoreClass;
65548 +       PVRSRV_DEVICE_CLASS eDevClass;
65549 +
65550 +       ui32DevIndex = va_arg(va, IMG_UINT32);
65551 +       bIgnoreClass = va_arg(va, IMG_BOOL);
65552 +       if (!bIgnoreClass)
65553 +       {
65554 +               eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
65555 +       }
65556 +       else
65557 +       {
65558 +
65559 +
65560 +               eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
65561 +       }
65562 +
65563 +       if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
65564 +               psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
65565 +       {
65566 +               return psDeviceNode;
65567 +       }
65568 +       return IMG_NULL;
65569 +}
65570 +
65571 +IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
65572 +{
65573 +       IMG_UINT32 ui32DeviceIndex;
65574 +
65575 +       ui32DeviceIndex = va_arg(va, IMG_UINT32);
65576 +
65577 +       if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
65578 +       {
65579 +               return psPowerDev;
65580 +       }
65581 +       else
65582 +       {
65583 +               return IMG_NULL;
65584 +       }
65585 +}
65586 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem.c
65587 new file mode 100644
65588 index 0000000..ad2ec50
65589 --- /dev/null
65590 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem.c
65591 @@ -0,0 +1,151 @@
65592 +/**********************************************************************
65593 + *
65594 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
65595 + *
65596 + * This program is free software; you can redistribute it and/or modify it
65597 + * under the terms and conditions of the GNU General Public License,
65598 + * version 2, as published by the Free Software Foundation.
65599 + *
65600 + * This program is distributed in the hope it will be useful but, except
65601 + * as otherwise stated in writing, without any warranty; without even the
65602 + * implied warranty of merchantability or fitness for a particular purpose.
65603 + * See the GNU General Public License for more details.
65604 + *
65605 + * You should have received a copy of the GNU General Public License along with
65606 + * this program; if not, write to the Free Software Foundation, Inc.,
65607 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
65608 + *
65609 + * The full GNU General Public License is included in this distribution in
65610 + * the file called "COPYING".
65611 + *
65612 + * Contact Information:
65613 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
65614 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
65615 + *
65616 + ******************************************************************************/
65617 +
65618 +#include "services_headers.h"
65619 +#include "pvr_bridge_km.h"
65620 +
65621 +
65622 +static PVRSRV_ERROR
65623 +FreeSharedSysMemCallBack(IMG_PVOID     pvParam,
65624 +                                                IMG_UINT32     ui32Param)
65625 +{
65626 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam;
65627 +
65628 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
65629 +
65630 +       OSFreePages(psKernelMemInfo->ui32Flags,
65631 +                               psKernelMemInfo->ui32AllocSize,
65632 +                               psKernelMemInfo->pvLinAddrKM,
65633 +                               psKernelMemInfo->sMemBlk.hOSMemHandle);
65634 +
65635 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
65636 +                         sizeof(PVRSRV_KERNEL_MEM_INFO),
65637 +                         psKernelMemInfo,
65638 +                         IMG_NULL);
65639 +
65640 +
65641 +       return PVRSRV_OK;
65642 +}
65643 +
65644 +
65645 +IMG_EXPORT PVRSRV_ERROR
65646 +PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA   *psPerProc,
65647 +                                                        IMG_UINT32                                     ui32Flags,
65648 +                                                        IMG_SIZE_T                             ui32Size,
65649 +                                                        PVRSRV_KERNEL_MEM_INFO         **ppsKernelMemInfo)
65650 +{
65651 +       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
65652 +
65653 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
65654 +                                 sizeof(PVRSRV_KERNEL_MEM_INFO),
65655 +                                 (IMG_VOID **)&psKernelMemInfo, IMG_NULL,
65656 +                                 "Kernel Memory Info") != PVRSRV_OK)
65657 +       {
65658 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo"));
65659 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
65660 +       }
65661 +
65662 +       OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));
65663 +
65664 +       ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
65665 +       ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
65666 +       psKernelMemInfo->ui32Flags = ui32Flags;
65667 +       psKernelMemInfo->ui32AllocSize = ui32Size;
65668 +
65669 +       if(OSAllocPages(psKernelMemInfo->ui32Flags,
65670 +                                       psKernelMemInfo->ui32AllocSize,
65671 +                                       HOST_PAGESIZE(),
65672 +                                       &psKernelMemInfo->pvLinAddrKM,
65673 +                                       &psKernelMemInfo->sMemBlk.hOSMemHandle)
65674 +               != PVRSRV_OK)
65675 +       {
65676 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block"));
65677 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
65678 +                                 sizeof(PVRSRV_KERNEL_MEM_INFO),
65679 +                                 psKernelMemInfo,
65680 +                                 0);
65681 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
65682 +       }
65683 +
65684 +
65685 +       psKernelMemInfo->sMemBlk.hResItem =
65686 +                               ResManRegisterRes(psPerProc->hResManContext,
65687 +                                                                 RESMAN_TYPE_SHARED_MEM_INFO,
65688 +                                                                 psKernelMemInfo,
65689 +                                                                 0,
65690 +                                                                 FreeSharedSysMemCallBack);
65691 +
65692 +       *ppsKernelMemInfo = psKernelMemInfo;
65693 +
65694 +       return PVRSRV_OK;
65695 +}
65696 +
65697 +
65698 +IMG_EXPORT PVRSRV_ERROR
65699 +PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
65700 +{
65701 +       PVRSRV_ERROR eError;
65702 +
65703 +       if(psKernelMemInfo->sMemBlk.hResItem)
65704 +       {
65705 +               eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem);
65706 +       }
65707 +       else
65708 +       {
65709 +               eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0);
65710 +       }
65711 +
65712 +       return eError;
65713 +}
65714 +
65715 +
65716 +IMG_EXPORT PVRSRV_ERROR
65717 +PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
65718 +{
65719 +       PVRSRV_ERROR eError = PVRSRV_OK;
65720 +
65721 +       if(!psKernelMemInfo)
65722 +       {
65723 +               return PVRSRV_ERROR_INVALID_PARAMS;
65724 +       }
65725 +
65726 +       if(psKernelMemInfo->sMemBlk.hResItem)
65727 +       {
65728 +               eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL);
65729 +
65730 +               if (eError != PVRSRV_OK)
65731 +               {
65732 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed"));
65733 +                       PVR_DBG_BREAK;
65734 +                       return eError;
65735 +               }
65736 +
65737 +               psKernelMemInfo->sMemBlk.hResItem = IMG_NULL;
65738 +       }
65739 +
65740 +       return eError;
65741 +}
65742 +
65743 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem_debug.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem_debug.c
65744 new file mode 100644
65745 index 0000000..eeb86ae
65746 --- /dev/null
65747 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/mem_debug.c
65748 @@ -0,0 +1,250 @@
65749 +/**********************************************************************
65750 + *
65751 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
65752 + *
65753 + * This program is free software; you can redistribute it and/or modify it
65754 + * under the terms and conditions of the GNU General Public License,
65755 + * version 2, as published by the Free Software Foundation.
65756 + *
65757 + * This program is distributed in the hope it will be useful but, except
65758 + * as otherwise stated in writing, without any warranty; without even the
65759 + * implied warranty of merchantability or fitness for a particular purpose.
65760 + * See the GNU General Public License for more details.
65761 + *
65762 + * You should have received a copy of the GNU General Public License along with
65763 + * this program; if not, write to the Free Software Foundation, Inc.,
65764 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
65765 + *
65766 + * The full GNU General Public License is included in this distribution in
65767 + * the file called "COPYING".
65768 + *
65769 + * Contact Information:
65770 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
65771 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
65772 + *
65773 + ******************************************************************************/
65774 +
65775 +#ifndef MEM_DEBUG_C
65776 +#define MEM_DEBUG_C
65777 +
65778 +#if defined(PVRSRV_DEBUG_OS_MEMORY)
65779 +
65780 +#include "img_types.h"
65781 +#include "services_headers.h"
65782 +
65783 +#if defined (__cplusplus)
65784 +extern "C"
65785 +{
65786 +#endif
65787 +
65788 +#define STOP_ON_ERROR 0
65789 +
65790 +
65791 +
65792 +
65793 +
65794 +
65795 +
65796 +
65797 +
65798 +       IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
65799 +       {
65800 +               IMG_UINT8 *pui8Addr;
65801 +               for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
65802 +               {
65803 +                       if (*pui8Addr != ui8Pattern)
65804 +                       {
65805 +                               return IMG_FALSE;
65806 +                       }
65807 +               }
65808 +               return IMG_TRUE;
65809 +       }
65810 +
65811 +
65812 +
65813 +       IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
65814 +       {
65815 +               OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
65816 +
65817 +
65818 +               if (pvCpuVAddr == IMG_NULL)
65819 +               {
65820 +                       PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer"
65821 +                                        " - referenced %s:%d - allocated %s:%d",
65822 +                                        pvCpuVAddr,
65823 +                                        pszFileName, uLine,
65824 +                                        psInfo->sFileName, psInfo->uLineNo));
65825 +                       while (STOP_ON_ERROR);
65826 +               }
65827 +
65828 +
65829 +               if (((IMG_UINT32)pvCpuVAddr&3) != 0)
65830 +               {
65831 +                       PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment"
65832 +                                        " - referenced %s:%d - allocated %s:%d",
65833 +                                        pvCpuVAddr,
65834 +                                        pszFileName, uLine,
65835 +                                        psInfo->sFileName, psInfo->uLineNo));
65836 +                       while (STOP_ON_ERROR);
65837 +               }
65838 +
65839 +
65840 +               if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
65841 +               {
65842 +                       PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten"
65843 +                                        " - referenced %s:%d - allocated %s:%d",
65844 +                                        pvCpuVAddr,
65845 +                                        pszFileName, uLine,
65846 +                                        psInfo->sFileName, psInfo->uLineNo));
65847 +                       while (STOP_ON_ERROR);
65848 +               }
65849 +
65850 +
65851 +               if (uSize != psInfo->uSize)
65852 +               {
65853 +                       PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)"
65854 +                                        " - referenced %s:%d - allocated %s:%d",
65855 +                                        pvCpuVAddr, uSize, psInfo->uSize,
65856 +                                        pszFileName, uLine,
65857 +                                        psInfo->sFileName, psInfo->uLineNo));
65858 +                       while (STOP_ON_ERROR);
65859 +               }
65860 +
65861 +
65862 +               if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
65863 +               {
65864 +                       PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)"
65865 +                                        " - referenced %s:%d - allocated %s:%d",
65866 +                                        pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
65867 +                                        pszFileName, uLine,
65868 +                                        psInfo->sFileName, psInfo->uLineNo));
65869 +                       while (STOP_ON_ERROR);
65870 +               }
65871 +               else
65872 +               {
65873 +
65874 +                       uSize = psInfo->uSize;
65875 +               }
65876 +
65877 +
65878 +               if (uSize)
65879 +               {
65880 +                       if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
65881 +                       {
65882 +                               PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten"
65883 +                                                " - referenced from %s:%d - allocated from %s:%d",
65884 +                                                pvCpuVAddr,
65885 +                                                pszFileName, uLine,
65886 +                                                psInfo->sFileName, psInfo->uLineNo));
65887 +                       }
65888 +               }
65889 +
65890 +
65891 +               if (psInfo->eValid != isAllocated)
65892 +               {
65893 +                       PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)"
65894 +                                        " - referenced %s:%d - freed %s:%d",
65895 +                                        pvCpuVAddr, psInfo->eValid == isFree,
65896 +                                        pszFileName, uLine,
65897 +                                        psInfo->sFileName, psInfo->uLineNo));
65898 +                       while (STOP_ON_ERROR);
65899 +               }
65900 +       }
65901 +
65902 +       IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
65903 +       {
65904 +               IMG_SIZE_T i = 0;
65905 +
65906 +               for (; i < 128; i++)
65907 +               {
65908 +                       *pDest = *pSrc;
65909 +                       if (*pSrc == '\0') break;
65910 +                       pDest++;
65911 +                       pSrc++;
65912 +               }
65913 +       }
65914 +
65915 +       PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
65916 +                                                                                 IMG_UINT32 ui32Size,
65917 +                                                                                 IMG_PVOID *ppvCpuVAddr,
65918 +                                                                                 IMG_HANDLE *phBlockAlloc,
65919 +                                                                                 IMG_CHAR *pszFilename,
65920 +                                                                                 IMG_UINT32 ui32Line)
65921 +       {
65922 +               OSMEM_DEBUG_INFO *psInfo;
65923 +
65924 +               PVRSRV_ERROR eError;
65925 +
65926 +               eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
65927 +                                ui32Size + TEST_BUFFER_PADDING,
65928 +                                ppvCpuVAddr,
65929 +                                phBlockAlloc,
65930 +                                pszFilename,
65931 +                                ui32Line);
65932 +
65933 +               if (eError != PVRSRV_OK)
65934 +               {
65935 +                       return eError;
65936 +               }
65937 +
65938 +
65939 +               OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
65940 +               OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
65941 +
65942 +
65943 +               psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
65944 +
65945 +               OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
65946 +               debug_strcpy(psInfo->sFileName, pszFilename);
65947 +               psInfo->uLineNo = ui32Line;
65948 +               psInfo->eValid = isAllocated;
65949 +               psInfo->uSize = ui32Size;
65950 +               psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
65951 +
65952 +
65953 +               *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
65954 +
65955 +#ifdef PVRSRV_LOG_MEMORY_ALLOCS
65956 +
65957 +               PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
65958 +#endif
65959 +
65960 +               return PVRSRV_OK;
65961 +       }
65962 +
65963 +       PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
65964 +                                                                                IMG_UINT32 ui32Size,
65965 +                                                                                IMG_PVOID pvCpuVAddr,
65966 +                                                                                IMG_HANDLE hBlockAlloc,
65967 +                                                                                IMG_CHAR *pszFilename,
65968 +                                                                                IMG_UINT32 ui32Line)
65969 +       {
65970 +               OSMEM_DEBUG_INFO *psInfo;
65971 +
65972 +
65973 +               OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
65974 +
65975 +
65976 +               OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);
65977 +
65978 +
65979 +               psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
65980 +
65981 +
65982 +               psInfo->uSize = 0;
65983 +               psInfo->uSizeParityCheck = 0;
65984 +               psInfo->eValid = isFree;
65985 +               psInfo->uLineNo = ui32Line;
65986 +               debug_strcpy(psInfo->sFileName, pszFilename);
65987 +
65988 +               return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
65989 +       }
65990 +
65991 +#if defined (__cplusplus)
65992 +
65993 +}
65994 +#endif
65995 +
65996 +#endif
65997 +
65998 +#endif
65999 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/metrics.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/metrics.c
66000 new file mode 100644
66001 index 0000000..216696e
66002 --- /dev/null
66003 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/metrics.c
66004 @@ -0,0 +1,160 @@
66005 +/**********************************************************************
66006 + *
66007 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
66008 + *
66009 + * This program is free software; you can redistribute it and/or modify it
66010 + * under the terms and conditions of the GNU General Public License,
66011 + * version 2, as published by the Free Software Foundation.
66012 + *
66013 + * This program is distributed in the hope it will be useful but, except
66014 + * as otherwise stated in writing, without any warranty; without even the
66015 + * implied warranty of merchantability or fitness for a particular purpose.
66016 + * See the GNU General Public License for more details.
66017 + *
66018 + * You should have received a copy of the GNU General Public License along with
66019 + * this program; if not, write to the Free Software Foundation, Inc.,
66020 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
66021 + *
66022 + * The full GNU General Public License is included in this distribution in
66023 + * the file called "COPYING".
66024 + *
66025 + * Contact Information:
66026 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
66027 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
66028 + *
66029 + ******************************************************************************/
66030 +
66031 +#include "services_headers.h"
66032 +#include "metrics.h"
66033 +
66034 +#if defined(SUPPORT_VGX)
66035 +#include "vgxapi_km.h"
66036 +#endif
66037 +
66038 +#if defined(SUPPORT_SGX)
66039 +#include "sgxapi_km.h"
66040 +#endif
66041 +
66042 +#if defined(DEBUG) || defined(TIMING)
66043 +
66044 +static volatile IMG_UINT32 *pui32TimerRegister = 0;
66045 +
66046 +#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total
66047 +#define PVRSRV_TIMER_TOTAL_IN_MS(X)            ((1000*asTimers[X].ui32Total)/ui32TicksPerMS)
66048 +#define PVRSRV_TIMER_COUNT(X)                  asTimers[X].ui32Count
66049 +
66050 +
66051 +Temporal_Data asTimers[PVRSRV_NUM_TIMERS];
66052 +
66053 +
66054 +IMG_UINT32 PVRSRVTimeNow(IMG_VOID)
66055 +{
66056 +       if (!pui32TimerRegister)
66057 +       {
66058 +               static IMG_BOOL bFirstTime = IMG_TRUE;
66059 +
66060 +               if (bFirstTime)
66061 +               {
66062 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up"));
66063 +
66064 +                       bFirstTime = IMG_FALSE;
66065 +               }
66066 +
66067 +               return 0;
66068 +       }
66069 +
66070 +#if defined(__sh__)
66071 +
66072 +       return (0xffffffff-*pui32TimerRegister);
66073 +
66074 +#else
66075 +
66076 +       return 0;
66077 +
66078 +#endif
66079 +}
66080 +
66081 +
66082 +static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID)
66083 +{
66084 +       IMG_UINT32 ui32Time1, ui32Time2;
66085 +
66086 +       ui32Time1 = PVRSRVTimeNow();
66087 +
66088 +       OSWaitus(1000000);
66089 +
66090 +       ui32Time2 = PVRSRVTimeNow();
66091 +
66092 +       PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1));
66093 +
66094 +       return (ui32Time2 - ui32Time1);
66095 +}
66096 +
66097 +
66098 +IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo)
66099 +{
66100 +       IMG_UINT32 ui32Loop;
66101 +
66102 +       PVR_UNREFERENCED_PARAMETER(pvDevInfo);
66103 +
66104 +       for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
66105 +       {
66106 +               asTimers[ui32Loop].ui32Total = 0;
66107 +               asTimers[ui32Loop].ui32Count = 0;
66108 +       }
66109 +
66110 +
66111 +       #if defined(__sh__)
66112 +
66113 +
66114 +
66115 +
66116 +
66117 +               *TCR_2 = TIMER_DIVISOR;
66118 +
66119 +
66120 +               *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff;
66121 +
66122 +
66123 +               *TST_REG |= (IMG_UINT8)0x04;
66124 +
66125 +               pui32TimerRegister = (IMG_UINT32 *)TCNT_2;
66126 +
66127 +       #else
66128 +
66129 +               pui32TimerRegister = 0;
66130 +
66131 +       #endif
66132 +
66133 +}
66134 +
66135 +
66136 +IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID)
66137 +{
66138 +       IMG_UINT32 ui32TicksPerMS, ui32Loop;
66139 +
66140 +       ui32TicksPerMS = PVRSRVGetCPUFreq();
66141 +
66142 +       if (!ui32TicksPerMS)
66143 +       {
66144 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq"));
66145 +               return;
66146 +       }
66147 +
66148 +       for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++)
66149 +       {
66150 +               if (asTimers[ui32Loop].ui32Count & 0x80000000L)
66151 +               {
66152 +                       PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop));
66153 +               }
66154 +       }
66155 +#if 0
66156 +
66157 +       PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1)));
66158 +       PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1)));
66159 +       PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1)));
66160 +#endif
66161 +}
66162 +
66163 +#endif
66164 +
66165 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pdump_common.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pdump_common.c
66166 new file mode 100644
66167 index 0000000..94bfc09
66168 --- /dev/null
66169 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pdump_common.c
66170 @@ -0,0 +1,1723 @@
66171 +/**********************************************************************
66172 + *
66173 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
66174 + *
66175 + * This program is free software; you can redistribute it and/or modify it
66176 + * under the terms and conditions of the GNU General Public License,
66177 + * version 2, as published by the Free Software Foundation.
66178 + *
66179 + * This program is distributed in the hope it will be useful but, except
66180 + * as otherwise stated in writing, without any warranty; without even the
66181 + * implied warranty of merchantability or fitness for a particular purpose.
66182 + * See the GNU General Public License for more details.
66183 + *
66184 + * You should have received a copy of the GNU General Public License along with
66185 + * this program; if not, write to the Free Software Foundation, Inc.,
66186 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
66187 + *
66188 + * The full GNU General Public License is included in this distribution in
66189 + * the file called "COPYING".
66190 + *
66191 + * Contact Information:
66192 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
66193 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
66194 + *
66195 + ******************************************************************************/
66196 +
66197 +#if defined(PDUMP)
66198 +#include <stdarg.h>
66199 +
66200 +#include "services_headers.h"
66201 +#if defined(SUPPORT_SGX)
66202 +#include "sgxdefs.h"
66203 +#include "sgxmmu.h"
66204 +#endif
66205 +#include "pdump_km.h"
66206 +
66207 +#if !defined(PDUMP_TEMP_BUFFER_SIZE)
66208 +#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024L)
66209 +#endif
66210 +
66211 +#if 1
66212 +#define PDUMP_DBG(a)   PDumpOSDebugPrintf a
66213 +#else
66214 +#define PDUMP_DBG(a)
66215 +#endif
66216 +
66217 +#define PDUMP_DATAMASTER_PIXEL         (1)
66218 +#define PDUMP_DATAMASTER_EDM           (3)
66219 +
66220 +#define        MIN(x, y) (((x) < (y)) ? (x) : (y))
66221 +#define        PTR_PLUS(t, p, x) ((t *)(((IMG_CHAR *)(p)) + (x)))
66222 +#define        VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID, p, x)
66223 +#define        VPTR_INC(p, x) (p = VPTR_PLUS(p, x))
66224 +#define MAX_PDUMP_MMU_CONTEXTS (32)
66225 +static IMG_VOID *gpvTempBuffer = IMG_NULL;
66226 +static IMG_HANDLE ghTempBufferBlockAlloc;
66227 +static IMG_UINT16 gui16MMUContextUsage = 0;
66228 +
66229 +
66230 +
66231 +static IMG_VOID *GetTempBuffer(IMG_VOID)
66232 +{
66233 +
66234 +       if (gpvTempBuffer == IMG_NULL)
66235 +       {
66236 +               PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
66237 +                                         PDUMP_TEMP_BUFFER_SIZE,
66238 +                                         &gpvTempBuffer,
66239 +                                         &ghTempBufferBlockAlloc,
66240 +                                         "PDUMP Temporary Buffer");
66241 +               if (eError != PVRSRV_OK)
66242 +               {
66243 +                       PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
66244 +               }
66245 +       }
66246 +
66247 +       return gpvTempBuffer;
66248 +}
66249 +
66250 +static IMG_VOID FreeTempBuffer(IMG_VOID)
66251 +{
66252 +
66253 +       if (gpvTempBuffer != IMG_NULL)
66254 +       {
66255 +               PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
66256 +                                         PDUMP_TEMP_BUFFER_SIZE,
66257 +                                         gpvTempBuffer,
66258 +                                         ghTempBufferBlockAlloc);
66259 +               if (eError != PVRSRV_OK)
66260 +               {
66261 +                       PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
66262 +               }
66263 +               else
66264 +               {
66265 +                       gpvTempBuffer = IMG_NULL;
66266 +               }
66267 +       }
66268 +}
66269 +
66270 +IMG_VOID PDumpInitCommon(IMG_VOID)
66271 +{
66272 +
66273 +       (IMG_VOID) GetTempBuffer();
66274 +
66275 +
66276 +       PDumpInit();
66277 +}
66278 +
66279 +IMG_VOID PDumpDeInitCommon(IMG_VOID)
66280 +{
66281 +
66282 +       FreeTempBuffer();
66283 +
66284 +
66285 +       PDumpDeInit();
66286 +}
66287 +
66288 +#if defined(SGX_SUPPORT_COMMON_PDUMP)
66289 +
66290 +IMG_BOOL PDumpIsSuspended(IMG_VOID)
66291 +{
66292 +       return PDumpOSIsSuspended();
66293 +}
66294 +
66295 +PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data, IMG_UINT32 ui32Flags)
66296 +{
66297 +       PVRSRV_ERROR eErr;
66298 +       PDUMP_GET_SCRIPT_STRING()
66299 +       PDUMP_DBG(("PDumpRegWithFlagsKM"));
66300 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :SGXREG:0x%8.8lX 0x%8.8lX\r\n", ui32Reg, ui32Data);
66301 +       if(eErr != PVRSRV_OK)
66302 +       {
66303 +               return eErr;
66304 +       }
66305 +       PDumpOSWriteString2(hScript, ui32Flags);
66306 +
66307 +       return PVRSRV_OK;
66308 +}
66309 +
66310 +PVRSRV_ERROR PDumpRegKM(IMG_UINT32 ui32Reg,IMG_UINT32 ui32Data)
66311 +{
66312 +       return PDumpRegWithFlagsKM(ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
66313 +}
66314 +
66315 +PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, IMG_UINT32 ui32Flags)
66316 +{
66317 +
66318 +       #define POLL_DELAY                      1000UL
66319 +       #define POLL_COUNT_LONG         (2000000000UL / POLL_DELAY)
66320 +       #define POLL_COUNT_SHORT        (1000000UL / POLL_DELAY)
66321 +
66322 +       PVRSRV_ERROR eErr;
66323 +       IMG_UINT32      ui32PollCount;
66324 +
66325 +       PDUMP_GET_SCRIPT_STRING();
66326 +       PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
66327 +
66328 +       if (((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
66329 +               (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK) != 0) ||
66330 +           ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
66331 +               (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK) != 0) ||
66332 +           ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
66333 +               (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK) != 0))
66334 +       {
66335 +               ui32PollCount = POLL_COUNT_LONG;
66336 +       }
66337 +       else
66338 +       {
66339 +               ui32PollCount = POLL_COUNT_SHORT;
66340 +       }
66341 +
66342 +
66343 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :SGXREG:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %lu %d\r\n",
66344 +                       ui32RegAddr, ui32RegValue, ui32Mask, 0, ui32PollCount, POLL_DELAY);
66345 +       if(eErr != PVRSRV_OK)
66346 +       {
66347 +               return eErr;
66348 +       }
66349 +       PDumpOSWriteString2(hScript, ui32Flags);
66350 +
66351 +       return PVRSRV_OK;
66352 +}
66353 +
66354 +
66355 +PVRSRV_ERROR PDumpRegPolKM(IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask)
66356 +{
66357 +       return PDumpRegPolWithFlagsKM(ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS);
66358 +}
66359 +
66360 +PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_TYPE eDeviceType,
66361 +                           IMG_UINT32         ui32DevVAddr,
66362 +                           IMG_CPU_VIRTADDR   pvLinAddr,
66363 +                           IMG_HANDLE         hOSMemHandle,
66364 +                           IMG_UINT32         ui32NumBytes,
66365 +                           IMG_UINT32         ui32PageSize,
66366 +                           IMG_HANDLE         hUniqueTag)
66367 +{
66368 +       PVRSRV_ERROR eErr;
66369 +       IMG_PUINT8              pui8LinAddr;
66370 +    IMG_UINT32      ui32Offset;
66371 +       IMG_UINT32              ui32NumPages;
66372 +       IMG_DEV_PHYADDR sDevPAddr;
66373 +       IMG_UINT32              ui32Page;
66374 +
66375 +       PDUMP_GET_SCRIPT_STRING();
66376 +
66377 +#if defined(LINUX)
66378 +       PVR_ASSERT(hOSMemHandle);
66379 +#else
66380 +
66381 +       PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
66382 +       PVR_ASSERT(((IMG_UINT32) pvLinAddr & (SGX_MMU_PAGE_MASK)) == 0);
66383 +#endif
66384 +
66385 +       PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & (SGX_MMU_PAGE_MASK)) == 0);
66386 +       PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (SGX_MMU_PAGE_MASK)) == 0);
66387 +
66388 +
66389 +
66390 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :SGXMEM:VA_%8.8lX 0x%8.8lX %lu\r\n",
66391 +                       ui32DevVAddr, ui32NumBytes, ui32PageSize);
66392 +       if(eErr != PVRSRV_OK)
66393 +       {
66394 +               return eErr;
66395 +       }
66396 +       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66397 +
66398 +
66399 +
66400 +       pui8LinAddr = (IMG_PUINT8) pvLinAddr;
66401 +       ui32Offset = 0;
66402 +       ui32NumPages = ui32NumBytes / ui32PageSize;
66403 +       while (ui32NumPages)
66404 +       {
66405 +               ui32NumPages--;
66406 +
66407 +
66408 +               PDumpOSCPUVAddrToDevPAddr(eDeviceType,
66409 +                               hOSMemHandle,
66410 +                               ui32Offset,
66411 +                               pui8LinAddr,
66412 +                               ui32PageSize,
66413 +                               &sDevPAddr);
66414 +               ui32Page = sDevPAddr.uiAddr / ui32PageSize;
66415 +
66416 +               pui8LinAddr     += ui32PageSize;
66417 +               ui32Offset += ui32PageSize;
66418 +
66419 +               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :SGXMEM:PA_%8.8lX%8.8lX %lu %lu 0x%8.8lX\r\n",
66420 +                                                                                               (IMG_UINT32) hUniqueTag,
66421 +                                                                                               ui32Page * ui32PageSize,
66422 +                                                                                               ui32PageSize,
66423 +                                                                                               ui32PageSize,
66424 +                                                                                               ui32Page * ui32PageSize);
66425 +               if(eErr != PVRSRV_OK)
66426 +               {
66427 +                       return eErr;
66428 +               }
66429 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66430 +       }
66431 +       return PVRSRV_OK;
66432 +}
66433 +
66434 +PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_TYPE eDeviceType,
66435 +                               IMG_CPU_VIRTADDR   pvLinAddr,
66436 +                                                               IMG_UINT32        ui32PTSize,
66437 +                               IMG_HANDLE         hUniqueTag)
66438 +{
66439 +       PVRSRV_ERROR eErr;
66440 +       IMG_DEV_PHYADDR sDevPAddr;
66441 +       IMG_UINT32              ui32Page;
66442 +
66443 +       PDUMP_GET_SCRIPT_STRING();
66444 +
66445 +       PVR_ASSERT(((IMG_UINT32) pvLinAddr & (ui32PTSize - 1)) == 0);
66446 +
66447 +
66448 +
66449 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :SGXMEM:PAGE_TABLE 0x%8.8lX %lu\r\n", ui32PTSize, SGX_MMU_PAGE_SIZE);
66450 +       if(eErr != PVRSRV_OK)
66451 +       {
66452 +               return eErr;
66453 +       }
66454 +       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66455 +
66456 +
66457 +
66458 +
66459 +
66460 +
66461 +
66462 +
66463 +
66464 +
66465 +
66466 +
66467 +
66468 +
66469 +       {
66470 +
66471 +
66472 +               PDumpOSCPUVAddrToDevPAddr(eDeviceType,
66473 +                               IMG_NULL,
66474 +                               0,
66475 +                               (IMG_PUINT8) pvLinAddr,
66476 +                               SGX_MMU_PAGE_SIZE,
66477 +                               &sDevPAddr);
66478 +               ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;
66479 +
66480 +               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :SGXMEM:PA_%8.8lX%8.8lX 0x%lX %lu 0x%8.8lX\r\n",
66481 +                                                                                               (IMG_UINT32) hUniqueTag,
66482 +                                                                                               ui32Page * SGX_MMU_PAGE_SIZE,
66483 +                                                                                               SGX_MMU_PAGE_SIZE,
66484 +                                                                                               SGX_MMU_PAGE_SIZE,
66485 +                                                                                               ui32Page * SGX_MMU_PAGE_SIZE);
66486 +               if(eErr != PVRSRV_OK)
66487 +               {
66488 +                       return eErr;
66489 +               }
66490 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66491 +
66492 +       }
66493 +       return PVRSRV_OK;
66494 +}
66495 +
66496 +PVRSRV_ERROR PDumpFreePages    (BM_HEAP                        *psBMHeap,
66497 +                         IMG_DEV_VIRTADDR  sDevVAddr,
66498 +                         IMG_UINT32        ui32NumBytes,
66499 +                         IMG_UINT32        ui32PageSize,
66500 +                         IMG_HANDLE        hUniqueTag,
66501 +                                                IMG_BOOL                  bInterleaved)
66502 +{
66503 +       PVRSRV_ERROR eErr;
66504 +       IMG_UINT32 ui32NumPages, ui32PageCounter;
66505 +       IMG_DEV_PHYADDR sDevPAddr;
66506 +       PVRSRV_DEVICE_NODE *psDeviceNode;
66507 +
66508 +       PDUMP_GET_SCRIPT_STRING();
66509 +
66510 +       PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
66511 +       PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
66512 +
66513 +
66514 +
66515 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :SGXMEM:VA_%8.8lX\r\n", sDevVAddr.uiAddr);
66516 +       if(eErr != PVRSRV_OK)
66517 +       {
66518 +               return eErr;
66519 +       }
66520 +       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66521 +
66522 +
66523 +
66524 +       ui32NumPages = ui32NumBytes / ui32PageSize;
66525 +       psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
66526 +       for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
66527 +       {
66528 +               if (!bInterleaved || (ui32PageCounter % 2) == 0)
66529 +               {
66530 +                       sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
66531 +                       {
66532 +                               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :SGXMEM:PA_%8.8lX%8.8lX\r\n", (IMG_UINT32) hUniqueTag, sDevPAddr.uiAddr);
66533 +                               if(eErr != PVRSRV_OK)
66534 +                               {
66535 +                                       return eErr;
66536 +                               }
66537 +                               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66538 +                       }
66539 +               }
66540 +               else
66541 +               {
66542 +
66543 +               }
66544 +
66545 +               sDevVAddr.uiAddr += ui32PageSize;
66546 +       }
66547 +       return PVRSRV_OK;
66548 +}
66549 +
66550 +PVRSRV_ERROR PDumpFreePageTable        (PVRSRV_DEVICE_TYPE eDeviceType,
66551 +                                                        IMG_CPU_VIRTADDR   pvLinAddr,
66552 +                                                        IMG_UINT32         ui32PTSize,
66553 +                                                        IMG_HANDLE         hUniqueTag)
66554 +{
66555 +       PVRSRV_ERROR eErr;
66556 +       IMG_DEV_PHYADDR sDevPAddr;
66557 +       IMG_UINT32              ui32Page;
66558 +
66559 +       PDUMP_GET_SCRIPT_STRING();
66560 +
66561 +       PVR_UNREFERENCED_PARAMETER(ui32PTSize);
66562 +
66563 +
66564 +       PVR_ASSERT(((IMG_UINT32) pvLinAddr & (ui32PTSize-1UL)) == 0);
66565 +
66566 +
66567 +
66568 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :SGXMEM:PAGE_TABLE\r\n");
66569 +       if(eErr != PVRSRV_OK)
66570 +       {
66571 +               return eErr;
66572 +       }
66573 +       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66574 +
66575 +
66576 +
66577 +
66578 +
66579 +
66580 +
66581 +
66582 +
66583 +
66584 +
66585 +
66586 +       {
66587 +               PDumpOSCPUVAddrToDevPAddr(eDeviceType,
66588 +                               IMG_NULL,
66589 +                               0,
66590 +                               (IMG_PUINT8) pvLinAddr,
66591 +                               SGX_MMU_PAGE_SIZE,
66592 +                               &sDevPAddr);
66593 +               ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;
66594 +
66595 +               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :SGXMEM:PA_%8.8lX%8.8lX\r\n", (IMG_UINT32) hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE);
66596 +               if(eErr != PVRSRV_OK)
66597 +               {
66598 +                       return eErr;
66599 +               }
66600 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
66601 +       }
66602 +       return PVRSRV_OK;
66603 +}
66604 +
66605 +PVRSRV_ERROR PDumpPDRegWithFlags(IMG_UINT32 ui32Reg,
66606 +                                                        IMG_UINT32 ui32Data,
66607 +                                                        IMG_UINT32     ui32Flags,
66608 +                                                        IMG_HANDLE hUniqueTag)
66609 +{
66610 +       PVRSRV_ERROR eErr;
66611 +       PDUMP_GET_SCRIPT_STRING()
66612 +
66613 +
66614 +
66615 +#if defined(SGX_FEATURE_36BIT_MMU)
66616 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
66617 +                        "WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n",
66618 +                        (IMG_UINT32)hUniqueTag,
66619 +                        (ui32Data & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PDE_ADDR_ALIGNSHIFT);
66620 +       if(eErr != PVRSRV_OK)
66621 +       {
66622 +               return eErr;
66623 +       }
66624 +       PDumpOSWriteString2(hScript, ui32Flags);
66625 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :SGXMEM:$1 :SGXMEM:$1 0x4\r\n");
66626 +       if(eErr != PVRSRV_OK)
66627 +       {
66628 +               return eErr;
66629 +       }
66630 +       PDumpOSWriteString2(hScript, ui32Flags);
66631 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
66632 +                        "WRW :SGXREG:0x%8.8lX: SGXMEM:$1\r\n",
66633 +                        ui32Reg);
66634 +       if(eErr != PVRSRV_OK)
66635 +       {
66636 +               return eErr;
66637 +       }
66638 +       PDumpOSWriteString2(hScript, ui32Flags);
66639 +#else
66640 +       eErr = PDumpOSBufprintf(hScript,
66641 +                               ui32MaxLen,
66642 +                               "WRW :SGXREG:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n",
66643 +                               ui32Reg,
66644 +                               (IMG_UINT32) hUniqueTag,
66645 +                               (ui32Data & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PDE_ADDR_ALIGNSHIFT,
66646 +                               ui32Data & ~SGX_MMU_PDE_ADDR_MASK);
66647 +       if(eErr != PVRSRV_OK)
66648 +       {
66649 +               return eErr;
66650 +       }
66651 +       PDumpOSWriteString2(hScript, ui32Flags);
66652 +#endif
66653 +       return PVRSRV_OK;
66654 +}
66655 +
66656 +PVRSRV_ERROR PDumpPDReg        (IMG_UINT32 ui32Reg,
66657 +                                        IMG_UINT32 ui32Data,
66658 +                                        IMG_HANDLE hUniqueTag)
66659 +{
66660 +       return PDumpPDRegWithFlags(ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
66661 +}
66662 +
66663 +PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO              *psMemInfo,
66664 +                                                  IMG_UINT32                   ui32Offset,
66665 +                                                  IMG_UINT32                   ui32Value,
66666 +                                                  IMG_UINT32                   ui32Mask,
66667 +                                                  PDUMP_POLL_OPERATOR  eOperator,
66668 +                                                  IMG_UINT32                   ui32Flags,
66669 +                                                  IMG_HANDLE                   hUniqueTag)
66670 +{
66671 +       #define MEMPOLL_DELAY           (1000)
66672 +       #define MEMPOLL_COUNT           (2000000000 / MEMPOLL_DELAY)
66673 +
66674 +       PVRSRV_ERROR eErr;
66675 +       IMG_UINT32                      ui32PageOffset;
66676 +       IMG_UINT8                       *pui8LinAddr;
66677 +       IMG_DEV_PHYADDR         sDevPAddr;
66678 +       IMG_DEV_VIRTADDR        sDevVPageAddr;
66679 +       PDUMP_GET_SCRIPT_STRING();
66680 +
66681 +
66682 +       PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->ui32AllocSize);
66683 +
66684 +
66685 +
66686 +       eErr = PDumpOSBufprintf(hScript,
66687 +                        ui32MaxLen,
66688 +                        "-- POL :SGXMEM:VA_%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n",
66689 +                        psMemInfo->sDevVAddr.uiAddr + ui32Offset,
66690 +                        ui32Value,
66691 +                        ui32Mask,
66692 +                        eOperator,
66693 +                        MEMPOLL_COUNT,
66694 +                        MEMPOLL_DELAY);
66695 +       if(eErr != PVRSRV_OK)
66696 +       {
66697 +               return eErr;
66698 +       }
66699 +       PDumpOSWriteString2(hScript, ui32Flags);
66700 +
66701 +
66702 +       pui8LinAddr = psMemInfo->pvLinAddrKM;
66703 +
66704 +
66705 +       pui8LinAddr += ui32Offset;
66706 +
66707 +
66708 +
66709 +
66710 +       PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
66711 +                       ui32Offset,
66712 +                       pui8LinAddr,
66713 +                       &ui32PageOffset);
66714 +
66715 +
66716 +       sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
66717 +
66718 +       PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
66719 +
66720 +
66721 +       BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
66722 +
66723 +
66724 +       sDevPAddr.uiAddr += ui32PageOffset;
66725 +
66726 +       eErr = PDumpOSBufprintf(hScript,
66727 +                        ui32MaxLen,
66728 +                        "POL :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n",
66729 +                        (IMG_UINT32) hUniqueTag,
66730 +                        sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
66731 +                        sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
66732 +                        ui32Value,
66733 +                        ui32Mask,
66734 +                        eOperator,
66735 +                        MEMPOLL_COUNT,
66736 +                        MEMPOLL_DELAY);
66737 +       if(eErr != PVRSRV_OK)
66738 +       {
66739 +               return eErr;
66740 +       }
66741 +       PDumpOSWriteString2(hScript, ui32Flags);
66742 +
66743 +       return PVRSRV_OK;
66744 +}
66745 +
66746 +PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
66747 +                                               PVRSRV_KERNEL_MEM_INFO *psMemInfo,
66748 +                                               IMG_UINT32 ui32Offset,
66749 +                                               IMG_UINT32 ui32Bytes,
66750 +                                               IMG_UINT32 ui32Flags,
66751 +                                               IMG_HANDLE hUniqueTag)
66752 +{
66753 +       PVRSRV_ERROR eErr;
66754 +       IMG_UINT32 ui32NumPages;
66755 +       IMG_UINT32 ui32PageByteOffset;
66756 +       IMG_UINT32 ui32BlockBytes;
66757 +       IMG_UINT8* pui8LinAddr;
66758 +       IMG_UINT8* pui8DataLinAddr = IMG_NULL;
66759 +       IMG_DEV_VIRTADDR sDevVPageAddr;
66760 +       IMG_DEV_VIRTADDR sDevVAddr;
66761 +       IMG_DEV_PHYADDR sDevPAddr;
66762 +       IMG_UINT32 ui32ParamOutPos;
66763 +
66764 +       PDUMP_GET_SCRIPT_AND_FILE_STRING();
66765 +
66766 +
66767 +       PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize);
66768 +
66769 +       if (!PDumpOSJTInitialised())
66770 +       {
66771 +               return PVRSRV_ERROR_GENERIC;
66772 +       }
66773 +
66774 +       if (ui32Bytes == 0 || PDumpOSIsSuspended())
66775 +       {
66776 +               return PVRSRV_OK;
66777 +       }
66778 +
66779 +
66780 +       if(pvAltLinAddr)
66781 +       {
66782 +               pui8DataLinAddr = pvAltLinAddr;
66783 +       }
66784 +       else if(psMemInfo->pvLinAddrKM)
66785 +       {
66786 +               pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
66787 +       }
66788 +       pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
66789 +       sDevVAddr = psMemInfo->sDevVAddr;
66790 +
66791 +
66792 +       sDevVAddr.uiAddr += ui32Offset;
66793 +       pui8LinAddr += ui32Offset;
66794 +
66795 +       PVR_ASSERT(pui8DataLinAddr);
66796 +
66797 +       PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
66798 +
66799 +       ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
66800 +
66801 +
66802 +
66803 +       if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
66804 +                                               pui8DataLinAddr,
66805 +                                               ui32Bytes,
66806 +                                               ui32Flags))
66807 +       {
66808 +               return PVRSRV_ERROR_GENERIC;
66809 +       }
66810 +
66811 +       if (PDumpOSGetParamFileNum() == 0)
66812 +       {
66813 +               eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
66814 +       }
66815 +       else
66816 +       {
66817 +               eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%%lu.prm", PDumpOSGetParamFileNum());
66818 +       }
66819 +       if(eErr != PVRSRV_OK)
66820 +       {
66821 +               return eErr;
66822 +       }
66823 +
66824 +
66825 +
66826 +       eErr = PDumpOSBufprintf(hScript,
66827 +                        ui32MaxLenScript,
66828 +                        "-- LDB :SGXMEM:VA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n",
66829 +                        (IMG_UINT32)hUniqueTag,
66830 +                        psMemInfo->sDevVAddr.uiAddr,
66831 +                        ui32Offset,
66832 +                        ui32Bytes,
66833 +                        ui32ParamOutPos,
66834 +                        pszFileName);
66835 +       if(eErr != PVRSRV_OK)
66836 +       {
66837 +               return eErr;
66838 +       }
66839 +       PDumpOSWriteString2(hScript, ui32Flags);
66840 +
66841 +
66842 +
66843 +
66844 +       PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
66845 +                       ui32Offset,
66846 +                       pui8LinAddr,
66847 +                       &ui32PageByteOffset);
66848 +       ui32NumPages = (ui32PageByteOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE();
66849 +
66850 +       while(ui32NumPages)
66851 +       {
66852 +#if 0
66853 +               IMG_UINT32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE);
66854 +               CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle,
66855 +                                                ui32CurrentOffset);
66856 +#endif
66857 +               ui32NumPages--;
66858 +
66859 +
66860 +               sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
66861 +
66862 +               PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
66863 +
66864 +
66865 +               BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
66866 +
66867 +
66868 +               sDevPAddr.uiAddr += ui32PageByteOffset;
66869 +#if 0
66870 +               if(ui32PageByteOffset)
66871 +               {
66872 +                   ui32BlockBytes =
66873 +                       MIN(ui32BytesRemaining, PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr);
66874 +
66875 +                   ui32PageByteOffset = 0;
66876 +               }
66877 +#endif
66878 +
66879 +               if (ui32PageByteOffset + ui32Bytes > HOST_PAGESIZE())
66880 +               {
66881 +
66882 +                       ui32BlockBytes = HOST_PAGESIZE() - ui32PageByteOffset;
66883 +               }
66884 +               else
66885 +               {
66886 +
66887 +                       ui32BlockBytes = ui32Bytes;
66888 +               }
66889 +
66890 +               eErr = PDumpOSBufprintf(hScript,
66891 +                                        ui32MaxLenScript,
66892 +                                        "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n",
66893 +                                        (IMG_UINT32) hUniqueTag,
66894 +                                        sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
66895 +                                        sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
66896 +                                        ui32BlockBytes,
66897 +                                        ui32ParamOutPos,
66898 +                                        pszFileName);
66899 +               if(eErr != PVRSRV_OK)
66900 +               {
66901 +                       return eErr;
66902 +               }
66903 +               PDumpOSWriteString2(hScript, ui32Flags);
66904 +
66905 +
66906 +
66907 +
66908 +               ui32PageByteOffset = 0;
66909 +
66910 +               ui32Bytes -= ui32BlockBytes;
66911 +
66912 +               sDevVAddr.uiAddr += ui32BlockBytes;
66913 +
66914 +               pui8LinAddr += ui32BlockBytes;
66915 +
66916 +               ui32ParamOutPos += ui32BlockBytes;
66917 +       }
66918 +
66919 +       return PVRSRV_OK;
66920 +}
66921 +
66922 +PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE eDeviceType,
66923 +                                                IMG_CPU_VIRTADDR pvLinAddr,
66924 +                                                IMG_UINT32 ui32Bytes,
66925 +                                                IMG_UINT32 ui32Flags,
66926 +                                                IMG_BOOL bInitialisePages,
66927 +                                                IMG_HANDLE hUniqueTag1,
66928 +                                                IMG_HANDLE hUniqueTag2)
66929 +{
66930 +       PVRSRV_ERROR eErr;
66931 +       IMG_UINT32 ui32NumPages;
66932 +       IMG_UINT32 ui32PageOffset;
66933 +       IMG_UINT32 ui32BlockBytes;
66934 +       IMG_UINT8* pui8LinAddr;
66935 +       IMG_DEV_PHYADDR sDevPAddr;
66936 +       IMG_CPU_PHYADDR sCpuPAddr;
66937 +       IMG_UINT32 ui32Offset;
66938 +       IMG_UINT32 ui32ParamOutPos;
66939 +
66940 +       PDUMP_GET_SCRIPT_AND_FILE_STRING();
66941 +
66942 +       if (!pvLinAddr || !PDumpOSJTInitialised())
66943 +       {
66944 +               return PVRSRV_ERROR_GENERIC;
66945 +       }
66946 +
66947 +       if (PDumpOSIsSuspended())
66948 +       {
66949 +               return PVRSRV_OK;
66950 +       }
66951 +
66952 +       PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
66953 +
66954 +       ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
66955 +
66956 +       if (bInitialisePages)
66957 +       {
66958 +
66959 +
66960 +
66961 +               if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
66962 +                                                       pvLinAddr,
66963 +                                                       ui32Bytes,
66964 +                                                       PDUMP_FLAGS_CONTINUOUS))
66965 +               {
66966 +                       return PVRSRV_ERROR_GENERIC;
66967 +               }
66968 +
66969 +               if (PDumpOSGetParamFileNum() == 0)
66970 +               {
66971 +                       eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
66972 +               }
66973 +               else
66974 +               {
66975 +                       eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%%lu.prm", PDumpOSGetParamFileNum());
66976 +               }
66977 +               if(eErr != PVRSRV_OK)
66978 +               {
66979 +                       return eErr;
66980 +               }
66981 +       }
66982 +
66983 +
66984 +
66985 +
66986 +       ui32PageOffset  = (IMG_UINT32) pvLinAddr & (HOST_PAGESIZE() - 1);
66987 +       ui32NumPages    = (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE();
66988 +       pui8LinAddr             = (IMG_UINT8*) pvLinAddr;
66989 +
66990 +       while (ui32NumPages)
66991 +       {
66992 +               ui32NumPages--;
66993 +               sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
66994 +               sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
66995 +
66996 +
66997 +               if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE())
66998 +               {
66999 +
67000 +                       ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset;
67001 +               }
67002 +               else
67003 +               {
67004 +
67005 +                       ui32BlockBytes = ui32Bytes;
67006 +               }
67007 +
67008 +
67009 +
67010 +               if (bInitialisePages)
67011 +               {
67012 +                       eErr = PDumpOSBufprintf(hScript,
67013 +                                        ui32MaxLenScript,
67014 +                                        "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n",
67015 +                                        (IMG_UINT32) hUniqueTag1,
67016 +                                        sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
67017 +                                        sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
67018 +                                        ui32BlockBytes,
67019 +                                        ui32ParamOutPos,
67020 +                                        pszFileName);
67021 +                       if(eErr != PVRSRV_OK)
67022 +                       {
67023 +                               return eErr;
67024 +                       }
67025 +                       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67026 +               }
67027 +               else
67028 +               {
67029 +                       for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
67030 +                       {
67031 +                               IMG_UINT32 ui32PTE = *((IMG_UINT32 *) (pui8LinAddr + ui32Offset));
67032 +
67033 +                               if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0)
67034 +                               {
67035 +#if defined(SGX_FEATURE_36BIT_MMU)
67036 +                                       eErr = PDumpOSBufprintf(hScript,
67037 +                                                       ui32MaxLenScript,
67038 +                                                        "WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n",
67039 +                                                        (IMG_UINT32)hUniqueTag2,
67040 +                                                        (ui32PTE & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PTE_ADDR_ALIGNSHIFT);
67041 +                                       if(eErr != PVRSRV_OK)
67042 +                                       {
67043 +                                               return eErr;
67044 +                                       }
67045 +                                       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67046 +                                       eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :SGXMEM:$1 :SGXMEM:$1 0x4\r\n");
67047 +                                       if(eErr != PVRSRV_OK)
67048 +                                       {
67049 +                                               return eErr;
67050 +                                       }
67051 +                                       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67052 +                                       eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :SGXMEM:$1 :SGXMEM:$1 0x%8.8lX\r\n", ui32PTE & ~SGX_MMU_PDE_ADDR_MASK);
67053 +                                       if(eErr != PVRSRV_OK)
67054 +                                       {
67055 +                                               return eErr;
67056 +                                       }
67057 +                                       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67058 +                                       eErr = PDumpOSBufprintf(hScript,
67059 +                                                       ui32MaxLenScript,
67060 +                                                        "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$1\r\n",
67061 +                                                        (IMG_UINT32)hUniqueTag1,
67062 +                                                        (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_MASK),
67063 +                                                        (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK));
67064 +                                       if(eErr != PVRSRV_OK)
67065 +                                       {
67066 +                                               return eErr;
67067 +                                       }
67068 +                                       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67069 +#else
67070 +                                       eErr = PDumpOSBufprintf(hScript,
67071 +                                                       ui32MaxLenScript,
67072 +                                                        "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n",
67073 +                                                        (IMG_UINT32) hUniqueTag1,
67074 +                                                        (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_MASK),
67075 +                                                        (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK),
67076 +                                                        (IMG_UINT32) hUniqueTag2,
67077 +                                                        (ui32PTE & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PTE_ADDR_ALIGNSHIFT,
67078 +                                                        ui32PTE & ~SGX_MMU_PDE_ADDR_MASK);
67079 +                                       if(eErr != PVRSRV_OK)
67080 +                                       {
67081 +                                               return eErr;
67082 +                                       }
67083 +#endif
67084 +                               }
67085 +                               else
67086 +                               {
67087 +                                       PVR_ASSERT((ui32PTE & SGX_MMU_PTE_VALID) == 0UL);
67088 +                                       eErr = PDumpOSBufprintf(hScript,
67089 +                                                       ui32MaxLenScript,
67090 +                                                        "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX%8.8lX\r\n",
67091 +                                                        (IMG_UINT32) hUniqueTag1,
67092 +                                                        (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_MASK),
67093 +                                                        (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK),
67094 +                                                        (ui32PTE << SGX_MMU_PTE_ADDR_ALIGNSHIFT),
67095 +                                                        (IMG_UINT32) hUniqueTag2);
67096 +                                       if(eErr != PVRSRV_OK)
67097 +                                       {
67098 +                                               return eErr;
67099 +                                       }
67100 +                               }
67101 +                               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67102 +                       }
67103 +               }
67104 +
67105 +
67106 +
67107 +
67108 +               ui32PageOffset = 0;
67109 +
67110 +               ui32Bytes -= ui32BlockBytes;
67111 +
67112 +               pui8LinAddr += ui32BlockBytes;
67113 +
67114 +               ui32ParamOutPos += ui32BlockBytes;
67115 +       }
67116 +
67117 +       return PVRSRV_OK;
67118 +}
67119 +
67120 +PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
67121 +                                                          IMG_UINT32 ui32Offset,
67122 +                                                          IMG_DEV_PHYADDR sPDDevPAddr,
67123 +                                                          IMG_HANDLE hUniqueTag1,
67124 +                                                          IMG_HANDLE hUniqueTag2)
67125 +{
67126 +       PVRSRV_ERROR eErr;
67127 +       IMG_UINT32 ui32PageByteOffset;
67128 +       IMG_DEV_VIRTADDR sDevVAddr;
67129 +       IMG_DEV_VIRTADDR sDevVPageAddr;
67130 +       IMG_DEV_PHYADDR sDevPAddr;
67131 +
67132 +       PDUMP_GET_SCRIPT_STRING();
67133 +
67134 +       if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
67135 +                                               (IMG_UINT8 *)&sPDDevPAddr,
67136 +                                               sizeof(IMG_DEV_PHYADDR),
67137 +                                               PDUMP_FLAGS_CONTINUOUS))
67138 +       {
67139 +               return PVRSRV_ERROR_GENERIC;
67140 +       }
67141 +
67142 +       sDevVAddr = psMemInfo->sDevVAddr;
67143 +       ui32PageByteOffset = sDevVAddr.uiAddr & (SGX_MMU_PAGE_MASK);
67144 +
67145 +       sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
67146 +       PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
67147 +
67148 +       BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
67149 +       sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
67150 +
67151 +       if ((sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK) != 0UL)
67152 +       {
67153 +#if defined(SGX_FEATURE_36BIT_MMU)
67154 +               eErr = PDumpOSBufprintf(hScript,
67155 +                               ui32MaxLen,
67156 +                                "WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n",
67157 +                                (IMG_UINT32)hUniqueTag2,
67158 +                                sPDDevPAddr.uiAddr);
67159 +               if(eErr != PVRSRV_OK)
67160 +               {
67161 +                       return eErr;
67162 +               }
67163 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67164 +
67165 +               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "AND  :SGXMEM:$2 :SGXMEM:$1 0xFFFFFFFF\r\n");
67166 +               if(eErr != PVRSRV_OK)
67167 +               {
67168 +                       return eErr;
67169 +               }
67170 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67171 +
67172 +               eErr = PDumpOSBufprintf(hScript,
67173 +                               ui32MaxLen,
67174 +                                "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$2\r\n",
67175 +                                (IMG_UINT32)hUniqueTag1,
67176 +                                (sDevPAddr.uiAddr) & ~(SGX_MMU_PAGE_MASK),
67177 +                                (sDevPAddr.uiAddr) & (SGX_MMU_PAGE_MASK));
67178 +               if(eErr != PVRSRV_OK)
67179 +               {
67180 +                       return eErr;
67181 +               }
67182 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67183 +
67184 +               eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :SGXMEM:$2 :SGXMEM:$1 0x20\r\n");
67185 +               if(eErr != PVRSRV_OK)
67186 +               {
67187 +                       return eErr;
67188 +               }
67189 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67190 +
67191 +               eErr = PDumpOSBufprintf(hScript,
67192 +                               ui32MaxLen,
67193 +                                "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$2\r\n",
67194 +                                (IMG_UINT32)hUniqueTag1,
67195 +                                (sDevPAddr.uiAddr + 4) & ~(SGX_MMU_PAGE_MASK),
67196 +                                (sDevPAddr.uiAddr + 4) & (SGX_MMU_PAGE_MASK));
67197 +               if(eErr != PVRSRV_OK)
67198 +               {
67199 +                       return eErr;
67200 +               }
67201 +               PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67202 +#else
67203 +               eErr = PDumpOSBufprintf(hScript,
67204 +                                ui32MaxLen,
67205 +                                "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n",
67206 +                                (IMG_UINT32) hUniqueTag1,
67207 +                                sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
67208 +                                sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
67209 +                                (IMG_UINT32) hUniqueTag2,
67210 +                                sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK,
67211 +                                sPDDevPAddr.uiAddr & ~SGX_MMU_PDE_ADDR_MASK);
67212 +               if(eErr != PVRSRV_OK)
67213 +               {
67214 +                       return eErr;
67215 +               }
67216 +#endif
67217 +       }
67218 +       else
67219 +       {
67220 +               PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID));
67221 +               eErr = PDumpOSBufprintf(hScript,
67222 +                                ui32MaxLen,
67223 +                                "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX\r\n",
67224 +                                (IMG_UINT32) hUniqueTag1,
67225 +                                sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
67226 +                                sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
67227 +                                sPDDevPAddr.uiAddr);
67228 +               if(eErr != PVRSRV_OK)
67229 +               {
67230 +                       return eErr;
67231 +               }
67232 +       }
67233 +       PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
67234 +
67235 +       return PVRSRV_OK;
67236 +}
67237 +
67238 +PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
67239 +{
67240 +       PVRSRV_ERROR eErr;
67241 +       PDUMP_GET_MSG_STRING();
67242 +       PDUMP_DBG(("PDumpCommentKM"));
67243 +
67244 +
67245 +       if (!PDumpOSWriteString2("-- ", ui32Flags))
67246 +       {
67247 +               if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
67248 +               {
67249 +                       return PVRSRV_ERROR_GENERIC;
67250 +               }
67251 +               else
67252 +               {
67253 +                       return PVRSRV_ERROR_CMD_NOT_PROCESSED;
67254 +               }
67255 +       }
67256 +
67257 +
67258 +       eErr = PDumpOSBufprintf(hMsg, ui32MaxLen, "%s", pszComment);
67259 +       if( (eErr != PVRSRV_OK) &&
67260 +               (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
67261 +       {
67262 +               return eErr;
67263 +       }
67264 +
67265 +
67266 +       PDumpOSVerifyLineEnding(hMsg, ui32MaxLen);
67267 +       PDumpOSWriteString2(hMsg, ui32Flags);
67268 +
67269 +       return PVRSRV_OK;
67270 +}
67271 +
67272 +PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
67273 +{
67274 +       PVRSRV_ERROR eErr;
67275 +       PDUMP_va_list ap;
67276 +       PDUMP_GET_MSG_STRING();
67277 +
67278 +
67279 +       PDUMP_va_start(ap, pszFormat);
67280 +       eErr = PDumpOSVSprintf(hMsg, ui32MaxLen, pszFormat, ap);
67281 +       PDUMP_va_end(ap);
67282 +
67283 +       if(eErr != PVRSRV_OK)
67284 +       {
67285 +               return eErr;
67286 +       }
67287 +       return PDumpCommentKM(hMsg, ui32Flags);
67288 +}
67289 +
67290 +PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
67291 +{
67292 +       PVRSRV_ERROR eErr;
67293 +       PDUMP_va_list ap;
67294 +       PDUMP_GET_MSG_STRING();
67295 +
67296 +
67297 +       PDUMP_va_start(ap, pszFormat);
67298 +       eErr = PDumpOSVSprintf(hMsg, ui32MaxLen, pszFormat, ap);
67299 +       PDUMP_va_end(ap);
67300 +
67301 +       if(eErr != PVRSRV_OK)
67302 +       {
67303 +               return eErr;
67304 +       }
67305 +       return PDumpCommentKM(hMsg, PDUMP_FLAGS_CONTINUOUS);
67306 +}
67307 +
67308 +PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
67309 +{
67310 +       PVRSRV_ERROR eErr;
67311 +       IMG_UINT32      ui32MsgLen;
67312 +       PDUMP_GET_MSG_STRING();
67313 +
67314 +
67315 +       eErr = PDumpOSBufprintf(hMsg, ui32MaxLen, "%s", pszString);
67316 +       if(eErr != PVRSRV_OK)
67317 +       {
67318 +               return eErr;
67319 +       }
67320 +
67321 +
67322 +       PDumpOSVerifyLineEnding(hMsg, ui32MaxLen);
67323 +       ui32MsgLen = PDumpOSBuflen(hMsg, ui32MaxLen);
67324 +
67325 +       if      (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
67326 +                                                 (IMG_UINT8 *)hMsg,
67327 +                                                 ui32MsgLen,
67328 +                                                 ui32Flags))
67329 +       {
67330 +               if      (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
67331 +               {
67332 +                       return PVRSRV_ERROR_GENERIC;
67333 +               }
67334 +               else
67335 +               {
67336 +                       return PVRSRV_ERROR_CMD_NOT_PROCESSED;
67337 +               }
67338 +       }
67339 +
67340 +       return PVRSRV_OK;
67341 +}
67342 +
67343 +PVRSRV_ERROR PDumpBitmapKM(    IMG_CHAR *pszFileName,
67344 +                                                       IMG_UINT32 ui32FileOffset,
67345 +                                                       IMG_UINT32 ui32Width,
67346 +                                                       IMG_UINT32 ui32Height,
67347 +                                                       IMG_UINT32 ui32StrideInBytes,
67348 +                                                       IMG_DEV_VIRTADDR sDevBaseAddr,
67349 +                                                       IMG_UINT32 ui32Size,
67350 +                                                       PDUMP_PIXEL_FORMAT ePixelFormat,
67351 +                                                       PDUMP_MEM_FORMAT eMemFormat,
67352 +                                                       IMG_UINT32 ui32PDumpFlags)
67353 +{
67354 +       PVRSRV_ERROR eErr;
67355 +       PDUMP_GET_SCRIPT_STRING();
67356 +       PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
67357 +
67358 +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
67359 +
67360 +       eErr = PDumpOSBufprintf(hScript,
67361 +                               ui32MaxLen,
67362 +                               "SII %s %s.bin :SGXMEM:v%x:0x%08lX 0x%08lX 0x%08lX 0x%08X 0x%08lX 0x%08lX 0x%08lX 0x%08X\r\n",
67363 +                               pszFileName,
67364 +                               pszFileName,
67365 +                               PDUMP_DATAMASTER_PIXEL,
67366 +                               sDevBaseAddr.uiAddr,
67367 +                               ui32Size,
67368 +                               ui32FileOffset,
67369 +                               ePixelFormat,
67370 +                               ui32Width,
67371 +                               ui32Height,
67372 +                               ui32StrideInBytes,
67373 +                               eMemFormat);
67374 +#else
67375 +       eErr = PDumpOSBufprintf(hScript,
67376 +                               ui32MaxLen,
67377 +                               "SII %s %s.bin :SGXMEM:v:0x%08lX 0x%08lX 0x%08lX 0x%08X 0x%08lX 0x%08lX 0x%08lX 0x%08X\r\n",
67378 +                               pszFileName,
67379 +                               pszFileName,
67380 +                               sDevBaseAddr.uiAddr,
67381 +                               ui32Size,
67382 +                               ui32FileOffset,
67383 +                               ePixelFormat,
67384 +                               ui32Width,
67385 +                               ui32Height,
67386 +                               ui32StrideInBytes,
67387 +                               eMemFormat);
67388 +#endif
67389 +       if(eErr != PVRSRV_OK)
67390 +       {
67391 +               return eErr;
67392 +       }
67393 +
67394 +       PDumpOSWriteString2( hScript, ui32PDumpFlags);
67395 +       return PVRSRV_OK;
67396 +}
67397 +
67398 +PVRSRV_ERROR PDumpReadRegKM            (       IMG_CHAR *pszFileName,
67399 +                                                                       IMG_UINT32 ui32FileOffset,
67400 +                                                                       IMG_UINT32 ui32Address,
67401 +                                                                       IMG_UINT32 ui32Size,
67402 +                                                                       IMG_UINT32 ui32PDumpFlags)
67403 +{
67404 +       PVRSRV_ERROR eErr;
67405 +       PDUMP_GET_SCRIPT_STRING();
67406 +
67407 +       PVR_UNREFERENCED_PARAMETER(ui32Size);
67408 +
67409 +       eErr = PDumpOSBufprintf(hScript,
67410 +                       ui32MaxLen,
67411 +                       "SAB :SGXREG:0x%08lX 0x%08lX %s\r\n",
67412 +                       ui32Address,
67413 +                       ui32FileOffset,
67414 +                       pszFileName);
67415 +       if(eErr != PVRSRV_OK)
67416 +       {
67417 +               return eErr;
67418 +       }
67419 +
67420 +       PDumpOSWriteString2( hScript, ui32PDumpFlags);
67421 +
67422 +       return PVRSRV_OK;
67423 +}
67424 +
67425 +IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
67426 +{
67427 +       IMG_BOOL        bFrameDumped;
67428 +
67429 +
67430 +
67431 +       (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
67432 +       bFrameDumped = PDumpIsCaptureFrameKM();
67433 +       (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
67434 +
67435 +       return bFrameDumped;
67436 +}
67437 +
67438 +static PVRSRV_ERROR PDumpSignatureRegister     (IMG_CHAR       *pszFileName,
67439 +                                                                        IMG_UINT32             ui32Address,
67440 +                                                                        IMG_UINT32             ui32Size,
67441 +                                                                        IMG_UINT32             *pui32FileOffset,
67442 +                                                                        IMG_UINT32             ui32Flags)
67443 +{
67444 +       PVRSRV_ERROR eErr;
67445 +       PDUMP_GET_SCRIPT_STRING();
67446 +
67447 +       eErr = PDumpOSBufprintf(hScript,
67448 +                       ui32MaxLen,
67449 +                       "SAB :SGXREG:0x%08X 0x%08X %s\r\n",
67450 +                       ui32Address,
67451 +                       *pui32FileOffset,
67452 +                       pszFileName);
67453 +       if(eErr != PVRSRV_OK)
67454 +       {
67455 +               return eErr;
67456 +       }
67457 +
67458 +       PDumpOSWriteString2(hScript, ui32Flags);
67459 +       *pui32FileOffset += ui32Size;
67460 +       return PVRSRV_OK;
67461 +}
67462 +
67463 +static IMG_VOID PDumpRegisterRange(IMG_CHAR *pszFileName,
67464 +               IMG_UINT32 *pui32Registers,
67465 +               IMG_UINT32  ui32NumRegisters,
67466 +               IMG_UINT32 *pui32FileOffset,
67467 +               IMG_UINT32      ui32Size,
67468 +               IMG_UINT32      ui32Flags)
67469 +{
67470 +       IMG_UINT32 i;
67471 +       for (i = 0; i < ui32NumRegisters; i++)
67472 +       {
67473 +               PDumpSignatureRegister(pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
67474 +       }
67475 +}
67476 +
67477 +PVRSRV_ERROR PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum,
67478 +                       IMG_BOOL bLastFrame,
67479 +                       IMG_UINT32 *pui32Registers,
67480 +                       IMG_UINT32 ui32NumRegisters)
67481 +{
67482 +       PVRSRV_ERROR eErr;
67483 +       IMG_UINT32      ui32FileOffset, ui32Flags;
67484 +
67485 +       PDUMP_GET_FILE_STRING();
67486 +
67487 +       ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
67488 +       ui32FileOffset = 0;
67489 +
67490 +       PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
67491 +       eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%lu_3d.sig", ui32DumpFrameNum);
67492 +       if(eErr != PVRSRV_OK)
67493 +       {
67494 +               return eErr;
67495 +       }
67496 +
67497 +       PDumpRegisterRange(pszFileName, pui32Registers, ui32NumRegisters, &ui32FileOffset, sizeof(IMG_UINT32), ui32Flags);
67498 +       return PVRSRV_OK;
67499 +}
67500 +
67501 +PVRSRV_ERROR PDumpTASignatureRegisters (IMG_UINT32 ui32DumpFrameNum,
67502 +                        IMG_UINT32     ui32TAKickCount,
67503 +                        IMG_BOOL       bLastFrame,
67504 +                        IMG_UINT32 *pui32Registers,
67505 +                        IMG_UINT32 ui32NumRegisters)
67506 +{
67507 +       PVRSRV_ERROR eErr;
67508 +       IMG_UINT32      ui32FileOffset, ui32Flags;
67509 +
67510 +       PDUMP_GET_FILE_STRING();
67511 +
67512 +       ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
67513 +       ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
67514 +
67515 +       PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
67516 +       eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%lu_ta.sig", ui32DumpFrameNum);
67517 +       if(eErr != PVRSRV_OK)
67518 +       {
67519 +               return eErr;
67520 +       }
67521 +
67522 +       PDumpRegisterRange(pszFileName, pui32Registers, ui32NumRegisters, &ui32FileOffset, sizeof(IMG_UINT32), ui32Flags);
67523 +       return PVRSRV_OK;
67524 +}
67525 +
67526 +PVRSRV_ERROR PDumpCounterRegisters (IMG_UINT32 ui32DumpFrameNum,
67527 +                                                               IMG_BOOL        bLastFrame,
67528 +                                                               IMG_UINT32 *pui32Registers,
67529 +                                                               IMG_UINT32 ui32NumRegisters)
67530 +{
67531 +       PVRSRV_ERROR eErr;
67532 +       IMG_UINT32      ui32FileOffset, ui32Flags;
67533 +
67534 +       PDUMP_GET_FILE_STRING();
67535 +
67536 +       ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
67537 +       ui32FileOffset = 0UL;
67538 +
67539 +       PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
67540 +       eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%lu.perf", ui32DumpFrameNum);
67541 +       if(eErr != PVRSRV_OK)
67542 +       {
67543 +               return eErr;
67544 +       }
67545 +
67546 +       PDumpRegisterRange(pszFileName, pui32Registers, ui32NumRegisters, &ui32FileOffset, sizeof(IMG_UINT32), ui32Flags);
67547 +       return PVRSRV_OK;
67548 +}
67549 +
67550 +PVRSRV_ERROR PDumpRegRead(const IMG_UINT32 ui32RegOffset, IMG_UINT32 ui32Flags)
67551 +{
67552 +       PVRSRV_ERROR eErr;
67553 +       PDUMP_GET_SCRIPT_STRING();
67554 +
67555 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :SGXREG:0x%lX\r\n", ui32RegOffset);
67556 +       if(eErr != PVRSRV_OK)
67557 +       {
67558 +               return eErr;
67559 +       }
67560 +       PDumpOSWriteString2(hScript, ui32Flags);
67561 +       return PVRSRV_OK;
67562 +}
67563 +
67564 +PVRSRV_ERROR PDumpCycleCountRegRead(const IMG_UINT32 ui32RegOffset, IMG_BOOL bLastFrame)
67565 +{
67566 +       PVRSRV_ERROR eErr;
67567 +       PDUMP_GET_SCRIPT_STRING();
67568 +
67569 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :SGXREG:0x%lX\r\n", ui32RegOffset);
67570 +       if(eErr != PVRSRV_OK)
67571 +       {
67572 +               return eErr;
67573 +       }
67574 +       PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
67575 +       return PVRSRV_OK;
67576 +}
67577 +
67578 +PVRSRV_ERROR PDumpHWPerfCBKM (IMG_CHAR                 *pszFileName,
67579 +                                                 IMG_UINT32            ui32FileOffset,
67580 +                                                 IMG_DEV_VIRTADDR      sDevBaseAddr,
67581 +                                                 IMG_UINT32            ui32Size,
67582 +                                                 IMG_UINT32            ui32PDumpFlags)
67583 +{
67584 +       PVRSRV_ERROR eErr;
67585 +       PDUMP_GET_SCRIPT_STRING();
67586 +       PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
67587 +
67588 +       eErr = PDumpOSBufprintf(hScript,
67589 +                               ui32MaxLen,
67590 +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
67591 +                               "SAB :SGXMEM:v%x:0x%08lX 0x%08lX 0x%08lX %s.bin\r\n",
67592 +                               PDUMP_DATAMASTER_EDM,
67593 +#else
67594 +                               "SAB :SGXMEM:v:0x%08lX 0x%08lX 0x%08lX %s.bin\r\n",
67595 +#endif
67596 +                               sDevBaseAddr.uiAddr,
67597 +                               ui32Size,
67598 +                               ui32FileOffset,
67599 +                               pszFileName);
67600 +       if(eErr != PVRSRV_OK)
67601 +       {
67602 +               return eErr;
67603 +       }
67604 +
67605 +       PDumpOSWriteString2(hScript, ui32PDumpFlags);
67606 +       return PVRSRV_OK;
67607 +}
67608 +
67609 +
67610 +PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO          psROffMemInfo,
67611 +                         IMG_UINT32                                    ui32ROffOffset,
67612 +                         IMG_UINT32                                    ui32WPosVal,
67613 +                         IMG_UINT32                                    ui32PacketSize,
67614 +                         IMG_UINT32                                    ui32BufferSize,
67615 +                         IMG_UINT32                                    ui32Flags,
67616 +                         IMG_HANDLE                                    hUniqueTag)
67617 +{
67618 +       PVRSRV_ERROR eErr;
67619 +       IMG_UINT32                      ui32PageOffset;
67620 +       IMG_UINT8                       *pui8LinAddr;
67621 +       IMG_DEV_VIRTADDR        sDevVAddr;
67622 +       IMG_DEV_PHYADDR         sDevPAddr;
67623 +       IMG_DEV_VIRTADDR        sDevVPageAddr;
67624 +
67625 +
67626 +       PDUMP_GET_SCRIPT_STRING();
67627 +
67628 +
67629 +       PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->ui32AllocSize);
67630 +
67631 +       pui8LinAddr = psROffMemInfo->pvLinAddrKM;
67632 +       sDevVAddr = psROffMemInfo->sDevVAddr;
67633 +
67634 +
67635 +       pui8LinAddr += ui32ROffOffset;
67636 +       sDevVAddr.uiAddr += ui32ROffOffset;
67637 +
67638 +
67639 +
67640 +
67641 +
67642 +
67643 +       PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
67644 +                       ui32ROffOffset,
67645 +                       pui8LinAddr,
67646 +                       &ui32PageOffset);
67647 +
67648 +
67649 +       sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
67650 +
67651 +       PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
67652 +
67653 +
67654 +       BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
67655 +
67656 +
67657 +       sDevPAddr.uiAddr += ui32PageOffset;
67658 +
67659 +       eErr = PDumpOSBufprintf(hScript,
67660 +                        ui32MaxLen,
67661 +                        "CBP :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX 0x%8.8lX\r\n",
67662 +                        (IMG_UINT32) hUniqueTag,
67663 +                        sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK),
67664 +                        sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK),
67665 +                        ui32WPosVal,
67666 +                        ui32PacketSize,
67667 +                        ui32BufferSize);
67668 +       if(eErr != PVRSRV_OK)
67669 +       {
67670 +               return eErr;
67671 +       }
67672 +       PDumpOSWriteString2(hScript, ui32Flags);
67673 +       return PVRSRV_OK;
67674 +}
67675 +
67676 +
67677 +PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
67678 +{
67679 +       PVRSRV_ERROR eErr;
67680 +       PDUMP_GET_SCRIPT_STRING();
67681 +       PDUMP_DBG(("PDumpIDLWithFlags"));
67682 +
67683 +       eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %lu\r\n", ui32Clocks);
67684 +       if(eErr != PVRSRV_OK)
67685 +       {
67686 +               return eErr;
67687 +       }
67688 +       PDumpOSWriteString2(hScript, ui32Flags);
67689 +       return PVRSRV_OK;
67690 +}
67691 +
67692 +
67693 +PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
67694 +{
67695 +       return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
67696 +}
67697 +#endif
67698 +
67699 +
67700 +PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
67701 +                                               IMG_PVOID pvAltLinAddrUM,
67702 +                                               IMG_PVOID pvLinAddrUM,
67703 +                                               PVRSRV_KERNEL_MEM_INFO *psMemInfo,
67704 +                                               IMG_UINT32 ui32Offset,
67705 +                                               IMG_UINT32 ui32Bytes,
67706 +                                               IMG_UINT32 ui32Flags,
67707 +                                               IMG_HANDLE hUniqueTag)
67708 +{
67709 +       IMG_VOID *pvAddrUM;
67710 +       IMG_VOID *pvAddrKM;
67711 +       IMG_UINT32 ui32BytesDumped;
67712 +       IMG_UINT32 ui32CurrentOffset;
67713 +
67714 +       if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
67715 +       {
67716 +
67717 +               return PDumpMemKM(IMG_NULL,
67718 +                                          psMemInfo,
67719 +                                          ui32Offset,
67720 +                                          ui32Bytes,
67721 +                                          ui32Flags,
67722 +                                          hUniqueTag);
67723 +       }
67724 +
67725 +       pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
67726 +
67727 +       pvAddrKM = GetTempBuffer();
67728 +
67729 +
67730 +       PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
67731 +       if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
67732 +       {
67733 +               PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
67734 +               return PVRSRV_ERROR_GENERIC;
67735 +       }
67736 +
67737 +       if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
67738 +       {
67739 +               PDumpCommentWithFlags(ui32Flags, "Dumping 0x%8.8lx bytes of memory, in blocks of 0x%8.8lx bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
67740 +       }
67741 +
67742 +       ui32CurrentOffset = ui32Offset;
67743 +       for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
67744 +       {
67745 +               PVRSRV_ERROR eError;
67746 +               IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
67747 +
67748 +               eError = OSCopyFromUser(psPerProc,
67749 +                                          pvAddrKM,
67750 +                                          pvAddrUM,
67751 +                                          ui32BytesToDump);
67752 +               if (eError != PVRSRV_OK)
67753 +               {
67754 +                       PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d), eError"));
67755 +                       return PVRSRV_ERROR_GENERIC;
67756 +               }
67757 +
67758 +               eError = PDumpMemKM(pvAddrKM,
67759 +                                          psMemInfo,
67760 +                                          ui32CurrentOffset,
67761 +                                          ui32BytesToDump,
67762 +                                          ui32Flags,
67763 +                                          hUniqueTag);
67764 +
67765 +               if (eError != PVRSRV_OK)
67766 +               {
67767 +
67768 +                       if (ui32BytesDumped != 0)
67769 +                       {
67770 +                               PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
67771 +                       }
67772 +                       PVR_ASSERT(ui32BytesDumped == 0);
67773 +                       return eError;
67774 +               }
67775 +
67776 +               VPTR_INC(pvAddrUM, ui32BytesToDump);
67777 +               ui32CurrentOffset += ui32BytesToDump;
67778 +               ui32BytesDumped += ui32BytesToDump;
67779 +       }
67780 +
67781 +       return PVRSRV_OK;
67782 +}
67783 +
67784 +
67785 +static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
67786 +{
67787 +       IMG_UINT32 i;
67788 +
67789 +
67790 +       for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
67791 +       {
67792 +               if((gui16MMUContextUsage & (1U << i)) == 0)
67793 +               {
67794 +
67795 +                       gui16MMUContextUsage |= 1U << i;
67796 +                       *pui32MMUContextID = i;
67797 +                       return PVRSRV_OK;
67798 +               }
67799 +       }
67800 +
67801 +       PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
67802 +
67803 +       return PVRSRV_ERROR_GENERIC;
67804 +}
67805 +
67806 +
67807 +static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
67808 +{
67809 +       if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
67810 +       {
67811 +
67812 +               gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
67813 +               return PVRSRV_OK;
67814 +       }
67815 +
67816 +       PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
67817 +
67818 +       return PVRSRV_ERROR_GENERIC;
67819 +}
67820 +
67821 +
67822 +PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
67823 +                                                               IMG_CHAR *pszMemSpace,
67824 +                                                               IMG_UINT32 *pui32MMUContextID,
67825 +                                                               IMG_UINT32 ui32MMUType,
67826 +                                                               IMG_HANDLE hUniqueTag1,
67827 +                                                               IMG_VOID *pvPDCPUAddr)
67828 +{
67829 +       IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
67830 +       IMG_CPU_PHYADDR sCpuPAddr;
67831 +       IMG_DEV_PHYADDR sDevPAddr;
67832 +       IMG_UINT32 ui32MMUContextID;
67833 +       PVRSRV_ERROR eError;
67834 +
67835 +       eError = _PdumpAllocMMUContext(&ui32MMUContextID);
67836 +       if(eError != PVRSRV_OK)
67837 +       {
67838 +               PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eError));
67839 +               return eError;
67840 +       }
67841 +
67842 +
67843 +       sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
67844 +       sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
67845 +
67846 +       sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
67847 +
67848 +       PDumpComment("Set MMU Context\r\n");
67849 +
67850 +       PDumpComment("MMU :%s:v%d %d :%s:PA_%8.8lX%8.8lX\r\n",
67851 +                                               pszMemSpace,
67852 +                                               ui32MMUContextID,
67853 +                                               ui32MMUType,
67854 +                                               pszMemSpace,
67855 +                                               hUniqueTag1,
67856 +                                               sDevPAddr.uiAddr);
67857 +
67858 +
67859 +       *pui32MMUContextID = ui32MMUContextID;
67860 +
67861 +       return PVRSRV_OK;
67862 +}
67863 +
67864 +
67865 +PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
67866 +                                                               IMG_CHAR *pszMemSpace,
67867 +                                                               IMG_UINT32 ui32MMUContextID,
67868 +                                                               IMG_UINT32 ui32MMUType)
67869 +{
67870 +       PVRSRV_ERROR eError;
67871 +
67872 +       PVR_UNREFERENCED_PARAMETER(eDeviceType);
67873 +
67874 +
67875 +       PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
67876 +
67877 +       PDumpComment("MMU :%s:v%d %d\r\n",
67878 +                                               pszMemSpace,
67879 +                                               ui32MMUContextID,
67880 +                                               ui32MMUType);
67881 +
67882 +       eError = _PdumpFreeMMUContext(ui32MMUContextID);
67883 +       if(eError != PVRSRV_OK)
67884 +       {
67885 +               PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eError));
67886 +               return eError;
67887 +       }
67888 +
67889 +       return PVRSRV_OK;
67890 +}
67891 +
67892 +#else
67893 +#endif
67894 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/perproc.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/perproc.c
67895 new file mode 100644
67896 index 0000000..982c31f
67897 --- /dev/null
67898 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/perproc.c
67899 @@ -0,0 +1,283 @@
67900 +/**********************************************************************
67901 + *
67902 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
67903 + *
67904 + * This program is free software; you can redistribute it and/or modify it
67905 + * under the terms and conditions of the GNU General Public License,
67906 + * version 2, as published by the Free Software Foundation.
67907 + *
67908 + * This program is distributed in the hope it will be useful but, except
67909 + * as otherwise stated in writing, without any warranty; without even the
67910 + * implied warranty of merchantability or fitness for a particular purpose.
67911 + * See the GNU General Public License for more details.
67912 + *
67913 + * You should have received a copy of the GNU General Public License along with
67914 + * this program; if not, write to the Free Software Foundation, Inc.,
67915 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
67916 + *
67917 + * The full GNU General Public License is included in this distribution in
67918 + * the file called "COPYING".
67919 + *
67920 + * Contact Information:
67921 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
67922 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
67923 + *
67924 + ******************************************************************************/
67925 +
67926 +#include "services_headers.h"
67927 +#include "resman.h"
67928 +#include "handle.h"
67929 +#include "perproc.h"
67930 +#include "osperproc.h"
67931 +
67932 +#define        HASH_TAB_INIT_SIZE 32
67933 +
67934 +static HASH_TABLE *psHashTab = IMG_NULL;
67935 +
67936 +static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
67937 +{
67938 +       PVRSRV_ERROR eError;
67939 +       IMG_UINTPTR_T uiPerProc;
67940 +
67941 +       PVR_ASSERT(psPerProc != IMG_NULL);
67942 +
67943 +       if (psPerProc == IMG_NULL)
67944 +       {
67945 +               PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
67946 +               return PVRSRV_ERROR_INVALID_PARAMS;
67947 +       }
67948 +
67949 +       uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
67950 +       if (uiPerProc == 0)
67951 +       {
67952 +               PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
67953 +
67954 +               PVR_ASSERT(psPerProc->ui32PID == 0);
67955 +       }
67956 +       else
67957 +       {
67958 +               PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
67959 +               PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
67960 +       }
67961 +
67962 +
67963 +       if (psPerProc->psHandleBase != IMG_NULL)
67964 +       {
67965 +               eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
67966 +               if (eError != PVRSRV_OK)
67967 +               {
67968 +                       PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
67969 +                       return eError;
67970 +               }
67971 +       }
67972 +
67973 +
67974 +       if (psPerProc->hPerProcData != IMG_NULL)
67975 +       {
67976 +               eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
67977 +
67978 +               if (eError != PVRSRV_OK)
67979 +               {
67980 +                       PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
67981 +                       return eError;
67982 +               }
67983 +       }
67984 +
67985 +
67986 +       eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
67987 +       if (eError != PVRSRV_OK)
67988 +       {
67989 +                PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
67990 +               return eError;
67991 +       }
67992 +
67993 +       eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
67994 +               sizeof(*psPerProc),
67995 +               psPerProc,
67996 +               psPerProc->hBlockAlloc);
67997 +
67998 +       if (eError != PVRSRV_OK)
67999 +       {
68000 +               PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
68001 +               return eError;
68002 +       }
68003 +
68004 +       return PVRSRV_OK;
68005 +}
68006 +
68007 +
68008 +PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
68009 +{
68010 +       PVRSRV_PER_PROCESS_DATA *psPerProc;
68011 +
68012 +       PVR_ASSERT(psHashTab != IMG_NULL);
68013 +
68014 +
68015 +       psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
68016 +       return psPerProc;
68017 +}
68018 +
68019 +
68020 +PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32    ui32PID)
68021 +{
68022 +       PVRSRV_PER_PROCESS_DATA *psPerProc;
68023 +       IMG_HANDLE hBlockAlloc;
68024 +       PVRSRV_ERROR eError = PVRSRV_OK;
68025 +
68026 +       PVR_ASSERT(psHashTab != IMG_NULL);
68027 +
68028 +
68029 +       psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
68030 +
68031 +       if (psPerProc == IMG_NULL)
68032 +       {
68033 +
68034 +               eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
68035 +                                                       sizeof(*psPerProc),
68036 +                                                       (IMG_PVOID *)&psPerProc,
68037 +                                                       &hBlockAlloc,
68038 +                                                       "Per Process Data");
68039 +               if (eError != PVRSRV_OK)
68040 +               {
68041 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
68042 +                       return eError;
68043 +               }
68044 +               OSMemSet(psPerProc, 0, sizeof(*psPerProc));
68045 +               psPerProc->hBlockAlloc = hBlockAlloc;
68046 +
68047 +               if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
68048 +               {
68049 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
68050 +                       eError = PVRSRV_ERROR_GENERIC;
68051 +                       goto failure;
68052 +               }
68053 +
68054 +               psPerProc->ui32PID = ui32PID;
68055 +               psPerProc->ui32RefCount = 0;
68056 +
68057 +
68058 +               eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
68059 +               if (eError != PVRSRV_OK)
68060 +               {
68061 +                        PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
68062 +                       goto failure;
68063 +               }
68064 +
68065 +
68066 +               eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
68067 +                                                                  &psPerProc->hPerProcData,
68068 +                                                                  psPerProc,
68069 +                                                                  PVRSRV_HANDLE_TYPE_PERPROC_DATA,
68070 +                                                                  PVRSRV_HANDLE_ALLOC_FLAG_NONE);
68071 +               if (eError != PVRSRV_OK)
68072 +               {
68073 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
68074 +                       goto failure;
68075 +               }
68076 +
68077 +
68078 +               eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
68079 +               if (eError != PVRSRV_OK)
68080 +               {
68081 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
68082 +                       goto failure;
68083 +               }
68084 +
68085 +
68086 +               eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
68087 +               if (eError != PVRSRV_OK)
68088 +               {
68089 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
68090 +                       goto failure;
68091 +               }
68092 +
68093 +
68094 +               eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
68095 +               if (eError != PVRSRV_OK)
68096 +               {
68097 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
68098 +                       goto failure;
68099 +               }
68100 +       }
68101 +
68102 +       psPerProc->ui32RefCount++;
68103 +       PVR_DPF((PVR_DBG_MESSAGE,
68104 +                       "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
68105 +                       ui32PID, psPerProc->ui32RefCount));
68106 +
68107 +       return eError;
68108 +
68109 +failure:
68110 +       (IMG_VOID)FreePerProcessData(psPerProc);
68111 +       return eError;
68112 +}
68113 +
68114 +
68115 +IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32     ui32PID)
68116 +{
68117 +       PVRSRV_ERROR eError;
68118 +       PVRSRV_PER_PROCESS_DATA *psPerProc;
68119 +
68120 +       PVR_ASSERT(psHashTab != IMG_NULL);
68121 +
68122 +       psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
68123 +       if (psPerProc == IMG_NULL)
68124 +       {
68125 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
68126 +       }
68127 +       else
68128 +       {
68129 +               psPerProc->ui32RefCount--;
68130 +               if (psPerProc->ui32RefCount == 0)
68131 +               {
68132 +                       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
68133 +                                       "Last close from process 0x%x received", ui32PID));
68134 +
68135 +
68136 +                       PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
68137 +
68138 +
68139 +                       eError = FreePerProcessData(psPerProc);
68140 +                       if (eError != PVRSRV_OK)
68141 +                       {
68142 +                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
68143 +                       }
68144 +               }
68145 +       }
68146 +
68147 +       eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
68148 +       if (eError != PVRSRV_OK)
68149 +       {
68150 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
68151 +       }
68152 +}
68153 +
68154 +
68155 +PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
68156 +{
68157 +       PVR_ASSERT(psHashTab == IMG_NULL);
68158 +
68159 +
68160 +       psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
68161 +       if (psHashTab == IMG_NULL)
68162 +       {
68163 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
68164 +               return PVRSRV_ERROR_GENERIC;
68165 +       }
68166 +
68167 +       return PVRSRV_OK;
68168 +}
68169 +
68170 +PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
68171 +{
68172 +
68173 +       if (psHashTab != IMG_NULL)
68174 +       {
68175 +
68176 +               HASH_Delete(psHashTab);
68177 +               psHashTab = IMG_NULL;
68178 +       }
68179 +
68180 +       return PVRSRV_OK;
68181 +}
68182 +
68183 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/power.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/power.c
68184 new file mode 100644
68185 index 0000000..826aaa2
68186 --- /dev/null
68187 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/power.c
68188 @@ -0,0 +1,818 @@
68189 +/**********************************************************************
68190 + *
68191 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
68192 + *
68193 + * This program is free software; you can redistribute it and/or modify it
68194 + * under the terms and conditions of the GNU General Public License,
68195 + * version 2, as published by the Free Software Foundation.
68196 + *
68197 + * This program is distributed in the hope it will be useful but, except
68198 + * as otherwise stated in writing, without any warranty; without even the
68199 + * implied warranty of merchantability or fitness for a particular purpose.
68200 + * See the GNU General Public License for more details.
68201 + *
68202 + * You should have received a copy of the GNU General Public License along with
68203 + * this program; if not, write to the Free Software Foundation, Inc.,
68204 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
68205 + *
68206 + * The full GNU General Public License is included in this distribution in
68207 + * the file called "COPYING".
68208 + *
68209 + * Contact Information:
68210 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
68211 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
68212 + *
68213 + ******************************************************************************/
68214 +
68215 +#include "services_headers.h"
68216 +#include "pdump_km.h"
68217 +
68218 +#include "lists.h"
68219 +
68220 +DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
68221 +DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
68222 +DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
68223 +DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
68224 +
68225 +IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
68226 +
68227 +
68228 +static IMG_BOOL gbInitServerRunning = IMG_FALSE;
68229 +static IMG_BOOL gbInitServerRan = IMG_FALSE;
68230 +static IMG_BOOL gbInitSuccessful = IMG_FALSE;
68231 +
68232 +IMG_EXPORT
68233 +PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState)
68234 +{
68235 +
68236 +       switch(eInitServerState)
68237 +       {
68238 +               case PVRSRV_INIT_SERVER_RUNNING:
68239 +                       gbInitServerRunning     = bState;
68240 +                       break;
68241 +               case PVRSRV_INIT_SERVER_RAN:
68242 +                       gbInitServerRan = bState;
68243 +                       break;
68244 +               case PVRSRV_INIT_SERVER_SUCCESSFUL:
68245 +                       gbInitSuccessful = bState;
68246 +                       break;
68247 +               default:
68248 +                       PVR_DPF((PVR_DBG_ERROR,
68249 +                               "PVRSRVSetInitServerState : Unknown state %lx", eInitServerState));
68250 +                       return PVRSRV_ERROR_GENERIC;
68251 +       }
68252 +
68253 +       return PVRSRV_OK;
68254 +}
68255 +
68256 +IMG_EXPORT
68257 +IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState)
68258 +{
68259 +       IMG_BOOL        bReturnVal;
68260 +
68261 +       switch(eInitServerState)
68262 +       {
68263 +               case PVRSRV_INIT_SERVER_RUNNING:
68264 +                       bReturnVal = gbInitServerRunning;
68265 +                       break;
68266 +               case PVRSRV_INIT_SERVER_RAN:
68267 +                       bReturnVal = gbInitServerRan;
68268 +                       break;
68269 +               case PVRSRV_INIT_SERVER_SUCCESSFUL:
68270 +                       bReturnVal = gbInitSuccessful;
68271 +                       break;
68272 +               default:
68273 +                       PVR_DPF((PVR_DBG_ERROR,
68274 +                               "PVRSRVGetInitServerState : Unknown state %lx", eInitServerState));
68275 +                       bReturnVal = IMG_FALSE;
68276 +       }
68277 +
68278 +       return bReturnVal;
68279 +}
68280 +
68281 +static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
68282 +{
68283 +       return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2);
68284 +}
68285 +
68286 +
68287 +IMG_EXPORT
68288 +PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32        ui32CallerID,
68289 +                                                        IMG_BOOL       bSystemPowerEvent)
68290 +{
68291 +       PVRSRV_ERROR    eError;
68292 +       SYS_DATA                *psSysData;
68293 +#if !defined(SYS_NO_POWER_LOCK_TIMEOUT)
68294 +       IMG_UINT32              ui32Timeout = 1000000;
68295 +
68296 +#if defined(SUPPORT_LMA)
68297 +       ui32Timeout *= 60;
68298 +#endif
68299 +#endif
68300 +       SysAcquireData(&psSysData);
68301 +
68302 +#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
68303 +       eError = SysPowerLockWrap(psSysData);
68304 +       if (eError != PVRSRV_OK)
68305 +       {
68306 +               return eError;
68307 +       }
68308 +#endif
68309 +       do
68310 +       {
68311 +               eError = OSLockResource(&psSysData->sPowerStateChangeResource,
68312 +                                                               ui32CallerID);
68313 +               if (eError == PVRSRV_OK)
68314 +               {
68315 +                       break;
68316 +               }
68317 +               else if (ui32CallerID == ISR_ID)
68318 +               {
68319 +
68320 +
68321 +                       eError = PVRSRV_ERROR_RETRY;
68322 +                       break;
68323 +               }
68324 +
68325 +               OSWaitus(1);
68326 +#if defined(SYS_NO_POWER_LOCK_TIMEOUT)
68327 +       } while (1);
68328 +#else
68329 +               ui32Timeout--;
68330 +       } while (ui32Timeout > 0);
68331 +#endif
68332 +
68333 +#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
68334 +       if (eError != PVRSRV_OK)
68335 +       {
68336 +               SysPowerLockUnwrap(psSysData);
68337 +       }
68338 +#endif
68339 +       if ((eError == PVRSRV_OK) &&
68340 +               !bSystemPowerEvent &&
68341 +               !_IsSystemStatePowered(psSysData->eCurrentPowerState))
68342 +       {
68343 +
68344 +               PVRSRVPowerUnlock(ui32CallerID);
68345 +               eError = PVRSRV_ERROR_RETRY;
68346 +       }
68347 +
68348 +       return eError;
68349 +}
68350 +
68351 +
68352 +IMG_EXPORT
68353 +IMG_VOID PVRSRVPowerUnlock(IMG_UINT32  ui32CallerID)
68354 +{
68355 +       OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID);
68356 +#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
68357 +       SysPowerLockUnwrap(gpsSysData);
68358 +#endif
68359 +}
68360 +
68361 +
68362 +PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
68363 +{
68364 +       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
68365 +       PVRSRV_ERROR                    eError;
68366 +
68367 +
68368 +       IMG_BOOL                                bAllDevices;
68369 +       IMG_UINT32                              ui32DeviceIndex;
68370 +       PVRSRV_DEV_POWER_STATE  eNewPowerState;
68371 +
68372 +
68373 +       bAllDevices = va_arg(va, IMG_BOOL);
68374 +       ui32DeviceIndex = va_arg(va, IMG_UINT32);
68375 +       eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
68376 +
68377 +       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
68378 +       {
68379 +               eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
68380 +                                                       psPowerDevice->eDefaultPowerState : eNewPowerState;
68381 +
68382 +               if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
68383 +               {
68384 +                       if (psPowerDevice->pfnPrePower != IMG_NULL)
68385 +                       {
68386 +
68387 +                               eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie,
68388 +                                                                                                       eNewDevicePowerState,
68389 +                                                                                                       psPowerDevice->eCurrentPowerState);
68390 +                               if (eError != PVRSRV_OK)
68391 +                               {
68392 +                                       return eError;
68393 +                               }
68394 +                       }
68395 +
68396 +
68397 +                       eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex,
68398 +                                                                                       eNewDevicePowerState,
68399 +                                                                                       psPowerDevice->eCurrentPowerState);
68400 +                       if (eError != PVRSRV_OK)
68401 +                       {
68402 +                               return eError;
68403 +                       }
68404 +               }
68405 +       }
68406 +
68407 +       return  PVRSRV_OK;
68408 +}
68409 +
68410 +static
68411 +PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL                              bAllDevices,
68412 +                                                                                IMG_UINT32                             ui32DeviceIndex,
68413 +                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState)
68414 +{
68415 +       PVRSRV_ERROR            eError;
68416 +       SYS_DATA                        *psSysData;
68417 +
68418 +       SysAcquireData(&psSysData);
68419 +
68420 +
68421 +       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
68422 +                                                                                                               PVRSRVDevicePrePowerStateKM_AnyVaCb,
68423 +                                                                                                               bAllDevices,
68424 +                                                                                                               ui32DeviceIndex,
68425 +                                                                                                               eNewPowerState);
68426 +
68427 +       return eError;
68428 +}
68429 +
68430 +PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
68431 +{
68432 +       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
68433 +       PVRSRV_ERROR                    eError;
68434 +
68435 +
68436 +       IMG_BOOL                                bAllDevices;
68437 +       IMG_UINT32                              ui32DeviceIndex;
68438 +       PVRSRV_DEV_POWER_STATE  eNewPowerState;
68439 +
68440 +
68441 +       bAllDevices = va_arg(va, IMG_BOOL);
68442 +       ui32DeviceIndex = va_arg(va, IMG_UINT32);
68443 +       eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
68444 +
68445 +       if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
68446 +       {
68447 +               eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
68448 +                                                               psPowerDevice->eDefaultPowerState : eNewPowerState;
68449 +
68450 +               if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
68451 +               {
68452 +
68453 +                       eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex,
68454 +                                                                                        eNewDevicePowerState,
68455 +                                                                                        psPowerDevice->eCurrentPowerState);
68456 +                       if (eError != PVRSRV_OK)
68457 +                       {
68458 +                               return eError;
68459 +                       }
68460 +
68461 +                       if (psPowerDevice->pfnPostPower != IMG_NULL)
68462 +                       {
68463 +
68464 +                               eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie,
68465 +                                                                                                        eNewDevicePowerState,
68466 +                                                                                                        psPowerDevice->eCurrentPowerState);
68467 +                               if (eError != PVRSRV_OK)
68468 +                               {
68469 +                                       return eError;
68470 +                               }
68471 +                       }
68472 +
68473 +                       psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
68474 +               }
68475 +       }
68476 +       return PVRSRV_OK;
68477 +}
68478 +
68479 +static
68480 +PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL                                     bAllDevices,
68481 +                                                                                 IMG_UINT32                            ui32DeviceIndex,
68482 +                                                                                 PVRSRV_DEV_POWER_STATE        eNewPowerState)
68483 +{
68484 +       PVRSRV_ERROR            eError;
68485 +       SYS_DATA                        *psSysData;
68486 +
68487 +       SysAcquireData(&psSysData);
68488 +
68489 +
68490 +       eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
68491 +                                                                                                               PVRSRVDevicePostPowerStateKM_AnyVaCb,
68492 +                                                                                                               bAllDevices,
68493 +                                                                                                               ui32DeviceIndex,
68494 +                                                                                                               eNewPowerState);
68495 +
68496 +       return eError;
68497 +}
68498 +
68499 +
68500 +PVRSRV_ERROR PVRSRVSetDevicePowerStateCoreKM(IMG_UINT32                                ui32DeviceIndex,
68501 +                                             PVRSRV_DEV_POWER_STATE    eNewPowerState)
68502 +{
68503 +       PVRSRV_ERROR    eError;
68504 +       eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
68505 +       if(eError != PVRSRV_OK)
68506 +       {
68507 +               return eError;
68508 +       }
68509 +
68510 +       eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
68511 +       return eError;
68512 +}
68513 +
68514 +
68515 +IMG_EXPORT
68516 +PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32                            ui32DeviceIndex,
68517 +                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState,
68518 +                                                                                IMG_UINT32                             ui32CallerID,
68519 +                                                                                IMG_BOOL                               bRetainMutex)
68520 +{
68521 +       PVRSRV_ERROR    eError;
68522 +       SYS_DATA                *psSysData;
68523 +
68524 +       SysAcquireData(&psSysData);
68525 +
68526 +       eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
68527 +       if(eError != PVRSRV_OK)
68528 +       {
68529 +               return eError;
68530 +       }
68531 +
68532 +       #if defined(PDUMP)
68533 +       if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
68534 +       {
68535 +
68536 +
68537 +
68538 +
68539 +               eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
68540 +               if(eError != PVRSRV_OK)
68541 +               {
68542 +                       goto Exit;
68543 +               }
68544 +
68545 +               eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
68546 +
68547 +               if (eError != PVRSRV_OK)
68548 +               {
68549 +                       goto Exit;
68550 +               }
68551 +
68552 +               PDUMPSUSPEND();
68553 +       }
68554 +       #endif
68555 +
68556 +       eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
68557 +       if(eError != PVRSRV_OK)
68558 +       {
68559 +               if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
68560 +               {
68561 +                       PDUMPRESUME();
68562 +               }
68563 +               goto Exit;
68564 +       }
68565 +
68566 +       eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
68567 +
68568 +       if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
68569 +       {
68570 +               PDUMPRESUME();
68571 +       }
68572 +
68573 +Exit:
68574 +
68575 +       if(eError != PVRSRV_OK)
68576 +       {
68577 +               PVR_DPF((PVR_DBG_ERROR,
68578 +                               "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
68579 +       }
68580 +
68581 +       if (!bRetainMutex || (eError != PVRSRV_OK))
68582 +       {
68583 +               PVRSRVPowerUnlock(ui32CallerID);
68584 +       }
68585 +
68586 +       return eError;
68587 +}
68588 +
68589 +
68590 +IMG_EXPORT
68591 +PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
68592 +{
68593 +       PVRSRV_ERROR                    eError;
68594 +       SYS_DATA                                *psSysData;
68595 +       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
68596 +
68597 +       SysAcquireData(&psSysData);
68598 +
68599 +
68600 +       eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE);
68601 +       if(eError != PVRSRV_OK)
68602 +       {
68603 +               return eError;
68604 +       }
68605 +
68606 +       if (_IsSystemStatePowered(eNewSysPowerState) !=
68607 +               _IsSystemStatePowered(psSysData->eCurrentPowerState))
68608 +       {
68609 +               if (_IsSystemStatePowered(eNewSysPowerState))
68610 +               {
68611 +
68612 +                       eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
68613 +               }
68614 +               else
68615 +               {
68616 +                       eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
68617 +               }
68618 +
68619 +
68620 +               eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
68621 +               if (eError != PVRSRV_OK)
68622 +               {
68623 +                       goto ErrorExit;
68624 +               }
68625 +       }
68626 +
68627 +       if (eNewSysPowerState != psSysData->eCurrentPowerState)
68628 +       {
68629 +
68630 +               eError = SysSystemPrePowerState(eNewSysPowerState);
68631 +               if (eError != PVRSRV_OK)
68632 +               {
68633 +                       goto ErrorExit;
68634 +               }
68635 +       }
68636 +
68637 +       return eError;
68638 +
68639 +ErrorExit:
68640 +
68641 +       PVR_DPF((PVR_DBG_ERROR,
68642 +                       "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x",
68643 +                       psSysData->eCurrentPowerState, eNewSysPowerState, eError));
68644 +
68645 +
68646 +       psSysData->eFailedPowerState = eNewSysPowerState;
68647 +
68648 +       PVRSRVPowerUnlock(KERNEL_ID);
68649 +
68650 +       return eError;
68651 +}
68652 +
68653 +
68654 +IMG_EXPORT
68655 +PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
68656 +{
68657 +       PVRSRV_ERROR                    eError = PVRSRV_OK;
68658 +       SYS_DATA                                *psSysData;
68659 +       PVRSRV_DEV_POWER_STATE  eNewDevicePowerState;
68660 +
68661 +       SysAcquireData(&psSysData);
68662 +
68663 +       if (eNewSysPowerState != psSysData->eCurrentPowerState)
68664 +       {
68665 +
68666 +               eError = SysSystemPostPowerState(eNewSysPowerState);
68667 +               if (eError != PVRSRV_OK)
68668 +               {
68669 +                       goto Exit;
68670 +               }
68671 +       }
68672 +
68673 +       if (_IsSystemStatePowered(eNewSysPowerState) !=
68674 +               _IsSystemStatePowered(psSysData->eCurrentPowerState))
68675 +       {
68676 +               if (_IsSystemStatePowered(eNewSysPowerState))
68677 +               {
68678 +
68679 +                       eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
68680 +               }
68681 +               else
68682 +               {
68683 +                       eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
68684 +               }
68685 +
68686 +
68687 +               eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
68688 +               if (eError != PVRSRV_OK)
68689 +               {
68690 +                       goto Exit;
68691 +               }
68692 +       }
68693 +
68694 +       PVR_DPF((PVR_DBG_MESSAGE,
68695 +                       "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK",
68696 +                       psSysData->eCurrentPowerState, eNewSysPowerState));
68697 +
68698 +       psSysData->eCurrentPowerState = eNewSysPowerState;
68699 +
68700 +Exit:
68701 +
68702 +       PVRSRVPowerUnlock(KERNEL_ID);
68703 +
68704 +       if (_IsSystemStatePowered(eNewSysPowerState) &&
68705 +                       PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
68706 +       {
68707 +
68708 +
68709 +
68710 +               PVRSRVCommandCompleteCallbacks();
68711 +       }
68712 +
68713 +       return eError;
68714 +}
68715 +
68716 +
68717 +IMG_EXPORT
68718 +PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
68719 +{
68720 +       PVRSRV_ERROR    eError;
68721 +       SYS_DATA                *psSysData;
68722 +
68723 +       SysAcquireData(&psSysData);
68724 +
68725 +       eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState);
68726 +       if(eError != PVRSRV_OK)
68727 +       {
68728 +               goto ErrorExit;
68729 +       }
68730 +
68731 +       eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState);
68732 +       if(eError != PVRSRV_OK)
68733 +       {
68734 +               goto ErrorExit;
68735 +       }
68736 +
68737 +
68738 +       psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
68739 +
68740 +       return PVRSRV_OK;
68741 +
68742 +ErrorExit:
68743 +
68744 +       PVR_DPF((PVR_DBG_ERROR,
68745 +                       "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x",
68746 +                       psSysData->eCurrentPowerState, eNewSysPowerState, eError));
68747 +
68748 +
68749 +       psSysData->eFailedPowerState = eNewSysPowerState;
68750 +
68751 +       return eError;
68752 +}
68753 +
68754 +
68755 +PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32                                      ui32DeviceIndex,
68756 +                                                                          PFN_PRE_POWER                                pfnPrePower,
68757 +                                                                          PFN_POST_POWER                               pfnPostPower,
68758 +                                                                          PFN_PRE_CLOCKSPEED_CHANGE    pfnPreClockSpeedChange,
68759 +                                                                          PFN_POST_CLOCKSPEED_CHANGE   pfnPostClockSpeedChange,
68760 +                                                                          IMG_HANDLE                                   hDevCookie,
68761 +                                                                          PVRSRV_DEV_POWER_STATE               eCurrentPowerState,
68762 +                                                                          PVRSRV_DEV_POWER_STATE               eDefaultPowerState)
68763 +{
68764 +       PVRSRV_ERROR            eError;
68765 +       SYS_DATA                        *psSysData;
68766 +       PVRSRV_POWER_DEV        *psPowerDevice;
68767 +
68768 +       if (pfnPrePower == IMG_NULL &&
68769 +               pfnPostPower == IMG_NULL)
68770 +       {
68771 +               return PVRSRVRemovePowerDevice(ui32DeviceIndex);
68772 +       }
68773 +
68774 +       SysAcquireData(&psSysData);
68775 +
68776 +       eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
68777 +                                                sizeof(PVRSRV_POWER_DEV),
68778 +                                                (IMG_VOID **)&psPowerDevice, IMG_NULL,
68779 +                                                "Power Device");
68780 +       if(eError != PVRSRV_OK)
68781 +       {
68782 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
68783 +               return eError;
68784 +       }
68785 +
68786 +
68787 +       psPowerDevice->pfnPrePower = pfnPrePower;
68788 +       psPowerDevice->pfnPostPower = pfnPostPower;
68789 +       psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
68790 +       psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
68791 +       psPowerDevice->hDevCookie = hDevCookie;
68792 +       psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
68793 +       psPowerDevice->eCurrentPowerState = eCurrentPowerState;
68794 +       psPowerDevice->eDefaultPowerState = eDefaultPowerState;
68795 +
68796 +
68797 +       List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice);
68798 +
68799 +       return (PVRSRV_OK);
68800 +}
68801 +
68802 +
68803 +PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
68804 +{
68805 +       SYS_DATA                        *psSysData;
68806 +       PVRSRV_POWER_DEV        *psPowerDev;
68807 +
68808 +       SysAcquireData(&psSysData);
68809 +
68810 +
68811 +       psPowerDev = (PVRSRV_POWER_DEV*)
68812 +                                       List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
68813 +                                                                                                MatchPowerDeviceIndex_AnyVaCb,
68814 +                                                                                                ui32DeviceIndex);
68815 +
68816 +       if (psPowerDev)
68817 +       {
68818 +               List_PVRSRV_POWER_DEV_Remove(psPowerDev);
68819 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL);
68820 +
68821 +       }
68822 +
68823 +       return (PVRSRV_OK);
68824 +}
68825 +
68826 +
68827 +IMG_EXPORT
68828 +IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
68829 +{
68830 +       SYS_DATA                        *psSysData;
68831 +       PVRSRV_POWER_DEV        *psPowerDevice;
68832 +
68833 +       SysAcquireData(&psSysData);
68834 +
68835 +       if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) ||
68836 +               OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID))
68837 +       {
68838 +               return IMG_FALSE;
68839 +       }
68840 +
68841 +       psPowerDevice = (PVRSRV_POWER_DEV*)
68842 +                                       List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
68843 +                                                                                                MatchPowerDeviceIndex_AnyVaCb,
68844 +                                                                                                ui32DeviceIndex);
68845 +       return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON))
68846 +                       ? IMG_TRUE : IMG_FALSE;
68847 +}
68848 +
68849 +
68850 +PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32        ui32DeviceIndex,
68851 +                                                                                        IMG_BOOL       bIdleDevice,
68852 +                                                                                        IMG_VOID       *pvInfo)
68853 +{
68854 +       PVRSRV_ERROR            eError = PVRSRV_OK;
68855 +       SYS_DATA                        *psSysData;
68856 +       PVRSRV_POWER_DEV        *psPowerDevice;
68857 +
68858 +       PVR_UNREFERENCED_PARAMETER(pvInfo);
68859 +
68860 +       SysAcquireData(&psSysData);
68861 +
68862 +       if (bIdleDevice)
68863 +       {
68864 +
68865 +               eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
68866 +               if (eError != PVRSRV_OK)
68867 +               {
68868 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%lx", eError));
68869 +                       return eError;
68870 +               }
68871 +       }
68872 +
68873 +
68874 +       psPowerDevice = (PVRSRV_POWER_DEV*)
68875 +                                       List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
68876 +                                                                                                MatchPowerDeviceIndex_AnyVaCb,
68877 +                                                                                                ui32DeviceIndex);
68878 +
68879 +       if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
68880 +       {
68881 +                       eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
68882 +                                                                                                                  bIdleDevice,
68883 +                                                                                                                  psPowerDevice->eCurrentPowerState);
68884 +                       if (eError != PVRSRV_OK)
68885 +                       {
68886 +                               PVR_DPF((PVR_DBG_ERROR,
68887 +                                               "PVRSRVDevicePreClockSpeedChange : Device %lu failed, error:0x%lx",
68888 +                                               ui32DeviceIndex, eError));
68889 +                       }
68890 +       }
68891 +
68892 +       if (bIdleDevice && eError != PVRSRV_OK)
68893 +       {
68894 +               PVRSRVPowerUnlock(KERNEL_ID);
68895 +       }
68896 +
68897 +       return eError;
68898 +}
68899 +
68900 +
68901 +IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32   ui32DeviceIndex,
68902 +                                                                                 IMG_BOOL              bIdleDevice,
68903 +                                                                                 IMG_VOID              *pvInfo)
68904 +{
68905 +       PVRSRV_ERROR            eError;
68906 +       SYS_DATA                        *psSysData;
68907 +       PVRSRV_POWER_DEV        *psPowerDevice;
68908 +
68909 +       PVR_UNREFERENCED_PARAMETER(pvInfo);
68910 +
68911 +       SysAcquireData(&psSysData);
68912 +
68913 +
68914 +       psPowerDevice = (PVRSRV_POWER_DEV*)
68915 +                                       List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
68916 +                                                                                                MatchPowerDeviceIndex_AnyVaCb,
68917 +                                                                                                ui32DeviceIndex);
68918 +
68919 +       if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
68920 +       {
68921 +               eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
68922 +                                                                                                               bIdleDevice,
68923 +                                                                                                               psPowerDevice->eCurrentPowerState);
68924 +               if (eError != PVRSRV_OK)
68925 +               {
68926 +                       PVR_DPF((PVR_DBG_ERROR,
68927 +                                       "PVRSRVDevicePostClockSpeedChange : Device %lu failed, error:0x%lx",
68928 +                                       ui32DeviceIndex, eError));
68929 +               }
68930 +       }
68931 +
68932 +
68933 +       if (bIdleDevice)
68934 +       {
68935 +
68936 +               PVRSRVPowerUnlock(KERNEL_ID);
68937 +       }
68938 +}
68939 +
68940 +
68941 +/*
68942 + * PVRSRVPowerOnSystemWithDevice
68943 + *
68944 + * Description: Power on the System if it is off, but instead of powering all
68945 + * of the devices to their "default" state, only turn on the specified
68946 + * device index.
68947 + */
68948 +IMG_EXPORT
68949 +PVRSRV_ERROR PVRSRVPowerOnSystemWithDevice(IMG_UINT32  ui32DeviceIndex,
68950 +                                          IMG_UINT32   ui32CallerID,
68951 +                                          IMG_BOOL     bRetainMutex)
68952 +{
68953 +       PVRSRV_ERROR    eError;
68954 +       SYS_DATA        *psSysData;
68955 +
68956 +       SysAcquireData(&psSysData);
68957 +
68958 +       eError = PVRSRVPowerLock(ui32CallerID, IMG_TRUE);
68959 +       if(eError != PVRSRV_OK)
68960 +       {
68961 +               return eError;
68962 +       }
68963 +
68964 +       eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
68965 +       if (eError != PVRSRV_OK)
68966 +       {
68967 +               goto ErrorExit;
68968 +       }
68969 +
68970 +       if (!_IsSystemStatePowered(psSysData->eCurrentPowerState))
68971 +       {
68972 +               eError = SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE_D0);
68973 +               if (eError != PVRSRV_OK)
68974 +               {
68975 +                       goto ErrorExit;
68976 +               }
68977 +
68978 +               eError = SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE_D0);
68979 +               if (eError != PVRSRV_OK)
68980 +               {
68981 +                       goto ErrorExit;
68982 +               }
68983 +               psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
68984 +       }
68985 +
68986 +       eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
68987 +       if (eError != PVRSRV_OK)
68988 +       {
68989 +               goto ErrorExit;
68990 +       }
68991 +
68992 +ErrorExit:
68993 +
68994 +       if(eError != PVRSRV_OK)
68995 +       {
68996 +               PVR_DPF((PVR_DBG_ERROR,
68997 +                               "PVRSRVPowerOnSystemWithDevice : FAILED 0x%x", eError));
68998 +       }
68999 +
69000 +       if (!bRetainMutex || (eError != PVRSRV_OK))
69001 +       {
69002 +               PVRSRVPowerUnlock(ui32CallerID);
69003 +       }
69004 +
69005 +       return eError;
69006 +}
69007 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pvrsrv.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pvrsrv.c
69008 new file mode 100644
69009 index 0000000..2c33fce
69010 --- /dev/null
69011 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/pvrsrv.c
69012 @@ -0,0 +1,1195 @@
69013 +/**********************************************************************
69014 + *
69015 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
69016 + *
69017 + * This program is free software; you can redistribute it and/or modify it
69018 + * under the terms and conditions of the GNU General Public License,
69019 + * version 2, as published by the Free Software Foundation.
69020 + *
69021 + * This program is distributed in the hope it will be useful but, except
69022 + * as otherwise stated in writing, without any warranty; without even the
69023 + * implied warranty of merchantability or fitness for a particular purpose.
69024 + * See the GNU General Public License for more details.
69025 + *
69026 + * You should have received a copy of the GNU General Public License along with
69027 + * this program; if not, write to the Free Software Foundation, Inc.,
69028 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
69029 + *
69030 + * The full GNU General Public License is included in this distribution in
69031 + * the file called "COPYING".
69032 + *
69033 + * Contact Information:
69034 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
69035 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
69036 + *
69037 + ******************************************************************************/
69038 +
69039 +#include "services_headers.h"
69040 +#include "buffer_manager.h"
69041 +#include "handle.h"
69042 +#include "perproc.h"
69043 +#include "pdump_km.h"
69044 +#include "ra.h"
69045 +
69046 +#include "pvrversion.h"
69047 +
69048 +#include "lists.h"
69049 +
69050 +DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK);
69051 +
69052 +DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
69053 +
69054 +DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
69055 +DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
69056 +DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
69057 +DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
69058 +DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
69059 +DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
69060 +DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
69061 +
69062 +IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
69063 +
69064 +
69065 +PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
69066 +{
69067 +       SYS_DEVICE_ID* psDeviceWalker;
69068 +       SYS_DEVICE_ID* psDeviceEnd;
69069 +
69070 +       psDeviceWalker = &psSysData->sDeviceID[0];
69071 +       psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
69072 +
69073 +
69074 +       while (psDeviceWalker < psDeviceEnd)
69075 +       {
69076 +               if (!psDeviceWalker->bInUse)
69077 +               {
69078 +                       psDeviceWalker->bInUse = IMG_TRUE;
69079 +                       *pui32DevID = psDeviceWalker->uiID;
69080 +                       return PVRSRV_OK;
69081 +               }
69082 +               psDeviceWalker++;
69083 +       }
69084 +
69085 +       PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
69086 +
69087 +
69088 +       PVR_ASSERT(psDeviceWalker < psDeviceEnd);
69089 +
69090 +       return PVRSRV_ERROR_GENERIC;
69091 +}
69092 +
69093 +
69094 +PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
69095 +{
69096 +       SYS_DEVICE_ID* psDeviceWalker;
69097 +       SYS_DEVICE_ID* psDeviceEnd;
69098 +
69099 +       psDeviceWalker = &psSysData->sDeviceID[0];
69100 +       psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
69101 +
69102 +
69103 +       while (psDeviceWalker < psDeviceEnd)
69104 +       {
69105 +
69106 +               if      (
69107 +                               (psDeviceWalker->uiID == ui32DevID) &&
69108 +                               (psDeviceWalker->bInUse)
69109 +                       )
69110 +               {
69111 +                       psDeviceWalker->bInUse = IMG_FALSE;
69112 +                       return PVRSRV_OK;
69113 +               }
69114 +               psDeviceWalker++;
69115 +       }
69116 +
69117 +       PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
69118 +
69119 +
69120 +       PVR_ASSERT(psDeviceWalker < psDeviceEnd);
69121 +
69122 +       return PVRSRV_ERROR_GENERIC;
69123 +}
69124 +
69125 +
69126 +#ifndef ReadHWReg
69127 +IMG_EXPORT
69128 +IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
69129 +{
69130 +       return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
69131 +}
69132 +#endif
69133 +
69134 +
69135 +#ifndef WriteHWReg
69136 +IMG_EXPORT
69137 +IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
69138 +{
69139 +       PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",pvLinRegBaseAddr,ui32Offset,ui32Value));
69140 +
69141 +       *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
69142 +}
69143 +#endif
69144 +
69145 +
69146 +#ifndef WriteHWRegs
69147 +IMG_EXPORT
69148 +IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
69149 +{
69150 +       while (ui32Count)
69151 +       {
69152 +               WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
69153 +               psHWRegs++;
69154 +               ui32Count--;
69155 +       }
69156 +}
69157 +#endif
69158 +
69159 +IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
69160 +{
69161 +       IMG_UINT *pui32DevCount;
69162 +       PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
69163 +
69164 +       pui32DevCount = va_arg(va, IMG_UINT*);
69165 +       ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
69166 +
69167 +       if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
69168 +       {
69169 +               *(*ppsDevIdList) = psDeviceNode->sDevId;
69170 +               (*ppsDevIdList)++;
69171 +               (*pui32DevCount)++;
69172 +       }
69173 +}
69174 +
69175 +
69176 +
69177 +IMG_EXPORT
69178 +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
69179 +                                                                                                  PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
69180 +{
69181 +       SYS_DATA                        *psSysData;
69182 +       IMG_UINT32                      i;
69183 +
69184 +       if (!pui32NumDevices || !psDevIdList)
69185 +       {
69186 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
69187 +               return PVRSRV_ERROR_INVALID_PARAMS;
69188 +       }
69189 +
69190 +       SysAcquireData(&psSysData);
69191 +
69192 +
69193 +
69194 +       for (i=0; i<PVRSRV_MAX_DEVICES; i++)
69195 +       {
69196 +               psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
69197 +       }
69198 +
69199 +
69200 +       *pui32NumDevices = 0;
69201 +
69202 +
69203 +
69204 +
69205 +
69206 +       List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
69207 +                                                                          PVRSRVEnumerateDevicesKM_ForEachVaCb,
69208 +                                                                          pui32NumDevices,
69209 +                                                                          &psDevIdList);
69210 +
69211 +
69212 +       return PVRSRV_OK;
69213 +}
69214 +
69215 +
69216 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
69217 +{
69218 +       PVRSRV_ERROR    eError;
69219 +
69220 +
69221 +       eError = ResManInit();
69222 +       if (eError != PVRSRV_OK)
69223 +       {
69224 +               goto Error;
69225 +       }
69226 +
69227 +       eError = PVRSRVPerProcessDataInit();
69228 +       if(eError != PVRSRV_OK)
69229 +       {
69230 +               goto Error;
69231 +       }
69232 +
69233 +
69234 +       eError = PVRSRVHandleInit();
69235 +       if(eError != PVRSRV_OK)
69236 +       {
69237 +               goto Error;
69238 +       }
69239 +
69240 +
69241 +       eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
69242 +       if (eError != PVRSRV_OK)
69243 +       {
69244 +               goto Error;
69245 +       }
69246 +
69247 +
69248 +       psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
69249 +       psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
69250 +
69251 +
69252 +       if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
69253 +                                        sizeof(PVRSRV_EVENTOBJECT) ,
69254 +                                        (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
69255 +                                        "Event Object") != PVRSRV_OK)
69256 +       {
69257 +
69258 +               goto Error;
69259 +       }
69260 +
69261 +       if(OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
69262 +       {
69263 +               goto Error;
69264 +       }
69265 +
69266 +       return eError;
69267 +
69268 +Error:
69269 +       PVRSRVDeInit(psSysData);
69270 +       return eError;
69271 +}
69272 +
69273 +
69274 +
69275 +IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
69276 +{
69277 +       PVRSRV_ERROR    eError;
69278 +
69279 +       PVR_UNREFERENCED_PARAMETER(psSysData);
69280 +
69281 +       if (psSysData == IMG_NULL)
69282 +       {
69283 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
69284 +               return;
69285 +       }
69286 +
69287 +
69288 +       if(psSysData->psGlobalEventObject)
69289 +       {
69290 +               OSEventObjectDestroy(psSysData->psGlobalEventObject);
69291 +               OSFreeMem( PVRSRV_PAGEABLE_SELECT,
69292 +                                                sizeof(PVRSRV_EVENTOBJECT),
69293 +                                                psSysData->psGlobalEventObject,
69294 +                                                0);
69295 +               psSysData->psGlobalEventObject = IMG_NULL;
69296 +       }
69297 +
69298 +       eError = PVRSRVHandleDeInit();
69299 +       if (eError != PVRSRV_OK)
69300 +       {
69301 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
69302 +       }
69303 +
69304 +       eError = PVRSRVPerProcessDataDeInit();
69305 +       if (eError != PVRSRV_OK)
69306 +       {
69307 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
69308 +       }
69309 +
69310 +       ResManDeInit();
69311 +}
69312 +
69313 +
69314 +PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
69315 +                                                                                         PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
69316 +                                                                                         IMG_UINT32 ui32SOCInterruptBit,
69317 +                                                                                         IMG_UINT32 *pui32DeviceIndex)
69318 +{
69319 +       PVRSRV_ERROR            eError;
69320 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
69321 +
69322 +
69323 +       if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
69324 +                                        sizeof(PVRSRV_DEVICE_NODE),
69325 +                                        (IMG_VOID **)&psDeviceNode, IMG_NULL,
69326 +                                        "Device Node") != PVRSRV_OK)
69327 +       {
69328 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
69329 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
69330 +       }
69331 +       OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
69332 +
69333 +       eError = pfnRegisterDevice(psDeviceNode);
69334 +       if (eError != PVRSRV_OK)
69335 +       {
69336 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
69337 +                                       sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
69338 +
69339 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
69340 +               return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
69341 +       }
69342 +
69343 +
69344 +
69345 +
69346 +
69347 +
69348 +       psDeviceNode->ui32RefCount = 1;
69349 +       psDeviceNode->psSysData = psSysData;
69350 +       psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
69351 +
69352 +
69353 +       AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
69354 +
69355 +
69356 +       List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
69357 +
69358 +
69359 +       *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
69360 +
69361 +       return PVRSRV_OK;
69362 +}
69363 +
69364 +
69365 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
69366 +{
69367 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
69368 +       SYS_DATA                        *psSysData;
69369 +       PVRSRV_ERROR            eError;
69370 +
69371 +       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
69372 +
69373 +       SysAcquireData(&psSysData);
69374 +
69375 +
69376 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)
69377 +                                        List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
69378 +                                                                                                       MatchDeviceKM_AnyVaCb,
69379 +                                                                                                       ui32DevIndex,
69380 +                                                                                                       IMG_TRUE);
69381 +       if(!psDeviceNode)
69382 +       {
69383 +
69384 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
69385 +               return PVRSRV_ERROR_INIT_FAILURE;
69386 +       }
69387 +       PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
69388 +
69389 +
69390 +
69391 +       eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
69392 +       if (eError != PVRSRV_OK)
69393 +       {
69394 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
69395 +               return eError;
69396 +       }
69397 +
69398 +
69399 +       if(psDeviceNode->pfnInitDevice != IMG_NULL)
69400 +       {
69401 +               eError = psDeviceNode->pfnInitDevice(psDeviceNode);
69402 +               if (eError != PVRSRV_OK)
69403 +               {
69404 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
69405 +                       return eError;
69406 +               }
69407 +       }
69408 +
69409 +       return PVRSRV_OK;
69410 +}
69411 +
69412 +
69413 +PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
69414 +{
69415 +       PVRSRV_ERROR eError;
69416 +       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
69417 +                                                                                PVRSRV_DEV_POWER_STATE_DEFAULT,
69418 +                                                                                KERNEL_ID, IMG_FALSE);
69419 +       if (eError != PVRSRV_OK)
69420 +       {
69421 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
69422 +       }
69423 +       return eError;
69424 +}
69425 +
69426 +PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
69427 +{
69428 +       PVRSRV_ERROR eError;
69429 +       eError = PVRSRVDevInitCompatCheck(psDeviceNode);
69430 +       if (eError != PVRSRV_OK)
69431 +       {
69432 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
69433 +       }
69434 +       return eError;
69435 +}
69436 +
69437 +
69438 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
69439 +{
69440 +       SYS_DATA                *psSysData;
69441 +       PVRSRV_ERROR            eError;
69442 +
69443 +       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
69444 +
69445 +       SysAcquireData(&psSysData);
69446 +
69447 +       if (bInitSuccessful)
69448 +       {
69449 +               eError = SysFinalise();
69450 +               if (eError != PVRSRV_OK)
69451 +               {
69452 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
69453 +                       return eError;
69454 +               }
69455 +
69456 +
69457 +               eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
69458 +                                                                                                               PVRSRVFinaliseSystem_SetPowerState_AnyCb);
69459 +               if (eError != PVRSRV_OK)
69460 +               {
69461 +                       return eError;
69462 +               }
69463 +
69464 +
69465 +               eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
69466 +                                                                                                       PVRSRVFinaliseSystem_CompatCheck_AnyCb);
69467 +               if (eError != PVRSRV_OK)
69468 +               {
69469 +                       return eError;
69470 +               }
69471 +       }
69472 +
69473 +       
69474 +
69475 +
69476 +
69477 +
69478 +
69479 +
69480 +#if !defined(SUPPORT_PDUMP_DELAYED_INITPHASE_TERMINATION)
69481 +       PDUMPENDINITPHASE();
69482 +#endif
69483 +
69484 +       return PVRSRV_OK;
69485 +}
69486 +
69487 +
69488 +PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
69489 +{
69490 +
69491 +       if (psDeviceNode->pfnInitDeviceCompatCheck)
69492 +               return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
69493 +       else
69494 +               return PVRSRV_OK;
69495 +}
69496 +
69497 +IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
69498 +{
69499 +       PVRSRV_DEVICE_TYPE eDeviceType;
69500 +       IMG_UINT32 ui32DevIndex;
69501 +
69502 +       eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
69503 +       ui32DevIndex = va_arg(va, IMG_UINT32);
69504 +
69505 +       if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
69506 +               psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
69507 +               (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
69508 +                psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
69509 +       {
69510 +               return psDeviceNode;
69511 +       }
69512 +       else
69513 +       {
69514 +               return IMG_NULL;
69515 +       }
69516 +}
69517 +
69518 +IMG_EXPORT
69519 +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32                        ui32DevIndex,
69520 +                                                                                                        PVRSRV_DEVICE_TYPE     eDeviceType,
69521 +                                                                                                        IMG_HANDLE                     *phDevCookie)
69522 +{
69523 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
69524 +       SYS_DATA                        *psSysData;
69525 +
69526 +       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
69527 +
69528 +       SysAcquireData(&psSysData);
69529 +
69530 +
69531 +       psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
69532 +                                                                                               PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
69533 +                                                                                               eDeviceType,
69534 +                                                                                               ui32DevIndex);
69535 +
69536 +
69537 +       if (!psDeviceNode)
69538 +       {
69539 +
69540 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
69541 +               return PVRSRV_ERROR_INIT_FAILURE;
69542 +       }
69543 +
69544 +       PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
69545 +
69546 +
69547 +       if (phDevCookie)
69548 +       {
69549 +               *phDevCookie = (IMG_HANDLE)psDeviceNode;
69550 +       }
69551 +
69552 +       return PVRSRV_OK;
69553 +}
69554 +
69555 +
69556 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
69557 +{
69558 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
69559 +       SYS_DATA                        *psSysData;
69560 +       PVRSRV_ERROR            eError;
69561 +
69562 +       SysAcquireData(&psSysData);
69563 +
69564 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)
69565 +                                        List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
69566 +                                                                                                       MatchDeviceKM_AnyVaCb,
69567 +                                                                                                       ui32DevIndex,
69568 +                                                                                                       IMG_TRUE);
69569 +
69570 +       if (!psDeviceNode)
69571 +       {
69572 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
69573 +               return PVRSRV_ERROR_GENERIC;
69574 +       }
69575 +
69576 +
69577 +
69578 +       eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
69579 +                                                                                PVRSRV_DEV_POWER_STATE_OFF,
69580 +                                                                                KERNEL_ID,
69581 +                                                                                IMG_FALSE);
69582 +       if (eError != PVRSRV_OK)
69583 +       {
69584 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
69585 +               return eError;
69586 +       }
69587 +
69588 +
69589 +
69590 +       eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
69591 +                                                                        RESMAN_CRITERIA_RESTYPE,
69592 +                                                                        RESMAN_TYPE_DEVICEMEM_ALLOCATION,
69593 +                                                                        IMG_NULL, 0);
69594 +       if (eError != PVRSRV_OK)
69595 +       {
69596 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
69597 +               return eError;
69598 +       }
69599 +
69600 +
69601 +
69602 +       if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
69603 +       {
69604 +               eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
69605 +               if (eError != PVRSRV_OK)
69606 +               {
69607 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
69608 +                       return eError;
69609 +               }
69610 +       }
69611 +
69612 +
69613 +
69614 +       PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
69615 +       psDeviceNode->hResManContext = IMG_NULL;
69616 +
69617 +
69618 +       List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
69619 +
69620 +
69621 +       (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
69622 +       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
69623 +                               sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
69624 +
69625 +
69626 +       return (PVRSRV_OK);
69627 +}
69628 +
69629 +
69630 +IMG_EXPORT
69631 +PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
69632 +                                                                                 IMG_UINT32 ui32Value,
69633 +                                                                                 IMG_UINT32 ui32Mask,
69634 +                                                                                 IMG_UINT32 ui32Waitus,
69635 +                                                                                 IMG_UINT32 ui32Tries)
69636 +{
69637 +       {
69638 +               IMG_UINT32      uiMaxTime = ui32Tries * ui32Waitus;
69639 +
69640 +               LOOP_UNTIL_TIMEOUT(uiMaxTime)
69641 +               {
69642 +                       if((*pui32LinMemAddr & ui32Mask) == ui32Value)
69643 +                       {
69644 +                               return PVRSRV_OK;
69645 +                       }
69646 +                       OSWaitus(ui32Waitus);
69647 +               } END_LOOP_UNTIL_TIMEOUT();
69648 +       }
69649 +
69650 +
69651 +       return PVRSRV_ERROR_GENERIC;
69652 +}
69653 +
69654 +
69655 +#if defined (USING_ISR_INTERRUPTS)
69656 +
69657 +extern IMG_UINT32 gui32EventStatusServicesByISR;
69658 +
69659 +PVRSRV_ERROR PollForInterruptKM (IMG_UINT32 ui32Value,
69660 +                                                                IMG_UINT32 ui32Mask,
69661 +                                                                IMG_UINT32 ui32Waitus,
69662 +                                                                IMG_UINT32 ui32Tries)
69663 +{
69664 +       IMG_UINT32      uiMaxTime;
69665 +
69666 +       uiMaxTime = ui32Tries * ui32Waitus;
69667 +
69668 +
69669 +       LOOP_UNTIL_TIMEOUT(uiMaxTime)
69670 +       {
69671 +               if ((gui32EventStatusServicesByISR & ui32Mask) == ui32Value)
69672 +               {
69673 +                       gui32EventStatusServicesByISR = 0;
69674 +                       return PVRSRV_OK;
69675 +               }
69676 +               OSWaitus(ui32Waitus);
69677 +       } END_LOOP_UNTIL_TIMEOUT();
69678 +
69679 +       return PVRSRV_ERROR_GENERIC;
69680 +}
69681 +#endif
69682 +
69683 +IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
69684 +{
69685 +       IMG_CHAR **ppszStr;
69686 +       IMG_UINT32 *pui32StrLen;
69687 +
69688 +       ppszStr = va_arg(va, IMG_CHAR**);
69689 +       pui32StrLen = va_arg(va, IMG_UINT32*);
69690 +
69691 +       if(psBMHeap->pImportArena)
69692 +       {
69693 +               RA_GetStats(psBMHeap->pImportArena,
69694 +                                       ppszStr,
69695 +                                       pui32StrLen);
69696 +       }
69697 +
69698 +       if(psBMHeap->pVMArena)
69699 +       {
69700 +               RA_GetStats(psBMHeap->pVMArena,
69701 +                                       ppszStr,
69702 +                                       pui32StrLen);
69703 +       }
69704 +}
69705 +
69706 +PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
69707 +{
69708 +
69709 +       IMG_UINT32 *pui32StrLen;
69710 +       IMG_INT32 *pi32Count;
69711 +       IMG_CHAR **ppszStr;
69712 +
69713 +       pui32StrLen = va_arg(va, IMG_UINT32*);
69714 +       pi32Count = va_arg(va, IMG_INT32*);
69715 +       ppszStr = va_arg(va, IMG_CHAR**);
69716 +
69717 +       CHECK_SPACE(*pui32StrLen);
69718 +       *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) 0x%08X:\n",
69719 +                                                       (IMG_HANDLE)psBMContext);
69720 +       UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
69721 +
69722 +       List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
69723 +                                                       PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
69724 +                                                       ppszStr,
69725 +                                                       pui32StrLen);
69726 +       return PVRSRV_OK;
69727 +}
69728 +
69729 +
69730 +PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
69731 +{
69732 +       IMG_UINT32 *pui32StrLen;
69733 +       IMG_INT32 *pi32Count;
69734 +       IMG_CHAR **ppszStr;
69735 +
69736 +       pui32StrLen = va_arg(va, IMG_UINT32*);
69737 +       pi32Count = va_arg(va, IMG_INT32*);
69738 +       ppszStr = va_arg(va, IMG_CHAR**);
69739 +
69740 +       CHECK_SPACE(*pui32StrLen);
69741 +       *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
69742 +       UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
69743 +
69744 +
69745 +       if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
69746 +       {
69747 +               CHECK_SPACE(*pui32StrLen);
69748 +               *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
69749 +               UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
69750 +
69751 +
69752 +               List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
69753 +                                                               PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
69754 +                                                               ppszStr,
69755 +                                                               pui32StrLen);
69756 +       }
69757 +
69758 +
69759 +       return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
69760 +                                                                                               PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
69761 +                                                                                               pui32StrLen,
69762 +                                                                                               pi32Count,
69763 +                                                                                               ppszStr);
69764 +}
69765 +
69766 +
69767 +IMG_EXPORT
69768 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
69769 +{
69770 +       SYS_DATA *psSysData;
69771 +
69772 +       if(!psMiscInfo)
69773 +       {
69774 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
69775 +               return PVRSRV_ERROR_INVALID_PARAMS;
69776 +       }
69777 +
69778 +       psMiscInfo->ui32StatePresent = 0;
69779 +
69780 +
69781 +       if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
69782 +                                                                               |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
69783 +                                                                               |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
69784 +                                                                               |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
69785 +                                                                               |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
69786 +                                                                               |PVRSRV_MISC_INFO_CPUCACHEFLUSH_PRESENT
69787 +                                                                               |PVRSRV_MISC_INFO_RESET_PRESENT))
69788 +       {
69789 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
69790 +               return PVRSRV_ERROR_INVALID_PARAMS;
69791 +       }
69792 +
69793 +       SysAcquireData(&psSysData);
69794 +
69795 +
69796 +       if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
69797 +               (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
69798 +       {
69799 +               psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
69800 +               psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
69801 +               psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
69802 +       }
69803 +       else
69804 +       {
69805 +               psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
69806 +               psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
69807 +       }
69808 +
69809 +
69810 +       if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
69811 +               (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
69812 +       {
69813 +               psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
69814 +               psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
69815 +               psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
69816 +       }
69817 +
69818 +
69819 +       if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
69820 +               (psMiscInfo->pszMemoryStr != IMG_NULL))
69821 +       {
69822 +               RA_ARENA                        **ppArena;
69823 +               IMG_CHAR                        *pszStr;
69824 +               IMG_UINT32                      ui32StrLen;
69825 +               IMG_INT32                       i32Count;
69826 +
69827 +               pszStr = psMiscInfo->pszMemoryStr;
69828 +               ui32StrLen = psMiscInfo->ui32MemoryStrLen;
69829 +
69830 +               psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
69831 +
69832 +
69833 +               ppArena = &psSysData->apsLocalDevMemArena[0];
69834 +               while(*ppArena)
69835 +               {
69836 +                       CHECK_SPACE(ui32StrLen);
69837 +                       i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
69838 +                       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
69839 +
69840 +                       RA_GetStats(*ppArena,
69841 +                                                       &pszStr,
69842 +                                                       &ui32StrLen);
69843 +
69844 +                       ppArena++;
69845 +               }
69846 +
69847 +
69848 +
69849 +               List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
69850 +                                                                                                       PVRSRVGetMiscInfoKM_Device_AnyVaCb,
69851 +                                                                                                       &ui32StrLen,
69852 +                                                                                                       &i32Count,
69853 +                                                                                                       &pszStr);
69854 +
69855 +
69856 +               i32Count = OSSNPrintf(pszStr, 100, "\n\0");
69857 +               UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
69858 +       }
69859 +
69860 +       if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
69861 +               (psSysData->psGlobalEventObject != IMG_NULL))
69862 +       {
69863 +               psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
69864 +               psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
69865 +       }
69866 +
69867 +
69868 +
69869 +       if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
69870 +               && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
69871 +               && (psMiscInfo->pszMemoryStr != IMG_NULL))
69872 +       {
69873 +               IMG_CHAR        *pszStr;
69874 +               IMG_UINT32      ui32StrLen;
69875 +               IMG_UINT32      ui32LenStrPerNum = 12;
69876 +               IMG_INT32       i32Count;
69877 +               IMG_INT i;
69878 +               psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
69879 +
69880 +
69881 +               psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
69882 +               psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
69883 +               psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
69884 +               psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
69885 +
69886 +               pszStr = psMiscInfo->pszMemoryStr;
69887 +               ui32StrLen = psMiscInfo->ui32MemoryStrLen;
69888 +
69889 +               for (i=0; i<4; i++)
69890 +               {
69891 +                       if (ui32StrLen < ui32LenStrPerNum)
69892 +                       {
69893 +                               return PVRSRV_ERROR_INVALID_PARAMS;
69894 +                       }
69895 +
69896 +                       i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%ld", psMiscInfo->aui32DDKVersion[i]);
69897 +                       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
69898 +                       if (i != 3)
69899 +                       {
69900 +                               i32Count = OSSNPrintf(pszStr, 2, ".");
69901 +                               UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
69902 +                       }
69903 +               }
69904 +       }
69905 +
69906 +#if defined(SUPPORT_CPU_CACHED_BUFFERS)
69907 +       if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEFLUSH_PRESENT) != 0UL)
69908 +       {
69909 +               if(psMiscInfo->bDeferCPUCacheFlush)
69910 +               {
69911 +                       
69912 +                       if(!psMiscInfo->bCPUCacheFlushAll)
69913 +                       {
69914 +                               
69915 +
69916 +
69917 +                               PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVGetMiscInfoKM: don't support deferred range flushes"));
69918 +                               PVR_DPF((PVR_DBG_MESSAGE,"                     using deferred flush all instead"));
69919 +                       }
69920 +                       
69921 +                       psSysData->bFlushAll = IMG_TRUE;
69922 +               }
69923 +               else
69924 +               {
69925 +                       
69926 +                       if(psMiscInfo->bCPUCacheFlushAll)
69927 +                       {
69928 +                               
69929 +                               OSFlushCPUCacheKM();
69930 +                               
69931 +                               psSysData->bFlushAll = IMG_FALSE;
69932 +                       }
69933 +                       else
69934 +                       {
69935 +                               
69936 +                               OSFlushCPUCacheRangeKM(psMiscInfo->pvRangeAddrStart, psMiscInfo->pvRangeAddrEnd);
69937 +                       }
69938 +               }
69939 +       }
69940 +#endif 
69941 +
69942 +#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
69943 +       if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
69944 +       {
69945 +               PVR_LOG(("User requested OS reset"));
69946 +               OSPanic();
69947 +       }
69948 +#endif 
69949 +
69950 +       return PVRSRV_OK;
69951 +}
69952 +
69953 +
69954 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFBStatsKM(IMG_UINT32                *pui32Total,
69955 +                                                                                        IMG_UINT32             *pui32Available)
69956 +{
69957 +       IMG_UINT32 ui32Total = 0, i = 0;
69958 +       IMG_UINT32 ui32Available = 0;
69959 +
69960 +       *pui32Total             = 0;
69961 +       *pui32Available = 0;
69962 +
69963 +
69964 +       while(BM_ContiguousStatistics(i, &ui32Total, &ui32Available) == IMG_TRUE)
69965 +       {
69966 +               *pui32Total             += ui32Total;
69967 +               *pui32Available += ui32Available;
69968 +
69969 +               i++;
69970 +       }
69971 +
69972 +       return PVRSRV_OK;
69973 +}
69974 +
69975 +
69976 +IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
69977 +{
69978 +       SYS_DATA                        *psSysData;
69979 +       IMG_BOOL                        bStatus = IMG_FALSE;
69980 +       IMG_UINT32                      ui32InterruptSource;
69981 +
69982 +       if(!psDeviceNode)
69983 +       {
69984 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
69985 +               goto out;
69986 +       }
69987 +       psSysData = psDeviceNode->psSysData;
69988 +
69989 +
69990 +       ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
69991 +       if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
69992 +       {
69993 +               if(psDeviceNode->pfnDeviceISR != IMG_NULL)
69994 +               {
69995 +                       bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
69996 +               }
69997 +
69998 +               SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
69999 +       }
70000 +
70001 +out:
70002 +       return bStatus;
70003 +}
70004 +
70005 +IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
70006 +{
70007 +
70008 +       IMG_BOOL *pbStatus;
70009 +       IMG_UINT32 *pui32InterruptSource;
70010 +       IMG_UINT32 *pui32ClearInterrupts;
70011 +
70012 +       pbStatus = va_arg(va, IMG_BOOL*);
70013 +       pui32InterruptSource = va_arg(va, IMG_UINT32*);
70014 +       pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
70015 +
70016 +
70017 +       if(psDeviceNode->pfnDeviceISR != IMG_NULL)
70018 +       {
70019 +               if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
70020 +               {
70021 +                       if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
70022 +                       {
70023 +
70024 +                               *pbStatus = IMG_TRUE;
70025 +                       }
70026 +
70027 +                       *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
70028 +               }
70029 +       }
70030 +}
70031 +
70032 +IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
70033 +{
70034 +       SYS_DATA                        *psSysData = pvSysData;
70035 +       IMG_BOOL                        bStatus = IMG_FALSE;
70036 +       IMG_UINT32                      ui32InterruptSource;
70037 +       IMG_UINT32                      ui32ClearInterrupts = 0;
70038 +       if(!psSysData)
70039 +       {
70040 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
70041 +       }
70042 +       else
70043 +       {
70044 +
70045 +               ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
70046 +
70047 +
70048 +               if(ui32InterruptSource)
70049 +               {
70050 +
70051 +                       List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
70052 +                                                                                               PVRSRVSystemLISR_ForEachVaCb,
70053 +                                                                                               &bStatus,
70054 +                                                                                               &ui32InterruptSource,
70055 +                                                                                               &ui32ClearInterrupts);
70056 +
70057 +                       SysClearInterrupts(psSysData, ui32ClearInterrupts);
70058 +               }
70059 +       }
70060 +       return bStatus;
70061 +}
70062 +
70063 +
70064 +IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
70065 +{
70066 +       if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
70067 +       {
70068 +               (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
70069 +       }
70070 +}
70071 +
70072 +IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
70073 +{
70074 +       SYS_DATA                        *psSysData = pvSysData;
70075 +       if(!psSysData)
70076 +       {
70077 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
70078 +               return;
70079 +       }
70080 +
70081 +
70082 +       List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
70083 +                                                                       PVRSRVMISR_ForEachCb);
70084 +
70085 +
70086 +       if (PVRSRVProcessQueues(ISR_ID, IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
70087 +       {
70088 +               PVRSRVProcessQueues(ISR_ID, IMG_FALSE);
70089 +       }
70090 +
70091 +
70092 +       if (psSysData->psGlobalEventObject)
70093 +       {
70094 +               IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
70095 +               if(hOSEventKM)
70096 +               {
70097 +                       OSEventObjectSignal(hOSEventKM);
70098 +               }
70099 +       }
70100 +}
70101 +
70102 +
70103 +IMG_EXPORT
70104 +PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32      ui32PID)
70105 +{
70106 +       return PVRSRVPerProcessDataConnect(ui32PID);
70107 +}
70108 +
70109 +
70110 +IMG_EXPORT
70111 +IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32       ui32PID)
70112 +{
70113 +       PVRSRVPerProcessDataDisconnect(ui32PID);
70114 +}
70115 +
70116 +
70117 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
70118 +                                                                                                               IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
70119 +{
70120 +       IMG_SIZE_T         uiBytesSaved = 0;
70121 +       IMG_PVOID          pvLocalMemCPUVAddr;
70122 +       RA_SEGMENT_DETAILS sSegDetails;
70123 +
70124 +       if (hArena == IMG_NULL)
70125 +       {
70126 +               return (PVRSRV_ERROR_INVALID_PARAMS);
70127 +       }
70128 +
70129 +       sSegDetails.uiSize = 0;
70130 +       sSegDetails.sCpuPhyAddr.uiAddr = 0;
70131 +       sSegDetails.hSegment = 0;
70132 +
70133 +
70134 +       while (RA_GetNextLiveSegment(hArena, &sSegDetails))
70135 +       {
70136 +               if (pbyBuffer == IMG_NULL)
70137 +               {
70138 +
70139 +                       uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
70140 +               }
70141 +               else
70142 +               {
70143 +                       if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
70144 +                       {
70145 +                               return (PVRSRV_ERROR_OUT_OF_MEMORY);
70146 +                       }
70147 +
70148 +                       PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
70149 +
70150 +
70151 +                       pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
70152 +                                                                       sSegDetails.uiSize,
70153 +                                                                       PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
70154 +                                                                       IMG_NULL);
70155 +                       if (pvLocalMemCPUVAddr == IMG_NULL)
70156 +                       {
70157 +                               PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
70158 +                               return (PVRSRV_ERROR_OUT_OF_MEMORY);
70159 +                       }
70160 +
70161 +                       if (bSave)
70162 +                       {
70163 +
70164 +                               OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
70165 +                               pbyBuffer += sizeof(sSegDetails.uiSize);
70166 +
70167 +                               OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
70168 +                               pbyBuffer += sSegDetails.uiSize;
70169 +                       }
70170 +                       else
70171 +                       {
70172 +                               IMG_UINT32 uiSize;
70173 +
70174 +                               OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
70175 +
70176 +                               if (uiSize != sSegDetails.uiSize)
70177 +                               {
70178 +                                       PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
70179 +                               }
70180 +                               else
70181 +                               {
70182 +                                       pbyBuffer += sizeof(sSegDetails.uiSize);
70183 +
70184 +                                       OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
70185 +                                       pbyBuffer += sSegDetails.uiSize;
70186 +                               }
70187 +                       }
70188 +
70189 +
70190 +                       uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
70191 +
70192 +                       OSUnMapPhysToLin(pvLocalMemCPUVAddr,
70193 +                                    sSegDetails.uiSize,
70194 +                                    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
70195 +                                    IMG_NULL);
70196 +               }
70197 +       }
70198 +
70199 +       if (pbyBuffer == IMG_NULL)
70200 +       {
70201 +               *puiBufSize = uiBytesSaved;
70202 +       }
70203 +
70204 +       return (PVRSRV_OK);
70205 +}
70206 +
70207 +
70208 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/queue.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/queue.c
70209 new file mode 100644
70210 index 0000000..e535ddd
70211 --- /dev/null
70212 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/queue.c
70213 @@ -0,0 +1,1137 @@
70214 +/**********************************************************************
70215 + *
70216 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
70217 + *
70218 + * This program is free software; you can redistribute it and/or modify it
70219 + * under the terms and conditions of the GNU General Public License,
70220 + * version 2, as published by the Free Software Foundation.
70221 + *
70222 + * This program is distributed in the hope it will be useful but, except
70223 + * as otherwise stated in writing, without any warranty; without even the
70224 + * implied warranty of merchantability or fitness for a particular purpose.
70225 + * See the GNU General Public License for more details.
70226 + *
70227 + * You should have received a copy of the GNU General Public License along with
70228 + * this program; if not, write to the Free Software Foundation, Inc.,
70229 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
70230 + *
70231 + * The full GNU General Public License is included in this distribution in
70232 + * the file called "COPYING".
70233 + *
70234 + * Contact Information:
70235 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
70236 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
70237 + *
70238 + ******************************************************************************/
70239 +
70240 +#include "services_headers.h"
70241 +
70242 +#include "lists.h"
70243 +
70244 +DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
70245 +
70246 +#if defined(__linux__) && defined(__KERNEL__)
70247 +
70248 +#include "proc.h"
70249 +
70250 +static IMG_INT
70251 +QueuePrintCommands (PVRSRV_QUEUE_INFO * psQueue, IMG_CHAR * buffer, size_t size)
70252 +{
70253 +       off_t off = 0;
70254 +       IMG_INT cmds = 0;
70255 +       IMG_SIZE_T ui32ReadOffset  = psQueue->ui32ReadOffset;
70256 +       IMG_SIZE_T ui32WriteOffset = psQueue->ui32WriteOffset;
70257 +       PVRSRV_COMMAND * psCmd;
70258 +
70259 +       while (ui32ReadOffset != ui32WriteOffset)
70260 +       {
70261 +               psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
70262 +
70263 +               off = printAppend(buffer, size, off, "%p %p  %5lu  %6lu  %3lu  %5lu   %2lu   %2lu    %3lu  \n",
70264 +                                                       psQueue,
70265 +                                                       psCmd,
70266 +                                                       psCmd->ui32ProcessID,
70267 +                                                       psCmd->CommandType,
70268 +                                                       psCmd->ui32CmdSize,
70269 +                                                       psCmd->ui32DevIndex,
70270 +                                                       psCmd->ui32DstSyncCount,
70271 +                                                       psCmd->ui32SrcSyncCount,
70272 +                                                       psCmd->ui32DataSize);
70273 +
70274 +               ui32ReadOffset += psCmd->ui32CmdSize;
70275 +               ui32ReadOffset &= psQueue->ui32QueueSize - 1;
70276 +               cmds++;
70277 +       }
70278 +       if (cmds == 0)
70279 +               off = printAppend(buffer, size, off, "%p <empty>\n", psQueue);
70280 +       return off;
70281 +}
70282 +
70283 +
70284 +
70285 +#ifdef PVR_PROC_USE_SEQ_FILE
70286 +
70287 +void ProcSeqShowQueue(struct seq_file *sfile,void* el)
70288 +{
70289 +       PVRSRV_QUEUE_INFO * psQueue = (PVRSRV_QUEUE_INFO*)el;
70290 +       IMG_INT cmds = 0;
70291 +       IMG_SIZE_T ui32ReadOffset;
70292 +       IMG_SIZE_T ui32WriteOffset;
70293 +       PVRSRV_COMMAND * psCmd;
70294 +
70295 +       if(el == PVR_PROC_SEQ_START_TOKEN)
70296 +       {
70297 +               seq_printf( sfile,
70298 +                                       "Command Queues\n"
70299 +                                       "Queue    CmdPtr      Pid Command Size DevInd  DSC  SSC  #Data ...\n");
70300 +               return;
70301 +       }
70302 +
70303 +       ui32ReadOffset = psQueue->ui32ReadOffset;
70304 +       ui32WriteOffset = psQueue->ui32WriteOffset;
70305 +
70306 +       while (ui32ReadOffset != ui32WriteOffset)
70307 +       {
70308 +               psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
70309 +
70310 +               seq_printf(sfile, "%p %p  %5lu  %6lu  %3lu  %5lu   %2lu   %2lu    %3lu  \n",
70311 +                                                       psQueue,
70312 +                                                       psCmd,
70313 +                                                       psCmd->ui32ProcessID,
70314 +                                                       psCmd->CommandType,
70315 +                                                       psCmd->ui32CmdSize,
70316 +                                                       psCmd->ui32DevIndex,
70317 +                                                       psCmd->ui32DstSyncCount,
70318 +                                                       psCmd->ui32SrcSyncCount,
70319 +                                                       psCmd->ui32DataSize);
70320 +
70321 +               ui32ReadOffset += psCmd->ui32CmdSize;
70322 +               ui32ReadOffset &= psQueue->ui32QueueSize - 1;
70323 +               cmds++;
70324 +       }
70325 +
70326 +       if (cmds == 0)
70327 +               seq_printf(sfile, "%p <empty>\n", psQueue);
70328 +}
70329 +
70330 +void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
70331 +{
70332 +       PVRSRV_QUEUE_INFO * psQueue;
70333 +       SYS_DATA * psSysData;
70334 +
70335 +       if(!off)
70336 +       {
70337 +               return PVR_PROC_SEQ_START_TOKEN;
70338 +       }
70339 +
70340 +
70341 +       SysAcquireData(&psSysData);
70342 +
70343 +       for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
70344 +       return psQueue;
70345 +}
70346 +
70347 +#endif
70348 +
70349 +off_t
70350 +QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off)
70351 +{
70352 +       SYS_DATA * psSysData;
70353 +       PVRSRV_QUEUE_INFO * psQueue;
70354 +
70355 +       SysAcquireData(&psSysData);
70356 +
70357 +        if (!off)
70358 +                 return printAppend (buffer, size, 0,
70359 +                                                               "Command Queues\n"
70360 +                                                               "Queue    CmdPtr      Pid Command Size DevInd  DSC  SSC  #Data ...\n");
70361 +
70362 +
70363 +
70364 +       for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM)
70365 +               ;
70366 +
70367 +       return psQueue ? QueuePrintCommands (psQueue, buffer, size) : END_OF_FILE;
70368 +}
70369 +#endif
70370 +
70371 +#define GET_SPACE_IN_CMDQ(psQueue)                                                                             \
70372 +       (((psQueue->ui32ReadOffset - psQueue->ui32WriteOffset)                          \
70373 +       + (psQueue->ui32QueueSize - 1)) & (psQueue->ui32QueueSize - 1))
70374 +
70375 +#define UPDATE_QUEUE_WOFF(psQueue, ui32Size)                                                   \
70376 +       psQueue->ui32WriteOffset = (psQueue->ui32WriteOffset + ui32Size)        \
70377 +       & (psQueue->ui32QueueSize - 1);
70378 +
70379 +#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending)                                 \
70380 +       (ui32OpsComplete >= ui32OpsPending)
70381 +
70382 +
70383 +DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
70384 +
70385 +static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
70386 +                                                                        IMG_UINT32                             i,
70387 +                                                                        IMG_BOOL                               bIsSrc)
70388 +{
70389 +       PVRSRV_SYNC_OBJECT      *psSyncObject;
70390 +
70391 +       psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
70392 +
70393 +       if (psCmdCompleteData->bInUse)
70394 +       {
70395 +               PVR_LOG(("\t%s %lu: ROC DevVAddr:0x%lX ROP:0x%lx ROC:0x%lx, WOC DevVAddr:0x%lX WOP:0x%lx WOC:0x%lx",
70396 +                               bIsSrc ? "SRC" : "DEST", i,
70397 +                               psSyncObject[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
70398 +                               psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsPending,
70399 +                               psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete,
70400 +                               psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
70401 +                               psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
70402 +                               psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete));
70403 +       }
70404 +       else
70405 +       {
70406 +               PVR_LOG(("\t%s %lu: (Not in use)", bIsSrc ? "SRC" : "DEST", i));
70407 +       }
70408 +}
70409 +
70410 +
70411 +static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
70412 +{
70413 +       if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
70414 +       {
70415 +               IMG_UINT32                              i;
70416 +               SYS_DATA                                *psSysData;
70417 +               COMMAND_COMPLETE_DATA   **ppsCmdCompleteData;
70418 +               COMMAND_COMPLETE_DATA   *psCmdCompleteData;
70419 +
70420 +               SysAcquireData(&psSysData);
70421 +
70422 +               ppsCmdCompleteData = psSysData->ppsCmdCompleteData[psDeviceNode->sDevId.ui32DeviceIndex];
70423 +
70424 +               if (ppsCmdCompleteData != IMG_NULL)
70425 +               {
70426 +                       psCmdCompleteData = ppsCmdCompleteData[DC_FLIP_COMMAND];
70427 +
70428 +                       PVR_LOG(("Command Complete Data for display device %lu:", psDeviceNode->sDevId.ui32DeviceIndex));
70429 +
70430 +                       for (i = 0; i < psCmdCompleteData->ui32SrcSyncCount; i++)
70431 +                       {
70432 +                               QueueDumpCmdComplete(psCmdCompleteData, i, IMG_TRUE);
70433 +                       }
70434 +
70435 +                       for (i = 0; i < psCmdCompleteData->ui32DstSyncCount; i++)
70436 +                       {
70437 +                               QueueDumpCmdComplete(psCmdCompleteData, i, IMG_FALSE);
70438 +                       }
70439 +               }
70440 +               else
70441 +               {
70442 +                       PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex));
70443 +               }
70444 +       }
70445 +}
70446 +
70447 +
70448 +IMG_VOID QueueDumpDebugInfo(IMG_VOID)
70449 +{
70450 +       SYS_DATA        *psSysData;
70451 +       SysAcquireData(&psSysData);
70452 +       List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, QueueDumpDebugInfo_ForEachCb);
70453 +}
70454 +
70455 +
70456 +IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
70457 +{
70458 +       IMG_SIZE_T ui32Temp, ui32Result = 1;
70459 +
70460 +       if(!ui32Value)
70461 +               return 0;
70462 +
70463 +       ui32Temp = ui32Value - 1;
70464 +       while(ui32Temp)
70465 +       {
70466 +               ui32Result <<= 1;
70467 +               ui32Temp >>= 1;
70468 +       }
70469 +
70470 +       return ui32Result;
70471 +}
70472 +
70473 +
70474 +IMG_EXPORT
70475 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
70476 +                                                                                                        PVRSRV_QUEUE_INFO **ppsQueueInfo)
70477 +{
70478 +       PVRSRV_QUEUE_INFO       *psQueueInfo;
70479 +       IMG_SIZE_T                      ui32Power2QueueSize = NearestPower2(ui32QueueSize);
70480 +       SYS_DATA                        *psSysData;
70481 +       PVRSRV_ERROR            eError;
70482 +       IMG_HANDLE                      hMemBlock;
70483 +
70484 +       SysAcquireData(&psSysData);
70485 +
70486 +
70487 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70488 +                                        sizeof(PVRSRV_QUEUE_INFO),
70489 +                                        (IMG_VOID **)&psQueueInfo, &hMemBlock,
70490 +                                        "Queue Info") != PVRSRV_OK)
70491 +       {
70492 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
70493 +               goto ErrorExit;
70494 +       }
70495 +       OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
70496 +
70497 +       psQueueInfo->hMemBlock[0] = hMemBlock;
70498 +       psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
70499 +
70500 +
70501 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70502 +                                        ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
70503 +                                        &psQueueInfo->pvLinQueueKM, &hMemBlock,
70504 +                                        "Command Queue") != PVRSRV_OK)
70505 +       {
70506 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
70507 +               goto ErrorExit;
70508 +       }
70509 +
70510 +       psQueueInfo->hMemBlock[1] = hMemBlock;
70511 +       psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
70512 +
70513 +
70514 +       PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
70515 +       PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
70516 +
70517 +       psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
70518 +
70519 +
70520 +       if (psSysData->psQueueList == IMG_NULL)
70521 +       {
70522 +               eError = OSCreateResource(&psSysData->sQProcessResource);
70523 +               if (eError != PVRSRV_OK)
70524 +               {
70525 +                       goto ErrorExit;
70526 +               }
70527 +       }
70528 +
70529 +
70530 +       if (OSLockResource(&psSysData->sQProcessResource,
70531 +                                                       KERNEL_ID) != PVRSRV_OK)
70532 +       {
70533 +               goto ErrorExit;
70534 +       }
70535 +
70536 +       psQueueInfo->psNextKM = psSysData->psQueueList;
70537 +       psSysData->psQueueList = psQueueInfo;
70538 +
70539 +       if (OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID) != PVRSRV_OK)
70540 +       {
70541 +               goto ErrorExit;
70542 +       }
70543 +
70544 +       *ppsQueueInfo = psQueueInfo;
70545 +
70546 +       return PVRSRV_OK;
70547 +
70548 +ErrorExit:
70549 +
70550 +       if(psQueueInfo)
70551 +       {
70552 +               if(psQueueInfo->pvLinQueueKM)
70553 +               {
70554 +                       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70555 +                                               psQueueInfo->ui32QueueSize,
70556 +                                               psQueueInfo->pvLinQueueKM,
70557 +                                               psQueueInfo->hMemBlock[1]);
70558 +                       psQueueInfo->pvLinQueueKM = IMG_NULL;
70559 +               }
70560 +
70561 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70562 +                                       sizeof(PVRSRV_QUEUE_INFO),
70563 +                                       psQueueInfo,
70564 +                                       psQueueInfo->hMemBlock[0]);
70565 +
70566 +       }
70567 +
70568 +       return PVRSRV_ERROR_GENERIC;
70569 +}
70570 +
70571 +
70572 +IMG_EXPORT
70573 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
70574 +{
70575 +       PVRSRV_QUEUE_INFO       *psQueue;
70576 +       SYS_DATA                        *psSysData;
70577 +       PVRSRV_ERROR            eError;
70578 +       IMG_BOOL                        bTimeout = IMG_TRUE;
70579 +
70580 +       SysAcquireData(&psSysData);
70581 +
70582 +       psQueue = psSysData->psQueueList;
70583 +
70584 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
70585 +       {
70586 +               if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
70587 +               {
70588 +                       bTimeout = IMG_FALSE;
70589 +                       break;
70590 +               }
70591 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
70592 +       } END_LOOP_UNTIL_TIMEOUT();
70593 +
70594 +       if (bTimeout)
70595 +       {
70596 +
70597 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
70598 +               eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
70599 +               goto ErrorExit;
70600 +       }
70601 +
70602 +
70603 +       eError = OSLockResource(&psSysData->sQProcessResource,
70604 +                                                               KERNEL_ID);
70605 +       if (eError != PVRSRV_OK)
70606 +       {
70607 +               goto ErrorExit;
70608 +       }
70609 +
70610 +       if(psQueue == psQueueInfo)
70611 +       {
70612 +               psSysData->psQueueList = psQueueInfo->psNextKM;
70613 +
70614 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70615 +                                       NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
70616 +                                       psQueueInfo->pvLinQueueKM,
70617 +                                       psQueueInfo->hMemBlock[1]);
70618 +               psQueueInfo->pvLinQueueKM = IMG_NULL;
70619 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70620 +                                       sizeof(PVRSRV_QUEUE_INFO),
70621 +                                       psQueueInfo,
70622 +                                       psQueueInfo->hMemBlock[0]);
70623 +               psQueueInfo = IMG_NULL;
70624 +       }
70625 +       else
70626 +       {
70627 +               while(psQueue)
70628 +               {
70629 +                       if(psQueue->psNextKM == psQueueInfo)
70630 +                       {
70631 +                               psQueue->psNextKM = psQueueInfo->psNextKM;
70632 +
70633 +                               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70634 +                                                       psQueueInfo->ui32QueueSize,
70635 +                                                       psQueueInfo->pvLinQueueKM,
70636 +                                                       psQueueInfo->hMemBlock[1]);
70637 +                               psQueueInfo->pvLinQueueKM = IMG_NULL;
70638 +                               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
70639 +                                                       sizeof(PVRSRV_QUEUE_INFO),
70640 +                                                       psQueueInfo,
70641 +                                                       psQueueInfo->hMemBlock[0]);
70642 +                               psQueueInfo = IMG_NULL;
70643 +                               break;
70644 +                       }
70645 +                       psQueue = psQueue->psNextKM;
70646 +               }
70647 +
70648 +               if(!psQueue)
70649 +               {
70650 +                       eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
70651 +                       if (eError != PVRSRV_OK)
70652 +                       {
70653 +                               goto ErrorExit;
70654 +                       }
70655 +                       eError = PVRSRV_ERROR_INVALID_PARAMS;
70656 +                       goto ErrorExit;
70657 +               }
70658 +       }
70659 +
70660 +
70661 +       eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
70662 +       if (eError != PVRSRV_OK)
70663 +       {
70664 +               goto ErrorExit;
70665 +       }
70666 +
70667 +
70668 +       if (psSysData->psQueueList == IMG_NULL)
70669 +       {
70670 +               eError = OSDestroyResource(&psSysData->sQProcessResource);
70671 +               if (eError != PVRSRV_OK)
70672 +               {
70673 +                       goto ErrorExit;
70674 +               }
70675 +       }
70676 +
70677 +ErrorExit:
70678 +
70679 +       return eError;
70680 +}
70681 +
70682 +
70683 +IMG_EXPORT
70684 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
70685 +                                                                                               IMG_SIZE_T ui32ParamSize,
70686 +                                                                                               IMG_VOID **ppvSpace)
70687 +{
70688 +       IMG_BOOL bTimeout = IMG_TRUE;
70689 +
70690 +
70691 +       ui32ParamSize =  (ui32ParamSize+3) & 0xFFFFFFFC;
70692 +
70693 +       if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
70694 +       {
70695 +               PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
70696 +               return PVRSRV_ERROR_CMD_TOO_BIG;
70697 +       }
70698 +
70699 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
70700 +       {
70701 +               if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
70702 +               {
70703 +                       bTimeout = IMG_FALSE;
70704 +                       break;
70705 +               }
70706 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
70707 +       } END_LOOP_UNTIL_TIMEOUT();
70708 +
70709 +       if (bTimeout == IMG_TRUE)
70710 +       {
70711 +               *ppvSpace = IMG_NULL;
70712 +
70713 +               return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
70714 +       }
70715 +       else
70716 +       {
70717 +               *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
70718 +       }
70719 +
70720 +       return PVRSRV_OK;
70721 +}
70722 +
70723 +
70724 +IMG_EXPORT
70725 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO      *psQueue,
70726 +                                                                                               PVRSRV_COMMAND          **ppsCommand,
70727 +                                                                                               IMG_UINT32                      ui32DevIndex,
70728 +                                                                                               IMG_UINT16                      CommandType,
70729 +                                                                                               IMG_UINT32                      ui32DstSyncCount,
70730 +                                                                                               PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
70731 +                                                                                               IMG_UINT32                      ui32SrcSyncCount,
70732 +                                                                                               PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
70733 +                                                                                               IMG_SIZE_T                      ui32DataByteSize )
70734 +{
70735 +       PVRSRV_ERROR    eError;
70736 +       PVRSRV_COMMAND  *psCommand;
70737 +       IMG_SIZE_T              ui32CommandSize;
70738 +       IMG_UINT32              i;
70739 +
70740 +
70741 +       ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
70742 +
70743 +
70744 +       ui32CommandSize = sizeof(PVRSRV_COMMAND)
70745 +                                       + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
70746 +                                       + ui32DataByteSize;
70747 +
70748 +
70749 +       eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
70750 +       if(eError != PVRSRV_OK)
70751 +       {
70752 +               return eError;
70753 +       }
70754 +
70755 +       psCommand->ui32ProcessID        = OSGetCurrentProcessIDKM();
70756 +
70757 +
70758 +       psCommand->ui32CmdSize          = ui32CommandSize;
70759 +       psCommand->ui32DevIndex         = ui32DevIndex;
70760 +       psCommand->CommandType          = CommandType;
70761 +       psCommand->ui32DstSyncCount     = ui32DstSyncCount;
70762 +       psCommand->ui32SrcSyncCount     = ui32SrcSyncCount;
70763 +
70764 +
70765 +       psCommand->psDstSync            = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
70766 +
70767 +
70768 +       psCommand->psSrcSync            = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
70769 +                                                               + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
70770 +
70771 +       psCommand->pvData                       = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
70772 +                                                               + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
70773 +       psCommand->ui32DataSize         = ui32DataByteSize;
70774 +
70775 +
70776 +       for (i=0; i<ui32DstSyncCount; i++)
70777 +       {
70778 +               psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
70779 +               psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
70780 +               psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
70781 +
70782 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
70783 +                               i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
70784 +                               psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
70785 +                               psCommand->psDstSync[i].ui32ReadOpsPending,
70786 +                               psCommand->psDstSync[i].ui32WriteOpsPending));
70787 +       }
70788 +
70789 +
70790 +       for (i=0; i<ui32SrcSyncCount; i++)
70791 +       {
70792 +               psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
70793 +               psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
70794 +               psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
70795 +
70796 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
70797 +                               i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
70798 +                               psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
70799 +                               psCommand->psSrcSync[i].ui32ReadOpsPending,
70800 +                               psCommand->psSrcSync[i].ui32WriteOpsPending));
70801 +       }
70802 +
70803 +
70804 +       *ppsCommand = psCommand;
70805 +
70806 +       return PVRSRV_OK;
70807 +}
70808 +
70809 +
70810 +IMG_EXPORT
70811 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
70812 +                                                                                               PVRSRV_COMMAND *psCommand)
70813 +{
70814 +
70815 +
70816 +
70817 +       if (psCommand->ui32DstSyncCount > 0)
70818 +       {
70819 +               psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
70820 +                                                                       + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
70821 +       }
70822 +
70823 +       if (psCommand->ui32SrcSyncCount > 0)
70824 +       {
70825 +               psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
70826 +                                                                       + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
70827 +                                                                       + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
70828 +       }
70829 +
70830 +       psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
70831 +                                                                       + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
70832 +                                                                       + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
70833 +                                                                       + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
70834 +
70835 +
70836 +       UPDATE_QUEUE_WOFF(psQueue, psCommand->ui32CmdSize);
70837 +
70838 +       return PVRSRV_OK;
70839 +}
70840 +
70841 +
70842 +
70843 +IMG_EXPORT
70844 +PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA                     *psSysData,
70845 +                                                                 PVRSRV_COMMAND        *psCommand,
70846 +                                                                 IMG_BOOL                      bFlush)
70847 +{
70848 +       PVRSRV_SYNC_OBJECT              *psWalkerObj;
70849 +       PVRSRV_SYNC_OBJECT              *psEndObj;
70850 +       IMG_UINT32                              i;
70851 +       COMMAND_COMPLETE_DATA   *psCmdCompleteData;
70852 +       PVRSRV_ERROR                    eError = PVRSRV_OK;
70853 +       IMG_UINT32                              ui32WriteOpsComplete;
70854 +       IMG_UINT32                              ui32ReadOpsComplete;
70855 +
70856 +
70857 +       psWalkerObj = psCommand->psDstSync;
70858 +       psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
70859 +       while (psWalkerObj < psEndObj)
70860 +       {
70861 +               PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
70862 +
70863 +               ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
70864 +               ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
70865 +
70866 +               if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
70867 +               ||      (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
70868 +               {
70869 +                       if (!bFlush ||
70870 +                               !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
70871 +                               !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
70872 +                       {
70873 +                               return PVRSRV_ERROR_FAILED_DEPENDENCIES;
70874 +                       }
70875 +               }
70876 +
70877 +               psWalkerObj++;
70878 +       }
70879 +
70880 +
70881 +       psWalkerObj = psCommand->psSrcSync;
70882 +       psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
70883 +       while (psWalkerObj < psEndObj)
70884 +       {
70885 +               PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
70886 +
70887 +               ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
70888 +               ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
70889 +
70890 +               if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
70891 +               || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
70892 +               {
70893 +                       if (!bFlush &&
70894 +                               SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
70895 +                               SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
70896 +                       {
70897 +                               PVR_DPF((PVR_DBG_WARNING,
70898 +                                               "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
70899 +                                               psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
70900 +                       }
70901 +
70902 +                       if (!bFlush ||
70903 +                               !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
70904 +                               !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
70905 +                       {
70906 +                               return PVRSRV_ERROR_FAILED_DEPENDENCIES;
70907 +                       }
70908 +               }
70909 +               psWalkerObj++;
70910 +       }
70911 +
70912 +
70913 +       if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
70914 +       {
70915 +               PVR_DPF((PVR_DBG_ERROR,
70916 +                                       "PVRSRVProcessCommand: invalid DeviceType 0x%x",
70917 +                                       psCommand->ui32DevIndex));
70918 +               return PVRSRV_ERROR_INVALID_PARAMS;
70919 +       }
70920 +
70921 +
70922 +       psCmdCompleteData = psSysData->ppsCmdCompleteData[psCommand->ui32DevIndex][psCommand->CommandType];
70923 +       if (psCmdCompleteData->bInUse)
70924 +       {
70925 +
70926 +               return PVRSRV_ERROR_FAILED_DEPENDENCIES;
70927 +       }
70928 +
70929 +
70930 +       psCmdCompleteData->bInUse = IMG_TRUE;
70931 +
70932 +
70933 +       psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
70934 +       for (i=0; i<psCommand->ui32DstSyncCount; i++)
70935 +       {
70936 +               psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
70937 +
70938 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
70939 +                               i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
70940 +                               psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
70941 +                               psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
70942 +                               psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
70943 +       }
70944 +
70945 +
70946 +       psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
70947 +       for (i=0; i<psCommand->ui32SrcSyncCount; i++)
70948 +       {
70949 +               psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
70950 +
70951 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
70952 +                               i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
70953 +                               psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
70954 +                               psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
70955 +                               psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
70956 +       }
70957 +
70958 +
70959 +
70960 +
70961 +
70962 +
70963 +
70964 +
70965 +
70966 +
70967 +
70968 +       if (psSysData->ppfnCmdProcList[psCommand->ui32DevIndex][psCommand->CommandType]((IMG_HANDLE)psCmdCompleteData,
70969 +                                                                                                                                                               psCommand->ui32DataSize,
70970 +                                                                                                                                                               psCommand->pvData) == IMG_FALSE)
70971 +       {
70972 +
70973 +
70974 +
70975 +               psCmdCompleteData->bInUse = IMG_FALSE;
70976 +               eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
70977 +       }
70978 +
70979 +       return eError;
70980 +}
70981 +
70982 +
70983 +IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
70984 +{
70985 +       if (psDeviceNode->bReProcessDeviceCommandComplete &&
70986 +               psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
70987 +       {
70988 +               (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
70989 +       }
70990 +}
70991 +
70992 +IMG_EXPORT
70993 +PVRSRV_ERROR PVRSRVProcessQueues(IMG_UINT32    ui32CallerID,
70994 +                                                                IMG_BOOL       bFlush)
70995 +{
70996 +       PVRSRV_QUEUE_INFO       *psQueue;
70997 +       SYS_DATA                        *psSysData;
70998 +       PVRSRV_COMMAND          *psCommand;
70999 +       PVRSRV_ERROR            eError;
71000 +
71001 +       SysAcquireData(&psSysData);
71002 +
71003 +
71004 +       psSysData->bReProcessQueues = IMG_FALSE;
71005 +
71006 +
71007 +       eError = OSLockResource(&psSysData->sQProcessResource,
71008 +                                                       ui32CallerID);
71009 +       if(eError != PVRSRV_OK)
71010 +       {
71011 +
71012 +               psSysData->bReProcessQueues = IMG_TRUE;
71013 +
71014 +
71015 +               if(ui32CallerID == ISR_ID)
71016 +               {
71017 +                       if (bFlush)
71018 +                       {
71019 +                               PVR_DPF((PVR_DBG_ERROR,"PVRSRVProcessQueues: Couldn't acquire queue processing lock for FLUSH"));
71020 +                       }
71021 +                       else
71022 +                       {
71023 +                               PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Couldn't acquire queue processing lock"));
71024 +                       }
71025 +               }
71026 +               else
71027 +               {
71028 +                       PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Queue processing lock-acquire failed when called from the Services driver."));
71029 +                       PVR_DPF((PVR_DBG_MESSAGE,"                     This is due to MISR queue processing being interrupted by the Services driver."));
71030 +               }
71031 +
71032 +               return PVRSRV_OK;
71033 +       }
71034 +
71035 +       psQueue = psSysData->psQueueList;
71036 +
71037 +       if(!psQueue)
71038 +       {
71039 +               PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
71040 +       }
71041 +
71042 +       if (bFlush)
71043 +       {
71044 +               PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
71045 +       }
71046 +
71047 +       while (psQueue)
71048 +       {
71049 +               while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
71050 +               {
71051 +                       psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
71052 +
71053 +                       if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
71054 +                       {
71055 +
71056 +                               UPDATE_QUEUE_ROFF(psQueue, psCommand->ui32CmdSize)
71057 +
71058 +                               if (bFlush)
71059 +                               {
71060 +                                       continue;
71061 +                               }
71062 +                       }
71063 +
71064 +                       break;
71065 +               }
71066 +               psQueue = psQueue->psNextKM;
71067 +       }
71068 +
71069 +       if (bFlush)
71070 +       {
71071 +               PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
71072 +       }
71073 +
71074 +
71075 +       List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
71076 +                                                                       PVRSRVProcessQueues_ForEachCb);
71077 +
71078 +
71079 +
71080 +       OSUnlockResource(&psSysData->sQProcessResource, ui32CallerID);
71081 +
71082 +
71083 +       if(psSysData->bReProcessQueues)
71084 +       {
71085 +               return PVRSRV_ERROR_PROCESSING_BLOCKED;
71086 +       }
71087 +
71088 +       return PVRSRV_OK;
71089 +}
71090 +
71091 +
71092 +IMG_EXPORT
71093 +IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE    hCmdCookie,
71094 +                                                                IMG_BOOL       bScheduleMISR)
71095 +{
71096 +       IMG_UINT32                              i;
71097 +       COMMAND_COMPLETE_DATA   *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
71098 +       SYS_DATA                                *psSysData;
71099 +
71100 +       SysAcquireData(&psSysData);
71101 +
71102 +
71103 +       for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
71104 +       {
71105 +               psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
71106 +
71107 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
71108 +                               i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
71109 +                               psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
71110 +                               psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
71111 +                               psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
71112 +       }
71113 +
71114 +
71115 +       for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
71116 +       {
71117 +               psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
71118 +
71119 +               PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
71120 +                               i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
71121 +                               psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
71122 +                               psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
71123 +                               psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
71124 +       }
71125 +
71126 +
71127 +       psCmdCompleteData->bInUse = IMG_FALSE;
71128 +
71129 +
71130 +       PVRSRVCommandCompleteCallbacks();
71131 +
71132 +#if defined(SYS_USING_INTERRUPTS)
71133 +       if(bScheduleMISR)
71134 +       {
71135 +               OSScheduleMISR(psSysData);
71136 +       }
71137 +#else
71138 +       PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
71139 +#endif
71140 +}
71141 +
71142 +
71143 +IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
71144 +{
71145 +       if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
71146 +       {
71147 +
71148 +               (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
71149 +       }
71150 +}
71151 +
71152 +IMG_VOID PVRSRVCommandCompleteCallbacks(IMG_VOID)
71153 +{
71154 +       SYS_DATA                                *psSysData;
71155 +       SysAcquireData(&psSysData);
71156 +
71157 +
71158 +       List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
71159 +                                                                       PVRSRVCommandCompleteCallbacks_ForEachCb);
71160 +}
71161 +
71162 +IMG_EXPORT
71163 +PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32            ui32DevIndex,
71164 +                                                                                PFN_CMD_PROC   *ppfnCmdProcList,
71165 +                                                                                IMG_UINT32             ui32MaxSyncsPerCmd[][2],
71166 +                                                                                IMG_UINT32             ui32CmdCount)
71167 +{
71168 +       SYS_DATA                                *psSysData;
71169 +       PVRSRV_ERROR                    eError;
71170 +       IMG_UINT32                              i;
71171 +       IMG_SIZE_T                              ui32AllocSize;
71172 +       PFN_CMD_PROC                    *ppfnCmdProc;
71173 +       COMMAND_COMPLETE_DATA   *psCmdCompleteData;
71174 +
71175 +
71176 +       if(ui32DevIndex >= SYS_DEVICE_COUNT)
71177 +       {
71178 +               PVR_DPF((PVR_DBG_ERROR,
71179 +                                       "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
71180 +                                       ui32DevIndex));
71181 +               return PVRSRV_ERROR_INVALID_PARAMS;
71182 +       }
71183 +
71184 +
71185 +       SysAcquireData(&psSysData);
71186 +
71187 +
71188 +       eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
71189 +                                        ui32CmdCount * sizeof(PFN_CMD_PROC),
71190 +                                        (IMG_VOID **)&psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL,
71191 +                                        "Internal Queue Info structure");
71192 +       if (eError != PVRSRV_OK)
71193 +       {
71194 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc queue"));
71195 +               return eError;
71196 +       }
71197 +
71198 +
71199 +       ppfnCmdProc = psSysData->ppfnCmdProcList[ui32DevIndex];
71200 +
71201 +
71202 +       for (i=0; i<ui32CmdCount; i++)
71203 +       {
71204 +               ppfnCmdProc[i] = ppfnCmdProcList[i];
71205 +       }
71206 +
71207 +
71208 +       ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
71209 +       eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
71210 +                                        ui32AllocSize,
71211 +                                        (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL,
71212 +                                        "Array of Pointers for Command Store");
71213 +       if (eError != PVRSRV_OK)
71214 +       {
71215 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
71216 +               goto ErrorExit;
71217 +       }
71218 +
71219 +       for (i=0; i<ui32CmdCount; i++)
71220 +       {
71221 +
71222 +
71223 +               ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
71224 +                                         + ((ui32MaxSyncsPerCmd[i][0]
71225 +                                         +     ui32MaxSyncsPerCmd[i][1])
71226 +                                         * sizeof(PVRSRV_SYNC_OBJECT));
71227 +
71228 +               eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
71229 +                                                       ui32AllocSize,
71230 +                                                       (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex][i],
71231 +                                                       IMG_NULL,
71232 +                                                       "Command Complete Data");
71233 +               if (eError != PVRSRV_OK)
71234 +               {
71235 +                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d",i));
71236 +                       goto ErrorExit;
71237 +               }
71238 +
71239 +
71240 +               OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex][i], 0x00, ui32AllocSize);
71241 +
71242 +               psCmdCompleteData = psSysData->ppsCmdCompleteData[ui32DevIndex][i];
71243 +
71244 +
71245 +               psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
71246 +                                                                               (((IMG_UINTPTR_T)psCmdCompleteData)
71247 +                                                                               + sizeof(COMMAND_COMPLETE_DATA));
71248 +               psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
71249 +                                                                               (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
71250 +                                                                               + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[i][0]));
71251 +
71252 +               psCmdCompleteData->ui32AllocSize = ui32AllocSize;
71253 +       }
71254 +
71255 +       return PVRSRV_OK;
71256 +
71257 +ErrorExit:
71258 +
71259 +
71260 +
71261 +       if(psSysData->ppsCmdCompleteData[ui32DevIndex] != IMG_NULL)
71262 +       {
71263 +               for (i=0; i<ui32CmdCount; i++)
71264 +               {
71265 +                       if (psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
71266 +                       {
71267 +                               ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
71268 +                                                         + ((ui32MaxSyncsPerCmd[i][0]
71269 +                                                         +     ui32MaxSyncsPerCmd[i][1])
71270 +                                                         * sizeof(PVRSRV_SYNC_OBJECT));
71271 +                               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex][i], IMG_NULL);
71272 +                               psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
71273 +                       }
71274 +               }
71275 +               ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
71276 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL);
71277 +               psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
71278 +       }
71279 +
71280 +       if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
71281 +       {
71282 +               ui32AllocSize = ui32CmdCount * sizeof(PFN_CMD_PROC);
71283 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL);
71284 +               psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;
71285 +       }
71286 +
71287 +       return eError;
71288 +}
71289 +
71290 +
71291 +IMG_EXPORT
71292 +PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
71293 +                                                                          IMG_UINT32 ui32CmdCount)
71294 +{
71295 +       SYS_DATA                *psSysData;
71296 +       IMG_UINT32              i;
71297 +
71298 +
71299 +       if(ui32DevIndex >= SYS_DEVICE_COUNT)
71300 +       {
71301 +               PVR_DPF((PVR_DBG_ERROR,
71302 +                                       "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
71303 +                                       ui32DevIndex));
71304 +               return PVRSRV_ERROR_INVALID_PARAMS;
71305 +       }
71306 +
71307 +
71308 +       SysAcquireData(&psSysData);
71309 +
71310 +       if(psSysData->ppsCmdCompleteData[ui32DevIndex] == IMG_NULL)
71311 +       {
71312 +               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveCmdProcListKM: Invalid command array"));
71313 +               return PVRSRV_ERROR_INVALID_PARAMS;
71314 +       }
71315 +       else
71316 +       {
71317 +               for(i=0; i<ui32CmdCount; i++)
71318 +               {
71319 +
71320 +                       if(psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
71321 +                       {
71322 +                               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
71323 +                                                psSysData->ppsCmdCompleteData[ui32DevIndex][i]->ui32AllocSize,
71324 +                                                psSysData->ppsCmdCompleteData[ui32DevIndex][i],
71325 +                                                IMG_NULL);
71326 +                               psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
71327 +                       }
71328 +               }
71329 +
71330 +
71331 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
71332 +                                ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*),
71333 +                                psSysData->ppsCmdCompleteData[ui32DevIndex],
71334 +                                IMG_NULL);
71335 +               psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
71336 +       }
71337 +
71338 +
71339 +       if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
71340 +       {
71341 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
71342 +                                ui32CmdCount * sizeof(PFN_CMD_PROC),
71343 +                                psSysData->ppfnCmdProcList[ui32DevIndex],
71344 +                                IMG_NULL);
71345 +               psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;
71346 +       }
71347 +
71348 +       return PVRSRV_OK;
71349 +}
71350 +
71351 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/ra.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/ra.c
71352 new file mode 100644
71353 index 0000000..d4eab59
71354 --- /dev/null
71355 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/ra.c
71356 @@ -0,0 +1,1871 @@
71357 +/**********************************************************************
71358 + *
71359 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
71360 + *
71361 + * This program is free software; you can redistribute it and/or modify it
71362 + * under the terms and conditions of the GNU General Public License,
71363 + * version 2, as published by the Free Software Foundation.
71364 + *
71365 + * This program is distributed in the hope it will be useful but, except
71366 + * as otherwise stated in writing, without any warranty; without even the
71367 + * implied warranty of merchantability or fitness for a particular purpose.
71368 + * See the GNU General Public License for more details.
71369 + *
71370 + * You should have received a copy of the GNU General Public License along with
71371 + * this program; if not, write to the Free Software Foundation, Inc.,
71372 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
71373 + *
71374 + * The full GNU General Public License is included in this distribution in
71375 + * the file called "COPYING".
71376 + *
71377 + * Contact Information:
71378 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
71379 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
71380 + *
71381 + ******************************************************************************/
71382 +
71383 +#include "services_headers.h"
71384 +#include "hash.h"
71385 +#include "ra.h"
71386 +#include "buffer_manager.h"
71387 +#include "osfunc.h"
71388 +
71389 +#ifdef __linux__
71390 +#include <linux/kernel.h>
71391 +#include "proc.h"
71392 +#endif
71393 +
71394 +#ifdef USE_BM_FREESPACE_CHECK
71395 +#include <stdio.h>
71396 +#endif
71397 +
71398 +#define MINIMUM_HASH_SIZE (64)
71399 +
71400 +#if defined(VALIDATE_ARENA_TEST)
71401 +
71402 +typedef enum RESOURCE_DESCRIPTOR_TAG {
71403 +
71404 +       RESOURCE_SPAN_LIVE                              = 10,
71405 +       RESOURCE_SPAN_FREE,
71406 +       IMPORTED_RESOURCE_SPAN_START,
71407 +       IMPORTED_RESOURCE_SPAN_LIVE,
71408 +       IMPORTED_RESOURCE_SPAN_FREE,
71409 +       IMPORTED_RESOURCE_SPAN_END,
71410 +
71411 +} RESOURCE_DESCRIPTOR;
71412 +
71413 +typedef enum RESOURCE_TYPE_TAG {
71414 +
71415 +       IMPORTED_RESOURCE_TYPE          = 20,
71416 +       NON_IMPORTED_RESOURCE_TYPE
71417 +
71418 +} RESOURCE_TYPE;
71419 +
71420 +
71421 +static IMG_UINT32 ui32BoundaryTagID = 0;
71422 +
71423 +IMG_UINT32 ValidateArena(RA_ARENA *pArena);
71424 +#endif
71425 +
71426 +struct _BT_
71427 +{
71428 +       enum bt_type
71429 +       {
71430 +               btt_span,
71431 +               btt_free,
71432 +               btt_live
71433 +       } type;
71434 +
71435 +
71436 +       IMG_UINTPTR_T base;
71437 +       IMG_SIZE_T uSize;
71438 +
71439 +
71440 +       struct _BT_ *pNextSegment;
71441 +       struct _BT_ *pPrevSegment;
71442 +
71443 +       struct _BT_ *pNextFree;
71444 +       struct _BT_ *pPrevFree;
71445 +
71446 +       BM_MAPPING *psMapping;
71447 +
71448 +#if defined(VALIDATE_ARENA_TEST)
71449 +       RESOURCE_DESCRIPTOR eResourceSpan;
71450 +       RESOURCE_TYPE           eResourceType;
71451 +
71452 +
71453 +       IMG_UINT32                      ui32BoundaryTagID;
71454 +#endif
71455 +
71456 +};
71457 +typedef struct _BT_ BT;
71458 +
71459 +
71460 +struct _RA_ARENA_
71461 +{
71462 +
71463 +       IMG_CHAR *name;
71464 +
71465 +
71466 +       IMG_SIZE_T uQuantum;
71467 +
71468 +
71469 +       IMG_BOOL (*pImportAlloc)(IMG_VOID *,
71470 +                                                        IMG_SIZE_T uSize,
71471 +                                                        IMG_SIZE_T *pActualSize,
71472 +                                                        BM_MAPPING **ppsMapping,
71473 +                                                        IMG_UINT32 uFlags,
71474 +                                                        IMG_UINTPTR_T *pBase);
71475 +       IMG_VOID (*pImportFree) (IMG_VOID *,
71476 +                                                IMG_UINTPTR_T,
71477 +                                                BM_MAPPING *psMapping);
71478 +       IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE);
71479 +
71480 +
71481 +       IMG_VOID *pImportHandle;
71482 +
71483 +
71484 +#define FREE_TABLE_LIMIT 32
71485 +
71486 +
71487 +       BT *aHeadFree [FREE_TABLE_LIMIT];
71488 +
71489 +
71490 +       BT *pHeadSegment;
71491 +       BT *pTailSegment;
71492 +
71493 +
71494 +       HASH_TABLE *pSegmentHash;
71495 +
71496 +#ifdef RA_STATS
71497 +       RA_STATISTICS sStatistics;
71498 +#endif
71499 +
71500 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
71501 +#define PROC_NAME_SIZE         32
71502 +
71503 +#ifdef PVR_PROC_USE_SEQ_FILE
71504 +       struct proc_dir_entry* pProcInfo;
71505 +       struct proc_dir_entry* pProcSegs;
71506 +#else
71507 +       IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
71508 +       IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
71509 +#endif
71510 +
71511 +       IMG_BOOL bInitProcEntry;
71512 +#endif
71513 +};
71514 +#if defined(ENABLE_RA_DUMP)
71515 +IMG_VOID RA_Dump (RA_ARENA *pArena);
71516 +#endif
71517 +
71518 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
71519 +
71520 +#ifdef PVR_PROC_USE_SEQ_FILE
71521 +
71522 +static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el);
71523 +static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off);
71524 +
71525 +static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el);
71526 +static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off);
71527 +
71528 +#else
71529 +static IMG_INT
71530 +RA_DumpSegs(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data);
71531 +static IMG_INT
71532 +RA_DumpInfo(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data);
71533 +#endif
71534 +
71535 +#endif
71536 +
71537 +#ifdef USE_BM_FREESPACE_CHECK
71538 +IMG_VOID CheckBMFreespace(IMG_VOID);
71539 +#endif
71540 +
71541 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
71542 +static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS)
71543 +{
71544 +       IMG_CHAR *pT;
71545 +
71546 +       for(pT = pS; *pT != 0; pT++)
71547 +       {
71548 +               if (*pT == ' ' || *pT == '\t')
71549 +               {
71550 +                       *pT = '_';
71551 +               }
71552 +       }
71553 +
71554 +       return pS;
71555 +}
71556 +#endif
71557 +
71558 +static IMG_BOOL
71559 +_RequestAllocFail (IMG_VOID *_h,
71560 +                                 IMG_SIZE_T _uSize,
71561 +                                 IMG_SIZE_T *_pActualSize,
71562 +                                 BM_MAPPING **_ppsMapping,
71563 +                                 IMG_UINT32 _uFlags,
71564 +                                 IMG_UINTPTR_T *_pBase)
71565 +{
71566 +       PVR_UNREFERENCED_PARAMETER (_h);
71567 +       PVR_UNREFERENCED_PARAMETER (_uSize);
71568 +       PVR_UNREFERENCED_PARAMETER (_pActualSize);
71569 +       PVR_UNREFERENCED_PARAMETER (_ppsMapping);
71570 +       PVR_UNREFERENCED_PARAMETER (_uFlags);
71571 +       PVR_UNREFERENCED_PARAMETER (_pBase);
71572 +
71573 +       return IMG_FALSE;
71574 +}
71575 +
71576 +static IMG_UINT32
71577 +pvr_log2 (IMG_SIZE_T n)
71578 +{
71579 +       IMG_UINT32 l = 0;
71580 +       n>>=1;
71581 +       while (n>0)
71582 +       {
71583 +               n>>=1;
71584 +               l++;
71585 +       }
71586 +       return l;
71587 +}
71588 +
71589 +static PVRSRV_ERROR
71590 +_SegmentListInsertAfter (RA_ARENA *pArena,
71591 +                                                BT *pInsertionPoint,
71592 +                                                BT *pBT)
71593 +{
71594 +       PVR_ASSERT (pArena != IMG_NULL);
71595 +       PVR_ASSERT (pInsertionPoint != IMG_NULL);
71596 +
71597 +       if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL))
71598 +       {
71599 +               PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters"));
71600 +               return PVRSRV_ERROR_INVALID_PARAMS;
71601 +       }
71602 +
71603 +       pBT->pNextSegment = pInsertionPoint->pNextSegment;
71604 +       pBT->pPrevSegment = pInsertionPoint;
71605 +       if (pInsertionPoint->pNextSegment == IMG_NULL)
71606 +               pArena->pTailSegment = pBT;
71607 +       else
71608 +               pInsertionPoint->pNextSegment->pPrevSegment = pBT;
71609 +       pInsertionPoint->pNextSegment = pBT;
71610 +
71611 +       return PVRSRV_OK;
71612 +}
71613 +
71614 +static PVRSRV_ERROR
71615 +_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
71616 +{
71617 +       PVRSRV_ERROR eError = PVRSRV_OK;
71618 +
71619 +
71620 +       if (pArena->pHeadSegment == IMG_NULL)
71621 +       {
71622 +               pArena->pHeadSegment = pArena->pTailSegment = pBT;
71623 +               pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL;
71624 +       }
71625 +       else
71626 +       {
71627 +               BT *pBTScan;
71628 +
71629 +               if (pBT->base < pArena->pHeadSegment->base)
71630 +               {
71631 +
71632 +                       pBT->pNextSegment = pArena->pHeadSegment;
71633 +                       pArena->pHeadSegment->pPrevSegment = pBT;
71634 +                       pArena->pHeadSegment = pBT;
71635 +                       pBT->pPrevSegment = IMG_NULL;
71636 +               }
71637 +               else
71638 +               {
71639 +
71640 +
71641 +
71642 +
71643 +                       pBTScan = pArena->pHeadSegment;
71644 +
71645 +                       while ((pBTScan->pNextSegment != IMG_NULL)  && (pBT->base >= pBTScan->pNextSegment->base))
71646 +                       {
71647 +                               pBTScan = pBTScan->pNextSegment;
71648 +                       }
71649 +
71650 +                       eError = _SegmentListInsertAfter (pArena, pBTScan, pBT);
71651 +                       if (eError != PVRSRV_OK)
71652 +                       {
71653 +                               return eError;
71654 +                       }
71655 +               }
71656 +       }
71657 +       return eError;
71658 +}
71659 +
71660 +static IMG_VOID
71661 +_SegmentListRemove (RA_ARENA *pArena, BT *pBT)
71662 +{
71663 +       if (pBT->pPrevSegment == IMG_NULL)
71664 +               pArena->pHeadSegment = pBT->pNextSegment;
71665 +       else
71666 +               pBT->pPrevSegment->pNextSegment = pBT->pNextSegment;
71667 +
71668 +       if (pBT->pNextSegment == IMG_NULL)
71669 +               pArena->pTailSegment = pBT->pPrevSegment;
71670 +       else
71671 +               pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment;
71672 +}
71673 +
71674 +static BT *
71675 +_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize)
71676 +{
71677 +       BT *pNeighbour;
71678 +
71679 +       PVR_ASSERT (pArena != IMG_NULL);
71680 +
71681 +       if (pArena == IMG_NULL)
71682 +       {
71683 +               PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena"));
71684 +               return IMG_NULL;
71685 +       }
71686 +
71687 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
71688 +                                       sizeof(BT),
71689 +                                       (IMG_VOID **)&pNeighbour, IMG_NULL,
71690 +                                       "Boundary Tag") != PVRSRV_OK)
71691 +       {
71692 +               return IMG_NULL;
71693 +       }
71694 +
71695 +       OSMemSet(pNeighbour, 0, sizeof(BT));
71696 +
71697 +#if defined(VALIDATE_ARENA_TEST)
71698 +       pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID;
71699 +#endif
71700 +
71701 +       pNeighbour->pPrevSegment = pBT;
71702 +       pNeighbour->pNextSegment = pBT->pNextSegment;
71703 +       if (pBT->pNextSegment == IMG_NULL)
71704 +               pArena->pTailSegment = pNeighbour;
71705 +       else
71706 +               pBT->pNextSegment->pPrevSegment = pNeighbour;
71707 +       pBT->pNextSegment = pNeighbour;
71708 +
71709 +       pNeighbour->type = btt_free;
71710 +       pNeighbour->uSize = pBT->uSize - uSize;
71711 +       pNeighbour->base = pBT->base + uSize;
71712 +       pNeighbour->psMapping = pBT->psMapping;
71713 +       pBT->uSize = uSize;
71714 +
71715 +#if defined(VALIDATE_ARENA_TEST)
71716 +       if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
71717 +       {
71718 +               pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE;
71719 +               pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
71720 +       }
71721 +       else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
71722 +       {
71723 +               pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
71724 +               pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE;
71725 +       }
71726 +       else
71727 +       {
71728 +               PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized"));
71729 +               PVR_DBG_BREAK;
71730 +       }
71731 +#endif
71732 +
71733 +       return pNeighbour;
71734 +}
71735 +
71736 +static IMG_VOID
71737 +_FreeListInsert (RA_ARENA *pArena, BT *pBT)
71738 +{
71739 +       IMG_UINT32 uIndex;
71740 +       uIndex = pvr_log2 (pBT->uSize);
71741 +       pBT->type = btt_free;
71742 +       pBT->pNextFree = pArena->aHeadFree [uIndex];
71743 +       pBT->pPrevFree = IMG_NULL;
71744 +       if (pArena->aHeadFree[uIndex] != IMG_NULL)
71745 +               pArena->aHeadFree[uIndex]->pPrevFree = pBT;
71746 +       pArena->aHeadFree [uIndex] = pBT;
71747 +}
71748 +
71749 +static IMG_VOID
71750 +_FreeListRemove (RA_ARENA *pArena, BT *pBT)
71751 +{
71752 +       IMG_UINT32 uIndex;
71753 +       uIndex = pvr_log2 (pBT->uSize);
71754 +       if (pBT->pNextFree != IMG_NULL)
71755 +               pBT->pNextFree->pPrevFree = pBT->pPrevFree;
71756 +       if (pBT->pPrevFree == IMG_NULL)
71757 +               pArena->aHeadFree[uIndex] = pBT->pNextFree;
71758 +       else
71759 +               pBT->pPrevFree->pNextFree = pBT->pNextFree;
71760 +}
71761 +
71762 +static BT *
71763 +_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
71764 +{
71765 +       BT *pBT;
71766 +
71767 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
71768 +                                       sizeof(BT),
71769 +                                       (IMG_VOID **)&pBT, IMG_NULL,
71770 +                                       "Boundary Tag") != PVRSRV_OK)
71771 +       {
71772 +               return IMG_NULL;
71773 +       }
71774 +
71775 +       OSMemSet(pBT, 0, sizeof(BT));
71776 +
71777 +#if defined(VALIDATE_ARENA_TEST)
71778 +       pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
71779 +#endif
71780 +
71781 +       pBT->type = btt_span;
71782 +       pBT->base = base;
71783 +       pBT->uSize = uSize;
71784 +       pBT->psMapping = IMG_NULL;
71785 +
71786 +       return pBT;
71787 +}
71788 +
71789 +static BT *
71790 +_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize)
71791 +{
71792 +       BT *pBT;
71793 +
71794 +       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
71795 +                                       sizeof(BT),
71796 +                                       (IMG_VOID **)&pBT, IMG_NULL,
71797 +                                       "Boundary Tag") != PVRSRV_OK)
71798 +       {
71799 +               return IMG_NULL;
71800 +       }
71801 +
71802 +       OSMemSet(pBT, 0, sizeof(BT));
71803 +
71804 +#if defined(VALIDATE_ARENA_TEST)
71805 +       pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
71806 +#endif
71807 +
71808 +       pBT->type = btt_free;
71809 +       pBT->base = base;
71810 +       pBT->uSize = uSize;
71811 +
71812 +       return pBT;
71813 +}
71814 +
71815 +static BT *
71816 +_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
71817 +{
71818 +       BT *pBT;
71819 +       PVR_ASSERT (pArena!=IMG_NULL);
71820 +       if (pArena == IMG_NULL)
71821 +       {
71822 +               PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena"));
71823 +               return IMG_NULL;
71824 +       }
71825 +
71826 +       pBT = _BuildBT (base, uSize);
71827 +       if (pBT != IMG_NULL)
71828 +       {
71829 +
71830 +#if defined(VALIDATE_ARENA_TEST)
71831 +               pBT->eResourceSpan = RESOURCE_SPAN_FREE;
71832 +               pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
71833 +#endif
71834 +
71835 +               if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK)
71836 +               {
71837 +                       PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed"));
71838 +                       return IMG_NULL;
71839 +               }
71840 +               _FreeListInsert (pArena, pBT);
71841 +#ifdef RA_STATS
71842 +               pArena->sStatistics.uTotalResourceCount+=uSize;
71843 +               pArena->sStatistics.uFreeResourceCount+=uSize;
71844 +               pArena->sStatistics.uSpanCount++;
71845 +#endif
71846 +       }
71847 +       return pBT;
71848 +}
71849 +
71850 +static BT *
71851 +_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
71852 +{
71853 +       PVRSRV_ERROR eError;
71854 +       BT *pSpanStart;
71855 +       BT *pSpanEnd;
71856 +       BT *pBT;
71857 +
71858 +       PVR_ASSERT (pArena != IMG_NULL);
71859 +       if (pArena == IMG_NULL)
71860 +       {
71861 +               PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena"));
71862 +               return IMG_NULL;
71863 +       }
71864 +
71865 +       PVR_DPF ((PVR_DBG_MESSAGE,
71866 +                         "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x",
71867 +                         pArena->name, base, uSize));
71868 +
71869 +       pSpanStart = _BuildSpanMarker (base, uSize);
71870 +       if (pSpanStart == IMG_NULL)
71871 +       {
71872 +               goto fail_start;
71873 +       }
71874 +
71875 +#if defined(VALIDATE_ARENA_TEST)
71876 +       pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
71877 +       pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
71878 +#endif
71879 +
71880 +       pSpanEnd = _BuildSpanMarker (base + uSize, 0);
71881 +       if (pSpanEnd == IMG_NULL)
71882 +       {
71883 +               goto fail_end;
71884 +       }
71885 +
71886 +#if defined(VALIDATE_ARENA_TEST)
71887 +       pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
71888 +       pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
71889 +#endif
71890 +
71891 +       pBT = _BuildBT (base, uSize);
71892 +       if (pBT == IMG_NULL)
71893 +       {
71894 +               goto fail_bt;
71895 +       }
71896 +
71897 +#if defined(VALIDATE_ARENA_TEST)
71898 +       pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
71899 +       pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
71900 +#endif
71901 +
71902 +       eError = _SegmentListInsert (pArena, pSpanStart);
71903 +       if (eError != PVRSRV_OK)
71904 +       {
71905 +               goto fail_SegListInsert;
71906 +       }
71907 +
71908 +       eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT);
71909 +       if (eError != PVRSRV_OK)
71910 +       {
71911 +               goto fail_SegListInsert;
71912 +       }
71913 +
71914 +       _FreeListInsert (pArena, pBT);
71915 +
71916 +       eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd);
71917 +       if (eError != PVRSRV_OK)
71918 +       {
71919 +               goto fail_SegListInsert;
71920 +       }
71921 +
71922 +#ifdef RA_STATS
71923 +       pArena->sStatistics.uTotalResourceCount+=uSize;
71924 +#endif
71925 +       return pBT;
71926 +
71927 +  fail_SegListInsert:
71928 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
71929 +
71930 +  fail_bt:
71931 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
71932 +
71933 +  fail_end:
71934 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
71935 +
71936 +  fail_start:
71937 +       return IMG_NULL;
71938 +}
71939 +
71940 +static IMG_VOID
71941 +_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore)
71942 +{
71943 +       BT *pNeighbour;
71944 +       IMG_UINTPTR_T uOrigBase;
71945 +       IMG_SIZE_T uOrigSize;
71946 +
71947 +       PVR_ASSERT (pArena!=IMG_NULL);
71948 +       PVR_ASSERT (pBT!=IMG_NULL);
71949 +
71950 +       if ((pArena == IMG_NULL) || (pBT == IMG_NULL))
71951 +       {
71952 +               PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter"));
71953 +               return;
71954 +       }
71955 +
71956 +#ifdef RA_STATS
71957 +       pArena->sStatistics.uLiveSegmentCount--;
71958 +       pArena->sStatistics.uFreeSegmentCount++;
71959 +       pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
71960 +#endif
71961 +
71962 +       uOrigBase = pBT->base;
71963 +       uOrigSize = pBT->uSize;
71964 +
71965 +
71966 +       pNeighbour = pBT->pPrevSegment;
71967 +       if (pNeighbour!=IMG_NULL
71968 +               && pNeighbour->type == btt_free
71969 +               && pNeighbour->base + pNeighbour->uSize == pBT->base)
71970 +       {
71971 +               _FreeListRemove (pArena, pNeighbour);
71972 +               _SegmentListRemove (pArena, pNeighbour);
71973 +               pBT->base = pNeighbour->base;
71974 +               pBT->uSize += pNeighbour->uSize;
71975 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
71976 +
71977 +#ifdef RA_STATS
71978 +               pArena->sStatistics.uFreeSegmentCount--;
71979 +#endif
71980 +       }
71981 +
71982 +
71983 +       pNeighbour = pBT->pNextSegment;
71984 +       if (pNeighbour!=IMG_NULL
71985 +               && pNeighbour->type == btt_free
71986 +               && pBT->base + pBT->uSize == pNeighbour->base)
71987 +       {
71988 +               _FreeListRemove (pArena, pNeighbour);
71989 +               _SegmentListRemove (pArena, pNeighbour);
71990 +               pBT->uSize += pNeighbour->uSize;
71991 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL);
71992 +
71993 +#ifdef RA_STATS
71994 +               pArena->sStatistics.uFreeSegmentCount--;
71995 +#endif
71996 +       }
71997 +
71998 +
71999 +       if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore)
72000 +       {
72001 +               IMG_UINTPTR_T   uRoundedStart, uRoundedEnd;
72002 +
72003 +
72004 +               uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
72005 +
72006 +               if (uRoundedStart < pBT->base)
72007 +               {
72008 +                       uRoundedStart += pArena->uQuantum;
72009 +               }
72010 +
72011 +
72012 +               uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum;
72013 +
72014 +               if (uRoundedEnd > (pBT->base + pBT->uSize))
72015 +               {
72016 +                       uRoundedEnd -= pArena->uQuantum;
72017 +               }
72018 +
72019 +               if (uRoundedStart < uRoundedEnd)
72020 +               {
72021 +                       pArena->pBackingStoreFree(pArena->pImportHandle, uRoundedStart, uRoundedEnd, (IMG_HANDLE)0);
72022 +               }
72023 +       }
72024 +
72025 +       if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span
72026 +               && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span)
72027 +       {
72028 +               BT *next = pBT->pNextSegment;
72029 +               BT *prev = pBT->pPrevSegment;
72030 +               _SegmentListRemove (pArena, next);
72031 +               _SegmentListRemove (pArena, prev);
72032 +               _SegmentListRemove (pArena, pBT);
72033 +               pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping);
72034 +#ifdef RA_STATS
72035 +               pArena->sStatistics.uSpanCount--;
72036 +               pArena->sStatistics.uExportCount++;
72037 +               pArena->sStatistics.uFreeSegmentCount--;
72038 +               pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
72039 +               pArena->sStatistics.uTotalResourceCount-=pBT->uSize;
72040 +#endif
72041 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL);
72042 +
72043 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
72044 +
72045 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
72046 +
72047 +       }
72048 +       else
72049 +               _FreeListInsert (pArena, pBT);
72050 +}
72051 +
72052 +
72053 +static IMG_BOOL
72054 +_AttemptAllocAligned (RA_ARENA *pArena,
72055 +                                         IMG_SIZE_T uSize,
72056 +                                         BM_MAPPING **ppsMapping,
72057 +                                         IMG_UINT32 uFlags,
72058 +                                         IMG_UINT32 uAlignment,
72059 +                                         IMG_UINT32 uAlignmentOffset,
72060 +                                         IMG_UINTPTR_T *base)
72061 +{
72062 +       IMG_UINT32 uIndex;
72063 +       PVR_ASSERT (pArena!=IMG_NULL);
72064 +       if (pArena == IMG_NULL)
72065 +       {
72066 +               PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
72067 +               return IMG_FALSE;
72068 +       }
72069 +
72070 +       if (uAlignment>1)
72071 +               uAlignmentOffset %= uAlignment;
72072 +
72073 +
72074 +
72075 +       uIndex = pvr_log2 (uSize);
72076 +
72077 +#if 0
72078 +
72079 +       if (1u<<uIndex < uSize)
72080 +               uIndex++;
72081 +#endif
72082 +
72083 +       while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
72084 +               uIndex++;
72085 +
72086 +       while (uIndex < FREE_TABLE_LIMIT)
72087 +       {
72088 +               if (pArena->aHeadFree[uIndex]!=IMG_NULL)
72089 +               {
72090 +
72091 +                       BT *pBT;
72092 +
72093 +                       pBT = pArena->aHeadFree [uIndex];
72094 +                       while (pBT!=IMG_NULL)
72095 +                       {
72096 +                               IMG_UINTPTR_T aligned_base;
72097 +
72098 +                               if (uAlignment>1)
72099 +                                       aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
72100 +                               else
72101 +                                       aligned_base = pBT->base;
72102 +                               PVR_DPF ((PVR_DBG_MESSAGE,
72103 +                                                 "RA_AttemptAllocAligned: pBT-base=0x%x "
72104 +                                                 "pBT-size=0x%x alignedbase=0x%x size=0x%x",
72105 +                                               pBT->base, pBT->uSize, aligned_base, uSize));
72106 +
72107 +                               if (pBT->base + pBT->uSize >= aligned_base + uSize)
72108 +                               {
72109 +                                       if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
72110 +                                       {
72111 +                                               _FreeListRemove (pArena, pBT);
72112 +
72113 +                                               PVR_ASSERT (pBT->type == btt_free);
72114 +
72115 +#ifdef RA_STATS
72116 +                                               pArena->sStatistics.uLiveSegmentCount++;
72117 +                                               pArena->sStatistics.uFreeSegmentCount--;
72118 +                                               pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
72119 +#endif
72120 +
72121 +
72122 +                                               if (aligned_base > pBT->base)
72123 +                                               {
72124 +                                                       BT *pNeighbour;
72125 +
72126 +                                                       pNeighbour = _SegmentSplit (pArena, pBT, aligned_base-pBT->base);
72127 +
72128 +                                                       if (pNeighbour==IMG_NULL)
72129 +                                                       {
72130 +                                                               PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
72131 +
72132 +                                                               _FreeListInsert (pArena, pBT);
72133 +                                                               return IMG_FALSE;
72134 +                                                       }
72135 +
72136 +                                                       _FreeListInsert (pArena, pBT);
72137 +       #ifdef RA_STATS
72138 +                                                       pArena->sStatistics.uFreeSegmentCount++;
72139 +                                                       pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
72140 +       #endif
72141 +                                                       pBT = pNeighbour;
72142 +                                               }
72143 +
72144 +
72145 +                                               if (pBT->uSize > uSize)
72146 +                                               {
72147 +                                                       BT *pNeighbour;
72148 +                                                       pNeighbour = _SegmentSplit (pArena, pBT, uSize);
72149 +
72150 +                                                       if (pNeighbour==IMG_NULL)
72151 +                                                       {
72152 +                                                               PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
72153 +
72154 +                                                               _FreeListInsert (pArena, pBT);
72155 +                                                               return IMG_FALSE;
72156 +                                                       }
72157 +
72158 +                                                       _FreeListInsert (pArena, pNeighbour);
72159 +       #ifdef RA_STATS
72160 +                                                       pArena->sStatistics.uFreeSegmentCount++;
72161 +                                                       pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
72162 +       #endif
72163 +                                               }
72164 +
72165 +                                               pBT->type = btt_live;
72166 +
72167 +#if defined(VALIDATE_ARENA_TEST)
72168 +                                               if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
72169 +                                               {
72170 +                                                       pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
72171 +                                               }
72172 +                                               else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
72173 +                                               {
72174 +                                                       pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
72175 +                                               }
72176 +                                               else
72177 +                                               {
72178 +                                                       PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
72179 +                                                       PVR_DBG_BREAK;
72180 +                                               }
72181 +#endif
72182 +                                               if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
72183 +                                               {
72184 +                                                       _FreeBT (pArena, pBT, IMG_FALSE);
72185 +                                                       return IMG_FALSE;
72186 +                                               }
72187 +
72188 +                                               if (ppsMapping!=IMG_NULL)
72189 +                                                       *ppsMapping = pBT->psMapping;
72190 +
72191 +                                               *base = pBT->base;
72192 +
72193 +                                               return IMG_TRUE;
72194 +                                       }
72195 +                                       else
72196 +                                       {
72197 +                                               PVR_DPF ((PVR_DBG_MESSAGE,
72198 +                                                               "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));
72199 +
72200 +                                       }
72201 +                               }
72202 +                               pBT = pBT->pNextFree;
72203 +                       }
72204 +
72205 +               }
72206 +               uIndex++;
72207 +       }
72208 +
72209 +       return IMG_FALSE;
72210 +}
72211 +
72212 +
72213 +
72214 +RA_ARENA *
72215 +RA_Create (IMG_CHAR *name,
72216 +                  IMG_UINTPTR_T base,
72217 +                  IMG_SIZE_T uSize,
72218 +                  BM_MAPPING *psMapping,
72219 +                  IMG_SIZE_T uQuantum,
72220 +                  IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize,
72221 +                                    BM_MAPPING **ppsMapping, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase),
72222 +                  IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *),
72223 +                  IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE),
72224 +                  IMG_VOID *pImportHandle)
72225 +{
72226 +       RA_ARENA *pArena;
72227 +       BT *pBT;
72228 +       IMG_INT i;
72229 +
72230 +       PVR_DPF ((PVR_DBG_MESSAGE,
72231 +                         "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x",
72232 +                         name, base, uSize, imp_alloc, imp_free));
72233 +
72234 +
72235 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
72236 +                                        sizeof (*pArena),
72237 +                                        (IMG_VOID **)&pArena, IMG_NULL,
72238 +                                        "Resource Arena") != PVRSRV_OK)
72239 +       {
72240 +               goto arena_fail;
72241 +       }
72242 +
72243 +       pArena->name = name;
72244 +       pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : _RequestAllocFail;
72245 +       pArena->pImportFree = imp_free;
72246 +       pArena->pBackingStoreFree = backingstore_free;
72247 +       pArena->pImportHandle = pImportHandle;
72248 +       for (i=0; i<FREE_TABLE_LIMIT; i++)
72249 +               pArena->aHeadFree[i] = IMG_NULL;
72250 +       pArena->pHeadSegment = IMG_NULL;
72251 +       pArena->pTailSegment = IMG_NULL;
72252 +       pArena->uQuantum = uQuantum;
72253 +
72254 +#ifdef RA_STATS
72255 +       pArena->sStatistics.uSpanCount = 0;
72256 +       pArena->sStatistics.uLiveSegmentCount = 0;
72257 +       pArena->sStatistics.uFreeSegmentCount = 0;
72258 +       pArena->sStatistics.uFreeResourceCount = 0;
72259 +       pArena->sStatistics.uTotalResourceCount = 0;
72260 +       pArena->sStatistics.uCumulativeAllocs = 0;
72261 +       pArena->sStatistics.uCumulativeFrees = 0;
72262 +       pArena->sStatistics.uImportCount = 0;
72263 +       pArena->sStatistics.uExportCount = 0;
72264 +#endif
72265 +
72266 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
72267 +       if(strcmp(pArena->name,"") != 0)
72268 +       {
72269 +
72270 +#ifndef PVR_PROC_USE_SEQ_FILE
72271 +               IMG_INT ret;
72272 +               IMG_INT (*pfnCreateProcEntry)(const IMG_CHAR *, read_proc_t, write_proc_t, IMG_VOID *);
72273 +
72274 +               pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
72275 +
72276 +
72277 +               pfnCreateProcEntry = pArena->bInitProcEntry ? CreateProcEntry : CreatePerProcessProcEntry;
72278 +
72279 +               ret = snprintf(pArena->szProcInfoName, sizeof(pArena->szProcInfoName), "ra_info_%s", pArena->name);
72280 +               if (ret > 0 && ret < sizeof(pArena->szProcInfoName))
72281 +               {
72282 +                       (IMG_VOID) pfnCreateProcEntry(ReplaceSpaces(pArena->szProcInfoName), RA_DumpInfo, 0, pArena);
72283 +               }
72284 +               else
72285 +               {
72286 +                       pArena->szProcInfoName[0] = 0;
72287 +                       PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
72288 +               }
72289 +
72290 +               ret = snprintf(pArena->szProcSegsName, sizeof(pArena->szProcSegsName), "ra_segs_%s", pArena->name);
72291 +               if (ret > 0 && ret < sizeof(pArena->szProcSegsName))
72292 +               {
72293 +                       (IMG_VOID) pfnCreateProcEntry(ReplaceSpaces(pArena->szProcSegsName), RA_DumpSegs, 0, pArena);
72294 +               }
72295 +               else
72296 +               {
72297 +                       pArena->szProcSegsName[0] = 0;
72298 +                       PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
72299 +               }
72300 +#else
72301 +
72302 +               IMG_INT ret;
72303 +               IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
72304 +               IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
72305 +               struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *,
72306 +                                                                                IMG_VOID*,
72307 +                                                                                pvr_next_proc_seq_t,
72308 +                                                                                pvr_show_proc_seq_t,
72309 +                                                                                pvr_off2element_proc_seq_t,
72310 +                                                                                pvr_startstop_proc_seq_t,
72311 +                                                                                write_proc_t);
72312 +
72313 +               pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
72314 +
72315 +
72316 +               pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq;
72317 +
72318 +               ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name);
72319 +               if (ret > 0 && ret < sizeof(szProcInfoName))
72320 +               {
72321 +                       pArena->pProcInfo =  pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL,
72322 +                                                                                        RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL);
72323 +               }
72324 +               else
72325 +               {
72326 +                       pArena->pProcInfo = 0;
72327 +                       PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
72328 +               }
72329 +
72330 +               ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name);
72331 +               if (ret > 0 && ret < sizeof(szProcInfoName))
72332 +               {
72333 +                       pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
72334 +                                                                                        RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL);
72335 +               }
72336 +               else
72337 +               {
72338 +                       pArena->pProcSegs = 0;
72339 +                       PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
72340 +               }
72341 +
72342 +#endif
72343 +
72344 +       }
72345 +#endif
72346 +
72347 +       pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE);
72348 +       if (pArena->pSegmentHash==IMG_NULL)
72349 +       {
72350 +               goto hash_fail;
72351 +       }
72352 +       if (uSize>0)
72353 +       {
72354 +               uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum;
72355 +               pBT = _InsertResource (pArena, base, uSize);
72356 +               if (pBT == IMG_NULL)
72357 +               {
72358 +                       goto insert_fail;
72359 +               }
72360 +               pBT->psMapping = psMapping;
72361 +
72362 +       }
72363 +       return pArena;
72364 +
72365 +insert_fail:
72366 +       HASH_Delete (pArena->pSegmentHash);
72367 +hash_fail:
72368 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
72369 +
72370 +arena_fail:
72371 +       return IMG_NULL;
72372 +}
72373 +
72374 +IMG_VOID
72375 +RA_Delete (RA_ARENA *pArena)
72376 +{
72377 +       IMG_UINT32 uIndex;
72378 +
72379 +       PVR_ASSERT(pArena != IMG_NULL);
72380 +
72381 +       if (pArena == IMG_NULL)
72382 +       {
72383 +               PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena"));
72384 +               return;
72385 +       }
72386 +
72387 +       PVR_DPF ((PVR_DBG_MESSAGE,
72388 +                         "RA_Delete: name='%s'", pArena->name));
72389 +
72390 +       for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++)
72391 +               pArena->aHeadFree[uIndex] = IMG_NULL;
72392 +
72393 +       while (pArena->pHeadSegment != IMG_NULL)
72394 +       {
72395 +               BT *pBT = pArena->pHeadSegment;
72396 +
72397 +               if (pBT->type != btt_free)
72398 +               {
72399 +                       PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed"));
72400 +                       PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
72401 +                       PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
72402 +               }
72403 +
72404 +               _SegmentListRemove (pArena, pBT);
72405 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
72406 +
72407 +#ifdef RA_STATS
72408 +               pArena->sStatistics.uSpanCount--;
72409 +#endif
72410 +       }
72411 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
72412 +       {
72413 +
72414 +#ifdef PVR_PROC_USE_SEQ_FILE
72415 +               IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*);
72416 +
72417 +               pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq;
72418 +
72419 +               if (pArena->pProcInfo != 0)
72420 +               {
72421 +                       pfnRemoveProcEntrySeq( pArena->pProcInfo );
72422 +               }
72423 +
72424 +               if (pArena->pProcSegs != 0)
72425 +               {
72426 +                       pfnRemoveProcEntrySeq( pArena->pProcSegs );
72427 +               }
72428 +
72429 +#else
72430 +               IMG_VOID (*pfnRemoveProcEntry)(const IMG_CHAR *);
72431 +
72432 +               pfnRemoveProcEntry = pArena->bInitProcEntry ? RemoveProcEntry : RemovePerProcessProcEntry;
72433 +
72434 +               if (pArena->szProcInfoName[0] != 0)
72435 +               {
72436 +                       pfnRemoveProcEntry(pArena->szProcInfoName);
72437 +               }
72438 +
72439 +               if (pArena->szProcSegsName[0] != 0)
72440 +               {
72441 +                       pfnRemoveProcEntry(pArena->szProcSegsName);
72442 +               }
72443 +
72444 +#endif
72445 +       }
72446 +#endif
72447 +       HASH_Delete (pArena->pSegmentHash);
72448 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
72449 +
72450 +}
72451 +
72452 +IMG_BOOL
72453 +RA_TestDelete (RA_ARENA *pArena)
72454 +{
72455 +       PVR_ASSERT(pArena != IMG_NULL);
72456 +
72457 +       if (pArena != IMG_NULL)
72458 +       {
72459 +               while (pArena->pHeadSegment != IMG_NULL)
72460 +               {
72461 +                       BT *pBT = pArena->pHeadSegment;
72462 +                       if (pBT->type != btt_free)
72463 +                       {
72464 +                               PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!"));
72465 +                               PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
72466 +                               return IMG_FALSE;
72467 +                       }
72468 +               }
72469 +       }
72470 +
72471 +       return IMG_TRUE;
72472 +}
72473 +
72474 +IMG_BOOL
72475 +RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize)
72476 +{
72477 +       PVR_ASSERT (pArena != IMG_NULL);
72478 +
72479 +       if (pArena == IMG_NULL)
72480 +       {
72481 +               PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena"));
72482 +               return IMG_FALSE;
72483 +       }
72484 +
72485 +       PVR_DPF ((PVR_DBG_MESSAGE,
72486 +                         "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize));
72487 +
72488 +       uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum;
72489 +       return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL));
72490 +}
72491 +
72492 +IMG_BOOL
72493 +RA_Alloc (RA_ARENA *pArena,
72494 +                 IMG_SIZE_T uRequestSize,
72495 +                 IMG_SIZE_T *pActualSize,
72496 +                 BM_MAPPING **ppsMapping,
72497 +                 IMG_UINT32 uFlags,
72498 +                 IMG_UINT32 uAlignment,
72499 +                 IMG_UINT32 uAlignmentOffset,
72500 +                 IMG_UINTPTR_T *base)
72501 +{
72502 +       IMG_BOOL bResult;
72503 +       IMG_SIZE_T uSize = uRequestSize;
72504 +
72505 +       PVR_ASSERT (pArena!=IMG_NULL);
72506 +
72507 +       if (pArena == IMG_NULL)
72508 +       {
72509 +               PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena"));
72510 +               return IMG_FALSE;
72511 +       }
72512 +
72513 +#if defined(VALIDATE_ARENA_TEST)
72514 +       ValidateArena(pArena);
72515 +#endif
72516 +
72517 +#ifdef USE_BM_FREESPACE_CHECK
72518 +       CheckBMFreespace();
72519 +#endif
72520 +
72521 +       if (pActualSize != IMG_NULL)
72522 +       {
72523 +               *pActualSize = uSize;
72524 +       }
72525 +
72526 +       PVR_DPF ((PVR_DBG_MESSAGE,
72527 +                         "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x",
72528 +                  pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset));
72529 +
72530 +
72531 +
72532 +       bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags,
72533 +                                                                       uAlignment, uAlignmentOffset, base);
72534 +       if (!bResult)
72535 +       {
72536 +               BM_MAPPING *psImportMapping;
72537 +               IMG_UINTPTR_T import_base;
72538 +               IMG_SIZE_T uImportSize = uSize;
72539 +
72540 +
72541 +
72542 +
72543 +               if (uAlignment > pArena->uQuantum)
72544 +               {
72545 +                       uImportSize += (uAlignment - 1);
72546 +               }
72547 +
72548 +
72549 +               uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
72550 +
72551 +               bResult =
72552 +                       pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
72553 +                                                                &psImportMapping, uFlags, &import_base);
72554 +               if (bResult)
72555 +               {
72556 +                       BT *pBT;
72557 +                       pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
72558 +
72559 +                       if (pBT == IMG_NULL)
72560 +                       {
72561 +
72562 +                               pArena->pImportFree(pArena->pImportHandle, import_base,
72563 +                                                                       psImportMapping);
72564 +                               PVR_DPF ((PVR_DBG_MESSAGE,
72565 +                                                 "RA_Alloc: name='%s', size=0x%x failed!",
72566 +                                                 pArena->name, uSize));
72567 +
72568 +                               return IMG_FALSE;
72569 +                       }
72570 +                       pBT->psMapping = psImportMapping;
72571 +#ifdef RA_STATS
72572 +                       pArena->sStatistics.uFreeSegmentCount++;
72573 +                       pArena->sStatistics.uFreeResourceCount += uImportSize;
72574 +                       pArena->sStatistics.uImportCount++;
72575 +                       pArena->sStatistics.uSpanCount++;
72576 +#endif
72577 +                       bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags,
72578 +                                                                                  uAlignment, uAlignmentOffset,
72579 +                                                                                  base);
72580 +                       if (!bResult)
72581 +                       {
72582 +                               PVR_DPF ((PVR_DBG_MESSAGE,
72583 +                                                 "RA_Alloc: name='%s' uAlignment failed!",
72584 +                                                 pArena->name));
72585 +                       }
72586 +               }
72587 +       }
72588 +#ifdef RA_STATS
72589 +       if (bResult)
72590 +               pArena->sStatistics.uCumulativeAllocs++;
72591 +#endif
72592 +
72593 +       PVR_DPF ((PVR_DBG_MESSAGE,
72594 +                         "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d",
72595 +                         pArena->name, uSize, *base, bResult));
72596 +
72597 +
72598 +
72599 +#if defined(VALIDATE_ARENA_TEST)
72600 +       ValidateArena(pArena);
72601 +#endif
72602 +
72603 +       return bResult;
72604 +}
72605 +
72606 +
72607 +#if defined(VALIDATE_ARENA_TEST)
72608 +
72609 +IMG_UINT32 ValidateArena(RA_ARENA *pArena)
72610 +{
72611 +       BT* pSegment;
72612 +       RESOURCE_DESCRIPTOR eNextSpan;
72613 +
72614 +       pSegment = pArena->pHeadSegment;
72615 +
72616 +       if (pSegment == IMG_NULL)
72617 +       {
72618 +               return 0;
72619 +       }
72620 +
72621 +       if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
72622 +       {
72623 +               PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START);
72624 +
72625 +               while (pSegment->pNextSegment)
72626 +               {
72627 +                       eNextSpan = pSegment->pNextSegment->eResourceSpan;
72628 +
72629 +                       switch (pSegment->eResourceSpan)
72630 +                       {
72631 +                               case IMPORTED_RESOURCE_SPAN_LIVE:
72632 +
72633 +                                       if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
72634 +                                                 (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
72635 +                                                 (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
72636 +                                       {
72637 +
72638 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72639 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72640 +
72641 +                                               PVR_DBG_BREAK;
72642 +                                       }
72643 +                               break;
72644 +
72645 +                               case IMPORTED_RESOURCE_SPAN_FREE:
72646 +
72647 +                                       if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
72648 +                                                 (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
72649 +                                       {
72650 +
72651 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72652 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72653 +
72654 +                                               PVR_DBG_BREAK;
72655 +                                       }
72656 +                               break;
72657 +
72658 +                               case IMPORTED_RESOURCE_SPAN_END:
72659 +
72660 +                                       if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
72661 +                                               (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
72662 +                                               (eNextSpan == IMPORTED_RESOURCE_SPAN_END))
72663 +                                       {
72664 +
72665 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72666 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72667 +
72668 +                                               PVR_DBG_BREAK;
72669 +                                       }
72670 +                               break;
72671 +
72672 +
72673 +                               case IMPORTED_RESOURCE_SPAN_START:
72674 +
72675 +                                       if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
72676 +                                                 (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE)))
72677 +                                       {
72678 +
72679 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72680 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72681 +
72682 +                                               PVR_DBG_BREAK;
72683 +                                       }
72684 +                               break;
72685 +
72686 +                               default:
72687 +                                       PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72688 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72689 +
72690 +                                       PVR_DBG_BREAK;
72691 +                               break;
72692 +                       }
72693 +                       pSegment = pSegment->pNextSegment;
72694 +               }
72695 +       }
72696 +       else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
72697 +       {
72698 +               PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE));
72699 +
72700 +               while (pSegment->pNextSegment)
72701 +               {
72702 +                       eNextSpan = pSegment->pNextSegment->eResourceSpan;
72703 +
72704 +                       switch (pSegment->eResourceSpan)
72705 +                       {
72706 +                               case RESOURCE_SPAN_LIVE:
72707 +
72708 +                                       if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
72709 +                                                 (eNextSpan == RESOURCE_SPAN_LIVE)))
72710 +                                       {
72711 +
72712 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72713 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72714 +
72715 +                                               PVR_DBG_BREAK;
72716 +                                       }
72717 +                               break;
72718 +
72719 +                               case RESOURCE_SPAN_FREE:
72720 +
72721 +                                       if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
72722 +                                                 (eNextSpan == RESOURCE_SPAN_LIVE)))
72723 +                                       {
72724 +
72725 +                                               PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72726 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72727 +
72728 +                                               PVR_DBG_BREAK;
72729 +                                       }
72730 +                               break;
72731 +
72732 +                               default:
72733 +                                       PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
72734 +                                                               pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
72735 +
72736 +                                       PVR_DBG_BREAK;
72737 +                               break;
72738 +                       }
72739 +                       pSegment = pSegment->pNextSegment;
72740 +               }
72741 +
72742 +       }
72743 +       else
72744 +       {
72745 +               PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized"));
72746 +
72747 +               PVR_DBG_BREAK;
72748 +       }
72749 +
72750 +       return 0;
72751 +}
72752 +
72753 +#endif
72754 +
72755 +
72756 +IMG_VOID
72757 +RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore)
72758 +{
72759 +       BT *pBT;
72760 +
72761 +       PVR_ASSERT (pArena != IMG_NULL);
72762 +
72763 +       if (pArena == IMG_NULL)
72764 +       {
72765 +               PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena"));
72766 +               return;
72767 +       }
72768 +
72769 +#ifdef USE_BM_FREESPACE_CHECK
72770 +       CheckBMFreespace();
72771 +#endif
72772 +
72773 +       PVR_DPF ((PVR_DBG_MESSAGE,
72774 +                         "RA_Free: name='%s', base=0x%x", pArena->name, base));
72775 +
72776 +       pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base);
72777 +       PVR_ASSERT (pBT != IMG_NULL);
72778 +
72779 +       if (pBT)
72780 +       {
72781 +               PVR_ASSERT (pBT->base == base);
72782 +
72783 +#ifdef RA_STATS
72784 +               pArena->sStatistics.uCumulativeFrees++;
72785 +#endif
72786 +
72787 +#ifdef USE_BM_FREESPACE_CHECK
72788 +{
72789 +       IMG_BYTE* p;
72790 +       IMG_BYTE* endp;
72791 +
72792 +       p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
72793 +       endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize));
72794 +       while ((IMG_UINT32)p & 3)
72795 +       {
72796 +               *p++ = 0xAA;
72797 +       }
72798 +       while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc))
72799 +       {
72800 +               *(IMG_UINT32*)p = 0xAAAAAAAA;
72801 +               p += sizeof(IMG_UINT32);
72802 +       }
72803 +       while (p < endp)
72804 +       {
72805 +               *p++ = 0xAA;
72806 +       }
72807 +       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));
72808 +}
72809 +#endif
72810 +               _FreeBT (pArena, pBT, bFreeBackingStore);
72811 +       }
72812 +}
72813 +
72814 +
72815 +IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails)
72816 +{
72817 +       BT        *pBT;
72818 +
72819 +       if (psSegDetails->hSegment)
72820 +       {
72821 +               pBT = (BT *)psSegDetails->hSegment;
72822 +       }
72823 +       else
72824 +       {
72825 +               RA_ARENA *pArena = (RA_ARENA *)hArena;
72826 +
72827 +               pBT = pArena->pHeadSegment;
72828 +       }
72829 +
72830 +       while (pBT != IMG_NULL)
72831 +       {
72832 +               if (pBT->type == btt_live)
72833 +               {
72834 +                       psSegDetails->uiSize = pBT->uSize;
72835 +                       psSegDetails->sCpuPhyAddr.uiAddr = pBT->base;
72836 +                       psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment;
72837 +
72838 +                       return IMG_TRUE;
72839 +               }
72840 +
72841 +               pBT = pBT->pNextSegment;
72842 +       }
72843 +
72844 +       psSegDetails->uiSize = 0;
72845 +       psSegDetails->sCpuPhyAddr.uiAddr = 0;
72846 +       psSegDetails->hSegment = (IMG_HANDLE)-1;
72847 +
72848 +       return IMG_FALSE;
72849 +}
72850 +
72851 +
72852 +#ifdef USE_BM_FREESPACE_CHECK
72853 +RA_ARENA* pJFSavedArena = IMG_NULL;
72854 +
72855 +IMG_VOID CheckBMFreespace(IMG_VOID)
72856 +{
72857 +       BT *pBT;
72858 +       IMG_BYTE* p;
72859 +       IMG_BYTE* endp;
72860 +
72861 +       if (pJFSavedArena != IMG_NULL)
72862 +       {
72863 +               for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
72864 +               {
72865 +                       if (pBT->type == btt_free)
72866 +                       {
72867 +                               p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset();
72868 +                               endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc);
72869 +
72870 +                               while ((IMG_UINT32)p & 3)
72871 +                               {
72872 +                                       if (*p++ != 0xAA)
72873 +                                       {
72874 +                                               fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
72875 +                                               for (;;);
72876 +                                               break;
72877 +                                       }
72878 +                               }
72879 +                               while (p < endp)
72880 +                               {
72881 +                                       if (*(IMG_UINT32*)p != 0xAAAAAAAA)
72882 +                                       {
72883 +                                               fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p);
72884 +                                               for (;;);
72885 +                                               break;
72886 +                                       }
72887 +                                       p += 4;
72888 +                               }
72889 +                       }
72890 +               }
72891 +       }
72892 +}
72893 +#endif
72894 +
72895 +
72896 +#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS)
72897 +static IMG_CHAR *
72898 +_BTType (IMG_INT eType)
72899 +{
72900 +       switch (eType)
72901 +       {
72902 +       case btt_span: return "span";
72903 +       case btt_free: return "free";
72904 +       case btt_live: return "live";
72905 +       }
72906 +       return "junk";
72907 +}
72908 +#endif
72909 +
72910 +#if defined(ENABLE_RA_DUMP)
72911 +IMG_VOID
72912 +RA_Dump (RA_ARENA *pArena)
72913 +{
72914 +       BT *pBT;
72915 +       PVR_ASSERT (pArena != IMG_NULL);
72916 +       PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name));
72917 +       PVR_DPF ((PVR_DBG_MESSAGE,"  alloc=%08X free=%08X handle=%08X quantum=%d",
72918 +                        pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle,
72919 +                        pArena->uQuantum));
72920 +       PVR_DPF ((PVR_DBG_MESSAGE,"  segment Chain:"));
72921 +       if (pArena->pHeadSegment != IMG_NULL &&
72922 +           pArena->pHeadSegment->pPrevSegment != IMG_NULL)
72923 +               PVR_DPF ((PVR_DBG_MESSAGE,"  error: head boundary tag has invalid pPrevSegment"));
72924 +       if (pArena->pTailSegment != IMG_NULL &&
72925 +           pArena->pTailSegment->pNextSegment != IMG_NULL)
72926 +               PVR_DPF ((PVR_DBG_MESSAGE,"  error: tail boundary tag has invalid pNextSegment"));
72927 +
72928 +       for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
72929 +       {
72930 +               PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s ref=%08X",
72931 +                                (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type),
72932 +                                pBT->pRef));
72933 +       }
72934 +
72935 +#ifdef HASH_TRACE
72936 +       HASH_Dump (pArena->pSegmentHash);
72937 +#endif
72938 +}
72939 +#endif
72940 +
72941 +
72942 +#if defined(CONFIG_PROC_FS) && defined(DEBUG)
72943 +
72944 +
72945 +#ifdef PVR_PROC_USE_SEQ_FILE
72946 +
72947 +static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el)
72948 +{
72949 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
72950 +       RA_ARENA *pArena = (RA_ARENA *)handlers->data;
72951 +       IMG_INT off = (IMG_INT)el;
72952 +
72953 +       switch (off)
72954 +       {
72955 +       case 1:
72956 +               seq_printf(sfile, "quantum\t\t\t%lu\n", pArena->uQuantum);
72957 +               break;
72958 +       case 2:
72959 +               seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
72960 +               break;
72961 +#ifdef RA_STATS
72962 +       case 3:
72963 +               seq_printf(sfile,"span count\t\t%lu\n", pArena->sStatistics.uSpanCount);
72964 +               break;
72965 +       case 4:
72966 +               seq_printf(sfile, "live segment count\t%lu\n", pArena->sStatistics.uLiveSegmentCount);
72967 +               break;
72968 +       case 5:
72969 +               seq_printf(sfile, "free segment count\t%lu\n", pArena->sStatistics.uFreeSegmentCount);
72970 +               break;
72971 +       case 6:
72972 +               seq_printf(sfile, "free resource count\t%lu (0x%x)\n",
72973 +                                                       pArena->sStatistics.uFreeResourceCount,
72974 +                                                       (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
72975 +               break;
72976 +       case 7:
72977 +               seq_printf(sfile, "total allocs\t\t%lu\n", pArena->sStatistics.uCumulativeAllocs);
72978 +               break;
72979 +       case 8:
72980 +               seq_printf(sfile, "total frees\t\t%lu\n", pArena->sStatistics.uCumulativeFrees);
72981 +               break;
72982 +       case 9:
72983 +               seq_printf(sfile, "import count\t\t%lu\n", pArena->sStatistics.uImportCount);
72984 +               break;
72985 +       case 10:
72986 +               seq_printf(sfile, "export count\t\t%lu\n", pArena->sStatistics.uExportCount);
72987 +               break;
72988 +#endif
72989 +       }
72990 +
72991 +}
72992 +
72993 +static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off)
72994 +{
72995 +#ifdef RA_STATS
72996 +       if(off <= 9)
72997 +#else
72998 +       if(off <= 1)
72999 +#endif
73000 +               return (void*)(IMG_INT)(off+1);
73001 +       return 0;
73002 +}
73003 +
73004 +static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el)
73005 +{
73006 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
73007 +       RA_ARENA *pArena = (RA_ARENA *)handlers->data;
73008 +       BT *pBT = (BT*)el;
73009 +
73010 +       if (el == PVR_PROC_SEQ_START_TOKEN)
73011 +       {
73012 +               seq_printf(sfile, "Arena \"%s\"\nBase         Size Type Ref\n", pArena->name);
73013 +               return;
73014 +       }
73015 +
73016 +       if (pBT)
73017 +       {
73018 +               seq_printf(sfile, "%08x %8x %4s %08x\n",
73019 +                                  (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
73020 +                              (IMG_UINT)pBT->psMapping);
73021 +       }
73022 +}
73023 +
73024 +static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off)
73025 +{
73026 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
73027 +       RA_ARENA *pArena = (RA_ARENA *)handlers->data;
73028 +       BT *pBT = 0;
73029 +
73030 +       if(off == 0)
73031 +               return PVR_PROC_SEQ_START_TOKEN;
73032 +
73033 +       for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment);
73034 +
73035 +       return (void*)pBT;
73036 +}
73037 +
73038 +
73039 +
73040 +#else
73041 +static IMG_INT
73042 +RA_DumpSegs(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
73043 +{
73044 +       BT *pBT = 0;
73045 +       IMG_INT len = 0;
73046 +       RA_ARENA *pArena = (RA_ARENA *)data;
73047 +
73048 +       if (count < 80)
73049 +       {
73050 +               *start = (IMG_CHAR *)0;
73051 +               return (0);
73052 +       }
73053 +       *eof = 0;
73054 +       *start = (IMG_CHAR *)1;
73055 +       if (off == 0)
73056 +       {
73057 +               return printAppend(page, count, 0, "Arena \"%s\"\nBase         Size Type Ref\n", pArena->name);
73058 +       }
73059 +       for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment)
73060 +               ;
73061 +       if (pBT)
73062 +       {
73063 +               len = printAppend(page, count, 0, "%08x %8x %4s %08x\n",
73064 +                                                       (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
73065 +                                                       (IMG_UINT)pBT->psMapping);
73066 +       }
73067 +       else
73068 +       {
73069 +               *eof = 1;
73070 +       }
73071 +       return (len);
73072 +}
73073 +
73074 +static IMG_INT
73075 +RA_DumpInfo(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
73076 +{
73077 +       IMG_INT len = 0;
73078 +       RA_ARENA *pArena = (RA_ARENA *)data;
73079 +
73080 +       if (count < 80)
73081 +       {
73082 +               *start = (IMG_CHAR *)0;
73083 +               return (0);
73084 +       }
73085 +       *eof = 0;
73086 +       switch (off)
73087 +       {
73088 +       case 0:
73089 +               len = printAppend(page, count, 0, "quantum\t\t\t%lu\n", pArena->uQuantum);
73090 +               break;
73091 +       case 1:
73092 +               len = printAppend(page, count, 0, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
73093 +               break;
73094 +#ifdef RA_STATS
73095 +       case 2:
73096 +               len = printAppend(page, count, 0, "span count\t\t%lu\n", pArena->sStatistics.uSpanCount);
73097 +               break;
73098 +       case 3:
73099 +               len = printAppend(page, count, 0, "live segment count\t%lu\n", pArena->sStatistics.uLiveSegmentCount);
73100 +               break;
73101 +       case 4:
73102 +               len = printAppend(page, count, 0, "free segment count\t%lu\n", pArena->sStatistics.uFreeSegmentCount);
73103 +               break;
73104 +       case 5:
73105 +               len = printAppend(page, count, 0, "free resource count\t%lu (0x%x)\n",
73106 +                                                       pArena->sStatistics.uFreeResourceCount,
73107 +                                                       (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
73108 +               break;
73109 +       case 6:
73110 +               len = printAppend(page, count, 0, "total allocs\t\t%lu\n", pArena->sStatistics.uCumulativeAllocs);
73111 +               break;
73112 +       case 7:
73113 +               len = printAppend(page, count, 0, "total frees\t\t%lu\n", pArena->sStatistics.uCumulativeFrees);
73114 +               break;
73115 +       case 8:
73116 +               len = printAppend(page, count, 0, "import count\t\t%lu\n", pArena->sStatistics.uImportCount);
73117 +               break;
73118 +       case 9:
73119 +               len = printAppend(page, count, 0, "export count\t\t%lu\n", pArena->sStatistics.uExportCount);
73120 +               break;
73121 +#endif
73122 +
73123 +       default:
73124 +               *eof = 1;
73125 +       }
73126 +       *start = (IMG_CHAR *)1;
73127 +       return (len);
73128 +}
73129 +#endif
73130 +#endif
73131 +
73132 +
73133 +#ifdef RA_STATS
73134 +PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
73135 +                                                       IMG_CHAR **ppszStr,
73136 +                                                       IMG_UINT32 *pui32StrLen)
73137 +{
73138 +       IMG_CHAR        *pszStr = *ppszStr;
73139 +       IMG_UINT32      ui32StrLen = *pui32StrLen;
73140 +       IMG_INT32       i32Count;
73141 +       BT                      *pBT;
73142 +
73143 +       CHECK_SPACE(ui32StrLen);
73144 +       i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name);
73145 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73146 +
73147 +
73148 +       CHECK_SPACE(ui32StrLen);
73149 +       i32Count = OSSNPrintf(pszStr, 100, "  allocCB=%08X freeCB=%08X handle=%08X quantum=%d\n",
73150 +                                                        pArena->pImportAlloc,
73151 +                                                        pArena->pImportFree,
73152 +                                                        pArena->pImportHandle,
73153 +                                                        pArena->uQuantum);
73154 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73155 +
73156 +       CHECK_SPACE(ui32StrLen);
73157 +       i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%lu\n", pArena->sStatistics.uSpanCount);
73158 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73159 +
73160 +       CHECK_SPACE(ui32StrLen);
73161 +       i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%lu\n", pArena->sStatistics.uLiveSegmentCount);
73162 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73163 +
73164 +       CHECK_SPACE(ui32StrLen);
73165 +       i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%lu\n", pArena->sStatistics.uFreeSegmentCount);
73166 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73167 +
73168 +       CHECK_SPACE(ui32StrLen);
73169 +       i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%lu (0x%x)\n",
73170 +                                                       pArena->sStatistics.uFreeResourceCount,
73171 +                                                       (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
73172 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73173 +
73174 +       CHECK_SPACE(ui32StrLen);
73175 +       i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%lu\n", pArena->sStatistics.uCumulativeAllocs);
73176 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73177 +
73178 +       CHECK_SPACE(ui32StrLen);
73179 +       i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%lu\n", pArena->sStatistics.uCumulativeFrees);
73180 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73181 +
73182 +       CHECK_SPACE(ui32StrLen);
73183 +       i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%lu\n", pArena->sStatistics.uImportCount);
73184 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73185 +
73186 +       CHECK_SPACE(ui32StrLen);
73187 +       i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%lu\n", pArena->sStatistics.uExportCount);
73188 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73189 +
73190 +       CHECK_SPACE(ui32StrLen);
73191 +       i32Count = OSSNPrintf(pszStr, 100, "  segment Chain:\n");
73192 +       UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73193 +
73194 +       if (pArena->pHeadSegment != IMG_NULL &&
73195 +           pArena->pHeadSegment->pPrevSegment != IMG_NULL)
73196 +       {
73197 +               CHECK_SPACE(ui32StrLen);
73198 +               i32Count = OSSNPrintf(pszStr, 100, "  error: head boundary tag has invalid pPrevSegment\n");
73199 +               UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73200 +       }
73201 +
73202 +       if (pArena->pTailSegment != IMG_NULL &&
73203 +           pArena->pTailSegment->pNextSegment != IMG_NULL)
73204 +       {
73205 +               CHECK_SPACE(ui32StrLen);
73206 +               i32Count = OSSNPrintf(pszStr, 100, "  error: tail boundary tag has invalid pNextSegment\n");
73207 +               UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73208 +       }
73209 +
73210 +       for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
73211 +       {
73212 +               CHECK_SPACE(ui32StrLen);
73213 +               i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%08X\n",
73214 +                                                                                        (IMG_UINT32) pBT->base,
73215 +                                                                                        pBT->uSize,
73216 +                                                                                        _BTType(pBT->type),
73217 +                                                                                        pBT->psMapping);
73218 +               UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
73219 +       }
73220 +
73221 +       *ppszStr = pszStr;
73222 +       *pui32StrLen = ui32StrLen;
73223 +
73224 +       return PVRSRV_OK;
73225 +}
73226 +#endif
73227 +
73228 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/resman.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/resman.c
73229 new file mode 100644
73230 index 0000000..3f7ff03
73231 --- /dev/null
73232 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/common/resman.c
73233 @@ -0,0 +1,717 @@
73234 +/**********************************************************************
73235 + *
73236 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
73237 + *
73238 + * This program is free software; you can redistribute it and/or modify it
73239 + * under the terms and conditions of the GNU General Public License,
73240 + * version 2, as published by the Free Software Foundation.
73241 + *
73242 + * This program is distributed in the hope it will be useful but, except
73243 + * as otherwise stated in writing, without any warranty; without even the
73244 + * implied warranty of merchantability or fitness for a particular purpose.
73245 + * See the GNU General Public License for more details.
73246 + *
73247 + * You should have received a copy of the GNU General Public License along with
73248 + * this program; if not, write to the Free Software Foundation, Inc.,
73249 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
73250 + *
73251 + * The full GNU General Public License is included in this distribution in
73252 + * the file called "COPYING".
73253 + *
73254 + * Contact Information:
73255 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
73256 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
73257 + *
73258 + ******************************************************************************/
73259 +
73260 +#include "services_headers.h"
73261 +#include "resman.h"
73262 +
73263 +#ifdef __linux__
73264 +#ifndef AUTOCONF_INCLUDED
73265 + #include <linux/config.h>
73266 +#endif
73267 +
73268 +#include <linux/version.h>
73269 +#include <linux/sched.h>
73270 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
73271 +#include <linux/hardirq.h>
73272 +#else
73273 +#include <asm/hardirq.h>
73274 +#endif
73275 +
73276 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
73277 +#include <linux/semaphore.h>
73278 +#else
73279 +#include <asm/semaphore.h>
73280 +#endif
73281 +
73282 +static DECLARE_MUTEX(lock);
73283 +
73284 +#define ACQUIRE_SYNC_OBJ  do {                                                 \
73285 +               if (in_interrupt()) {                                                   \
73286 +                       printk ("ISR cannot take RESMAN mutex\n");      \
73287 +                       BUG();                                                                          \
73288 +               }                                                                                               \
73289 +               else down (&lock);                                                              \
73290 +} while (0)
73291 +#define RELEASE_SYNC_OBJ up (&lock)
73292 +
73293 +#else
73294 +
73295 +#define ACQUIRE_SYNC_OBJ
73296 +#define RELEASE_SYNC_OBJ
73297 +
73298 +#endif
73299 +
73300 +#define RESMAN_SIGNATURE 0x12345678
73301 +
73302 +typedef struct _RESMAN_ITEM_
73303 +{
73304 +#ifdef DEBUG
73305 +       IMG_UINT32                              ui32Signature;
73306 +#endif
73307 +       struct _RESMAN_ITEM_    **ppsThis;
73308 +       struct _RESMAN_ITEM_    *psNext;
73309 +
73310 +       IMG_UINT32                              ui32Flags;
73311 +       IMG_UINT32                              ui32ResType;
73312 +
73313 +       IMG_PVOID                               pvParam;
73314 +       IMG_UINT32                              ui32Param;
73315 +
73316 +       RESMAN_FREE_FN                  pfnFreeResource;
73317 +} RESMAN_ITEM;
73318 +
73319 +
73320 +typedef struct _RESMAN_CONTEXT_
73321 +{
73322 +#ifdef DEBUG
73323 +       IMG_UINT32                                      ui32Signature;
73324 +#endif
73325 +       struct  _RESMAN_CONTEXT_        **ppsThis;
73326 +       struct  _RESMAN_CONTEXT_        *psNext;
73327 +
73328 +       PVRSRV_PER_PROCESS_DATA         *psPerProc;
73329 +
73330 +       RESMAN_ITEM                                     *psResItemList;
73331 +
73332 +} RESMAN_CONTEXT;
73333 +
73334 +
73335 +typedef struct
73336 +{
73337 +       RESMAN_CONTEXT  *psContextList;
73338 +
73339 +} RESMAN_LIST, *PRESMAN_LIST;
73340 +
73341 +
73342 +PRESMAN_LIST   gpsResList = IMG_NULL;
73343 +
73344 +#include "lists.h"
73345 +
73346 +static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
73347 +static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
73348 +static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
73349 +static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
73350 +
73351 +static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
73352 +static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
73353 +
73354 +
73355 +#define PRINT_RESLIST(x, y, z)
73356 +
73357 +static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback);
73358 +
73359 +static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT     psContext,
73360 +                                                                                  IMG_UINT32           ui32SearchCriteria,
73361 +                                                                                  IMG_UINT32           ui32ResType,
73362 +                                                                                  IMG_PVOID            pvParam,
73363 +                                                                                  IMG_UINT32           ui32Param,
73364 +                                                                                  IMG_BOOL                     bExecuteCallback);
73365 +
73366 +
73367 +#ifdef DEBUG
73368 +       static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
73369 +       #define VALIDATERESLIST() ValidateResList(gpsResList)
73370 +#else
73371 +       #define VALIDATERESLIST()
73372 +#endif
73373 +
73374 +
73375 +
73376 +
73377 +
73378 +
73379 +PVRSRV_ERROR ResManInit(IMG_VOID)
73380 +{
73381 +       if (gpsResList == IMG_NULL)
73382 +       {
73383 +
73384 +               if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
73385 +                                               sizeof(*gpsResList),
73386 +                                               (IMG_VOID **)&gpsResList, IMG_NULL,
73387 +                                               "Resource Manager List") != PVRSRV_OK)
73388 +               {
73389 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
73390 +               }
73391 +
73392 +
73393 +               gpsResList->psContextList = IMG_NULL;
73394 +
73395 +
73396 +               VALIDATERESLIST();
73397 +       }
73398 +
73399 +       return PVRSRV_OK;
73400 +}
73401 +
73402 +
73403 +IMG_VOID ResManDeInit(IMG_VOID)
73404 +{
73405 +       if (gpsResList != IMG_NULL)
73406 +       {
73407 +
73408 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
73409 +               gpsResList = IMG_NULL;
73410 +       }
73411 +}
73412 +
73413 +
73414 +PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE                    hPerProc,
73415 +                                                                PRESMAN_CONTEXT        *phResManContext)
73416 +{
73417 +       PVRSRV_ERROR    eError;
73418 +       PRESMAN_CONTEXT psResManContext;
73419 +
73420 +
73421 +       ACQUIRE_SYNC_OBJ;
73422 +
73423 +
73424 +       VALIDATERESLIST();
73425 +
73426 +
73427 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
73428 +                                               (IMG_VOID **)&psResManContext, IMG_NULL,
73429 +                                               "Resource Manager Context");
73430 +       if (eError != PVRSRV_OK)
73431 +       {
73432 +               PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
73433 +
73434 +
73435 +               VALIDATERESLIST();
73436 +
73437 +
73438 +               RELEASE_SYNC_OBJ;
73439 +
73440 +               return eError;
73441 +       }
73442 +
73443 +#ifdef DEBUG
73444 +       psResManContext->ui32Signature = RESMAN_SIGNATURE;
73445 +#endif
73446 +       psResManContext->psResItemList  = IMG_NULL;
73447 +       psResManContext->psPerProc = hPerProc;
73448 +
73449 +
73450 +       List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
73451 +
73452 +
73453 +       VALIDATERESLIST();
73454 +
73455 +
73456 +       RELEASE_SYNC_OBJ;
73457 +
73458 +       *phResManContext = psResManContext;
73459 +
73460 +       return PVRSRV_OK;
73461 +}
73462 +
73463 +
73464 +IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
73465 +                                                               IMG_BOOL                bKernelContext)
73466 +{
73467 +
73468 +       ACQUIRE_SYNC_OBJ;
73469 +
73470 +
73471 +       VALIDATERESLIST();
73472 +
73473 +
73474 +       PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
73475 +
73476 +
73477 +
73478 +       if (!bKernelContext)
73479 +       {
73480 +
73481 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
73482 +
73483 +
73484 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
73485 +
73486 +
73487 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
73488 +
73489 +
73490 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
73491 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
73492 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
73493 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
73494 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
73495 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
73496 +
73497 +               
73498 +               
73499 +               
73500 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
73501 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
73502 +
73503 +
73504 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
73505 +
73506 +
73507 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
73508 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
73509 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
73510 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
73511 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
73512 +               FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
73513 +       }
73514 +
73515 +
73516 +       PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
73517 +
73518 +
73519 +       List_RESMAN_CONTEXT_Remove(psResManContext);
73520 +
73521 +
73522 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
73523 +
73524 +
73525 +
73526 +
73527 +       VALIDATERESLIST();
73528 +
73529 +
73530 +       PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
73531 +
73532 +
73533 +       RELEASE_SYNC_OBJ;
73534 +}
73535 +
73536 +
73537 +PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext,
73538 +                                                          IMG_UINT32           ui32ResType,
73539 +                                                          IMG_PVOID            pvParam,
73540 +                                                          IMG_UINT32           ui32Param,
73541 +                                                          RESMAN_FREE_FN       pfnFreeResource)
73542 +{
73543 +       PRESMAN_ITEM    psNewResItem;
73544 +
73545 +       PVR_ASSERT(psResManContext != IMG_NULL);
73546 +       PVR_ASSERT(ui32ResType != 0);
73547 +
73548 +       if (psResManContext == IMG_NULL)
73549 +       {
73550 +               PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
73551 +               return (PRESMAN_ITEM) IMG_NULL;
73552 +       }
73553 +
73554 +
73555 +       ACQUIRE_SYNC_OBJ;
73556 +
73557 +
73558 +       VALIDATERESLIST();
73559 +
73560 +       PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
73561 +                       "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
73562 +                       "FreeFunc %08X",
73563 +                       psResManContext, ui32ResType, (IMG_UINT32)pvParam,
73564 +                       ui32Param, pfnFreeResource));
73565 +
73566 +
73567 +       if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
73568 +                                  sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
73569 +                                  IMG_NULL,
73570 +                                  "Resource Manager Item") != PVRSRV_OK)
73571 +       {
73572 +               PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
73573 +                               "ERROR allocating new resource item"));
73574 +
73575 +
73576 +               RELEASE_SYNC_OBJ;
73577 +
73578 +               return((PRESMAN_ITEM)IMG_NULL);
73579 +       }
73580 +
73581 +
73582 +#ifdef DEBUG
73583 +       psNewResItem->ui32Signature             = RESMAN_SIGNATURE;
73584 +#endif
73585 +       psNewResItem->ui32ResType               = ui32ResType;
73586 +       psNewResItem->pvParam                   = pvParam;
73587 +       psNewResItem->ui32Param                 = ui32Param;
73588 +       psNewResItem->pfnFreeResource   = pfnFreeResource;
73589 +       psNewResItem->ui32Flags             = 0;
73590 +
73591 +
73592 +       List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
73593 +
73594 +
73595 +       VALIDATERESLIST();
73596 +
73597 +
73598 +       RELEASE_SYNC_OBJ;
73599 +
73600 +       return(psNewResItem);
73601 +}
73602 +
73603 +PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM    *psResItem)
73604 +{
73605 +       PVRSRV_ERROR eError;
73606 +
73607 +       PVR_ASSERT(psResItem != IMG_NULL);
73608 +
73609 +       if (psResItem == IMG_NULL)
73610 +       {
73611 +               PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
73612 +               return PVRSRV_OK;
73613 +       }
73614 +
73615 +       PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X", psResItem));
73616 +
73617 +
73618 +       ACQUIRE_SYNC_OBJ;
73619 +
73620 +
73621 +       VALIDATERESLIST();
73622 +
73623 +
73624 +       eError = FreeResourceByPtr(psResItem, IMG_TRUE);
73625 +
73626 +
73627 +       VALIDATERESLIST();
73628 +
73629 +
73630 +       RELEASE_SYNC_OBJ;
73631 +
73632 +       return(eError);
73633 +}
73634 +
73635 +
73636 +PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT   psResManContext,
73637 +                                                                        IMG_UINT32                     ui32SearchCriteria,
73638 +                                                                        IMG_UINT32                     ui32ResType,
73639 +                                                                        IMG_PVOID                      pvParam,
73640 +                                                                        IMG_UINT32                     ui32Param)
73641 +{
73642 +       PVRSRV_ERROR    eError;
73643 +
73644 +       PVR_ASSERT(psResManContext != IMG_NULL);
73645 +
73646 +
73647 +       ACQUIRE_SYNC_OBJ;
73648 +
73649 +
73650 +       VALIDATERESLIST();
73651 +
73652 +       PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
73653 +                       "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
73654 +                       psResManContext, ui32SearchCriteria, ui32ResType,
73655 +                       (IMG_UINT32)pvParam, ui32Param));
73656 +
73657 +
73658 +       eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
73659 +                                                                       ui32ResType, pvParam, ui32Param,
73660 +                                                                       IMG_TRUE);
73661 +
73662 +
73663 +       VALIDATERESLIST();
73664 +
73665 +
73666 +       RELEASE_SYNC_OBJ;
73667 +
73668 +       return eError;
73669 +}
73670 +
73671 +
73672 +PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM           *psResItem,
73673 +                                                        PRESMAN_CONTEXT        psNewResManContext)
73674 +{
73675 +       PVRSRV_ERROR eError = PVRSRV_OK;
73676 +
73677 +       PVR_ASSERT(psResItem != IMG_NULL);
73678 +
73679 +       if (psResItem == IMG_NULL)
73680 +       {
73681 +               PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
73682 +               PVR_DBG_BREAK;
73683 +               return PVRSRV_ERROR_INVALID_PARAMS;
73684 +       }
73685 +
73686 +#ifdef DEBUG
73687 +       PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
73688 +#endif
73689 +
73690 +       if (psNewResManContext != IMG_NULL)
73691 +       {
73692 +
73693 +               List_RESMAN_ITEM_Remove(psResItem);
73694 +
73695 +
73696 +               List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
73697 +
73698 +       }
73699 +       else
73700 +       {
73701 +               eError = FreeResourceByPtr(psResItem, IMG_FALSE);
73702 +               if(eError != PVRSRV_OK)
73703 +               {
73704 +                       PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
73705 +                       return eError;
73706 +               }
73707 +       }
73708 +
73709 +       return eError;
73710 +}
73711 +
73712 +IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
73713 +{
73714 +       RESMAN_ITEM             *psItem;
73715 +
73716 +       psItem = va_arg(va, RESMAN_ITEM*);
73717 +
73718 +       return (IMG_BOOL)(psCurItem == psItem);
73719 +}
73720 +
73721 +
73722 +IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT      psResManContext,
73723 +                                                                                                 RESMAN_ITEM           *psItem)
73724 +{
73725 +       PVRSRV_ERROR    eResult;
73726 +
73727 +       PVR_ASSERT(psResManContext != IMG_NULL);
73728 +       PVR_ASSERT(psItem != IMG_NULL);
73729 +
73730 +       if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
73731 +       {
73732 +               PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
73733 +               PVR_DBG_BREAK;
73734 +               return PVRSRV_ERROR_INVALID_PARAMS;
73735 +       }
73736 +
73737 +#ifdef DEBUG
73738 +       PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
73739 +#endif
73740 +
73741 +
73742 +       ACQUIRE_SYNC_OBJ;
73743 +
73744 +       PVR_DPF((PVR_DBG_MESSAGE,
73745 +                       "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
73746 +                       psItem, psItem->psNext));
73747 +
73748 +       PVR_DPF((PVR_DBG_MESSAGE,
73749 +                       "FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, "
73750 +                       "Param 0x%x, FnCall %08X, Flags 0x%x",
73751 +                       psResManContext,
73752 +                       psItem->ui32ResType, (IMG_UINT32)psItem->pvParam, psItem->ui32Param,
73753 +                       psItem->pfnFreeResource, psItem->ui32Flags));
73754 +
73755 +
73756 +       if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
73757 +                                                                               ResManFindResourceByPtr_AnyVaCb,
73758 +                                                                               psItem))
73759 +       {
73760 +               eResult = PVRSRV_OK;
73761 +       }
73762 +       else
73763 +       {
73764 +               eResult = PVRSRV_ERROR_NOT_OWNER;
73765 +       }
73766 +
73767 +
73768 +       RELEASE_SYNC_OBJ;
73769 +
73770 +       return eResult;
73771 +}
73772 +
73773 +static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM      *psItem,
73774 +                                                                         IMG_BOOL              bExecuteCallback)
73775 +{
73776 +       PVRSRV_ERROR eError = PVRSRV_OK;
73777 +
73778 +       PVR_ASSERT(psItem != IMG_NULL);
73779 +
73780 +       if (psItem == IMG_NULL)
73781 +       {
73782 +               PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
73783 +               return PVRSRV_ERROR_INVALID_PARAMS;
73784 +       }
73785 +
73786 +#ifdef DEBUG
73787 +       PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
73788 +#endif
73789 +
73790 +       PVR_DPF((PVR_DBG_MESSAGE,
73791 +                       "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
73792 +                       psItem, psItem->psNext));
73793 +
73794 +       PVR_DPF((PVR_DBG_MESSAGE,
73795 +                       "FreeResourceByPtr: Type 0x%x, Addr 0x%x, "
73796 +                       "Param 0x%x, FnCall %08X, Flags 0x%x",
73797 +                       psItem->ui32ResType, (IMG_UINT32)psItem->pvParam, psItem->ui32Param,
73798 +                       psItem->pfnFreeResource, psItem->ui32Flags));
73799 +
73800 +
73801 +       List_RESMAN_ITEM_Remove(psItem);
73802 +
73803 +
73804 +
73805 +       RELEASE_SYNC_OBJ;
73806 +
73807 +
73808 +       if (bExecuteCallback)
73809 +       {
73810 +               eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param);
73811 +               if (eError != PVRSRV_OK)
73812 +               {
73813 +                       PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
73814 +               }
73815 +       }
73816 +
73817 +
73818 +       ACQUIRE_SYNC_OBJ;
73819 +
73820 +
73821 +       if(OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL) != PVRSRV_OK)
73822 +       {
73823 +               PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR freeing resource list item memory"));
73824 +               eError = PVRSRV_ERROR_GENERIC;
73825 +       }
73826 +
73827 +       return(eError);
73828 +}
73829 +
73830 +IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
73831 +{
73832 +       IMG_UINT32 ui32SearchCriteria;
73833 +       IMG_UINT32 ui32ResType;
73834 +       IMG_PVOID pvParam;
73835 +       IMG_UINT32 ui32Param;
73836 +
73837 +       ui32SearchCriteria = va_arg(va, IMG_UINT32);
73838 +       ui32ResType = va_arg(va, IMG_UINT32);
73839 +       pvParam = va_arg(va, IMG_PVOID);
73840 +       ui32Param = va_arg(va, IMG_UINT32);
73841 +
73842 +
73843 +       if(
73844 +
73845 +               (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
73846 +               (psCurItem->ui32ResType == ui32ResType))
73847 +       &&
73848 +
73849 +               (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
73850 +                        (psCurItem->pvParam == pvParam))
73851 +       &&
73852 +
73853 +               (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
73854 +                        (psCurItem->ui32Param == ui32Param))
73855 +               )
73856 +       {
73857 +               return psCurItem;
73858 +       }
73859 +       else
73860 +       {
73861 +               return IMG_NULL;
73862 +       }
73863 +}
73864 +
73865 +static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT     psResManContext,
73866 +                                                                                  IMG_UINT32           ui32SearchCriteria,
73867 +                                                                                  IMG_UINT32           ui32ResType,
73868 +                                                                                  IMG_PVOID            pvParam,
73869 +                                                                                  IMG_UINT32           ui32Param,
73870 +                                                                                  IMG_BOOL                     bExecuteCallback)
73871 +{
73872 +       PRESMAN_ITEM    psCurItem;
73873 +       PVRSRV_ERROR    eError = PVRSRV_OK;
73874 +
73875 +
73876 +
73877 +       while((psCurItem = (PRESMAN_ITEM)
73878 +                               List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
73879 +                                                                               FreeResourceByCriteria_AnyVaCb,
73880 +                                                                               ui32SearchCriteria,
73881 +                                                                               ui32ResType,
73882 +                                                                               pvParam,
73883 +                                                                               ui32Param)) != IMG_NULL
73884 +                       && eError == PVRSRV_OK)
73885 +       {
73886 +               eError = FreeResourceByPtr(psCurItem, bExecuteCallback);
73887 +       }
73888 +
73889 +       return eError;
73890 +}
73891 +
73892 +
73893 +#ifdef DEBUG
73894 +static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
73895 +{
73896 +       PRESMAN_ITEM    psCurItem, *ppsThisItem;
73897 +       PRESMAN_CONTEXT psCurContext, *ppsThisContext;
73898 +
73899 +
73900 +       if (psResList == IMG_NULL)
73901 +       {
73902 +               PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
73903 +               return;
73904 +       }
73905 +
73906 +       psCurContext = psResList->psContextList;
73907 +       ppsThisContext = &psResList->psContextList;
73908 +
73909 +
73910 +       while(psCurContext != IMG_NULL)
73911 +       {
73912 +
73913 +               PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
73914 +               if (psCurContext->ppsThis != ppsThisContext)
73915 +               {
73916 +                       PVR_DPF((PVR_DBG_WARNING,
73917 +                                       "psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X",
73918 +                                       psCurContext, psCurContext->ppsThis,
73919 +                                       psCurContext->psNext, ppsThisContext));
73920 +                       PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
73921 +               }
73922 +
73923 +
73924 +               psCurItem = psCurContext->psResItemList;
73925 +               ppsThisItem = &psCurContext->psResItemList;
73926 +               while(psCurItem != IMG_NULL)
73927 +               {
73928 +
73929 +                       PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
73930 +                       if (psCurItem->ppsThis != ppsThisItem)
73931 +                       {
73932 +                               PVR_DPF((PVR_DBG_WARNING,
73933 +                                               "psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X",
73934 +                                               psCurItem, psCurItem->ppsThis, psCurItem->psNext, ppsThisItem));
73935 +                               PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
73936 +                       }
73937 +
73938 +
73939 +                       ppsThisItem = &psCurItem->psNext;
73940 +                       psCurItem = psCurItem->psNext;
73941 +               }
73942 +
73943 +
73944 +               ppsThisContext = &psCurContext->psNext;
73945 +               psCurContext = psCurContext->psNext;
73946 +       }
73947 +}
73948 +#endif
73949 +
73950 +
73951 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/.gitignore
73952 new file mode 100644
73953 index 0000000..2f89523
73954 --- /dev/null
73955 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/.gitignore
73956 @@ -0,0 +1,5 @@
73957 +bin_pc_i686*
73958 +tmp_pc_i686*
73959 +host_pc_i686*
73960 +*.o
73961 +*.o.cmd
73962 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.c
73963 new file mode 100644
73964 index 0000000..7408661
73965 --- /dev/null
73966 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.c
73967 @@ -0,0 +1,2776 @@
73968 +/**********************************************************************
73969 + *
73970 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
73971 + *
73972 + * This program is free software; you can redistribute it and/or modify it
73973 + * under the terms and conditions of the GNU General Public License,
73974 + * version 2, as published by the Free Software Foundation.
73975 + *
73976 + * This program is distributed in the hope it will be useful but, except
73977 + * as otherwise stated in writing, without any warranty; without even the
73978 + * implied warranty of merchantability or fitness for a particular purpose.
73979 + * See the GNU General Public License for more details.
73980 + *
73981 + * You should have received a copy of the GNU General Public License along with
73982 + * this program; if not, write to the Free Software Foundation, Inc.,
73983 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
73984 + *
73985 + * The full GNU General Public License is included in this distribution in
73986 + * the file called "COPYING".
73987 + *
73988 + * Contact Information:
73989 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
73990 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
73991 + *
73992 + ******************************************************************************/
73993 +
73994 +#include "sgxdefs.h"
73995 +#include "sgxmmu.h"
73996 +#include "services_headers.h"
73997 +#include "buffer_manager.h"
73998 +#include "hash.h"
73999 +#include "ra.h"
74000 +#include "pdump_km.h"
74001 +#include "sgxapi_km.h"
74002 +#include "sgxinfo.h"
74003 +#include "sgxinfokm.h"
74004 +#include "mmu.h"
74005 +#include "sgxconfig.h"
74006 +
74007 +#define UINT32_MAX_VALUE       0xFFFFFFFFUL
74008 +
74009 +#define SGX_MAX_PD_ENTRIES     (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
74010 +
74011 +typedef struct _MMU_PT_INFO_
74012 +{
74013 +
74014 +       IMG_VOID *hPTPageOSMemHandle;
74015 +       IMG_CPU_VIRTADDR PTPageCpuVAddr;
74016 +       IMG_UINT32 ui32ValidPTECount;
74017 +} MMU_PT_INFO;
74018 +
74019 +struct _MMU_CONTEXT_
74020 +{
74021 +
74022 +       PVRSRV_DEVICE_NODE *psDeviceNode;
74023 +
74024 +
74025 +       IMG_CPU_VIRTADDR pvPDCpuVAddr;
74026 +       IMG_DEV_PHYADDR sPDDevPAddr;
74027 +
74028 +       IMG_VOID *hPDOSMemHandle;
74029 +
74030 +
74031 +       MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
74032 +
74033 +       PVRSRV_SGXDEV_INFO *psDevInfo;
74034 +
74035 +#if defined(PDUMP)
74036 +       IMG_UINT32 ui32PDumpMMUContextID;
74037 +#endif
74038 +
74039 +       struct _MMU_CONTEXT_ *psNext;
74040 +};
74041 +
74042 +struct _MMU_HEAP_
74043 +{
74044 +
74045 +       MMU_CONTEXT                     *psMMUContext;
74046 +
74047 +
74048 +
74049 +
74050 +       IMG_UINT32                      ui32PDBaseIndex;
74051 +
74052 +       IMG_UINT32                      ui32PageTableCount;
74053 +
74054 +       IMG_UINT32                      ui32PTETotal;
74055 +
74056 +       IMG_UINT32                      ui32PDEPageSizeCtrl;
74057 +
74058 +
74059 +
74060 +
74061 +       IMG_UINT32                      ui32DataPageSize;
74062 +
74063 +       IMG_UINT32                      ui32DataPageBitWidth;
74064 +
74065 +       IMG_UINT32                      ui32DataPageMask;
74066 +
74067 +
74068 +
74069 +
74070 +       IMG_UINT32                      ui32PTShift;
74071 +
74072 +       IMG_UINT32                      ui32PTBitWidth;
74073 +
74074 +       IMG_UINT32                      ui32PTMask;
74075 +
74076 +       IMG_UINT32                      ui32PTSize;
74077 +
74078 +       IMG_UINT32                      ui32PTECount;
74079 +
74080 +
74081 +
74082 +
74083 +       IMG_UINT32                      ui32PDShift;
74084 +
74085 +       IMG_UINT32                      ui32PDBitWidth;
74086 +
74087 +       IMG_UINT32                      ui32PDMask;
74088 +
74089 +
74090 +
74091 +       RA_ARENA *psVMArena;
74092 +       DEV_ARENA_DESCRIPTOR *psDevArena;
74093 +};
74094 +
74095 +
74096 +
74097 +#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
74098 +#define DUMMY_DATA_PAGE_SIGNATURE      0xDEADBEEF
74099 +#endif
74100 +
74101 +#if defined(PDUMP)
74102 +static IMG_VOID
74103 +MMU_PDumpPageTables    (MMU_HEAP *pMMUHeap,
74104 +                                        IMG_DEV_VIRTADDR DevVAddr,
74105 +                                        IMG_SIZE_T uSize,
74106 +                                        IMG_BOOL bForUnmap,
74107 +                                        IMG_HANDLE hUniqueTag);
74108 +#endif
74109 +
74110 +#define PAGE_TEST                                      0
74111 +#if PAGE_TEST
74112 +static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
74113 +#endif
74114 +
74115 +#define PT_DEBUG 0
74116 +#if PT_DEBUG
74117 +static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
74118 +{
74119 +       IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
74120 +       IMG_UINT32 i;
74121 +
74122 +
74123 +       for(i = 0; i < 1024; i += 8)
74124 +       {
74125 +               PVR_DPF((PVR_DBG_WARNING,
74126 +                                "%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
74127 +                                p[i + 0], p[i + 1], p[i + 2], p[i + 3],
74128 +                                p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
74129 +       }
74130 +}
74131 +
74132 +static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
74133 +{
74134 +       IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
74135 +       IMG_UINT32 i, ui32Count = 0;
74136 +
74137 +
74138 +       for(i = 0; i < 1024; i++)
74139 +               if(p[i] & SGX_MMU_PTE_VALID)
74140 +                       ui32Count++;
74141 +
74142 +       if(psPTInfoList->ui32ValidPTECount != ui32Count)
74143 +       {
74144 +               PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %lu ui32Count: %lu\n",
74145 +                                psPTInfoList->ui32ValidPTECount, ui32Count));
74146 +               DumpPT(psPTInfoList);
74147 +               BUG();
74148 +       }
74149 +}
74150 +#else
74151 +static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
74152 +{
74153 +       PVR_UNREFERENCED_PARAMETER(psPTInfoList);
74154 +}
74155 +
74156 +static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
74157 +{
74158 +       PVR_UNREFERENCED_PARAMETER(psPTInfoList);
74159 +}
74160 +#endif
74161 +
74162 +#ifdef SUPPORT_SGX_MMU_BYPASS
74163 +IMG_VOID
74164 +EnableHostAccess (MMU_CONTEXT *psMMUContext)
74165 +{
74166 +       IMG_UINT32 ui32RegVal;
74167 +       IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
74168 +
74169 +
74170 +
74171 +
74172 +       ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
74173 +
74174 +       OSWriteHWReg(pvRegsBaseKM,
74175 +                               EUR_CR_BIF_CTRL,
74176 +                               ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
74177 +
74178 +       PDUMPREG(EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
74179 +}
74180 +
74181 +IMG_VOID
74182 +DisableHostAccess (MMU_CONTEXT *psMMUContext)
74183 +{
74184 +       IMG_UINT32 ui32RegVal;
74185 +       IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
74186 +
74187 +
74188 +
74189 +
74190 +
74191 +       OSWriteHWReg(pvRegsBaseKM,
74192 +                               EUR_CR_BIF_CTRL,
74193 +                               ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
74194 +
74195 +       PDUMPREG(EUR_CR_BIF_CTRL, 0);
74196 +}
74197 +#endif
74198 +
74199 +
74200 +IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
74201 +{
74202 +       #if defined(SGX_FEATURE_MP)
74203 +       psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_SLCACHE;
74204 +       #else
74205 +
74206 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
74207 +       #endif
74208 +}
74209 +
74210 +
74211 +IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
74212 +{
74213 +       psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PDCACHE;
74214 +       #if defined(SGX_FEATURE_SYSTEM_CACHE)
74215 +       MMU_InvalidateSystemLevelCache(psDevInfo);
74216 +       #endif
74217 +}
74218 +
74219 +
74220 +IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
74221 +{
74222 +       psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PTCACHE;
74223 +       #if defined(SGX_FEATURE_SYSTEM_CACHE)
74224 +       MMU_InvalidateSystemLevelCache(psDevInfo);
74225 +       #endif
74226 +}
74227 +
74228 +
74229 +static IMG_BOOL
74230 +_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
74231 +                                               MMU_PT_INFO *psPTInfoList,
74232 +                                               IMG_DEV_PHYADDR *psDevPAddr)
74233 +{
74234 +       IMG_DEV_PHYADDR sDevPAddr;
74235 +       IMG_CPU_PHYADDR sCpuPAddr;
74236 +
74237 +
74238 +
74239 +
74240 +       if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
74241 +       {
74242 +
74243 +               if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
74244 +                                                  pMMUHeap->ui32PTSize,
74245 +                                                  SGX_MMU_PAGE_SIZE,
74246 +                                                  (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
74247 +                                                  &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
74248 +               {
74249 +                       PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
74250 +                       return IMG_FALSE;
74251 +               }
74252 +
74253 +
74254 +               if(psPTInfoList->PTPageCpuVAddr)
74255 +               {
74256 +                       sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr);
74257 +               }
74258 +               else
74259 +               {
74260 +
74261 +                       sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
74262 +               }
74263 +
74264 +               sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
74265 +       }
74266 +       else
74267 +       {
74268 +               IMG_SYS_PHYADDR sSysPAddr;
74269 +
74270 +
74271 +
74272 +
74273 +
74274 +               if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
74275 +                                       SGX_MMU_PAGE_SIZE,
74276 +                                       IMG_NULL,
74277 +                                       IMG_NULL,
74278 +                                       0,
74279 +                                       SGX_MMU_PAGE_SIZE,
74280 +                                       0,
74281 +                                       &(sSysPAddr.uiAddr))!= IMG_TRUE)
74282 +               {
74283 +                       PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
74284 +                       return IMG_FALSE;
74285 +               }
74286 +
74287 +
74288 +               sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
74289 +
74290 +               psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
74291 +                                                                                                       SGX_MMU_PAGE_SIZE,
74292 +                                                                                                       PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
74293 +                                                                                                       &psPTInfoList->hPTPageOSMemHandle);
74294 +               if(!psPTInfoList->PTPageCpuVAddr)
74295 +               {
74296 +                       PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
74297 +                       return IMG_FALSE;
74298 +               }
74299 +
74300 +
74301 +               sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
74302 +
74303 +               #if PAGE_TEST
74304 +               PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
74305 +               #endif
74306 +       }
74307 +
74308 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74309 +       {
74310 +               IMG_UINT32 *pui32Tmp;
74311 +               IMG_UINT32 i;
74312 +
74313 +               pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
74314 +
74315 +               for(i=0; i<pMMUHeap->ui32PTECount; i++)
74316 +               {
74317 +                       pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
74318 +                                               | SGX_MMU_PTE_VALID;
74319 +               }
74320 +       }
74321 +#else
74322 +
74323 +       OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
74324 +#endif
74325 +
74326 +
74327 +       PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
74328 +
74329 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74330 +
74331 +
74332 +       *psDevPAddr = sDevPAddr;
74333 +
74334 +       return IMG_TRUE;
74335 +}
74336 +
74337 +
74338 +static IMG_VOID
74339 +_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
74340 +{
74341 +
74342 +
74343 +
74344 +
74345 +       if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
74346 +       {
74347 +
74348 +               OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
74349 +                                         pMMUHeap->ui32PTSize,
74350 +                                         psPTInfoList->PTPageCpuVAddr,
74351 +                                         psPTInfoList->hPTPageOSMemHandle);
74352 +       }
74353 +       else
74354 +       {
74355 +               IMG_SYS_PHYADDR sSysPAddr;
74356 +               IMG_CPU_PHYADDR sCpuPAddr;
74357 +
74358 +
74359 +               sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr);
74360 +               sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
74361 +
74362 +
74363 +
74364 +               OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
74365 +                         SGX_MMU_PAGE_SIZE,
74366 +                         PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
74367 +                         psPTInfoList->hPTPageOSMemHandle);
74368 +
74369 +
74370 +
74371 +
74372 +               RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
74373 +       }
74374 +}
74375 +
74376 +
74377 +
74378 +static IMG_VOID
74379 +_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
74380 +{
74381 +       IMG_UINT32 *pui32PDEntry;
74382 +       IMG_UINT32 i;
74383 +       IMG_UINT32 ui32PDIndex;
74384 +       SYS_DATA *psSysData;
74385 +       MMU_PT_INFO **ppsPTInfoList;
74386 +
74387 +       SysAcquireData(&psSysData);
74388 +
74389 +
74390 +       ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
74391 +
74392 +
74393 +       ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
74394 +
74395 +       {
74396 +#if PT_DEBUG
74397 +               if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
74398 +               {
74399 +                       DumpPT(ppsPTInfoList[ui32PTIndex]);
74400 +
74401 +               }
74402 +#endif
74403 +
74404 +
74405 +               PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
74406 +       }
74407 +
74408 +
74409 +       PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
74410 +       if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
74411 +       {
74412 +               PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
74413 +       }
74414 +
74415 +       switch(pMMUHeap->psDevArena->DevMemHeapType)
74416 +       {
74417 +               case DEVICE_MEMORY_HEAP_SHARED :
74418 +               case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
74419 +               {
74420 +
74421 +                       MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
74422 +
74423 +                       while(psMMUContext)
74424 +                       {
74425 +
74426 +                               pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
74427 +                               pui32PDEntry += ui32PDIndex;
74428 +
74429 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74430 +
74431 +                               pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
74432 +                                                                                       >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
74433 +                                                                                       | SGX_MMU_PDE_PAGE_SIZE_4K
74434 +                                                                                       | SGX_MMU_PDE_VALID;
74435 +#else
74436 +
74437 +                               if(bOSFreePT)
74438 +                               {
74439 +                                       pui32PDEntry[ui32PTIndex] = 0;
74440 +                               }
74441 +#endif
74442 +
74443 +
74444 +                               PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74445 +
74446 +
74447 +                               psMMUContext = psMMUContext->psNext;
74448 +                       }
74449 +                       break;
74450 +               }
74451 +               case DEVICE_MEMORY_HEAP_PERCONTEXT :
74452 +               case DEVICE_MEMORY_HEAP_KERNEL :
74453 +               {
74454 +
74455 +                       pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
74456 +                       pui32PDEntry += ui32PDIndex;
74457 +
74458 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74459 +
74460 +                       pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
74461 +                                                                               >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
74462 +                                                                               | SGX_MMU_PDE_PAGE_SIZE_4K
74463 +                                                                               | SGX_MMU_PDE_VALID;
74464 +#else
74465 +
74466 +                       if(bOSFreePT)
74467 +                       {
74468 +                               pui32PDEntry[ui32PTIndex] = 0;
74469 +                       }
74470 +#endif
74471 +
74472 +
74473 +                       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74474 +                       break;
74475 +               }
74476 +               default:
74477 +               {
74478 +                       PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"));
74479 +                       return;
74480 +               }
74481 +       }
74482 +
74483 +
74484 +       if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
74485 +       {
74486 +               if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
74487 +               {
74488 +                       IMG_PUINT32 pui32Tmp;
74489 +
74490 +                       pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
74491 +
74492 +
74493 +                       for(i=0;
74494 +                               (i<pMMUHeap->ui32PTETotal) && (i<pMMUHeap->ui32PTECount);
74495 +                                i++)
74496 +                       {
74497 +                               pui32Tmp[i] = 0;
74498 +                       }
74499 +
74500 +
74501 +
74502 +                       if(bOSFreePT)
74503 +                       {
74504 +                               _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
74505 +                       }
74506 +
74507 +
74508 +
74509 +
74510 +                       pMMUHeap->ui32PTETotal -= i;
74511 +               }
74512 +               else
74513 +               {
74514 +
74515 +                       pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
74516 +               }
74517 +
74518 +               if(bOSFreePT)
74519 +               {
74520 +
74521 +                       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
74522 +                                               sizeof(MMU_PT_INFO),
74523 +                                               ppsPTInfoList[ui32PTIndex],
74524 +                                               IMG_NULL);
74525 +                       ppsPTInfoList[ui32PTIndex] = IMG_NULL;
74526 +               }
74527 +       }
74528 +       else
74529 +       {
74530 +
74531 +               pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
74532 +       }
74533 +
74534 +       PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
74535 +}
74536 +
74537 +static IMG_VOID
74538 +_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
74539 +{
74540 +       IMG_UINT32 i;
74541 +
74542 +       for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
74543 +       {
74544 +               _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
74545 +       }
74546 +       MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
74547 +}
74548 +
74549 +
74550 +static IMG_BOOL
74551 +_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
74552 +{
74553 +       IMG_UINT32 ui32PageTableCount;
74554 +       IMG_UINT32 ui32PDIndex;
74555 +       IMG_UINT32 i;
74556 +       IMG_UINT32 *pui32PDEntry;
74557 +       MMU_PT_INFO **ppsPTInfoList;
74558 +       SYS_DATA *psSysData;
74559 +       IMG_DEV_VIRTADDR sHighDevVAddr;
74560 +
74561 +
74562 +#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
74563 +       PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
74564 +#endif
74565 +
74566 +
74567 +       SysAcquireData(&psSysData);
74568 +
74569 +
74570 +       ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
74571 +
74572 +
74573 +
74574 +       if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
74575 +               < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
74576 +       {
74577 +
74578 +               sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
74579 +       }
74580 +       else
74581 +       {
74582 +               sHighDevVAddr.uiAddr = DevVAddr.uiAddr
74583 +                                                               + ui32Size
74584 +                                                               + pMMUHeap->ui32DataPageMask
74585 +                                                               + pMMUHeap->ui32PTMask;
74586 +       }
74587 +
74588 +       ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
74589 +
74590 +       ui32PageTableCount -= ui32PDIndex;
74591 +
74592 +
74593 +       pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
74594 +       pui32PDEntry += ui32PDIndex;
74595 +
74596 +
74597 +       ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
74598 +
74599 +       PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PageTableCount);
74600 +       PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PageTableCount);
74601 +
74602 +
74603 +       for(i=0; i<ui32PageTableCount; i++)
74604 +       {
74605 +               if(ppsPTInfoList[i] == IMG_NULL)
74606 +               {
74607 +                       OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
74608 +                                                sizeof (MMU_PT_INFO),
74609 +                                                (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
74610 +                                                "MMU Page Table Info");
74611 +                       if (ppsPTInfoList[i] == IMG_NULL)
74612 +                       {
74613 +                               PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
74614 +                               return IMG_FALSE;
74615 +                       }
74616 +                       OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
74617 +               }
74618 +
74619 +               if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
74620 +               && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
74621 +               {
74622 +                       IMG_DEV_PHYADDR sDevPAddr;
74623 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74624 +                       IMG_UINT32 *pui32Tmp;
74625 +                       IMG_UINT32 j;
74626 +#else
74627 +
74628 +                       PVR_ASSERT(pui32PDEntry[i] == 0);
74629 +#endif
74630 +
74631 +                       if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
74632 +                       {
74633 +                               PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
74634 +                               return IMG_FALSE;
74635 +                       }
74636 +
74637 +                       switch(pMMUHeap->psDevArena->DevMemHeapType)
74638 +                       {
74639 +                               case DEVICE_MEMORY_HEAP_SHARED :
74640 +                               case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
74641 +                               {
74642 +
74643 +                                       MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
74644 +
74645 +                                       while(psMMUContext)
74646 +                                       {
74647 +
74648 +                                               pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
74649 +                                               pui32PDEntry += ui32PDIndex;
74650 +
74651 +
74652 +                                               pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
74653 +                                                                               | pMMUHeap->ui32PDEPageSizeCtrl
74654 +                                                                               | SGX_MMU_PDE_VALID;
74655 +
74656 +
74657 +                                               PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74658 +
74659 +
74660 +                                               psMMUContext = psMMUContext->psNext;
74661 +                                       }
74662 +                                       break;
74663 +                               }
74664 +                               case DEVICE_MEMORY_HEAP_PERCONTEXT :
74665 +                               case DEVICE_MEMORY_HEAP_KERNEL :
74666 +                               {
74667 +
74668 +                                       pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
74669 +                                                                       | pMMUHeap->ui32PDEPageSizeCtrl
74670 +                                                                       | SGX_MMU_PDE_VALID;
74671 +
74672 +
74673 +                                       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74674 +                                       break;
74675 +                               }
74676 +                               default:
74677 +                               {
74678 +                                       PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type"));
74679 +                                       return IMG_FALSE;
74680 +                               }
74681 +                       }
74682 +
74683 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
74684 +
74685 +
74686 +
74687 +
74688 +                       MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
74689 +#endif
74690 +               }
74691 +               else
74692 +               {
74693 +
74694 +                       PVR_ASSERT(pui32PDEntry[i] != 0);
74695 +               }
74696 +       }
74697 +
74698 +       #if defined(SGX_FEATURE_SYSTEM_CACHE)
74699 +       MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
74700 +       #endif
74701 +
74702 +       return IMG_TRUE;
74703 +}
74704 +
74705 +
74706 +PVRSRV_ERROR
74707 +MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr)
74708 +{
74709 +       IMG_UINT32 *pui32Tmp;
74710 +       IMG_UINT32 i;
74711 +       IMG_CPU_VIRTADDR pvPDCpuVAddr;
74712 +       IMG_DEV_PHYADDR sPDDevPAddr;
74713 +       IMG_CPU_PHYADDR sCpuPAddr;
74714 +       MMU_CONTEXT *psMMUContext;
74715 +       IMG_HANDLE hPDOSMemHandle;
74716 +       SYS_DATA *psSysData;
74717 +       PVRSRV_SGXDEV_INFO *psDevInfo;
74718 +
74719 +       PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
74720 +
74721 +       SysAcquireData(&psSysData);
74722 +
74723 +       OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
74724 +                                sizeof (MMU_CONTEXT),
74725 +                                (IMG_VOID **)&psMMUContext, IMG_NULL,
74726 +                                "MMU Context");
74727 +       if (psMMUContext == IMG_NULL)
74728 +       {
74729 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
74730 +               return PVRSRV_ERROR_GENERIC;
74731 +       }
74732 +       OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
74733 +
74734 +
74735 +       psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
74736 +       psMMUContext->psDevInfo = psDevInfo;
74737 +
74738 +
74739 +       psMMUContext->psDeviceNode = psDeviceNode;
74740 +
74741 +
74742 +       if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
74743 +       {
74744 +               if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
74745 +                                                       SGX_MMU_PAGE_SIZE,
74746 +                                                       SGX_MMU_PAGE_SIZE,
74747 +                                                       &pvPDCpuVAddr,
74748 +                                                       &hPDOSMemHandle) != PVRSRV_OK)
74749 +               {
74750 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
74751 +                       return PVRSRV_ERROR_GENERIC;
74752 +               }
74753 +
74754 +               if(pvPDCpuVAddr)
74755 +               {
74756 +                       sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr);
74757 +               }
74758 +               else
74759 +               {
74760 +
74761 +                       sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
74762 +               }
74763 +               sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
74764 +
74765 +               #if PAGE_TEST
74766 +               PageTest(pvPDCpuVAddr, sPDDevPAddr);
74767 +               #endif
74768 +
74769 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74770 +
74771 +               if(!psDevInfo->pvMMUContextList)
74772 +               {
74773 +
74774 +                       if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
74775 +                                                               SGX_MMU_PAGE_SIZE,
74776 +                                                               SGX_MMU_PAGE_SIZE,
74777 +                                                               &psDevInfo->pvDummyPTPageCpuVAddr,
74778 +                                                               &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
74779 +                       {
74780 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
74781 +                               return PVRSRV_ERROR_GENERIC;
74782 +                       }
74783 +
74784 +                       if(psDevInfo->pvDummyPTPageCpuVAddr)
74785 +                       {
74786 +                               sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr);
74787 +                       }
74788 +                       else
74789 +                       {
74790 +
74791 +                               sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
74792 +                       }
74793 +                       psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
74794 +
74795 +
74796 +                       if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
74797 +                                                               SGX_MMU_PAGE_SIZE,
74798 +                                                               SGX_MMU_PAGE_SIZE,
74799 +                                                               &psDevInfo->pvDummyDataPageCpuVAddr,
74800 +                                                               &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
74801 +                       {
74802 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
74803 +                               return PVRSRV_ERROR_GENERIC;
74804 +                       }
74805 +
74806 +                       if(psDevInfo->pvDummyDataPageCpuVAddr)
74807 +                       {
74808 +                               sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr);
74809 +                       }
74810 +                       else
74811 +                       {
74812 +                               sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
74813 +                       }
74814 +                       psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
74815 +               }
74816 +#endif
74817 +       }
74818 +       else
74819 +       {
74820 +               IMG_SYS_PHYADDR sSysPAddr;
74821 +
74822 +
74823 +               if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
74824 +                                       SGX_MMU_PAGE_SIZE,
74825 +                                       IMG_NULL,
74826 +                                       IMG_NULL,
74827 +                                       0,
74828 +                                       SGX_MMU_PAGE_SIZE,
74829 +                                       0,
74830 +                                       &(sSysPAddr.uiAddr))!= IMG_TRUE)
74831 +               {
74832 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
74833 +                       return PVRSRV_ERROR_GENERIC;
74834 +               }
74835 +
74836 +
74837 +               sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
74838 +               sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
74839 +               pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr,
74840 +                                                                               SGX_MMU_PAGE_SIZE,
74841 +                                                                               PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
74842 +                                                                               &hPDOSMemHandle);
74843 +               if(!pvPDCpuVAddr)
74844 +               {
74845 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
74846 +                       return PVRSRV_ERROR_GENERIC;
74847 +               }
74848 +
74849 +               #if PAGE_TEST
74850 +               PageTest(pvPDCpuVAddr, sPDDevPAddr);
74851 +               #endif
74852 +
74853 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74854 +
74855 +               if(!psDevInfo->pvMMUContextList)
74856 +               {
74857 +
74858 +                       if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
74859 +                                               SGX_MMU_PAGE_SIZE,
74860 +                                               IMG_NULL,
74861 +                                               IMG_NULL,
74862 +                                               0,
74863 +                                               SGX_MMU_PAGE_SIZE,
74864 +                                               0,
74865 +                                               &(sSysPAddr.uiAddr))!= IMG_TRUE)
74866 +                       {
74867 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
74868 +                               return PVRSRV_ERROR_GENERIC;
74869 +                       }
74870 +
74871 +
74872 +                       sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
74873 +                       psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
74874 +                       psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
74875 +                                                                                                                               SGX_MMU_PAGE_SIZE,
74876 +                                                                                                                               PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
74877 +                                                                                                                               &psDevInfo->hDummyPTPageOSMemHandle);
74878 +                       if(!psDevInfo->pvDummyPTPageCpuVAddr)
74879 +                       {
74880 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
74881 +                               return PVRSRV_ERROR_GENERIC;
74882 +                       }
74883 +
74884 +
74885 +                       if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
74886 +                                               SGX_MMU_PAGE_SIZE,
74887 +                                               IMG_NULL,
74888 +                                               IMG_NULL,
74889 +                                               0,
74890 +                                               SGX_MMU_PAGE_SIZE,
74891 +                                               0,
74892 +                                               &(sSysPAddr.uiAddr))!= IMG_TRUE)
74893 +                       {
74894 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
74895 +                               return PVRSRV_ERROR_GENERIC;
74896 +                       }
74897 +
74898 +
74899 +                       sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
74900 +                       psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
74901 +                       psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
74902 +                                                                                                                               SGX_MMU_PAGE_SIZE,
74903 +                                                                                                                               PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
74904 +                                                                                                                               &psDevInfo->hDummyDataPageOSMemHandle);
74905 +                       if(!psDevInfo->pvDummyDataPageCpuVAddr)
74906 +                       {
74907 +                               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
74908 +                               return PVRSRV_ERROR_GENERIC;
74909 +                       }
74910 +               }
74911 +#endif
74912 +       }
74913 +
74914 +
74915 +       PDUMPCOMMENT("Alloc page directory");
74916 +#ifdef SUPPORT_SGX_MMU_BYPASS
74917 +       EnableHostAccess(psMMUContext);
74918 +#endif
74919 +
74920 +       PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
74921 +
74922 +       if (pvPDCpuVAddr)
74923 +       {
74924 +               pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
74925 +       }
74926 +       else
74927 +       {
74928 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
74929 +               return PVRSRV_ERROR_GENERIC;
74930 +       }
74931 +
74932 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
74933 +
74934 +       for(i=0; i<SGX_MMU_PD_SIZE; i++)
74935 +       {
74936 +               pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
74937 +                                       | SGX_MMU_PDE_PAGE_SIZE_4K
74938 +                                       | SGX_MMU_PDE_VALID;
74939 +       }
74940 +
74941 +       if(!psDevInfo->pvMMUContextList)
74942 +       {
74943 +
74944 +
74945 +
74946 +               pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
74947 +               for(i=0; i<SGX_MMU_PT_SIZE; i++)
74948 +               {
74949 +                       pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
74950 +                                               | SGX_MMU_PTE_VALID;
74951 +               }
74952 +
74953 +               PDUMPCOMMENT("Dummy Page table contents");
74954 +               PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74955 +
74956 +
74957 +
74958 +               pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
74959 +               for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
74960 +               {
74961 +                       pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
74962 +               }
74963 +
74964 +               PDUMPCOMMENT("Dummy Data Page contents");
74965 +               PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74966 +       }
74967 +#else
74968 +
74969 +       for(i=0; i<SGX_MMU_PD_SIZE; i++)
74970 +       {
74971 +
74972 +               pui32Tmp[i] = 0;
74973 +       }
74974 +#endif
74975 +
74976 +
74977 +       PDUMPCOMMENT("Page directory contents");
74978 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
74979 +
74980 +
74981 +#if defined(PDUMP)
74982 +       if(PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
74983 +                                                       "SGXMEM",
74984 +                                                       &psMMUContext->ui32PDumpMMUContextID,
74985 +                                                       2,
74986 +                                                       PDUMP_PT_UNIQUETAG,
74987 +                                                       pvPDCpuVAddr) != PVRSRV_OK)
74988 +       {
74989 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
74990 +               return PVRSRV_ERROR_GENERIC;
74991 +       }
74992 +#endif
74993 +
74994 +
74995 +       psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
74996 +       psMMUContext->sPDDevPAddr = sPDDevPAddr;
74997 +       psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
74998 +
74999 +
75000 +       *ppsMMUContext = psMMUContext;
75001 +
75002 +
75003 +       *psPDDevPAddr = sPDDevPAddr;
75004 +
75005 +
75006 +       psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
75007 +       psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
75008 +
75009 +#ifdef SUPPORT_SGX_MMU_BYPASS
75010 +       DisableHostAccess(psMMUContext);
75011 +#endif
75012 +
75013 +       return PVRSRV_OK;
75014 +}
75015 +
75016 +IMG_VOID
75017 +MMU_Finalise (MMU_CONTEXT *psMMUContext)
75018 +{
75019 +       IMG_UINT32 *pui32Tmp, i;
75020 +       SYS_DATA *psSysData;
75021 +       MMU_CONTEXT **ppsMMUContext;
75022 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75023 +       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
75024 +       MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
75025 +#endif
75026 +
75027 +       SysAcquireData(&psSysData);
75028 +
75029 +
75030 +       PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, "SGXMEM", psMMUContext->ui32PDumpMMUContextID, 2);
75031 +
75032 +
75033 +       PDUMPCOMMENT("Free page directory");
75034 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
75035 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75036 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
75037 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
75038 +#endif
75039 +
75040 +       pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
75041 +
75042 +
75043 +       for(i=0; i<SGX_MMU_PD_SIZE; i++)
75044 +       {
75045 +
75046 +               pui32Tmp[i] = 0;
75047 +       }
75048 +
75049 +
75050 +
75051 +
75052 +
75053 +       if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
75054 +       {
75055 +               OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
75056 +                                               SGX_MMU_PAGE_SIZE,
75057 +                                               psMMUContext->pvPDCpuVAddr,
75058 +                                               psMMUContext->hPDOSMemHandle);
75059 +
75060 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75061 +
75062 +               if(!psMMUContextList->psNext)
75063 +               {
75064 +                       OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
75065 +                                                       SGX_MMU_PAGE_SIZE,
75066 +                                                       psDevInfo->pvDummyPTPageCpuVAddr,
75067 +                                                       psDevInfo->hDummyPTPageOSMemHandle);
75068 +                       OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
75069 +                                                       SGX_MMU_PAGE_SIZE,
75070 +                                                       psDevInfo->pvDummyDataPageCpuVAddr,
75071 +                                                       psDevInfo->hDummyDataPageOSMemHandle);
75072 +               }
75073 +#endif
75074 +       }
75075 +       else
75076 +       {
75077 +               IMG_SYS_PHYADDR sSysPAddr;
75078 +               IMG_CPU_PHYADDR sCpuPAddr;
75079 +
75080 +
75081 +               sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->pvPDCpuVAddr);
75082 +               sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
75083 +
75084 +
75085 +               OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
75086 +                                                       SGX_MMU_PAGE_SIZE,
75087 +                            PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
75088 +                                                       psMMUContext->hPDOSMemHandle);
75089 +
75090 +               RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
75091 +
75092 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75093 +
75094 +               if(!psMMUContextList->psNext)
75095 +               {
75096 +
75097 +                       sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr);
75098 +                       sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
75099 +
75100 +
75101 +                       OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
75102 +                                                               SGX_MMU_PAGE_SIZE,
75103 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
75104 +                                                               psDevInfo->hDummyPTPageOSMemHandle);
75105 +
75106 +                       RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
75107 +
75108 +
75109 +                       sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr);
75110 +                       sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
75111 +
75112 +
75113 +                       OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
75114 +                                                               SGX_MMU_PAGE_SIZE,
75115 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
75116 +                                                               psDevInfo->hDummyDataPageOSMemHandle);
75117 +
75118 +                       RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
75119 +               }
75120 +#endif
75121 +       }
75122 +
75123 +       PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
75124 +
75125 +
75126 +       ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
75127 +       while(*ppsMMUContext)
75128 +       {
75129 +               if(*ppsMMUContext == psMMUContext)
75130 +               {
75131 +
75132 +                       *ppsMMUContext = psMMUContext->psNext;
75133 +                       break;
75134 +               }
75135 +
75136 +
75137 +               ppsMMUContext = &((*ppsMMUContext)->psNext);
75138 +       }
75139 +
75140 +
75141 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
75142 +
75143 +}
75144 +
75145 +
75146 +IMG_VOID
75147 +MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
75148 +{
75149 +       IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
75150 +       IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr;
75151 +       IMG_UINT32 ui32PDEntry;
75152 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
75153 +       IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
75154 +#endif
75155 +
75156 +
75157 +       pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
75158 +       pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
75159 +
75160 +
75161 +
75162 +
75163 +       PDUMPCOMMENT("Page directory shared heap range copy");
75164 +#ifdef SUPPORT_SGX_MMU_BYPASS
75165 +       EnableHostAccess(psMMUContext);
75166 +#endif
75167 +
75168 +       for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
75169 +       {
75170 +#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75171 +
75172 +               PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
75173 +#endif
75174 +
75175 +
75176 +               pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
75177 +               if (pui32PDCpuVAddr[ui32PDEntry])
75178 +               {
75179 +                       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
75180 +
75181 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
75182 +                       bInvalidateDirectoryCache = IMG_TRUE;
75183 +#endif
75184 +               }
75185 +       }
75186 +
75187 +#ifdef SUPPORT_SGX_MMU_BYPASS
75188 +       DisableHostAccess(psMMUContext);
75189 +#endif
75190 +
75191 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
75192 +       if (bInvalidateDirectoryCache)
75193 +       {
75194 +
75195 +
75196 +
75197 +
75198 +               MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
75199 +       }
75200 +#endif
75201 +}
75202 +
75203 +
75204 +static IMG_VOID
75205 +MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
75206 +                                                 IMG_DEV_VIRTADDR sDevVAddr,
75207 +                                                 IMG_UINT32 ui32PageCount,
75208 +                                                 IMG_HANDLE hUniqueTag)
75209 +{
75210 +       IMG_DEV_VIRTADDR        sTmpDevVAddr;
75211 +       IMG_UINT32                      i;
75212 +       IMG_UINT32                      ui32PDIndex;
75213 +       IMG_UINT32                      ui32PTIndex;
75214 +       IMG_UINT32                      *pui32Tmp;
75215 +       IMG_BOOL                        bInvalidateDirectoryCache = IMG_FALSE;
75216 +
75217 +#if !defined (PDUMP)
75218 +       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
75219 +#endif
75220 +
75221 +       sTmpDevVAddr = sDevVAddr;
75222 +
75223 +       for(i=0; i<ui32PageCount; i++)
75224 +       {
75225 +               MMU_PT_INFO **ppsPTInfoList;
75226 +
75227 +
75228 +               ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
75229 +
75230 +
75231 +               ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
75232 +
75233 +               {
75234 +
75235 +                       ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
75236 +
75237 +
75238 +                       if (!ppsPTInfoList[0])
75239 +                       {
75240 +                               PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
75241 +
75242 +
75243 +                               sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
75244 +
75245 +
75246 +                               continue;
75247 +                       }
75248 +
75249 +
75250 +                       pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
75251 +
75252 +
75253 +                       if (!pui32Tmp)
75254 +                       {
75255 +                               continue;
75256 +                       }
75257 +
75258 +                       CheckPT(ppsPTInfoList[0]);
75259 +
75260 +
75261 +                       if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
75262 +                       {
75263 +                               ppsPTInfoList[0]->ui32ValidPTECount--;
75264 +                       }
75265 +                       else
75266 +                       {
75267 +                               PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
75268 +                       }
75269 +
75270 +
75271 +                       PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
75272 +
75273 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75274 +
75275 +                       pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
75276 +                                                                       | SGX_MMU_PTE_VALID;
75277 +#else
75278 +
75279 +                       pui32Tmp[ui32PTIndex] = 0;
75280 +#endif
75281 +
75282 +                       CheckPT(ppsPTInfoList[0]);
75283 +               }
75284 +
75285 +
75286 +
75287 +               if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0)
75288 +               {
75289 +                       _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
75290 +                       bInvalidateDirectoryCache = IMG_TRUE;
75291 +               }
75292 +
75293 +
75294 +               sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
75295 +       }
75296 +
75297 +       if(bInvalidateDirectoryCache)
75298 +       {
75299 +               MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
75300 +       }
75301 +       else
75302 +       {
75303 +               MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
75304 +       }
75305 +
75306 +#if defined(PDUMP)
75307 +       MMU_PDumpPageTables(psMMUHeap,
75308 +                                               sDevVAddr,
75309 +                                               psMMUHeap->ui32DataPageSize * ui32PageCount,
75310 +                                               IMG_TRUE,
75311 +                                               hUniqueTag);
75312 +#endif
75313 +}
75314 +
75315 +
75316 +IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
75317 +                            IMG_SIZE_T ui32Start,
75318 +                            IMG_SIZE_T ui32End,
75319 +                            IMG_HANDLE hUniqueTag)
75320 +{
75321 +       MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
75322 +       IMG_DEV_VIRTADDR Start;
75323 +
75324 +       Start.uiAddr = ui32Start;
75325 +
75326 +       MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) >> pMMUHeap->ui32PTShift, hUniqueTag);
75327 +}
75328 +
75329 +MMU_HEAP *
75330 +MMU_Create (MMU_CONTEXT *psMMUContext,
75331 +                       DEV_ARENA_DESCRIPTOR *psDevArena,
75332 +                       RA_ARENA **ppsVMArena)
75333 +{
75334 +       MMU_HEAP *pMMUHeap;
75335 +       IMG_UINT32 ui32ScaleSize;
75336 +
75337 +       PVR_ASSERT (psDevArena != IMG_NULL);
75338 +
75339 +       if (psDevArena == IMG_NULL)
75340 +       {
75341 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter"));
75342 +               return IMG_NULL;
75343 +       }
75344 +
75345 +       OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
75346 +                                sizeof (MMU_HEAP),
75347 +                                (IMG_VOID **)&pMMUHeap, IMG_NULL,
75348 +                                "MMU Heap");
75349 +       if (pMMUHeap == IMG_NULL)
75350 +       {
75351 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"));
75352 +               return IMG_NULL;
75353 +       }
75354 +
75355 +       pMMUHeap->psMMUContext = psMMUContext;
75356 +       pMMUHeap->psDevArena = psDevArena;
75357 +
75358 +
75359 +
75360 +
75361 +       switch(pMMUHeap->psDevArena->ui32DataPageSize)
75362 +       {
75363 +               case 0x1000:
75364 +                       ui32ScaleSize = 0;
75365 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
75366 +                       break;
75367 +#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
75368 +               case 0x4000:
75369 +                       ui32ScaleSize = 2;
75370 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
75371 +                       break;
75372 +               case 0x10000:
75373 +                       ui32ScaleSize = 4;
75374 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
75375 +                       break;
75376 +               case 0x40000:
75377 +                       ui32ScaleSize = 6;
75378 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
75379 +                       break;
75380 +               case 0x100000:
75381 +                       ui32ScaleSize = 8;
75382 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
75383 +                       break;
75384 +               case 0x400000:
75385 +                       ui32ScaleSize = 10;
75386 +                       pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
75387 +                       break;
75388 +#endif
75389 +               default:
75390 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
75391 +                       goto ErrorFreeHeap;
75392 +       }
75393 +
75394 +
75395 +       pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
75396 +       pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
75397 +       pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
75398 +
75399 +       pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
75400 +       pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
75401 +       pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
75402 +       pMMUHeap->ui32PTSize = (1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
75403 +
75404 +       if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
75405 +       {
75406 +               pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
75407 +       }
75408 +       pMMUHeap->ui32PTECount = pMMUHeap->ui32PTSize >> 2;
75409 +
75410 +
75411 +       pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
75412 +       pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
75413 +       pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
75414 +
75415 +
75416 +
75417 +
75418 +
75419 +       if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
75420 +       {
75421 +
75422 +
75423 +
75424 +               PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
75425 +                                               & (pMMUHeap->ui32DataPageMask
75426 +                                                       | pMMUHeap->ui32PTMask)) == 0);
75427 +       }
75428 +
75429 +
75430 +       pMMUHeap->ui32PTETotal = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
75431 +
75432 +
75433 +       pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
75434 +
75435 +
75436 +
75437 +
75438 +       pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotal + pMMUHeap->ui32PTECount - 1)
75439 +                                                                               >> pMMUHeap->ui32PTBitWidth;
75440 +
75441 +
75442 +       pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
75443 +                                                                       psDevArena->BaseDevVAddr.uiAddr,
75444 +                                                                       psDevArena->ui32Size,
75445 +                                                                       IMG_NULL,
75446 +                                                                       pMMUHeap->ui32DataPageSize,
75447 +                                                                       IMG_NULL,
75448 +                                                                       IMG_NULL,
75449 +                                                                       MMU_FreePageTables,
75450 +                                                                       pMMUHeap);
75451 +
75452 +       if (pMMUHeap->psVMArena == IMG_NULL)
75453 +       {
75454 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
75455 +               goto ErrorFreePagetables;
75456 +       }
75457 +
75458 +#if 0
75459 +
75460 +       if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID)
75461 +       {
75462 +               IMG_UINT32 ui32RegVal;
75463 +               IMG_UINT32 ui32XTileStride;
75464 +
75465 +
75466 +
75467 +
75468 +
75469 +
75470 +               ui32XTileStride = 2;
75471 +
75472 +               ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK
75473 +                                               & ((psDevArena->BaseDevVAddr.uiAddr>>20)
75474 +                                               << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT))
75475 +                                       |(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK
75476 +                                               & (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20)
75477 +                                               << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT))
75478 +                                       |(EUR_CR_BIF_TILE0_CFG_MASK
75479 +                                               & (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT));
75480 +               PDUMPREG(EUR_CR_BIF_TILE0, ui32RegVal);
75481 +       }
75482 +#endif
75483 +
75484 +
75485 +
75486 +       *ppsVMArena = pMMUHeap->psVMArena;
75487 +
75488 +       return pMMUHeap;
75489 +
75490 +
75491 +ErrorFreePagetables:
75492 +       _DeferredFreePageTables (pMMUHeap);
75493 +
75494 +ErrorFreeHeap:
75495 +       OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
75496 +
75497 +
75498 +       return IMG_NULL;
75499 +}
75500 +
75501 +IMG_VOID
75502 +MMU_Delete (MMU_HEAP *pMMUHeap)
75503 +{
75504 +       if (pMMUHeap != IMG_NULL)
75505 +       {
75506 +               PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete"));
75507 +
75508 +               if(pMMUHeap->psVMArena)
75509 +               {
75510 +                       RA_Delete (pMMUHeap->psVMArena);
75511 +               }
75512 +
75513 +#ifdef SUPPORT_SGX_MMU_BYPASS
75514 +               EnableHostAccess(pMMUHeap->psMMUContext);
75515 +#endif
75516 +               _DeferredFreePageTables (pMMUHeap);
75517 +#ifdef SUPPORT_SGX_MMU_BYPASS
75518 +               DisableHostAccess(pMMUHeap->psMMUContext);
75519 +#endif
75520 +
75521 +               OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
75522 +
75523 +       }
75524 +}
75525 +
75526 +IMG_BOOL
75527 +MMU_Alloc (MMU_HEAP *pMMUHeap,
75528 +                  IMG_SIZE_T uSize,
75529 +                  IMG_SIZE_T *pActualSize,
75530 +                  IMG_UINT32 uFlags,
75531 +                  IMG_UINT32 uDevVAddrAlignment,
75532 +                  IMG_DEV_VIRTADDR *psDevVAddr)
75533 +{
75534 +       IMG_BOOL bStatus;
75535 +
75536 +       PVR_DPF ((PVR_DBG_MESSAGE,
75537 +               "MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x",
75538 +               uSize, uFlags, uDevVAddrAlignment));
75539 +
75540 +
75541 +
75542 +       if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
75543 +       {
75544 +               IMG_UINTPTR_T uiAddr;
75545 +
75546 +               bStatus = RA_Alloc (pMMUHeap->psVMArena,
75547 +                                                       uSize,
75548 +                                                       pActualSize,
75549 +                                                       IMG_NULL,
75550 +                                                       0,
75551 +                                                       uDevVAddrAlignment,
75552 +                                                       0,
75553 +                                                       &uiAddr);
75554 +               if(!bStatus)
75555 +               {
75556 +                       PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
75557 +                       return bStatus;
75558 +               }
75559 +
75560 +               psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
75561 +       }
75562 +
75563 +       #ifdef SUPPORT_SGX_MMU_BYPASS
75564 +       EnableHostAccess(pMMUHeap->psMMUContext);
75565 +       #endif
75566 +
75567 +
75568 +       bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize);
75569 +
75570 +       #ifdef SUPPORT_SGX_MMU_BYPASS
75571 +       DisableHostAccess(pMMUHeap->psMMUContext);
75572 +       #endif
75573 +
75574 +       if (!bStatus)
75575 +       {
75576 +               PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
75577 +               if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
75578 +               {
75579 +
75580 +                       RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
75581 +               }
75582 +       }
75583 +
75584 +       return bStatus;
75585 +}
75586 +
75587 +IMG_VOID
75588 +MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
75589 +{
75590 +       PVR_ASSERT (pMMUHeap != IMG_NULL);
75591 +
75592 +       if (pMMUHeap == IMG_NULL)
75593 +       {
75594 +               PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
75595 +               return;
75596 +       }
75597 +
75598 +       PVR_DPF ((PVR_DBG_MESSAGE,
75599 +               "MMU_Free: mmu=%08X, dev_vaddr=%08X", pMMUHeap, DevVAddr.uiAddr));
75600 +
75601 +       if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) &&
75602 +               (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size))
75603 +       {
75604 +               RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE);
75605 +               return;
75606 +       }
75607 +
75608 +       PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't find DevVAddr %08X in a DevArena",DevVAddr.uiAddr));
75609 +}
75610 +
75611 +IMG_VOID
75612 +MMU_Enable (MMU_HEAP *pMMUHeap)
75613 +{
75614 +       PVR_UNREFERENCED_PARAMETER(pMMUHeap);
75615 +
75616 +}
75617 +
75618 +IMG_VOID
75619 +MMU_Disable (MMU_HEAP *pMMUHeap)
75620 +{
75621 +       PVR_UNREFERENCED_PARAMETER(pMMUHeap);
75622 +
75623 +}
75624 +
75625 +#if defined(PDUMP)
75626 +static IMG_VOID
75627 +MMU_PDumpPageTables    (MMU_HEAP *pMMUHeap,
75628 +                                        IMG_DEV_VIRTADDR DevVAddr,
75629 +                                        IMG_SIZE_T uSize,
75630 +                                        IMG_BOOL bForUnmap,
75631 +                                        IMG_HANDLE hUniqueTag)
75632 +{
75633 +       IMG_UINT32      ui32NumPTEntries;
75634 +       IMG_UINT32      ui32PTIndex;
75635 +       IMG_UINT32      *pui32PTEntry;
75636 +
75637 +       MMU_PT_INFO **ppsPTInfoList;
75638 +       IMG_UINT32 ui32PDIndex;
75639 +       IMG_UINT32 ui32PTDumpCount;
75640 +
75641 +
75642 +       ui32NumPTEntries = (uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift;
75643 +
75644 +
75645 +       ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
75646 +
75647 +
75648 +       ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
75649 +
75650 +
75651 +       ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
75652 +
75653 +
75654 +       PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
75655 +
75656 +
75657 +       while(ui32NumPTEntries > 0)
75658 +       {
75659 +               MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
75660 +
75661 +               if(ui32NumPTEntries <= pMMUHeap->ui32PTECount - ui32PTIndex)
75662 +               {
75663 +                       ui32PTDumpCount = ui32NumPTEntries;
75664 +               }
75665 +               else
75666 +               {
75667 +                       ui32PTDumpCount = pMMUHeap->ui32PTECount - ui32PTIndex;
75668 +               }
75669 +
75670 +               if (psPTInfo)
75671 +               {
75672 +                       pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
75673 +                       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
75674 +               }
75675 +
75676 +
75677 +               ui32NumPTEntries -= ui32PTDumpCount;
75678 +
75679 +
75680 +               ui32PTIndex = 0;
75681 +       }
75682 +
75683 +       PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
75684 +}
75685 +#endif
75686 +
75687 +
75688 +static IMG_VOID
75689 +MMU_MapPage (MMU_HEAP *pMMUHeap,
75690 +                        IMG_DEV_VIRTADDR DevVAddr,
75691 +                        IMG_DEV_PHYADDR DevPAddr,
75692 +                        IMG_UINT32 ui32MemFlags)
75693 +{
75694 +       IMG_UINT32 ui32Index;
75695 +       IMG_UINT32 *pui32Tmp;
75696 +       IMG_UINT32 ui32MMUFlags = 0;
75697 +       MMU_PT_INFO **ppsPTInfoList;
75698 +
75699 +
75700 +       PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
75701 +
75702 +
75703 +
75704 +       if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
75705 +       {
75706 +
75707 +               ui32MMUFlags = 0;
75708 +       }
75709 +       else if(PVRSRV_MEM_READ & ui32MemFlags)
75710 +       {
75711 +
75712 +               ui32MMUFlags |= SGX_MMU_PTE_READONLY;
75713 +       }
75714 +       else if(PVRSRV_MEM_WRITE & ui32MemFlags)
75715 +       {
75716 +
75717 +               ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
75718 +       }
75719 +
75720 +
75721 +       if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
75722 +       {
75723 +               ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
75724 +       }
75725 +
75726 +#if !defined(FIX_HW_BRN_25503)
75727 +
75728 +       if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
75729 +       {
75730 +               ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
75731 +       }
75732 +#endif
75733 +
75734 +
75735 +
75736 +
75737 +
75738 +       ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
75739 +
75740 +
75741 +       ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
75742 +
75743 +       CheckPT(ppsPTInfoList[0]);
75744 +
75745 +
75746 +       ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
75747 +
75748 +
75749 +       pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
75750 +
75751 +#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
75752 +
75753 +       if (pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID)
75754 +       {
75755 +               PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08lX PDIdx:%u PTIdx:%u",
75756 +                                                               DevVAddr.uiAddr,
75757 +                                                               DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
75758 +                                                               ui32Index ));
75759 +               PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08lX", pui32Tmp[ui32Index]));
75760 +               PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08lX", DevPAddr.uiAddr));
75761 +       }
75762 +
75763 +       PVR_ASSERT((pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) == 0);
75764 +#endif
75765 +
75766 +
75767 +       ppsPTInfoList[0]->ui32ValidPTECount++;
75768 +
75769 +
75770 +       pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
75771 +                                               & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
75772 +                                               | SGX_MMU_PTE_VALID
75773 +                                               | ui32MMUFlags;
75774 +
75775 +       CheckPT(ppsPTInfoList[0]);
75776 +}
75777 +
75778 +
75779 +IMG_VOID
75780 +MMU_MapScatter (MMU_HEAP *pMMUHeap,
75781 +                               IMG_DEV_VIRTADDR DevVAddr,
75782 +                               IMG_SYS_PHYADDR *psSysAddr,
75783 +                               IMG_SIZE_T uSize,
75784 +                               IMG_UINT32 ui32MemFlags,
75785 +                               IMG_HANDLE hUniqueTag)
75786 +{
75787 +#if defined(PDUMP)
75788 +       IMG_DEV_VIRTADDR MapBaseDevVAddr;
75789 +#endif
75790 +       IMG_UINT32 uCount, i;
75791 +       IMG_DEV_PHYADDR DevPAddr;
75792 +
75793 +       PVR_ASSERT (pMMUHeap != IMG_NULL);
75794 +
75795 +#if defined(PDUMP)
75796 +       MapBaseDevVAddr = DevVAddr;
75797 +#else
75798 +       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
75799 +#endif
75800 +
75801 +       for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
75802 +       {
75803 +               IMG_SYS_PHYADDR sSysAddr;
75804 +
75805 +               sSysAddr = psSysAddr[i];
75806 +
75807 +
75808 +
75809 +               PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
75810 +
75811 +               DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
75812 +
75813 +               MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
75814 +               DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
75815 +
75816 +               PVR_DPF ((PVR_DBG_MESSAGE,
75817 +                                "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
75818 +                                 DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
75819 +       }
75820 +
75821 +#if defined(PDUMP)
75822 +       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
75823 +#endif
75824 +}
75825 +
75826 +IMG_VOID
75827 +MMU_MapPages (MMU_HEAP *pMMUHeap,
75828 +                         IMG_DEV_VIRTADDR DevVAddr,
75829 +                         IMG_SYS_PHYADDR SysPAddr,
75830 +                         IMG_SIZE_T uSize,
75831 +                         IMG_UINT32 ui32MemFlags,
75832 +                         IMG_HANDLE hUniqueTag)
75833 +{
75834 +       IMG_DEV_PHYADDR DevPAddr;
75835 +#if defined(PDUMP)
75836 +       IMG_DEV_VIRTADDR MapBaseDevVAddr;
75837 +#endif
75838 +       IMG_UINT32 uCount;
75839 +       IMG_UINT32 ui32VAdvance;
75840 +       IMG_UINT32 ui32PAdvance;
75841 +
75842 +       PVR_ASSERT (pMMUHeap != IMG_NULL);
75843 +
75844 +       PVR_DPF ((PVR_DBG_MESSAGE,
75845 +                 "MMU_MapPages: mmu=%08X, devVAddr=%08X, SysPAddr=%08X, size=0x%x",
75846 +                 pMMUHeap, DevVAddr.uiAddr, SysPAddr.uiAddr, uSize));
75847 +
75848 +
75849 +       ui32VAdvance = pMMUHeap->ui32DataPageSize;
75850 +       ui32PAdvance = pMMUHeap->ui32DataPageSize;
75851 +
75852 +#if defined(PDUMP)
75853 +       MapBaseDevVAddr = DevVAddr;
75854 +#else
75855 +       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
75856 +#endif
75857 +
75858 +       DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
75859 +
75860 +
75861 +       PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
75862 +
75863 +#if defined(FIX_HW_BRN_23281)
75864 +       if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
75865 +       {
75866 +               ui32VAdvance *= 2;
75867 +       }
75868 +#endif
75869 +
75870 +
75871 +
75872 +
75873 +       if(ui32MemFlags & PVRSRV_MEM_DUMMY)
75874 +       {
75875 +               ui32PAdvance = 0;
75876 +       }
75877 +
75878 +       for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
75879 +       {
75880 +               MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
75881 +               DevVAddr.uiAddr += ui32VAdvance;
75882 +               DevPAddr.uiAddr += ui32PAdvance;
75883 +       }
75884 +
75885 +#if defined(PDUMP)
75886 +       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
75887 +#endif
75888 +}
75889 +
75890 +IMG_VOID
75891 +MMU_MapShadow (MMU_HEAP          *pMMUHeap,
75892 +                          IMG_DEV_VIRTADDR   MapBaseDevVAddr,
75893 +                          IMG_SIZE_T         uByteSize,
75894 +                          IMG_CPU_VIRTADDR   CpuVAddr,
75895 +                          IMG_HANDLE         hOSMemHandle,
75896 +                          IMG_DEV_VIRTADDR  *pDevVAddr,
75897 +                          IMG_UINT32         ui32MemFlags,
75898 +                          IMG_HANDLE         hUniqueTag)
75899 +{
75900 +       IMG_UINT32                      i;
75901 +       IMG_UINT32                      uOffset = 0;
75902 +       IMG_DEV_VIRTADDR        MapDevVAddr;
75903 +       IMG_UINT32                      ui32VAdvance;
75904 +       IMG_UINT32                      ui32PAdvance;
75905 +
75906 +#if !defined (PDUMP)
75907 +       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
75908 +#endif
75909 +
75910 +       PVR_DPF ((PVR_DBG_MESSAGE,
75911 +                       "MMU_MapShadow: %08X, 0x%x, %08X",
75912 +                       MapBaseDevVAddr.uiAddr,
75913 +                       uByteSize,
75914 +                       CpuVAddr));
75915 +
75916 +
75917 +       ui32VAdvance = pMMUHeap->ui32DataPageSize;
75918 +       ui32PAdvance = pMMUHeap->ui32DataPageSize;
75919 +
75920 +
75921 +       PVR_ASSERT(((IMG_UINT32)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
75922 +       PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
75923 +       pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
75924 +
75925 +#if defined(FIX_HW_BRN_23281)
75926 +       if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
75927 +       {
75928 +               ui32VAdvance *= 2;
75929 +       }
75930 +#endif
75931 +
75932 +
75933 +
75934 +
75935 +       if(ui32MemFlags & PVRSRV_MEM_DUMMY)
75936 +       {
75937 +               ui32PAdvance = 0;
75938 +       }
75939 +
75940 +
75941 +       MapDevVAddr = MapBaseDevVAddr;
75942 +       for (i=0; i<uByteSize; i+=ui32VAdvance)
75943 +       {
75944 +               IMG_CPU_PHYADDR CpuPAddr;
75945 +               IMG_DEV_PHYADDR DevPAddr;
75946 +
75947 +               if(CpuVAddr)
75948 +               {
75949 +                       CpuPAddr = OSMapLinToCPUPhys ((IMG_VOID *)((IMG_UINT32)CpuVAddr + uOffset));
75950 +               }
75951 +               else
75952 +               {
75953 +                       CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
75954 +               }
75955 +               DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
75956 +
75957 +
75958 +               PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
75959 +
75960 +               PVR_DPF ((PVR_DBG_MESSAGE,
75961 +                               "0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
75962 +                               uOffset,
75963 +                               (IMG_UINTPTR_T)CpuVAddr + uOffset,
75964 +                               CpuPAddr.uiAddr,
75965 +                               MapDevVAddr.uiAddr,
75966 +                               DevPAddr.uiAddr));
75967 +
75968 +               MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
75969 +
75970 +
75971 +               MapDevVAddr.uiAddr += ui32VAdvance;
75972 +               uOffset += ui32PAdvance;
75973 +       }
75974 +
75975 +#if defined(PDUMP)
75976 +       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
75977 +#endif
75978 +}
75979 +
75980 +
75981 +IMG_VOID
75982 +MMU_UnmapPages (MMU_HEAP *psMMUHeap,
75983 +                               IMG_DEV_VIRTADDR sDevVAddr,
75984 +                               IMG_UINT32 ui32PageCount,
75985 +                               IMG_HANDLE hUniqueTag)
75986 +{
75987 +       IMG_UINT32                      uPageSize = psMMUHeap->ui32DataPageSize;
75988 +       IMG_DEV_VIRTADDR        sTmpDevVAddr;
75989 +       IMG_UINT32                      i;
75990 +       IMG_UINT32                      ui32PDIndex;
75991 +       IMG_UINT32                      ui32PTIndex;
75992 +       IMG_UINT32                      *pui32Tmp;
75993 +
75994 +#if !defined (PDUMP)
75995 +       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
75996 +#endif
75997 +
75998 +
75999 +       sTmpDevVAddr = sDevVAddr;
76000 +
76001 +       for(i=0; i<ui32PageCount; i++)
76002 +       {
76003 +               MMU_PT_INFO **ppsPTInfoList;
76004 +
76005 +
76006 +               ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
76007 +
76008 +
76009 +               ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
76010 +
76011 +
76012 +               ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
76013 +
76014 +
76015 +               if (!ppsPTInfoList[0])
76016 +               {
76017 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",
76018 +                                                                       sTmpDevVAddr.uiAddr,
76019 +                                                                       sDevVAddr.uiAddr,
76020 +                                                                       i,
76021 +                                                                       ui32PDIndex,
76022 +                                                                       ui32PTIndex));
76023 +
76024 +
76025 +                       sTmpDevVAddr.uiAddr += uPageSize;
76026 +
76027 +
76028 +                       continue;
76029 +               }
76030 +
76031 +               CheckPT(ppsPTInfoList[0]);
76032 +
76033 +
76034 +               pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
76035 +
76036 +
76037 +               if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
76038 +               {
76039 +                       ppsPTInfoList[0]->ui32ValidPTECount--;
76040 +               }
76041 +               else
76042 +               {
76043 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",
76044 +                                                                       sTmpDevVAddr.uiAddr,
76045 +                                                                       sDevVAddr.uiAddr,
76046 +                                                                       i,
76047 +                                                                       ui32PDIndex,
76048 +                                                                       ui32PTIndex));
76049 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08lX", pui32Tmp[ui32PTIndex]));
76050 +               }
76051 +
76052 +
76053 +               PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
76054 +
76055 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
76056 +
76057 +               pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
76058 +                                                               | SGX_MMU_PTE_VALID;
76059 +#else
76060 +
76061 +               pui32Tmp[ui32PTIndex] = 0;
76062 +#endif
76063 +
76064 +               CheckPT(ppsPTInfoList[0]);
76065 +
76066 +
76067 +               sTmpDevVAddr.uiAddr += uPageSize;
76068 +       }
76069 +
76070 +       MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
76071 +
76072 +#if defined(PDUMP)
76073 +       MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
76074 +#endif
76075 +}
76076 +
76077 +
76078 +IMG_DEV_PHYADDR
76079 +MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr)
76080 +{
76081 +       IMG_UINT32 *pui32PageTable;
76082 +       IMG_UINT32 ui32Index;
76083 +       IMG_DEV_PHYADDR sDevPAddr;
76084 +       MMU_PT_INFO **ppsPTInfoList;
76085 +
76086 +
76087 +       ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
76088 +
76089 +
76090 +       ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
76091 +       if (!ppsPTInfoList[0])
76092 +       {
76093 +               PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
76094 +               sDevPAddr.uiAddr = 0;
76095 +               return sDevPAddr;
76096 +       }
76097 +
76098 +
76099 +       ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
76100 +
76101 +
76102 +       pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
76103 +
76104 +
76105 +       sDevPAddr.uiAddr = pui32PageTable[ui32Index];
76106 +
76107 +
76108 +       sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
76109 +
76110 +
76111 +       sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
76112 +
76113 +       return sDevPAddr;
76114 +}
76115 +
76116 +
76117 +IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
76118 +{
76119 +       return (pMMUContext->sPDDevPAddr);
76120 +}
76121 +
76122 +
76123 +IMG_EXPORT
76124 +PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap,
76125 +                                                                  IMG_DEV_VIRTADDR sDevVAddr,
76126 +                                                                  IMG_DEV_PHYADDR *pDevPAddr,
76127 +                                                                  IMG_CPU_PHYADDR *pCpuPAddr)
76128 +{
76129 +       MMU_HEAP *pMMUHeap;
76130 +       IMG_DEV_PHYADDR DevPAddr;
76131 +
76132 +
76133 +
76134 +       pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
76135 +
76136 +       DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
76137 +       pCpuPAddr->uiAddr = DevPAddr.uiAddr;
76138 +       pDevPAddr->uiAddr = DevPAddr.uiAddr;
76139 +
76140 +       return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
76141 +}
76142 +
76143 +
76144 +PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE              hDevCookie,
76145 +                                                               IMG_HANDLE              hDevMemContext,
76146 +                                                               IMG_DEV_PHYADDR *psPDDevPAddr)
76147 +{
76148 +       if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
76149 +       {
76150 +               return PVRSRV_ERROR_INVALID_PARAMS;
76151 +       }
76152 +
76153 +
76154 +       *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
76155 +
76156 +       return PVRSRV_OK;
76157 +}
76158 +
76159 +PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo)
76160 +{
76161 +       PVRSRV_ERROR eError;
76162 +       SYS_DATA *psSysData;
76163 +       RA_ARENA *psLocalDevMemArena;
76164 +       IMG_HANDLE hOSMemHandle = IMG_NULL;
76165 +       IMG_BYTE *pui8MemBlock = IMG_NULL;
76166 +       IMG_SYS_PHYADDR sMemBlockSysPAddr;
76167 +       IMG_CPU_PHYADDR sMemBlockCpuPAddr;
76168 +
76169 +       SysAcquireData(&psSysData);
76170 +
76171 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76172 +
76173 +
76174 +       if(psLocalDevMemArena == IMG_NULL)
76175 +       {
76176 +
76177 +               eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76178 +                                                     3 * SGX_MMU_PAGE_SIZE,
76179 +                                                     SGX_MMU_PAGE_SIZE,
76180 +                                                     (IMG_VOID **)&pui8MemBlock,
76181 +                                                     &hOSMemHandle);
76182 +               if (eError != PVRSRV_OK)
76183 +               {
76184 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
76185 +                       return eError;
76186 +               }
76187 +
76188 +
76189 +               if(pui8MemBlock)
76190 +               {
76191 +                       sMemBlockCpuPAddr = OSMapLinToCPUPhys(pui8MemBlock);
76192 +               }
76193 +               else
76194 +               {
76195 +
76196 +                       sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
76197 +               }
76198 +       }
76199 +       else
76200 +       {
76201 +
76202 +
76203 +               if(RA_Alloc(psLocalDevMemArena,
76204 +                                       3 * SGX_MMU_PAGE_SIZE,
76205 +                                       IMG_NULL,
76206 +                                       IMG_NULL,
76207 +                                       0,
76208 +                                       SGX_MMU_PAGE_SIZE,
76209 +                                       0,
76210 +                                       &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
76211 +               {
76212 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
76213 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
76214 +               }
76215 +
76216 +
76217 +               sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr);
76218 +               pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr,
76219 +                                                                         SGX_MMU_PAGE_SIZE * 3,
76220 +                                                                         PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76221 +                                                                         &hOSMemHandle);
76222 +               if(!pui8MemBlock)
76223 +               {
76224 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables"));
76225 +                       return PVRSRV_ERROR_BAD_MAPPING;
76226 +               }
76227 +       }
76228 +
76229 +       psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle;
76230 +       psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr);
76231 +       psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
76232 +       psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
76233 +
76234 +
76235 +       psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
76236 +       psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
76237 +
76238 +
76239 +       OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
76240 +       OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
76241 +
76242 +       OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
76243 +
76244 +       return PVRSRV_OK;
76245 +}
76246 +
76247 +IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
76248 +{
76249 +       SYS_DATA *psSysData;
76250 +       RA_ARENA *psLocalDevMemArena;
76251 +       IMG_SYS_PHYADDR sPDSysPAddr;
76252 +
76253 +       SysAcquireData(&psSysData);
76254 +
76255 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76256 +
76257 +
76258 +       if(psLocalDevMemArena == IMG_NULL)
76259 +       {
76260 +               OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76261 +                                       3 * SGX_MMU_PAGE_SIZE,
76262 +                                       psDevInfo->pui32BIFResetPD,
76263 +                                       psDevInfo->hBIFResetPDOSMemHandle);
76264 +       }
76265 +       else
76266 +       {
76267 +               OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD,
76268 +                         3 * SGX_MMU_PAGE_SIZE,
76269 +                         PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76270 +                         psDevInfo->hBIFResetPDOSMemHandle);
76271 +
76272 +               sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr);
76273 +               RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE);
76274 +       }
76275 +}
76276 +
76277 +
76278 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
76279 +PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo)
76280 +{
76281 +       PVRSRV_ERROR eError;
76282 +       SYS_DATA *psSysData;
76283 +       RA_ARENA *psLocalDevMemArena;
76284 +       IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
76285 +       IMG_HANDLE hPDPageOSMemHandle = IMG_NULL;
76286 +       IMG_UINT32 *pui32PD = IMG_NULL;
76287 +       IMG_UINT32 *pui32PT = IMG_NULL;
76288 +       IMG_CPU_PHYADDR sCpuPAddr;
76289 +       IMG_DEV_PHYADDR sPTDevPAddr;
76290 +       IMG_DEV_PHYADDR sPDDevPAddr;
76291 +
76292 +       SysAcquireData(&psSysData);
76293 +
76294 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76295 +
76296 +
76297 +       if(psLocalDevMemArena == IMG_NULL)
76298 +       {
76299 +
76300 +               eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76301 +                                                  SGX_MMU_PAGE_SIZE,
76302 +                                                  SGX_MMU_PAGE_SIZE,
76303 +                                                  (IMG_VOID **)&pui32PT,
76304 +                                                  &hPTPageOSMemHandle);
76305 +               if (eError != PVRSRV_OK)
76306 +               {
76307 +                       PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
76308 +                       return eError;
76309 +               }
76310 +
76311 +               eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76312 +                                                  SGX_MMU_PAGE_SIZE,
76313 +                                                  SGX_MMU_PAGE_SIZE,
76314 +                                                  (IMG_VOID **)&pui32PD,
76315 +                                                  &hPDPageOSMemHandle);
76316 +               if (eError != PVRSRV_OK)
76317 +               {
76318 +                       PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
76319 +                       return eError;
76320 +               }
76321 +
76322 +
76323 +               if(pui32PT)
76324 +        {
76325 +            sCpuPAddr = OSMapLinToCPUPhys(pui32PT);
76326 +        }
76327 +        else
76328 +        {
76329 +
76330 +            sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
76331 +        }
76332 +               sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
76333 +
76334 +               if(pui32PD)
76335 +        {
76336 +            sCpuPAddr = OSMapLinToCPUPhys(pui32PD);
76337 +        }
76338 +        else
76339 +        {
76340 +
76341 +            sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0);
76342 +        }
76343 +               sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
76344 +
76345 +       }
76346 +       else
76347 +       {
76348 +
76349 +
76350 +               if(RA_Alloc(psLocalDevMemArena,
76351 +                                       SGX_MMU_PAGE_SIZE * 2,
76352 +                                       IMG_NULL,
76353 +                                       IMG_NULL,
76354 +                                       0,
76355 +                                       SGX_MMU_PAGE_SIZE,
76356 +                                       0,
76357 +                                       &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE)
76358 +               {
76359 +                       PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed"));
76360 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
76361 +               }
76362 +
76363 +
76364 +               sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr);
76365 +               pui32PT = OSMapPhysToLin(sCpuPAddr,
76366 +                                                               SGX_MMU_PAGE_SIZE * 2,
76367 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76368 +                                                               &hPTPageOSMemHandle);
76369 +               if(!pui32PT)
76370 +               {
76371 +                       PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables"));
76372 +                       return PVRSRV_ERROR_BAD_MAPPING;
76373 +               }
76374 +
76375 +
76376 +               sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
76377 +
76378 +               pui32PD = pui32PT + 1024;
76379 +               sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + 4096;
76380 +       }
76381 +
76382 +       OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE);
76383 +       OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
76384 +
76385 +
76386 +       PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
76387 +       PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
76388 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
76389 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
76390 +
76391 +       psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle;
76392 +       psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle;
76393 +       psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr;
76394 +       psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr;
76395 +       psDevInfo->pui32BRN22997PD = pui32PD;
76396 +       psDevInfo->pui32BRN22997PT = pui32PT;
76397 +
76398 +       return PVRSRV_OK;
76399 +}
76400 +
76401 +
76402 +IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo)
76403 +{
76404 +       IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD;
76405 +       IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT;
76406 +       IMG_UINT32 ui32PDIndex;
76407 +       IMG_UINT32 ui32PTIndex;
76408 +       IMG_DEV_VIRTADDR sDevVAddr;
76409 +       volatile IMG_UINT32 *pui32HostPort;
76410 +       IMG_UINT32 ui32BIFCtrl;
76411 +
76412 +
76413 +
76414 +
76415 +       pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET);
76416 +
76417 +
76418 +       sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET;
76419 +
76420 +       ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
76421 +       ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
76422 +
76423 +
76424 +       pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
76425 +                                                       | SGX_MMU_PDE_VALID;
76426 +
76427 +       pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
76428 +                                                       | SGX_MMU_PTE_VALID;
76429 +
76430 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
76431 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
76432 +
76433 +
76434 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
76435 +                                psDevInfo->sBRN22997PDDevPAddr.uiAddr);
76436 +       PDUMPPDREG(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG);
76437 +
76438 +
76439 +       ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
76440 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
76441 +       PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
76442 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
76443 +       PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl);
76444 +
76445 +
76446 +       if (pui32HostPort)
76447 +       {
76448 +
76449 +               IMG_UINT32 ui32Tmp;
76450 +               ui32Tmp = *pui32HostPort;
76451 +       }
76452 +       else
76453 +       {
76454 +               PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround"));
76455 +       }
76456 +
76457 +
76458 +
76459 +
76460 +
76461 +
76462 +
76463 +       PDUMPCOMMENT("RDW :SGXMEM:v4:%08lX\r\n", sDevVAddr.uiAddr);
76464 +
76465 +    PDUMPCOMMENT("SAB :SGXMEM:v4:%08lX 4 0 hostport.bin", sDevVAddr.uiAddr);
76466 +
76467 +
76468 +       pui32PD[ui32PDIndex] = 0;
76469 +       pui32PT[ui32PTIndex] = 0;
76470 +
76471 +
76472 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
76473 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
76474 +
76475 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
76476 +       PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
76477 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
76478 +       PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl);
76479 +}
76480 +
76481 +
76482 +IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo)
76483 +{
76484 +       SYS_DATA *psSysData;
76485 +       RA_ARENA *psLocalDevMemArena;
76486 +
76487 +       SysAcquireData(&psSysData);
76488 +
76489 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76490 +
76491 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
76492 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
76493 +
76494 +
76495 +       if(psLocalDevMemArena == IMG_NULL)
76496 +       {
76497 +               if (psDevInfo->pui32BRN22997PD != IMG_NULL)
76498 +               {
76499 +                       OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76500 +                                                 SGX_MMU_PAGE_SIZE,
76501 +                                                 psDevInfo->pui32BRN22997PD,
76502 +                                                 psDevInfo->hBRN22997PDPageOSMemHandle);
76503 +               }
76504 +
76505 +               if (psDevInfo->pui32BRN22997PT != IMG_NULL)
76506 +               {
76507 +                       OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76508 +                                                 SGX_MMU_PAGE_SIZE,
76509 +                                                 psDevInfo->pui32BRN22997PT,
76510 +                                                 psDevInfo->hBRN22997PTPageOSMemHandle);
76511 +               }
76512 +       }
76513 +       else
76514 +       {
76515 +               if (psDevInfo->pui32BRN22997PT != IMG_NULL)
76516 +               {
76517 +                       OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT,
76518 +                                SGX_MMU_PAGE_SIZE * 2,
76519 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76520 +                                psDevInfo->hBRN22997PTPageOSMemHandle);
76521 +
76522 +
76523 +                       RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE);
76524 +               }
76525 +       }
76526 +}
76527 +#endif
76528 +
76529 +
76530 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
76531 +PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
76532 +{
76533 +       PVRSRV_ERROR eError;
76534 +       SYS_DATA *psSysData;
76535 +       RA_ARENA *psLocalDevMemArena;
76536 +       IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
76537 +       IMG_UINT32 *pui32PD;
76538 +       IMG_UINT32 *pui32PT = IMG_NULL;
76539 +       IMG_CPU_PHYADDR sCpuPAddr;
76540 +       IMG_DEV_PHYADDR sPTDevPAddr;
76541 +       PVRSRV_SGXDEV_INFO *psDevInfo;
76542 +       IMG_UINT32 ui32PDIndex;
76543 +       IMG_UINT32 ui32PTIndex;
76544 +
76545 +       psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
76546 +       pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
76547 +
76548 +       SysAcquireData(&psSysData);
76549 +
76550 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76551 +
76552 +
76553 +       if(psLocalDevMemArena == IMG_NULL)
76554 +       {
76555 +
76556 +               eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76557 +                                                  SGX_MMU_PAGE_SIZE,
76558 +                                                  SGX_MMU_PAGE_SIZE,
76559 +                                                  (IMG_VOID **)&pui32PT,
76560 +                                                  &hPTPageOSMemHandle);
76561 +               if (eError != PVRSRV_OK)
76562 +               {
76563 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to OSAllocPages failed"));
76564 +                       return eError;
76565 +               }
76566 +
76567 +
76568 +               if(pui32PT)
76569 +        {
76570 +            sCpuPAddr = OSMapLinToCPUPhys(pui32PT);
76571 +        }
76572 +        else
76573 +        {
76574 +
76575 +            sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
76576 +        }
76577 +               sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
76578 +       }
76579 +       else
76580 +       {
76581 +               IMG_SYS_PHYADDR sSysPAddr;
76582 +
76583 +
76584 +               if(RA_Alloc(psLocalDevMemArena,
76585 +                                       SGX_MMU_PAGE_SIZE,
76586 +                                       IMG_NULL,
76587 +                                       IMG_NULL,
76588 +                                       0,
76589 +                                       SGX_MMU_PAGE_SIZE,
76590 +                                       0,
76591 +                                       &(sSysPAddr.uiAddr))!= IMG_TRUE)
76592 +               {
76593 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to RA_Alloc failed"));
76594 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
76595 +               }
76596 +
76597 +
76598 +               sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
76599 +               pui32PT = OSMapPhysToLin(sCpuPAddr,
76600 +                                                               SGX_MMU_PAGE_SIZE,
76601 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76602 +                                                               &hPTPageOSMemHandle);
76603 +               if(!pui32PT)
76604 +               {
76605 +                       PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR failed to map page tables"));
76606 +                       return PVRSRV_ERROR_BAD_MAPPING;
76607 +               }
76608 +
76609 +
76610 +               sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
76611 +
76612 +
76613 +               psDevInfo->sExtSystemCacheRegsPTSysPAddr = sSysPAddr;
76614 +       }
76615 +
76616 +       OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
76617 +
76618 +       ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
76619 +       ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
76620 +
76621 +
76622 +       pui32PD[ui32PDIndex] = (sPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
76623 +                                                       | SGX_MMU_PDE_VALID;
76624 +
76625 +       pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
76626 +                                                       | SGX_MMU_PTE_VALID;
76627 +
76628 +
76629 +       PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
76630 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
76631 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
76632 +
76633 +
76634 +       psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT;
76635 +       psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle = hPTPageOSMemHandle;
76636 +
76637 +       return PVRSRV_OK;
76638 +}
76639 +
76640 +
76641 +PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
76642 +{
76643 +       SYS_DATA *psSysData;
76644 +       RA_ARENA *psLocalDevMemArena;
76645 +       PVRSRV_SGXDEV_INFO *psDevInfo;
76646 +       IMG_UINT32 ui32PDIndex;
76647 +       IMG_UINT32 *pui32PD;
76648 +
76649 +       psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
76650 +       pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
76651 +
76652 +       SysAcquireData(&psSysData);
76653 +
76654 +       psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
76655 +
76656 +
76657 +       ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
76658 +       pui32PD[ui32PDIndex] = 0;
76659 +
76660 +       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
76661 +       PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32ExtSystemCacheRegsPT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
76662 +
76663 +
76664 +       if(psLocalDevMemArena == IMG_NULL)
76665 +       {
76666 +               if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
76667 +               {
76668 +                       OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
76669 +                                                 SGX_MMU_PAGE_SIZE,
76670 +                                                 psDevInfo->pui32ExtSystemCacheRegsPT,
76671 +                                                 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
76672 +               }
76673 +       }
76674 +       else
76675 +       {
76676 +               if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
76677 +               {
76678 +                       OSUnMapPhysToLin(psDevInfo->pui32ExtSystemCacheRegsPT,
76679 +                                SGX_MMU_PAGE_SIZE,
76680 +                                PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
76681 +                                psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
76682 +
76683 +                       RA_Free(psLocalDevMemArena, psDevInfo->sExtSystemCacheRegsPTSysPAddr.uiAddr, IMG_FALSE);
76684 +               }
76685 +       }
76686 +
76687 +       return PVRSRV_OK;
76688 +}
76689 +#endif
76690 +
76691 +
76692 +#if PAGE_TEST
76693 +static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr)
76694 +{
76695 +       volatile IMG_UINT32 ui32WriteData;
76696 +       volatile IMG_UINT32 ui32ReadData;
76697 +       volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem;
76698 +       IMG_INT n;
76699 +       IMG_BOOL bOK=IMG_TRUE;
76700 +
76701 +       ui32WriteData = 0xffffffff;
76702 +
76703 +       for (n=0; n<1024; n++)
76704 +       {
76705 +               pMem32[n] = ui32WriteData;
76706 +               ui32ReadData = pMem32[n];
76707 +
76708 +               if (ui32WriteData != ui32ReadData)
76709 +               {
76710 +
76711 +                       PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
76712 +                       PVR_DBG_BREAK;
76713 +                       bOK = IMG_FALSE;
76714 +               }
76715 +       }
76716 +
76717 +       ui32WriteData = 0;
76718 +
76719 +       for (n=0; n<1024; n++)
76720 +       {
76721 +               pMem32[n] = ui32WriteData;
76722 +               ui32ReadData = pMem32[n];
76723 +
76724 +               if (ui32WriteData != ui32ReadData)
76725 +               {
76726 +
76727 +                       PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
76728 +                       PVR_DBG_BREAK;
76729 +                       bOK = IMG_FALSE;
76730 +               }
76731 +       }
76732 +
76733 +       if (bOK)
76734 +       {
76735 +               PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr));
76736 +       }
76737 +       else
76738 +       {
76739 +               PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr));
76740 +       }
76741 +}
76742 +#endif
76743 +
76744 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.h
76745 new file mode 100644
76746 index 0000000..7313769
76747 --- /dev/null
76748 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/mmu.h
76749 @@ -0,0 +1,139 @@
76750 +/**********************************************************************
76751 + *
76752 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
76753 + *
76754 + * This program is free software; you can redistribute it and/or modify it
76755 + * under the terms and conditions of the GNU General Public License,
76756 + * version 2, as published by the Free Software Foundation.
76757 + *
76758 + * This program is distributed in the hope it will be useful but, except
76759 + * as otherwise stated in writing, without any warranty; without even the
76760 + * implied warranty of merchantability or fitness for a particular purpose.
76761 + * See the GNU General Public License for more details.
76762 + *
76763 + * You should have received a copy of the GNU General Public License along with
76764 + * this program; if not, write to the Free Software Foundation, Inc.,
76765 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
76766 + *
76767 + * The full GNU General Public License is included in this distribution in
76768 + * the file called "COPYING".
76769 + *
76770 + * Contact Information:
76771 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
76772 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
76773 + *
76774 + ******************************************************************************/
76775 +
76776 +#ifndef _MMU_H_
76777 +#define _MMU_H_
76778 +
76779 +#include "sgxinfokm.h"
76780 +
76781 +PVRSRV_ERROR
76782 +MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr);
76783 +
76784 +IMG_VOID
76785 +MMU_Finalise (MMU_CONTEXT *psMMUContext);
76786 +
76787 +
76788 +IMG_VOID
76789 +MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap);
76790 +
76791 +MMU_HEAP *
76792 +MMU_Create (MMU_CONTEXT *psMMUContext,
76793 +                       DEV_ARENA_DESCRIPTOR *psDevArena,
76794 +                       RA_ARENA **ppsVMArena);
76795 +
76796 +IMG_VOID
76797 +MMU_Delete (MMU_HEAP *pMMU);
76798 +
76799 +IMG_BOOL
76800 +MMU_Alloc (MMU_HEAP *pMMU,
76801 +           IMG_SIZE_T uSize,
76802 +           IMG_SIZE_T *pActualSize,
76803 +           IMG_UINT32 uFlags,
76804 +                  IMG_UINT32 uDevVAddrAlignment,
76805 +           IMG_DEV_VIRTADDR *pDevVAddr);
76806 +
76807 +IMG_VOID
76808 +MMU_Free (MMU_HEAP *pMMU,
76809 +          IMG_DEV_VIRTADDR DevVAddr,
76810 +                 IMG_UINT32 ui32Size);
76811 +
76812 +IMG_VOID
76813 +MMU_Enable (MMU_HEAP *pMMU);
76814 +
76815 +IMG_VOID
76816 +MMU_Disable (MMU_HEAP *pMMU);
76817 +
76818 +IMG_VOID
76819 +MMU_MapPages (MMU_HEAP *pMMU,
76820 +                         IMG_DEV_VIRTADDR devVAddr,
76821 +                         IMG_SYS_PHYADDR SysPAddr,
76822 +                         IMG_SIZE_T uSize,
76823 +                         IMG_UINT32 ui32MemFlags,
76824 +                         IMG_HANDLE hUniqueTag);
76825 +
76826 +IMG_VOID
76827 +MMU_MapShadow (MMU_HEAP          * pMMU,
76828 +               IMG_DEV_VIRTADDR    MapBaseDevVAddr,
76829 +               IMG_SIZE_T          uSize,
76830 +               IMG_CPU_VIRTADDR    CpuVAddr,
76831 +               IMG_HANDLE          hOSMemHandle,
76832 +               IMG_DEV_VIRTADDR  * pDevVAddr,
76833 +               IMG_UINT32          ui32MemFlags,
76834 +               IMG_HANDLE          hUniqueTag);
76835 +
76836 +IMG_VOID
76837 +MMU_UnmapPages (MMU_HEAP *pMMU,
76838 +             IMG_DEV_VIRTADDR dev_vaddr,
76839 +             IMG_UINT32 ui32PageCount,
76840 +             IMG_HANDLE hUniqueTag);
76841 +
76842 +IMG_VOID
76843 +MMU_MapScatter (MMU_HEAP *pMMU,
76844 +                               IMG_DEV_VIRTADDR DevVAddr,
76845 +                               IMG_SYS_PHYADDR *psSysAddr,
76846 +                               IMG_SIZE_T uSize,
76847 +                               IMG_UINT32 ui32MemFlags,
76848 +                               IMG_HANDLE hUniqueTag);
76849 +
76850 +
76851 +IMG_DEV_PHYADDR
76852 +MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
76853 +
76854 +
76855 +IMG_DEV_PHYADDR
76856 +MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext);
76857 +
76858 +
76859 +#ifdef SUPPORT_SGX_MMU_BYPASS
76860 +IMG_VOID
76861 +EnableHostAccess (MMU_CONTEXT *psMMUContext);
76862 +
76863 +
76864 +IMG_VOID
76865 +DisableHostAccess (MMU_CONTEXT *psMMUContext);
76866 +#endif
76867 +
76868 +IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo);
76869 +
76870 +PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo);
76871 +
76872 +IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo);
76873 +
76874 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
76875 +PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo);
76876 +
76877 +IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo);
76878 +
76879 +IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo);
76880 +#endif
76881 +
76882 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
76883 +PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
76884 +
76885 +PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
76886 +#endif
76887 +
76888 +#endif
76889 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/pb.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/pb.c
76890 new file mode 100644
76891 index 0000000..afeb78a
76892 --- /dev/null
76893 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/pb.c
76894 @@ -0,0 +1,458 @@
76895 +/**********************************************************************
76896 + *
76897 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
76898 + *
76899 + * This program is free software; you can redistribute it and/or modify it
76900 + * under the terms and conditions of the GNU General Public License,
76901 + * version 2, as published by the Free Software Foundation.
76902 + *
76903 + * This program is distributed in the hope it will be useful but, except
76904 + * as otherwise stated in writing, without any warranty; without even the
76905 + * implied warranty of merchantability or fitness for a particular purpose.
76906 + * See the GNU General Public License for more details.
76907 + *
76908 + * You should have received a copy of the GNU General Public License along with
76909 + * this program; if not, write to the Free Software Foundation, Inc.,
76910 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
76911 + *
76912 + * The full GNU General Public License is included in this distribution in
76913 + * the file called "COPYING".
76914 + *
76915 + * Contact Information:
76916 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
76917 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
76918 + *
76919 + ******************************************************************************/
76920 +
76921 +#include <stddef.h>
76922 +
76923 +#include "services_headers.h"
76924 +#include "sgxapi_km.h"
76925 +#include "sgxinfo.h"
76926 +#include "sgxinfokm.h"
76927 +#include "pvr_bridge_km.h"
76928 +#include "pdump_km.h"
76929 +#include "sgxutils.h"
76930 +
76931 +#ifndef __linux__
76932 +#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
76933 +#endif
76934 +
76935 +#include "lists.h"
76936 +
76937 +static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
76938 +static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
76939 +
76940 +static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
76941 +static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
76942 +
76943 +static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
76944 +static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
76945 +
76946 +IMG_EXPORT PVRSRV_ERROR
76947 +SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA  *psPerProc,
76948 +                                         IMG_HANDLE                            hDevCookie,
76949 +                                         IMG_BOOL                              bLockOnFailure,
76950 +                                         IMG_UINT32                            ui32TotalPBSize,
76951 +                                         IMG_HANDLE                            *phSharedPBDesc,
76952 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsSharedPBDescKernelMemInfo,
76953 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsHWPBDescKernelMemInfo,
76954 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsBlockKernelMemInfo,
76955 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsHWBlockKernelMemInfo,
76956 +                                         PVRSRV_KERNEL_MEM_INFO        ***pppsSharedPBDescSubKernelMemInfos,
76957 +                                         IMG_UINT32                            *ui32SharedPBDescSubKernelMemInfosCount)
76958 +{
76959 +       PVRSRV_STUB_PBDESC *psStubPBDesc;
76960 +       PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
76961 +       PVRSRV_SGXDEV_INFO *psSGXDevInfo;
76962 +       PVRSRV_ERROR eError;
76963 +
76964 +       psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
76965 +
76966 +       psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
76967 +       if (psStubPBDesc != IMG_NULL)
76968 +       {
76969 +               IMG_UINT32 i;
76970 +               PRESMAN_ITEM psResItem;
76971 +
76972 +               if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
76973 +               {
76974 +                       PVR_DPF((PVR_DBG_WARNING,
76975 +                                       "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
76976 +                                       ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
76977 +               }
76978 +
76979 +               if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
76980 +                                         sizeof(PVRSRV_KERNEL_MEM_INFO *)
76981 +                                               * psStubPBDesc->ui32SubKernelMemInfosCount,
76982 +                                         (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
76983 +                                         IMG_NULL,
76984 +                                         "Array of Kernel Memory Info") != PVRSRV_OK)
76985 +               {
76986 +                       PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
76987 +
76988 +                       eError = PVRSRV_ERROR_OUT_OF_MEMORY;
76989 +                       goto ExitNotFound;
76990 +               }
76991 +
76992 +               psResItem = ResManRegisterRes(psPerProc->hResManContext,
76993 +                                                                         RESMAN_TYPE_SHARED_PB_DESC,
76994 +                                                                         psStubPBDesc,
76995 +                                                                         0,
76996 +                                                                         &SGXCleanupSharedPBDescCallback);
76997 +
76998 +               if (psResItem == IMG_NULL)
76999 +               {
77000 +                       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77001 +                                         sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
77002 +                                         ppsSharedPBDescSubKernelMemInfos,
77003 +                                         0);
77004 +
77005 +
77006 +                       PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
77007 +
77008 +                       eError = PVRSRV_ERROR_GENERIC;
77009 +                       goto ExitNotFound;
77010 +               }
77011 +
77012 +               *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
77013 +               *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
77014 +               *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
77015 +               *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
77016 +
77017 +               *ui32SharedPBDescSubKernelMemInfosCount =
77018 +                       psStubPBDesc->ui32SubKernelMemInfosCount;
77019 +
77020 +               *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
77021 +
77022 +               for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
77023 +               {
77024 +                       ppsSharedPBDescSubKernelMemInfos[i] =
77025 +                               psStubPBDesc->ppsSubKernelMemInfos[i];
77026 +               }
77027 +
77028 +               psStubPBDesc->ui32RefCount++;
77029 +               *phSharedPBDesc = (IMG_HANDLE)psResItem;
77030 +               return PVRSRV_OK;
77031 +       }
77032 +
77033 +       eError = PVRSRV_OK;
77034 +       if (bLockOnFailure)
77035 +       {
77036 +               if (psResItemCreateSharedPB == IMG_NULL)
77037 +               {
77038 +                       psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
77039 +                                 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
77040 +                                 psPerProc,
77041 +                                 0,
77042 +                                 &SGXCleanupSharedPBDescCreateLockCallback);
77043 +
77044 +                       if (psResItemCreateSharedPB == IMG_NULL)
77045 +                       {
77046 +                               PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
77047 +
77048 +                               eError = PVRSRV_ERROR_GENERIC;
77049 +                               goto ExitNotFound;
77050 +                       }
77051 +                       PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
77052 +                       psPerProcCreateSharedPB = psPerProc;
77053 +               }
77054 +               else
77055 +               {
77056 +                        eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
77057 +               }
77058 +       }
77059 +ExitNotFound:
77060 +       *phSharedPBDesc = IMG_NULL;
77061 +
77062 +       return eError;
77063 +}
77064 +
77065 +
77066 +static PVRSRV_ERROR
77067 +SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
77068 +{
77069 +
77070 +       IMG_UINT32 i;
77071 +       PVRSRV_DEVICE_NODE *psDeviceNode;
77072 +
77073 +       psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
77074 +
77075 +
77076 +
77077 +
77078 +       psStubPBDescIn->ui32RefCount--;
77079 +       if (psStubPBDescIn->ui32RefCount == 0)
77080 +       {
77081 +               List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
77082 +               for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
77083 +               {
77084 +
77085 +                       PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
77086 +                                                                 psStubPBDescIn->ppsSubKernelMemInfos[i]);
77087 +               }
77088 +
77089 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77090 +                                 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
77091 +                                 psStubPBDescIn->ppsSubKernelMemInfos,
77092 +                                 0);
77093 +               psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
77094 +
77095 +               PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
77096 +
77097 +               PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
77098 +
77099 +               PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
77100 +
77101 +               PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
77102 +
77103 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77104 +                                 sizeof(PVRSRV_STUB_PBDESC),
77105 +                                 psStubPBDescIn,
77106 +                                 0);
77107 +
77108 +
77109 +
77110 +               SGXCleanupRequest(psDeviceNode,
77111 +                                                 IMG_NULL,
77112 +                                                 PVRSRV_CLEANUPCMD_PB);
77113 +       }
77114 +       return PVRSRV_OK;
77115 +
77116 +}
77117 +
77118 +static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
77119 +{
77120 +       PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
77121 +
77122 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
77123 +
77124 +       return SGXCleanupSharedPBDescKM(psStubPBDesc);
77125 +}
77126 +
77127 +static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
77128 +{
77129 +#ifdef DEBUG
77130 +       PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
77131 +       PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
77132 +#else
77133 +       PVR_UNREFERENCED_PARAMETER(pvParam);
77134 +#endif
77135 +
77136 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
77137 +
77138 +       psPerProcCreateSharedPB = IMG_NULL;
77139 +       psResItemCreateSharedPB = IMG_NULL;
77140 +
77141 +       return PVRSRV_OK;
77142 +}
77143 +
77144 +
77145 +IMG_EXPORT PVRSRV_ERROR
77146 +SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
77147 +{
77148 +       PVR_ASSERT(hSharedPBDesc != IMG_NULL);
77149 +
77150 +       return ResManFreeResByPtr(hSharedPBDesc);
77151 +}
77152 +
77153 +
77154 +IMG_EXPORT PVRSRV_ERROR
77155 +SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA   *psPerProc,
77156 +                                        IMG_HANDLE                                     hDevCookie,
77157 +                                        PVRSRV_KERNEL_MEM_INFO         *psSharedPBDescKernelMemInfo,
77158 +                                        PVRSRV_KERNEL_MEM_INFO         *psHWPBDescKernelMemInfo,
77159 +                                        PVRSRV_KERNEL_MEM_INFO         *psBlockKernelMemInfo,
77160 +                                        PVRSRV_KERNEL_MEM_INFO         *psHWBlockKernelMemInfo,
77161 +                                        IMG_UINT32                                     ui32TotalPBSize,
77162 +                                        IMG_HANDLE                                     *phSharedPBDesc,
77163 +                                        PVRSRV_KERNEL_MEM_INFO         **ppsSharedPBDescSubKernelMemInfos,
77164 +                                        IMG_UINT32                                     ui32SharedPBDescSubKernelMemInfosCount)
77165 +{
77166 +       PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
77167 +       PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
77168 +       IMG_UINT32 i;
77169 +       PVRSRV_SGXDEV_INFO *psSGXDevInfo;
77170 +       PRESMAN_ITEM psResItem;
77171 +
77172 +
77173 +       if (psPerProcCreateSharedPB != psPerProc)
77174 +       {
77175 +               goto NoAdd;
77176 +       }
77177 +       else
77178 +       {
77179 +               PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
77180 +
77181 +               ResManFreeResByPtr(psResItemCreateSharedPB);
77182 +
77183 +               PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
77184 +               PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
77185 +       }
77186 +
77187 +       psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
77188 +
77189 +       psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
77190 +       if (psStubPBDesc != IMG_NULL)
77191 +       {
77192 +               if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
77193 +               {
77194 +                       PVR_DPF((PVR_DBG_WARNING,
77195 +                                       "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
77196 +                                       ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
77197 +
77198 +               }
77199 +
77200 +
77201 +               psResItem = ResManRegisterRes(psPerProc->hResManContext,
77202 +                                                                         RESMAN_TYPE_SHARED_PB_DESC,
77203 +                                                                         psStubPBDesc,
77204 +                                                                         0,
77205 +                                                                         &SGXCleanupSharedPBDescCallback);
77206 +               if (psResItem == IMG_NULL)
77207 +               {
77208 +                       PVR_DPF((PVR_DBG_ERROR,
77209 +                               "SGXAddSharedPBDescKM: "
77210 +                               "Failed to register existing shared "
77211 +                               "PBDesc with the resource manager"));
77212 +                       goto NoAddKeepPB;
77213 +               }
77214 +
77215 +
77216 +               psStubPBDesc->ui32RefCount++;
77217 +
77218 +               *phSharedPBDesc = (IMG_HANDLE)psResItem;
77219 +               eRet = PVRSRV_OK;
77220 +               goto NoAddKeepPB;
77221 +       }
77222 +
77223 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77224 +                                 sizeof(PVRSRV_STUB_PBDESC),
77225 +                                 (IMG_VOID **)&psStubPBDesc,
77226 +                                 0,
77227 +                                 "Stub Parameter Buffer Description") != PVRSRV_OK)
77228 +       {
77229 +               PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
77230 +                                       "StubPBDesc"));
77231 +               eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
77232 +               goto NoAdd;
77233 +       }
77234 +
77235 +
77236 +       psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
77237 +
77238 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77239 +                                 sizeof(PVRSRV_KERNEL_MEM_INFO *)
77240 +                                 * ui32SharedPBDescSubKernelMemInfosCount,
77241 +                                 (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
77242 +                                 0,
77243 +                                 "Array of Kernel Memory Info") != PVRSRV_OK)
77244 +       {
77245 +               PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
77246 +                                "Failed to alloc "
77247 +                                "StubPBDesc->ppsSubKernelMemInfos"));
77248 +               eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
77249 +               goto NoAdd;
77250 +       }
77251 +
77252 +       if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
77253 +          != PVRSRV_OK)
77254 +       {
77255 +               goto NoAdd;
77256 +       }
77257 +
77258 +       if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
77259 +          != PVRSRV_OK)
77260 +       {
77261 +               goto NoAdd;
77262 +       }
77263 +
77264 +       if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
77265 +          != PVRSRV_OK)
77266 +       {
77267 +               goto NoAdd;
77268 +       }
77269 +
77270 +       if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
77271 +          != PVRSRV_OK)
77272 +       {
77273 +               goto NoAdd;
77274 +       }
77275 +
77276 +       psStubPBDesc->ui32RefCount = 1;
77277 +       psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
77278 +       psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
77279 +       psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
77280 +       psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
77281 +       psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
77282 +
77283 +       psStubPBDesc->ui32SubKernelMemInfosCount =
77284 +               ui32SharedPBDescSubKernelMemInfosCount;
77285 +       for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
77286 +       {
77287 +               psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
77288 +               if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
77289 +                  != PVRSRV_OK)
77290 +               {
77291 +                       PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
77292 +                                        "Failed to dissociate shared PBDesc "
77293 +                                        "from process"));
77294 +                       goto NoAdd;
77295 +               }
77296 +       }
77297 +
77298 +       psResItem = ResManRegisterRes(psPerProc->hResManContext,
77299 +                                                                 RESMAN_TYPE_SHARED_PB_DESC,
77300 +                                                                 psStubPBDesc,
77301 +                                                                 0,
77302 +                                                                 &SGXCleanupSharedPBDescCallback);
77303 +       if (psResItem == IMG_NULL)
77304 +       {
77305 +               PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
77306 +                                        "Failed to register shared PBDesc "
77307 +                                        " with the resource manager"));
77308 +               goto NoAdd;
77309 +       }
77310 +       psStubPBDesc->hDevCookie = hDevCookie;
77311 +
77312 +
77313 +       List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
77314 +                                                                       psStubPBDesc);
77315 +
77316 +       *phSharedPBDesc = (IMG_HANDLE)psResItem;
77317 +
77318 +       return PVRSRV_OK;
77319 +
77320 +NoAdd:
77321 +       if(psStubPBDesc)
77322 +       {
77323 +               if(psStubPBDesc->ppsSubKernelMemInfos)
77324 +               {
77325 +                       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77326 +                                         sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
77327 +                                         psStubPBDesc->ppsSubKernelMemInfos,
77328 +                                         0);
77329 +                       psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
77330 +               }
77331 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
77332 +                                 sizeof(PVRSRV_STUB_PBDESC),
77333 +                                 psStubPBDesc,
77334 +                                 0);
77335 +
77336 +       }
77337 +
77338 +NoAddKeepPB:
77339 +       for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
77340 +       {
77341 +               PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
77342 +       }
77343 +
77344 +       PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
77345 +       PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
77346 +
77347 +       PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
77348 +       PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
77349 +
77350 +       return eRet;
77351 +}
77352 +
77353 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h
77354 new file mode 100644
77355 index 0000000..72f025d
77356 --- /dev/null
77357 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgx_bridge_km.h
77358 @@ -0,0 +1,147 @@
77359 +/**********************************************************************
77360 + *
77361 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
77362 + *
77363 + * This program is free software; you can redistribute it and/or modify it
77364 + * under the terms and conditions of the GNU General Public License,
77365 + * version 2, as published by the Free Software Foundation.
77366 + *
77367 + * This program is distributed in the hope it will be useful but, except
77368 + * as otherwise stated in writing, without any warranty; without even the
77369 + * implied warranty of merchantability or fitness for a particular purpose.
77370 + * See the GNU General Public License for more details.
77371 + *
77372 + * You should have received a copy of the GNU General Public License along with
77373 + * this program; if not, write to the Free Software Foundation, Inc.,
77374 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
77375 + *
77376 + * The full GNU General Public License is included in this distribution in
77377 + * the file called "COPYING".
77378 + *
77379 + * Contact Information:
77380 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
77381 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
77382 + *
77383 + ******************************************************************************/
77384 +
77385 +#if !defined(__SGX_BRIDGE_KM_H__)
77386 +#define __SGX_BRIDGE_KM_H__
77387 +
77388 +#include "sgxapi_km.h"
77389 +#include "sgxinfo.h"
77390 +#include "sgxinfokm.h"
77391 +#include "sgx_bridge.h"
77392 +#include "pvr_bridge.h"
77393 +#include "perproc.h"
77394 +
77395 +#if defined (__cplusplus)
77396 +extern "C" {
77397 +#endif
77398 +
77399 +IMG_IMPORT
77400 +PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick);
77401 +
77402 +#if defined(SGX_FEATURE_2D_HARDWARE)
77403 +IMG_IMPORT
77404 +PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick);
77405 +#endif
77406 +
77407 +IMG_IMPORT
77408 +PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle,
77409 +                                                SGX_CCB_KICK *psCCBKick);
77410 +
77411 +IMG_IMPORT
77412 +PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap,
77413 +                                                                 IMG_DEV_VIRTADDR sDevVAddr,
77414 +                                                                 IMG_DEV_PHYADDR *pDevPAddr,
77415 +                                                                 IMG_CPU_PHYADDR *pCpuPAddr);
77416 +
77417 +IMG_IMPORT
77418 +PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE         hDevCookie,
77419 +                                                                                       IMG_HANDLE              hDevMemContext,
77420 +                                                                                       IMG_DEV_PHYADDR *psPDDevPAddr);
77421 +
77422 +IMG_IMPORT
77423 +PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE                             hDevCookie,
77424 +                                                               SGX_CLIENT_INFO*        psClientInfo);
77425 +
77426 +IMG_IMPORT
77427 +PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO       *psDevInfo,
77428 +                                                         SGX_MISC_INFO                 *psMiscInfo,
77429 +                                                         PVRSRV_DEVICE_NODE    *psDeviceNode,
77430 +                                                         IMG_HANDLE                     hDevMemContext);
77431 +
77432 +#if defined(SUPPORT_SGX_HWPERF)
77433 +IMG_IMPORT
77434 +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE                          hDevHandle,
77435 +                                                                  IMG_UINT32                           ui32Reg,
77436 +                                                                  IMG_UINT32                           *pui32Old,
77437 +                                                                  IMG_BOOL                                     bNew,
77438 +                                                                  IMG_UINT32                           ui32New,
77439 +                                                                  IMG_UINT32                           ui32NewReset,
77440 +                                                                  IMG_UINT32                           ui32CountersReg,
77441 +                                                                  IMG_UINT32                           ui32Reg2,
77442 +                                                                  IMG_BOOL                                     *pbActive,
77443 +                                                                  PVRSRV_SGXDEV_DIFF_INFO      *psDiffs);
77444 +IMG_IMPORT
77445 +PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE                                      hDevHandle,
77446 +                                                          IMG_UINT32                                   ui32ArraySize,
77447 +                                                          PVRSRV_SGX_HWPERF_CB_ENTRY   *psHWPerfCBData,
77448 +                                                          IMG_UINT32                                   *pui32DataCount,
77449 +                                                          IMG_UINT32                                   *pui32ClockSpeed,
77450 +                                                          IMG_UINT32                                   *pui32HostTimeStamp);
77451 +#endif
77452 +
77453 +IMG_IMPORT
77454 +PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO              *psDevInfo,
77455 +                                                                          PVRSRV_KERNEL_SYNC_INFO      *psSyncInfo,
77456 +                                                                          IMG_BOOL bWaitForComplete);
77457 +
77458 +IMG_IMPORT
77459 +PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle,
77460 +                                                                       SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo);
77461 +
77462 +IMG_IMPORT
77463 +PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc,
77464 +                                                          IMG_HANDLE hDevHandle,
77465 +                                                          SGX_BRIDGE_INIT_INFO *psInitInfo);
77466 +
77467 +IMG_IMPORT PVRSRV_ERROR
77468 +SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA  *psPerProc,
77469 +                                         IMG_HANDLE                            hDevCookie,
77470 +                                         IMG_BOOL                              bLockOnFailure,
77471 +                                         IMG_UINT32                            ui32TotalPBSize,
77472 +                                         IMG_HANDLE                            *phSharedPBDesc,
77473 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsSharedPBDescKernelMemInfo,
77474 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsHWPBDescKernelMemInfo,
77475 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsBlockKernelMemInfo,
77476 +                                         PVRSRV_KERNEL_MEM_INFO        **ppsHWBlockKernelMemInfo,
77477 +                                         PVRSRV_KERNEL_MEM_INFO        ***pppsSharedPBDescSubKernelMemInfos,
77478 +                                         IMG_UINT32                            *ui32SharedPBDescSubKernelMemInfosCount);
77479 +
77480 +IMG_IMPORT PVRSRV_ERROR
77481 +SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc);
77482 +
77483 +IMG_IMPORT PVRSRV_ERROR
77484 +SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA   *psPerProc,
77485 +                                        IMG_HANDLE                             hDevCookie,
77486 +                                        PVRSRV_KERNEL_MEM_INFO         *psSharedPBDescKernelMemInfo,
77487 +                                        PVRSRV_KERNEL_MEM_INFO         *psHWPBDescKernelMemInfo,
77488 +                                        PVRSRV_KERNEL_MEM_INFO         *psBlockKernelMemInfo,
77489 +                                        PVRSRV_KERNEL_MEM_INFO         *psHWBlockKernelMemInfo,
77490 +                                        IMG_UINT32                                     ui32TotalPBSize,
77491 +                                        IMG_HANDLE                                     *phSharedPBDesc,
77492 +                                        PVRSRV_KERNEL_MEM_INFO         **psSharedPBDescSubKernelMemInfos,
77493 +                                        IMG_UINT32                                     ui32SharedPBDescSubKernelMemInfosCount);
77494 +
77495 +
77496 +IMG_IMPORT PVRSRV_ERROR
77497 +SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
77498 +                                               SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo);
77499 +
77500 +#if defined (__cplusplus)
77501 +}
77502 +#endif
77503 +
77504 +#endif
77505 +
77506 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxconfig.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxconfig.h
77507 new file mode 100644
77508 index 0000000..63cd151
77509 --- /dev/null
77510 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxconfig.h
77511 @@ -0,0 +1,134 @@
77512 +/**********************************************************************
77513 + *
77514 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
77515 + *
77516 + * This program is free software; you can redistribute it and/or modify it
77517 + * under the terms and conditions of the GNU General Public License,
77518 + * version 2, as published by the Free Software Foundation.
77519 + *
77520 + * This program is distributed in the hope it will be useful but, except
77521 + * as otherwise stated in writing, without any warranty; without even the
77522 + * implied warranty of merchantability or fitness for a particular purpose.
77523 + * See the GNU General Public License for more details.
77524 + *
77525 + * You should have received a copy of the GNU General Public License along with
77526 + * this program; if not, write to the Free Software Foundation, Inc.,
77527 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
77528 + *
77529 + * The full GNU General Public License is included in this distribution in
77530 + * the file called "COPYING".
77531 + *
77532 + * Contact Information:
77533 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
77534 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
77535 + *
77536 + ******************************************************************************/
77537 +
77538 +#ifndef __SGXCONFIG_H__
77539 +#define __SGXCONFIG_H__
77540 +
77541 +#include "sgxdefs.h"
77542 +
77543 +#define DEV_DEVICE_TYPE                        PVRSRV_DEVICE_TYPE_SGX
77544 +#define DEV_DEVICE_CLASS               PVRSRV_DEVICE_CLASS_3D
77545 +
77546 +#define DEV_MAJOR_VERSION              1
77547 +#define DEV_MINOR_VERSION              0
77548 +
77549 +#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
77550 +       #if defined(SGX_FEATURE_2D_HARDWARE)
77551 +       #define SGX_2D_HEAP_BASE                                         0x00100000
77552 +       #define SGX_2D_HEAP_SIZE                                        (0x08000000-0x00100000-0x00001000)
77553 +       #else
77554 +               #if defined(FIX_HW_BRN_26915)
77555 +               #define SGX_CGBUFFER_HEAP_BASE                                   0x00100000
77556 +               #define SGX_CGBUFFER_HEAP_SIZE                                  (0x08000000-0x00100000-0x00001000)
77557 +               #endif
77558 +       #endif
77559 +
77560 +       #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
77561 +       #define SGX_GENERAL_MAPPING_HEAP_BASE            0x08000000
77562 +       #define SGX_GENERAL_MAPPING_HEAP_SIZE           (0x08000000-0x00001000)
77563 +       #endif
77564 +
77565 +       #define SGX_GENERAL_HEAP_BASE                            0x10000000
77566 +       #define SGX_GENERAL_HEAP_SIZE                           (0xC8000000-0x00001000)
77567 +
77568 +       #define SGX_3DPARAMETERS_HEAP_BASE                       0xD8000000
77569 +       #define SGX_3DPARAMETERS_HEAP_SIZE                      (0x10000000-0x00001000)
77570 +
77571 +       #define SGX_TADATA_HEAP_BASE                             0xE8000000
77572 +       #define SGX_TADATA_HEAP_SIZE                            (0x0D000000-0x00001000)
77573 +
77574 +       #define SGX_SYNCINFO_HEAP_BASE                           0xF5000000
77575 +       #define SGX_SYNCINFO_HEAP_SIZE                          (0x01000000-0x00001000)
77576 +
77577 +       #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE          0xF6000000
77578 +       #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE         (0x02000000-0x00001000)
77579 +
77580 +       #define SGX_KERNEL_CODE_HEAP_BASE                        0xF8000000
77581 +       #define SGX_KERNEL_CODE_HEAP_SIZE                       (0x00080000-0x00001000)
77582 +
77583 +       #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE         0xF8400000
77584 +       #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE        (0x01C00000-0x00001000)
77585 +
77586 +       #define SGX_KERNEL_DATA_HEAP_BASE                        0xFA000000
77587 +       #define SGX_KERNEL_DATA_HEAP_SIZE                       (0x05000000-0x00001000)
77588 +
77589 +       #define SGX_PIXELSHADER_HEAP_BASE                        0xFF000000
77590 +       #define SGX_PIXELSHADER_HEAP_SIZE                       (0x00500000-0x00001000)
77591 +
77592 +       #define SGX_VERTEXSHADER_HEAP_BASE                       0xFF800000
77593 +       #define SGX_VERTEXSHADER_HEAP_SIZE                      (0x00200000-0x00001000)
77594 +
77595 +
77596 +       #define SGX_CORE_IDENTIFIED
77597 +#endif
77598 +
77599 +#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28
77600 +       #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
77601 +       #define SGX_GENERAL_MAPPING_HEAP_BASE            0x00001000
77602 +       #define SGX_GENERAL_MAPPING_HEAP_SIZE           (0x01800000-0x00001000-0x00001000)
77603 +       #endif
77604 +
77605 +       #define SGX_GENERAL_HEAP_BASE                            0x01800000
77606 +       #define SGX_GENERAL_HEAP_SIZE                           (0x07000000-0x00001000)
77607 +
77608 +       #define SGX_3DPARAMETERS_HEAP_BASE                       0x08800000
77609 +       #define SGX_3DPARAMETERS_HEAP_SIZE                      (0x04000000-0x00001000)
77610 +
77611 +       #define SGX_TADATA_HEAP_BASE                             0x0C800000
77612 +       #define SGX_TADATA_HEAP_SIZE                            (0x01000000-0x00001000)
77613 +
77614 +       #define SGX_SYNCINFO_HEAP_BASE                           0x0D800000
77615 +       #define SGX_SYNCINFO_HEAP_SIZE                          (0x00400000-0x00001000)
77616 +
77617 +       #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE          0x0DC00000
77618 +       #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE         (0x00800000-0x00001000)
77619 +
77620 +       #define SGX_KERNEL_CODE_HEAP_BASE                        0x0E400000
77621 +       #define SGX_KERNEL_CODE_HEAP_SIZE                       (0x00080000-0x00001000)
77622 +
77623 +       #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE         0x0E800000
77624 +       #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE        (0x00800000-0x00001000)
77625 +
77626 +       #define SGX_KERNEL_DATA_HEAP_BASE                        0x0F000000
77627 +       #define SGX_KERNEL_DATA_HEAP_SIZE                       (0x00400000-0x00001000)
77628 +
77629 +       #define SGX_PIXELSHADER_HEAP_BASE                        0x0F400000
77630 +       #define SGX_PIXELSHADER_HEAP_SIZE                       (0x00500000-0x00001000)
77631 +
77632 +       #define SGX_VERTEXSHADER_HEAP_BASE                       0x0FC00000
77633 +       #define SGX_VERTEXSHADER_HEAP_SIZE                      (0x00200000-0x00001000)
77634 +
77635 +
77636 +       #define SGX_CORE_IDENTIFIED
77637 +
77638 +#endif
77639 +
77640 +#if !defined(SGX_CORE_IDENTIFIED)
77641 +       #error "sgxconfig.h: ERROR: unspecified SGX Core version"
77642 +#endif
77643 +
77644 +#endif
77645 +
77646 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h
77647 new file mode 100644
77648 index 0000000..1ddd709
77649 --- /dev/null
77650 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinfokm.h
77651 @@ -0,0 +1,352 @@
77652 +/**********************************************************************
77653 + *
77654 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
77655 + * 
77656 + * This program is free software; you can redistribute it and/or modify it
77657 + * under the terms and conditions of the GNU General Public License,
77658 + * version 2, as published by the Free Software Foundation.
77659 + * 
77660 + * This program is distributed in the hope it will be useful but, except 
77661 + * as otherwise stated in writing, without any warranty; without even the 
77662 + * implied warranty of merchantability or fitness for a particular purpose. 
77663 + * See the GNU General Public License for more details.
77664 + * 
77665 + * You should have received a copy of the GNU General Public License along with
77666 + * this program; if not, write to the Free Software Foundation, Inc.,
77667 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
77668 + * 
77669 + * The full GNU General Public License is included in this distribution in
77670 + * the file called "COPYING".
77671 + *
77672 + * Contact Information:
77673 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
77674 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
77675 + *
77676 + ******************************************************************************/
77677 +
77678 +#ifndef __SGXINFOKM_H__
77679 +#define __SGXINFOKM_H__
77680 +
77681 +#include "sgxdefs.h"
77682 +#include "device.h"
77683 +#include "power.h"
77684 +#include "sysconfig.h"
77685 +#include "sgxscript.h"
77686 +#include "sgxinfo.h"
77687 +
77688 +#if defined (__cplusplus)
77689 +extern "C" {
77690 +#endif
77691 +
77692 +#define                SGX_HOSTPORT_PRESENT                    0x00000001UL
77693 +
77694 +
77695 +typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
77696 +
77697 +
77698 +typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO;
77699 +
77700 +typedef struct _PVRSRV_SGXDEV_INFO_
77701 +{
77702 +       PVRSRV_DEVICE_TYPE              eDeviceType;
77703 +       PVRSRV_DEVICE_CLASS             eDeviceClass;
77704 +
77705 +       IMG_UINT8                               ui8VersionMajor;
77706 +       IMG_UINT8                               ui8VersionMinor;
77707 +       IMG_UINT32                              ui32CoreConfig;
77708 +       IMG_UINT32                              ui32CoreFlags;
77709 +
77710 +       
77711 +       IMG_PVOID                               pvRegsBaseKM;
77712 +
77713 +#if defined(SGX_FEATURE_HOST_PORT)
77714 +       
77715 +       IMG_PVOID                               pvHostPortBaseKM;
77716 +       
77717 +       IMG_UINT32                              ui32HPSize;
77718 +       
77719 +       IMG_SYS_PHYADDR                 sHPSysPAddr;
77720 +#endif
77721 +
77722 +       
77723 +       IMG_HANDLE                              hRegMapping;
77724 +
77725 +       
77726 +       IMG_SYS_PHYADDR                 sRegsPhysBase;
77727 +       
77728 +       IMG_UINT32                              ui32RegSize;
77729 +
77730 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
77731 +       
77732 +       IMG_UINT32                              ui32ExtSysCacheRegsSize;
77733 +       
77734 +       IMG_DEV_PHYADDR                 sExtSysCacheRegsDevPBase;
77735 +       
77736 +       IMG_UINT32                              *pui32ExtSystemCacheRegsPT;
77737 +       
77738 +       IMG_HANDLE                              hExtSystemCacheRegsPTPageOSMemHandle;
77739 +       
77740 +       IMG_SYS_PHYADDR                 sExtSystemCacheRegsPTSysPAddr;
77741 +#endif
77742 +
77743 +       
77744 +       IMG_UINT32                              ui32CoreClockSpeed;
77745 +       IMG_UINT32                              ui32uKernelTimerClock;
77746 +
77747 +       PVRSRV_STUB_PBDESC              *psStubPBDescListKM;
77748 +
77749 +
77750 +       
77751 +       IMG_DEV_PHYADDR                 sKernelPDDevPAddr;
77752 +
77753 +       IMG_VOID                                *pvDeviceMemoryHeap;
77754 +       PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo;                     
77755 +       PVRSRV_SGX_KERNEL_CCB   *psKernelCCB;                   
77756 +       PPVRSRV_SGX_CCB_INFO    psKernelCCBInfo;                
77757 +       PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo;  
77758 +       PVRSRV_SGX_CCB_CTL              *psKernelCCBCtl;                
77759 +       PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; 
77760 +       IMG_UINT32                              *pui32KernelCCBEventKicker; 
77761 +#if defined(PDUMP)
77762 +       IMG_UINT32                              ui32KernelCCBEventKickerDumpVal; 
77763 +#endif 
77764 +       PVRSRV_KERNEL_MEM_INFO  *psKernelSGXMiscMemInfo;        
77765 +       IMG_UINT32                              aui32HostKickAddr[SGXMKIF_CMD_MAX];             
77766 +#if defined(SGX_SUPPORT_HWPROFILING)
77767 +       PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo;
77768 +#endif
77769 +       IMG_UINT32                              ui32KickTACounter;
77770 +       IMG_UINT32                              ui32KickTARenderCounter;
77771 +#if defined(SUPPORT_SGX_HWPERF)
77772 +       PPVRSRV_KERNEL_MEM_INFO         psKernelHWPerfCBMemInfo;
77773 +       IMG_UINT32                                      ui32HWGroupRequested;
77774 +       IMG_UINT32                                      ui32HWReset;
77775 +#endif
77776 +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
77777 +       PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo; 
77778 +#endif 
77779 +#if defined(SGX_FEATURE_OVERLAPPED_SPM)
77780 +       PPVRSRV_KERNEL_MEM_INFO psKernelTmpRgnHeaderMemInfo; 
77781 +#endif 
77782 +#if defined(SGX_FEATURE_SPM_MODE_0)
77783 +       PPVRSRV_KERNEL_MEM_INFO psKernelTmpDPMStateMemInfo; 
77784 +#endif 
77785 +
77786 +       
77787 +       IMG_UINT32                              ui32ClientRefCount;
77788 +
77789 +       
77790 +       IMG_UINT32                              ui32CacheControl;
77791 +
77792 +       
77793 +       IMG_UINT32                              ui32ClientBuildOptions;
77794 +
77795 +       
77796 +       SGX_MISCINFO_STRUCT_SIZES       sSGXStructSizes;
77797 +
77798 +       
77799 +
77800 +
77801 +       IMG_VOID                                *pvMMUContextList;
77802 +
77803 +       
77804 +       IMG_BOOL                                bForcePTOff;
77805 +
77806 +       IMG_UINT32                              ui32EDMTaskReg0;
77807 +       IMG_UINT32                              ui32EDMTaskReg1;
77808 +
77809 +       IMG_UINT32                              ui32ClkGateStatusReg;
77810 +       IMG_UINT32                              ui32ClkGateStatusMask;
77811 +#if defined(SGX_FEATURE_MP)
77812 +       IMG_UINT32                              ui32MasterClkGateStatusReg;
77813 +       IMG_UINT32                              ui32MasterClkGateStatusMask;
77814 +#endif 
77815 +       SGX_INIT_SCRIPTS                sScripts;
77816 +
77817 +       
77818 +       IMG_HANDLE                              hBIFResetPDOSMemHandle;
77819 +       IMG_DEV_PHYADDR                 sBIFResetPDDevPAddr;
77820 +       IMG_DEV_PHYADDR                 sBIFResetPTDevPAddr;
77821 +       IMG_DEV_PHYADDR                 sBIFResetPageDevPAddr;
77822 +       IMG_UINT32                              *pui32BIFResetPD;
77823 +       IMG_UINT32                              *pui32BIFResetPT;
77824 +
77825 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
77826 +       
77827 +       IMG_HANDLE                              hBRN22997PTPageOSMemHandle;
77828 +       IMG_HANDLE                              hBRN22997PDPageOSMemHandle;
77829 +       IMG_DEV_PHYADDR                 sBRN22997PTDevPAddr;
77830 +       IMG_DEV_PHYADDR                 sBRN22997PDDevPAddr;
77831 +       IMG_UINT32                              *pui32BRN22997PT;
77832 +       IMG_UINT32                              *pui32BRN22997PD;
77833 +       IMG_SYS_PHYADDR                 sBRN22997SysPAddr;
77834 +#endif 
77835 +
77836 +#if defined(SUPPORT_HW_RECOVERY)
77837 +       
77838 +       IMG_HANDLE                              hTimer;
77839 +       
77840 +       IMG_UINT32                              ui32TimeStamp;
77841 +#endif
77842 +
77843 +       
77844 +       IMG_UINT32                              ui32NumResets;
77845 +
77846 +       
77847 +       PVRSRV_KERNEL_MEM_INFO                  *psKernelSGXHostCtlMemInfo;
77848 +       SGXMKIF_HOST_CTL                                *psSGXHostCtl;
77849 +
77850 +       
77851 +       PVRSRV_KERNEL_MEM_INFO                  *psKernelSGXTA3DCtlMemInfo;
77852 +
77853 +       IMG_UINT32                              ui32Flags;
77854 +
77855 +       #if defined(PDUMP)
77856 +       PVRSRV_SGX_PDUMP_CONTEXT        sPDContext;
77857 +       #endif
77858 +
77859 +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
77860 +       
77861 +       IMG_VOID                                *pvDummyPTPageCpuVAddr;
77862 +       IMG_DEV_PHYADDR                 sDummyPTDevPAddr;
77863 +       IMG_HANDLE                              hDummyPTPageOSMemHandle;
77864 +       IMG_VOID                                *pvDummyDataPageCpuVAddr;
77865 +       IMG_DEV_PHYADDR                 sDummyDataDevPAddr;
77866 +       IMG_HANDLE                              hDummyDataPageOSMemHandle;
77867 +#endif
77868 +
77869 +       IMG_UINT32                              asSGXDevData[SGX_MAX_DEV_DATA];
77870 +
77871 +} PVRSRV_SGXDEV_INFO;
77872 +
77873 +
77874 +typedef struct _SGX_TIMING_INFORMATION_
77875 +{
77876 +       IMG_UINT32                      ui32CoreClockSpeed;
77877 +       IMG_UINT32                      ui32HWRecoveryFreq;
77878 +       IMG_BOOL                        bEnableActivePM;
77879 +       IMG_UINT32                      ui32ActivePowManLatencyms;
77880 +       IMG_UINT32                      ui32uKernelFreq;
77881 +} SGX_TIMING_INFORMATION;
77882 +
77883 +typedef struct _SGX_DEVICE_MAP_
77884 +{
77885 +       IMG_UINT32                              ui32Flags;
77886 +
77887 +       
77888 +       IMG_SYS_PHYADDR                 sRegsSysPBase;
77889 +       IMG_CPU_PHYADDR                 sRegsCpuPBase;
77890 +       IMG_CPU_VIRTADDR                pvRegsCpuVBase;
77891 +       IMG_UINT32                              ui32RegsSize;
77892 +
77893 +#if defined(SGX_FEATURE_HOST_PORT)
77894 +       IMG_SYS_PHYADDR                 sHPSysPBase;
77895 +       IMG_CPU_PHYADDR                 sHPCpuPBase;
77896 +       IMG_UINT32                              ui32HPSize;
77897 +#endif
77898 +
77899 +       
77900 +       IMG_SYS_PHYADDR                 sLocalMemSysPBase;
77901 +       IMG_DEV_PHYADDR                 sLocalMemDevPBase;
77902 +       IMG_CPU_PHYADDR                 sLocalMemCpuPBase;
77903 +       IMG_UINT32                              ui32LocalMemSize;
77904 +
77905 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
77906 +       IMG_UINT32                              ui32ExtSysCacheRegsSize;
77907 +       IMG_DEV_PHYADDR                 sExtSysCacheRegsDevPBase;
77908 +#endif
77909 +
77910 +       
77911 +       IMG_UINT32                              ui32IRQ;
77912 +
77913 +#if !defined(SGX_DYNAMIC_TIMING_INFO)
77914 +       
77915 +       SGX_TIMING_INFORMATION  sTimingInfo;
77916 +#endif
77917 +} SGX_DEVICE_MAP;
77918 +
77919 +
77920 +struct _PVRSRV_STUB_PBDESC_
77921 +{
77922 +       IMG_UINT32              ui32RefCount;
77923 +       IMG_UINT32              ui32TotalPBSize;
77924 +       PVRSRV_KERNEL_MEM_INFO  *psSharedPBDescKernelMemInfo;
77925 +       PVRSRV_KERNEL_MEM_INFO  *psHWPBDescKernelMemInfo;
77926 +       PVRSRV_KERNEL_MEM_INFO  **ppsSubKernelMemInfos;
77927 +       IMG_UINT32              ui32SubKernelMemInfosCount;
77928 +       IMG_HANDLE              hDevCookie;
77929 +       PVRSRV_KERNEL_MEM_INFO  *psBlockKernelMemInfo;
77930 +       PVRSRV_KERNEL_MEM_INFO  *psHWBlockKernelMemInfo;
77931 +       PVRSRV_STUB_PBDESC      *psNext;
77932 +       PVRSRV_STUB_PBDESC      **ppsThis;
77933 +};
77934 +
77935 +typedef struct _PVRSRV_SGX_CCB_INFO_
77936 +{
77937 +       PVRSRV_KERNEL_MEM_INFO  *psCCBMemInfo;                  
77938 +       PVRSRV_KERNEL_MEM_INFO  *psCCBCtlMemInfo;               
77939 +       SGXMKIF_COMMAND         *psCommands;                    
77940 +       IMG_UINT32                              *pui32WriteOffset;              
77941 +       volatile IMG_UINT32             *pui32ReadOffset;               
77942 +#if defined(PDUMP)
77943 +       IMG_UINT32                              ui32CCBDumpWOff;                
77944 +#endif
77945 +} PVRSRV_SGX_CCB_INFO;
77946 +
77947 +PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode);
77948 +
77949 +IMG_VOID SGXOSTimer(IMG_VOID *pvData);
77950 +
77951 +IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO   *psDevInfo,
77952 +                                 IMG_UINT32                     ui32PDUMPFlags);
77953 +
77954 +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO  *psDevInfo);
77955 +PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie);
77956 +
77957 +PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE                               hDevHandle, 
77958 +                                                         PVRSRV_DEV_POWER_STATE        eNewPowerState, 
77959 +                                                         PVRSRV_DEV_POWER_STATE        eCurrentPowerState);
77960 +
77961 +PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE                              hDevHandle, 
77962 +                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState, 
77963 +                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState);
77964 +
77965 +PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE                         hDevHandle,
77966 +                                                                       IMG_BOOL                                bIdleDevice,
77967 +                                                                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState);
77968 +
77969 +PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE                                hDevHandle,
77970 +                                                                        IMG_BOOL                               bIdleDevice,
77971 +                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState);
77972 +
77973 +IMG_VOID SGXPanic(PVRSRV_DEVICE_NODE   *psDeviceNode);
77974 +
77975 +PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
77976 +
77977 +#if defined(SGX_DYNAMIC_TIMING_INFO)
77978 +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo);
77979 +#endif
77980 +
77981 +#if defined(NO_HARDWARE)
77982 +static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO              *psDevInfo,
77983 +                                                                                               IMG_UINT32 ui32StatusRegister,
77984 +                                                                                               IMG_UINT32 ui32StatusValue,
77985 +                                                                                               IMG_UINT32 ui32StatusMask)
77986 +{
77987 +       IMG_UINT32 ui32RegVal;
77988 +
77989 +       ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister);
77990 +
77991 +       ui32RegVal &= ~ui32StatusMask;
77992 +       ui32RegVal |= (ui32StatusValue & ui32StatusMask);
77993 +
77994 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal);
77995 +}
77996 +#endif
77997 +
77998 +#if defined(__cplusplus)
77999 +}
78000 +#endif
78001 +
78002 +#endif 
78003 +
78004 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c
78005 new file mode 100644
78006 index 0000000..d8f6aef
78007 --- /dev/null
78008 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxinit.c
78009 @@ -0,0 +1,2218 @@
78010 +/**********************************************************************
78011 + *
78012 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
78013 + *
78014 + * This program is free software; you can redistribute it and/or modify it
78015 + * under the terms and conditions of the GNU General Public License,
78016 + * version 2, as published by the Free Software Foundation.
78017 + *
78018 + * This program is distributed in the hope it will be useful but, except
78019 + * as otherwise stated in writing, without any warranty; without even the
78020 + * implied warranty of merchantability or fitness for a particular purpose.
78021 + * See the GNU General Public License for more details.
78022 + *
78023 + * You should have received a copy of the GNU General Public License along with
78024 + * this program; if not, write to the Free Software Foundation, Inc.,
78025 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
78026 + *
78027 + * The full GNU General Public License is included in this distribution in
78028 + * the file called "COPYING".
78029 + *
78030 + * Contact Information:
78031 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
78032 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
78033 + *
78034 + ******************************************************************************/
78035 +
78036 +#include <stddef.h>
78037 +
78038 +#include "sgxdefs.h"
78039 +#include "sgxmmu.h"
78040 +#include "services_headers.h"
78041 +#include "buffer_manager.h"
78042 +#include "sgxapi_km.h"
78043 +#include "sgxinfo.h"
78044 +#include "sgx_mkif_km.h"
78045 +#include "sgxconfig.h"
78046 +#include "sysconfig.h"
78047 +#include "pvr_bridge_km.h"
78048 +
78049 +#include "sgx_bridge_km.h"
78050 +
78051 +#include "pdump_km.h"
78052 +#include "ra.h"
78053 +#include "mmu.h"
78054 +#include "handle.h"
78055 +#include "perproc.h"
78056 +
78057 +#include "sgxutils.h"
78058 +#include "pvrversion.h"
78059 +#include "sgx_options.h"
78060 +
78061 +#include "lists.h"
78062 +#include "srvkm.h"
78063 +
78064 +DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
78065 +
78066 +#if defined(SUPPORT_SGX_HWPERF)
78067 +IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
78068 +#endif
78069 +
78070 +#define VAR(x) #x
78071 +
78072 +#define CHECK_SIZE(NAME) \
78073 +{      \
78074 +       if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
78075 +       {       \
78076 +               PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
78077 +                       VAR(NAME), \
78078 +                       psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
78079 +                       psSGXStructSizes->ui32Sizeof_##NAME )); \
78080 +               bStructSizesFailed = IMG_TRUE; \
78081 +       }       \
78082 +}
78083 +
78084 +#if defined (SYS_USING_INTERRUPTS)
78085 +IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
78086 +#endif
78087 +
78088 +IMG_UINT32 gui32EventStatusServicesByISR = 0;
78089 +
78090 +
78091 +static
78092 +PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO  *psDevInfo,
78093 +                                                                  PVRSRV_DEVICE_NODE   *psDeviceNode);
78094 +
78095 +
78096 +static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
78097 +{
78098 +#if defined(OS_SUPPORTS_IN_LISR)
78099 +       if (OSInLISR(psDeviceNode->psSysData))
78100 +       {
78101 +
78102 +               psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
78103 +       }
78104 +       else
78105 +       {
78106 +               SGXScheduleProcessQueuesKM(psDeviceNode);
78107 +       }
78108 +#else
78109 +       SGXScheduleProcessQueuesKM(psDeviceNode);
78110 +#endif
78111 +}
78112 +
78113 +static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
78114 +{
78115 +       if (psDevInfo->psKernelCCBInfo != IMG_NULL)
78116 +       {
78117 +
78118 +
78119 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
78120 +       }
78121 +
78122 +       return PVRSRV_OK;
78123 +}
78124 +
78125 +static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
78126 +                                                               PVRSRV_DEVICE_NODE *psDeviceNode,
78127 +                                                               SGX_BRIDGE_INIT_INFO *psInitInfo)
78128 +{
78129 +       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
78130 +       PVRSRV_ERROR            eError;
78131 +
78132 +       PVRSRV_SGX_CCB_INFO     *psKernelCCBInfo = IMG_NULL;
78133 +
78134 +       PVR_UNREFERENCED_PARAMETER(psPerProc);
78135 +       psDevInfo->sScripts = psInitInfo->sScripts;
78136 +
78137 +       psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
78138 +       psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
78139 +
78140 +       psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
78141 +       psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
78142 +
78143 +       psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
78144 +       psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
78145 +
78146 +       psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
78147 +       psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
78148 +
78149 +       psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
78150 +
78151 +       psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
78152 +
78153 +#if defined(SGX_SUPPORT_HWPROFILING)
78154 +       psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;
78155 +#endif
78156 +#if defined(SUPPORT_SGX_HWPERF)
78157 +       psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;
78158 +#endif
78159 +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
78160 +       psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
78161 +#endif
78162 +#if defined(SGX_FEATURE_OVERLAPPED_SPM)
78163 +       psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;
78164 +#endif
78165 +#if defined(SGX_FEATURE_SPM_MODE_0)
78166 +       psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo;
78167 +#endif
78168 +
78169 +       psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
78170 +
78171 +
78172 +       psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
78173 +
78174 +
78175 +
78176 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
78177 +                                               sizeof(PVRSRV_SGX_CCB_INFO),
78178 +                                               (IMG_VOID **)&psKernelCCBInfo, 0,
78179 +                                               "SGX Circular Command Buffer Info");
78180 +       if (eError != PVRSRV_OK)
78181 +       {
78182 +               PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
78183 +               goto failed_allockernelccb;
78184 +       }
78185 +
78186 +
78187 +       OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
78188 +       psKernelCCBInfo->psCCBMemInfo           = psDevInfo->psKernelCCBMemInfo;
78189 +       psKernelCCBInfo->psCCBCtlMemInfo        = psDevInfo->psKernelCCBCtlMemInfo;
78190 +       psKernelCCBInfo->psCommands                     = psDevInfo->psKernelCCB->asCommands;
78191 +       psKernelCCBInfo->pui32WriteOffset       = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
78192 +       psKernelCCBInfo->pui32ReadOffset        = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
78193 +       psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
78194 +
78195 +
78196 +
78197 +       OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
78198 +                         SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
78199 +
78200 +       psDevInfo->bForcePTOff = IMG_FALSE;
78201 +
78202 +       psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
78203 +
78204 +       psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
78205 +       psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
78206 +       psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
78207 +       psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
78208 +#if defined(SGX_FEATURE_MP)
78209 +       psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
78210 +       psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
78211 +#endif
78212 +
78213 +
78214 +
78215 +       OSMemCopy(&psDevInfo->asSGXDevData,  &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
78216 +
78217 +       return PVRSRV_OK;
78218 +
78219 +failed_allockernelccb:
78220 +       DeinitDevInfo(psDevInfo);
78221 +
78222 +       return eError;
78223 +}
78224 +
78225 +
78226 +
78227 +
78228 +static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
78229 +{
78230 +       IMG_UINT32 ui32PC;
78231 +       SGX_INIT_COMMAND *psComm;
78232 +
78233 +       for (ui32PC = 0, psComm = psScript;
78234 +               ui32PC < ui32NumInitCommands;
78235 +               ui32PC++, psComm++)
78236 +       {
78237 +               switch (psComm->eOp)
78238 +               {
78239 +                       case SGX_INIT_OP_WRITE_HW_REG:
78240 +                       {
78241 +                               OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
78242 +                               PDUMPREG(psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
78243 +                               break;
78244 +                       }
78245 +#if defined(PDUMP)
78246 +                       case SGX_INIT_OP_PDUMP_HW_REG:
78247 +                       {
78248 +                               PDUMPREG(psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
78249 +                               break;
78250 +                       }
78251 +#endif
78252 +                       case SGX_INIT_OP_HALT:
78253 +                       {
78254 +                               return PVRSRV_OK;
78255 +                       }
78256 +                       case SGX_INIT_OP_ILLEGAL:
78257 +
78258 +                       default:
78259 +                       {
78260 +                               PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
78261 +                               return PVRSRV_ERROR_GENERIC;
78262 +                       }
78263 +               }
78264 +
78265 +       }
78266 +
78267 +       return PVRSRV_ERROR_GENERIC;
78268 +}
78269 +
78270 +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO  *psDevInfo)
78271 +{
78272 +       PVRSRV_ERROR                    eError;
78273 +       PVRSRV_KERNEL_MEM_INFO  *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
78274 +       SGXMKIF_HOST_CTL                *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
78275 +#if defined(PDUMP)
78276 +       static IMG_BOOL                 bFirstTime = IMG_TRUE;
78277 +#endif
78278 +
78279 +
78280 +
78281 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
78282 +       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
78283 +       if (eError != PVRSRV_OK)
78284 +       {
78285 +               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
78286 +               return (PVRSRV_ERROR_GENERIC);
78287 +       }
78288 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
78289 +
78290 +
78291 +       SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS);
78292 +
78293 +#if defined(EUR_CR_POWER)
78294 +#if defined(SGX531)
78295 +
78296 +
78297 +
78298 +
78299 +
78300 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
78301 +       PDUMPREG(EUR_CR_POWER, 1);
78302 +#else
78303 +
78304 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
78305 +       PDUMPREG(EUR_CR_POWER, 0);
78306 +#endif
78307 +#endif
78308 +
78309 +
78310 +       *psDevInfo->pui32KernelCCBEventKicker = 0;
78311 +#if defined(PDUMP)
78312 +       if (bFirstTime)
78313 +       {
78314 +               psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
78315 +               PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
78316 +                                psDevInfo->psKernelCCBEventKickerMemInfo, 0,
78317 +                                sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
78318 +                                MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
78319 +       }
78320 +#endif
78321 +
78322 +
78323 +
78324 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
78325 +       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
78326 +       if (eError != PVRSRV_OK)
78327 +       {
78328 +               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
78329 +               return (PVRSRV_ERROR_GENERIC);
78330 +       }
78331 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
78332 +
78333 +
78334 +       psSGXHostCtl->ui32InitStatus = 0;
78335 +#if defined(PDUMP)
78336 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
78337 +                                                 "Reset the SGX microkernel initialisation status\n");
78338 +       PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
78339 +                        offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
78340 +                        sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
78341 +                        MAKEUNIQUETAG(psSGXHostCtlMemInfo));
78342 +#endif
78343 +
78344 +       *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
78345 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM,
78346 +                                SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
78347 +                                EUR_CR_EVENT_KICK_NOW_MASK);
78348 +
78349 +#if defined(PDUMP)
78350 +
78351 +
78352 +
78353 +
78354 +
78355 +
78356 +       if (bFirstTime)
78357 +       {
78358 +               psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
78359 +               PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
78360 +                                                         "First increment of the SGX event kicker value\n");
78361 +               PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
78362 +                                psDevInfo->psKernelCCBEventKickerMemInfo,
78363 +                                0,
78364 +                                sizeof(IMG_UINT32),
78365 +                                PDUMP_FLAGS_CONTINUOUS,
78366 +                                MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
78367 +               PDUMPREG(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
78368 +               bFirstTime = IMG_FALSE;
78369 +       }
78370 +#endif
78371 +
78372 +#if !defined(NO_HARDWARE)
78373 +
78374 +
78375 +       if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
78376 +                                          PVRSRV_USSE_EDM_INIT_COMPLETE,
78377 +                                          PVRSRV_USSE_EDM_INIT_COMPLETE,
78378 +                                          MAX_HW_TIME_US/WAIT_TRY_COUNT,
78379 +                                          WAIT_TRY_COUNT) != PVRSRV_OK)
78380 +       {
78381 +               PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
78382 +               PVR_DBG_BREAK;
78383 +               return PVRSRV_ERROR_RETRY;
78384 +       }
78385 +#endif
78386 +
78387 +#if defined(PDUMP)
78388 +       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
78389 +                                                 "Wait for the SGX microkernel initialisation to complete");
78390 +       PDUMPMEMPOL(psSGXHostCtlMemInfo,
78391 +                               offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
78392 +                               PVRSRV_USSE_EDM_INIT_COMPLETE,
78393 +                               PVRSRV_USSE_EDM_INIT_COMPLETE,
78394 +                               PDUMP_POLL_OPERATOR_EQUAL,
78395 +                               PDUMP_FLAGS_CONTINUOUS,
78396 +                               MAKEUNIQUETAG(psSGXHostCtlMemInfo));
78397 +#endif
78398 +
78399 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
78400 +
78401 +
78402 +
78403 +       WorkaroundBRN22997ReadHostPort(psDevInfo);
78404 +#endif
78405 +
78406 +       PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
78407 +
78408 +       return PVRSRV_OK;
78409 +}
78410 +
78411 +PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
78412 +
78413 +{
78414 +       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
78415 +       PVRSRV_ERROR            eError;
78416 +
78417 +
78418 +       if (psDevInfo->pvRegsBaseKM == IMG_NULL)
78419 +       {
78420 +               return PVRSRV_OK;
78421 +       }
78422 +
78423 +       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
78424 +       if (eError != PVRSRV_OK)
78425 +       {
78426 +               PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
78427 +               return (PVRSRV_ERROR_GENERIC);
78428 +       }
78429 +
78430 +       return PVRSRV_OK;
78431 +}
78432 +
78433 +
78434 +static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
78435 +{
78436 +       PVRSRV_SGXDEV_INFO      *psDevInfo;
78437 +       IMG_HANDLE              hKernelDevMemContext;
78438 +       IMG_DEV_PHYADDR         sPDDevPAddr;
78439 +       IMG_UINT32              i;
78440 +       PVRSRV_DEVICE_NODE  *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
78441 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
78442 +       PVRSRV_ERROR            eError;
78443 +
78444 +       PDUMPCOMMENT("SGX Initialisation Part 1");
78445 +
78446 +
78447 +       PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
78448 +#ifdef SGX_CORE_REV
78449 +       PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
78450 +#else
78451 +       PDUMPCOMMENT("SGX Core Revision Information: head rtl");
78452 +#endif
78453 +
78454 +       #if defined(SGX_FEATURE_SYSTEM_CACHE)
78455 +       PDUMPCOMMENT("SGX System Level Cache is present\r\n");
78456 +       #if defined(SGX_BYPASS_SYSTEM_CACHE)
78457 +       PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
78458 +       #endif
78459 +       #endif
78460 +
78461 +
78462 +       if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
78463 +                                        sizeof(PVRSRV_SGXDEV_INFO),
78464 +                                        (IMG_VOID **)&psDevInfo, IMG_NULL,
78465 +                                        "SGX Device Info") != PVRSRV_OK)
78466 +       {
78467 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
78468 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
78469 +       }
78470 +       OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
78471 +
78472 +
78473 +       psDevInfo->eDeviceType          = DEV_DEVICE_TYPE;
78474 +       psDevInfo->eDeviceClass         = DEV_DEVICE_CLASS;
78475 +
78476 +
78477 +       psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
78478 +
78479 +
78480 +       psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
78481 +
78482 +
78483 +       hKernelDevMemContext = BM_CreateContext(psDeviceNode,
78484 +                                                                                       &sPDDevPAddr,
78485 +                                                                                       IMG_NULL,
78486 +                                                                                       IMG_NULL);
78487 +       if (hKernelDevMemContext == IMG_NULL)
78488 +       {
78489 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
78490 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
78491 +       }
78492 +
78493 +       psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
78494 +
78495 +
78496 +       for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
78497 +       {
78498 +               IMG_HANDLE hDevMemHeap;
78499 +
78500 +               switch(psDeviceMemoryHeap[i].DevMemHeapType)
78501 +               {
78502 +                       case DEVICE_MEMORY_HEAP_KERNEL:
78503 +                       case DEVICE_MEMORY_HEAP_SHARED:
78504 +                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
78505 +                       {
78506 +                               hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
78507 +                                                                                               &psDeviceMemoryHeap[i]);
78508 +
78509 +
78510 +
78511 +                               psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
78512 +                               break;
78513 +                       }
78514 +               }
78515 +       }
78516 +
78517 +       eError = MMU_BIFResetPDAlloc(psDevInfo);
78518 +       if (eError != PVRSRV_OK)
78519 +       {
78520 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
78521 +               return PVRSRV_ERROR_GENERIC;
78522 +       }
78523 +
78524 +       return PVRSRV_OK;
78525 +}
78526 +
78527 +IMG_EXPORT
78528 +PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
78529 +{
78530 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
78531 +       PVRSRV_SGXDEV_INFO      *psDevInfo;
78532 +       PVRSRV_ERROR            eError;
78533 +
78534 +       PDUMPCOMMENT("SGXGetInfoForSrvinit");
78535 +
78536 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
78537 +       psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
78538 +
78539 +       psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
78540 +
78541 +       eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
78542 +       if (eError != PVRSRV_OK)
78543 +       {
78544 +               PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
78545 +               return PVRSRV_ERROR_GENERIC;
78546 +       }
78547 +
78548 +       return eError;
78549 +}
78550 +
78551 +IMG_EXPORT
78552 +PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
78553 +                                IMG_HANDLE hDevHandle,
78554 +                                SGX_BRIDGE_INIT_INFO *psInitInfo)
78555 +{
78556 +       PVRSRV_DEVICE_NODE              *psDeviceNode;
78557 +       PVRSRV_SGXDEV_INFO              *psDevInfo;
78558 +       PVRSRV_ERROR                    eError;
78559 +       SGX_DEVICE_MAP                  *psSGXDeviceMap;
78560 +       PVRSRV_DEV_POWER_STATE  eDefaultPowerState;
78561 +
78562 +       PDUMPCOMMENT("SGX Initialisation Part 2");
78563 +
78564 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
78565 +       psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
78566 +
78567 +
78568 +
78569 +       eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
78570 +       if (eError != PVRSRV_OK)
78571 +       {
78572 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
78573 +               goto failed_init_dev_info;
78574 +       }
78575 +
78576 +
78577 +       eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
78578 +                                                                       (IMG_VOID**)&psSGXDeviceMap);
78579 +       if (eError != PVRSRV_OK)
78580 +       {
78581 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
78582 +               return PVRSRV_ERROR_INIT_FAILURE;
78583 +       }
78584 +
78585 +
78586 +       if (psSGXDeviceMap->pvRegsCpuVBase)
78587 +       {
78588 +               psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
78589 +       }
78590 +       else
78591 +       {
78592 +
78593 +               psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
78594 +                                                                                          psSGXDeviceMap->ui32RegsSize,
78595 +                                                                                          PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
78596 +                                                                                          IMG_NULL);
78597 +               if (!psDevInfo->pvRegsBaseKM)
78598 +               {
78599 +                       PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
78600 +                       return PVRSRV_ERROR_BAD_MAPPING;
78601 +               }
78602 +       }
78603 +       psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
78604 +       psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
78605 +
78606 +
78607 +#if defined(SGX_FEATURE_HOST_PORT)
78608 +       if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
78609 +       {
78610 +
78611 +               psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
78612 +                                                                                          psSGXDeviceMap->ui32HPSize,
78613 +                                                                                          PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
78614 +                                                                                          IMG_NULL);
78615 +               if (!psDevInfo->pvHostPortBaseKM)
78616 +               {
78617 +                       PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
78618 +                       return PVRSRV_ERROR_BAD_MAPPING;
78619 +               }
78620 +               psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
78621 +               psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
78622 +       }
78623 +#endif
78624 +
78625 +#if defined (SYS_USING_INTERRUPTS)
78626 +
78627 +
78628 +       psDeviceNode->pvISRData = psDeviceNode;
78629 +
78630 +       PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
78631 +
78632 +#endif
78633 +
78634 +
78635 +       psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
78636 +       eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
78637 +
78638 +       eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
78639 +                                                                               SGXPrePowerState, SGXPostPowerState,
78640 +                                                                               SGXPreClockSpeedChange, SGXPostClockSpeedChange,
78641 +                                                                               (IMG_HANDLE)psDeviceNode,
78642 +                                                                               PVRSRV_DEV_POWER_STATE_OFF,
78643 +                                                                               eDefaultPowerState);
78644 +       if (eError != PVRSRV_OK)
78645 +       {
78646 +               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
78647 +               return eError;
78648 +       }
78649 +
78650 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
78651 +       eError = WorkaroundBRN22997Alloc(psDevInfo);
78652 +       if (eError != PVRSRV_OK)
78653 +       {
78654 +               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));
78655 +               return eError;
78656 +       }
78657 +#endif
78658 +
78659 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
78660 +
78661 +       psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
78662 +       psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
78663 +       eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
78664 +       if (eError != PVRSRV_OK)
78665 +       {
78666 +               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
78667 +               return eError;
78668 +       }
78669 +#endif
78670 +
78671 +
78672 +
78673 +       OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
78674 +       OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
78675 +       OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
78676 +       PDUMPCOMMENT("Initialise Kernel CCB");
78677 +       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
78678 +       PDUMPCOMMENT("Initialise Kernel CCB Control");
78679 +       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
78680 +       PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
78681 +       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
78682 +
78683 +       return PVRSRV_OK;
78684 +
78685 +failed_init_dev_info:
78686 +       return eError;
78687 +}
78688 +
78689 +static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
78690 +{
78691 +       PVRSRV_DEVICE_NODE                      *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
78692 +       PVRSRV_SGXDEV_INFO                      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
78693 +       PVRSRV_ERROR                            eError;
78694 +       IMG_UINT32                                      ui32Heap;
78695 +       DEVICE_MEMORY_HEAP_INFO         *psDeviceMemoryHeap;
78696 +       SGX_DEVICE_MAP                          *psSGXDeviceMap;
78697 +
78698 +       if (!psDevInfo)
78699 +       {
78700 +
78701 +               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
78702 +               return PVRSRV_OK;
78703 +       }
78704 +
78705 +#if defined(SUPPORT_HW_RECOVERY)
78706 +       if (psDevInfo->hTimer)
78707 +       {
78708 +               eError = OSRemoveTimer(psDevInfo->hTimer);
78709 +               if (eError != PVRSRV_OK)
78710 +               {
78711 +                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));
78712 +                       return  eError;
78713 +               }
78714 +               psDevInfo->hTimer = IMG_NULL;
78715 +       }
78716 +#endif
78717 +
78718 +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
78719 +
78720 +       eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
78721 +       if (eError != PVRSRV_OK)
78722 +       {
78723 +               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
78724 +               return eError;
78725 +       }
78726 +#endif
78727 +
78728 +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
78729 +       WorkaroundBRN22997Free(psDevInfo);
78730 +#endif
78731 +
78732 +       MMU_BIFResetPDFree(psDevInfo);
78733 +
78734 +
78735 +
78736 +
78737 +       DeinitDevInfo(psDevInfo);
78738 +
78739 +
78740 +       psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
78741 +       for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
78742 +       {
78743 +               switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
78744 +               {
78745 +                       case DEVICE_MEMORY_HEAP_KERNEL:
78746 +                       case DEVICE_MEMORY_HEAP_SHARED:
78747 +                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
78748 +                       {
78749 +                               if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
78750 +                               {
78751 +                                       BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
78752 +                               }
78753 +                               break;
78754 +                       }
78755 +               }
78756 +       }
78757 +
78758 +
78759 +       eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
78760 +       if (eError != PVRSRV_OK)
78761 +       {
78762 +               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
78763 +               return eError;
78764 +       }
78765 +
78766 +
78767 +       eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
78768 +       if (eError != PVRSRV_OK)
78769 +       {
78770 +               return eError;
78771 +       }
78772 +
78773 +       eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
78774 +                                                                       (IMG_VOID**)&psSGXDeviceMap);
78775 +       if (eError != PVRSRV_OK)
78776 +       {
78777 +               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
78778 +               return eError;
78779 +       }
78780 +
78781 +
78782 +       if (!psSGXDeviceMap->pvRegsCpuVBase)
78783 +       {
78784 +
78785 +               if (psDevInfo->pvRegsBaseKM != IMG_NULL)
78786 +               {
78787 +                       OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
78788 +                                                        psDevInfo->ui32RegSize,
78789 +                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
78790 +                                                        IMG_NULL);
78791 +               }
78792 +       }
78793 +
78794 +#if defined(SGX_FEATURE_HOST_PORT)
78795 +       if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
78796 +       {
78797 +
78798 +               if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
78799 +               {
78800 +                       OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
78801 +                                                  psDevInfo->ui32HPSize,
78802 +                                                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
78803 +                                                  IMG_NULL);
78804 +               }
78805 +       }
78806 +#endif
78807 +
78808 +
78809 +
78810 +       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
78811 +                               sizeof(PVRSRV_SGXDEV_INFO),
78812 +                               psDevInfo,
78813 +                               0);
78814 +
78815 +       psDeviceNode->pvDevice = IMG_NULL;
78816 +
78817 +       if (psDeviceMemoryHeap != IMG_NULL)
78818 +       {
78819 +
78820 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
78821 +                               sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
78822 +                               psDeviceMemoryHeap,
78823 +                               0);
78824 +       }
78825 +
78826 +       return PVRSRV_OK;
78827 +}
78828 +
78829 +
78830 +IMG_VOID SGXDumpDebugInfo (PVRSRV_DEVICE_NODE *psDeviceNode,
78831 +                                                  IMG_BOOL                       bDumpSGXRegs)
78832 +{
78833 +       IMG_UINT                        ui32RegVal;
78834 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
78835 +
78836 +       if (bDumpSGXRegs)
78837 +       {
78838 +               PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear):   0x%08X", psDevInfo->pvRegsBaseKM));
78839 +               PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase));
78840 +
78841 +
78842 +
78843 +
78844 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
78845 +               if (ui32RegVal & (EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK | EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK))
78846 +               {
78847 +                       PVR_LOG(("DPM out of memory!!"));
78848 +               }
78849 +               PVR_LOG(("EUR_CR_EVENT_STATUS:     %x", ui32RegVal));
78850 +
78851 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
78852 +               PVR_LOG(("EUR_CR_EVENT_STATUS2:    %x", ui32RegVal));
78853 +
78854 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
78855 +               PVR_LOG(("EUR_CR_BIF_CTRL:         %x", ui32RegVal));
78856 +
78857 +               #if defined(EUR_CR_BIF_BANK0)
78858 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0);
78859 +               PVR_LOG(("EUR_CR_BIF_BANK0:        %x", ui32RegVal));
78860 +               #endif
78861 +
78862 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
78863 +               PVR_LOG(("EUR_CR_BIF_INT_STAT:     %x", ui32RegVal));
78864 +
78865 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
78866 +               PVR_LOG(("EUR_CR_BIF_FAULT:        %x", ui32RegVal));
78867 +
78868 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_REQ_STAT);
78869 +               PVR_LOG(("EUR_CR_BIF_MEM_REQ_STAT: %x", ui32RegVal));
78870 +
78871 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL);
78872 +               PVR_LOG(("EUR_CR_CLKGATECTL:       %x", ui32RegVal));
78873 +
78874 +               #if defined(EUR_CR_PDS_PC_BASE)
78875 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_PDS_PC_BASE);
78876 +               PVR_LOG(("EUR_CR_PDS_PC_BASE:      %x", ui32RegVal));
78877 +               #endif
78878 +
78879 +
78880 +       }
78881 +
78882 +       #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
78883 +       {
78884 +               IMG_UINT32      *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
78885 +               IMG_UINT32      ui32LastStatusCode, ui32WriteOffset;
78886 +
78887 +               ui32LastStatusCode = *pui32MKTraceBuffer;
78888 +               pui32MKTraceBuffer++;
78889 +               ui32WriteOffset = *pui32MKTraceBuffer;
78890 +               pui32MKTraceBuffer++;
78891 +
78892 +               PVR_LOG(("Last SGX microkernel status code: 0x%x", ui32LastStatusCode));
78893 +
78894 +               #if defined(PVRSRV_DUMP_MK_TRACE)
78895 +
78896 +
78897 +               {
78898 +                       IMG_UINT32      ui32LoopCounter;
78899 +
78900 +                       for (ui32LoopCounter = 0;
78901 +                                ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
78902 +                                ui32LoopCounter++)
78903 +                       {
78904 +                               IMG_UINT32      *pui32BufPtr;
78905 +                               pui32BufPtr = pui32MKTraceBuffer +
78906 +                                                               (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
78907 +                               PVR_LOG(("(MKT%u) %08X %08X %08X %08X", ui32LoopCounter,
78908 +                                                pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
78909 +                       }
78910 +               }
78911 +               #endif
78912 +       }
78913 +       #endif
78914 +
78915 +       {
78916 +
78917 +
78918 +               IMG_UINT32      *pui32HostCtlBuffer = (IMG_UINT32 *)psDevInfo->psSGXHostCtl;
78919 +               IMG_UINT32      ui32LoopCounter;
78920 +
78921 +               PVR_LOG(("SGX Host control:"));
78922 +
78923 +               for (ui32LoopCounter = 0;
78924 +                        ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
78925 +                        ui32LoopCounter += 4)
78926 +               {
78927 +                       PVR_LOG(("\t0x%X: 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
78928 +                                       pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
78929 +                                       pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
78930 +               }
78931 +       }
78932 +
78933 +       {
78934 +
78935 +
78936 +               IMG_UINT32      *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
78937 +               IMG_UINT32      ui32LoopCounter;
78938 +
78939 +               PVR_LOG(("SGX TA/3D control:"));
78940 +
78941 +               for (ui32LoopCounter = 0;
78942 +                        ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->ui32AllocSize / sizeof(*pui32TA3DCtlBuffer);
78943 +                        ui32LoopCounter += 4)
78944 +               {
78945 +                       PVR_LOG(("\t0x%X: 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
78946 +                                       pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
78947 +                                       pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
78948 +               }
78949 +       }
78950 +
78951 +       QueueDumpDebugInfo();
78952 +}
78953 +
78954 +
78955 +#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)
78956 +static
78957 +IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,
78958 +                                                        IMG_UINT32             ui32Component,
78959 +                                                        IMG_UINT32                     ui32CallerID)
78960 +{
78961 +       PVRSRV_ERROR            eError;
78962 +       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
78963 +       SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
78964 +
78965 +       PVR_UNREFERENCED_PARAMETER(ui32Component);
78966 +
78967 +
78968 +
78969 +       eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
78970 +       if(eError != PVRSRV_OK)
78971 +       {
78972 +
78973 +
78974 +
78975 +               PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
78976 +               return;
78977 +       }
78978 +
78979 +       psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
78980 +
78981 +       PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
78982 +
78983 +       SGXDumpDebugInfo(psDeviceNode, IMG_TRUE);
78984 +
78985 +
78986 +       PDUMPSUSPEND();
78987 +
78988 +
78989 +       eError = SGXInitialise(psDevInfo);
78990 +       if (eError != PVRSRV_OK)
78991 +       {
78992 +               PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
78993 +       }
78994 +
78995 +
78996 +       PDUMPRESUME();
78997 +
78998 +       PVRSRVPowerUnlock(ui32CallerID);
78999 +
79000 +
79001 +       SGXScheduleProcessQueuesKM(psDeviceNode);
79002 +
79003 +
79004 +
79005 +       PVRSRVProcessQueues(ui32CallerID, IMG_TRUE);
79006 +}
79007 +#endif
79008 +
79009 +
79010 +#if defined(SUPPORT_HW_RECOVERY)
79011 +IMG_VOID SGXOSTimer(IMG_VOID *pvData)
79012 +{
79013 +       PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
79014 +       PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
79015 +       static IMG_UINT32       ui32EDMTasks = 0;
79016 +       static IMG_UINT32       ui32LockupCounter = 0;
79017 +       static IMG_UINT32       ui32NumResets = 0;
79018 +       IMG_UINT32              ui32CurrentEDMTasks;
79019 +       IMG_BOOL                bLockup = IMG_FALSE;
79020 +       IMG_BOOL                bPoweredDown;
79021 +
79022 +
79023 +       psDevInfo->ui32TimeStamp++;
79024 +
79025 +#if defined(NO_HARDWARE)
79026 +       bPoweredDown = IMG_TRUE;
79027 +#else
79028 +       bPoweredDown = SGXIsDevicePowered(psDeviceNode) ? IMG_FALSE : IMG_TRUE;
79029 +#endif
79030 +
79031 +
79032 +
79033 +       if (bPoweredDown)
79034 +       {
79035 +               ui32LockupCounter = 0;
79036 +       }
79037 +       else
79038 +       {
79039 +
79040 +               ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
79041 +               if (psDevInfo->ui32EDMTaskReg1 != 0)
79042 +               {
79043 +                       ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
79044 +               }
79045 +               if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
79046 +                       (psDevInfo->ui32NumResets == ui32NumResets))
79047 +               {
79048 +                       ui32LockupCounter++;
79049 +                       if (ui32LockupCounter == 3)
79050 +                       {
79051 +                               ui32LockupCounter = 0;
79052 +                               PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
79053 +
79054 +                               bLockup = IMG_TRUE;
79055 +                       }
79056 +               }
79057 +               else
79058 +               {
79059 +                       ui32LockupCounter = 0;
79060 +                       ui32EDMTasks = ui32CurrentEDMTasks;
79061 +                       ui32NumResets = psDevInfo->ui32NumResets;
79062 +               }
79063 +       }
79064 +
79065 +       if (bLockup)
79066 +       {
79067 +               SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
79068 +
79069 +
79070 +               psSGXHostCtl->ui32HostDetectedLockups ++;
79071 +
79072 +
79073 +               HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID);
79074 +       }
79075 +}
79076 +#endif
79077 +
79078 +
79079 +#if defined(SYS_USING_INTERRUPTS)
79080 +
79081 +IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
79082 +{
79083 +       IMG_BOOL bInterruptProcessed = IMG_FALSE;
79084 +
79085 +
79086 +
79087 +       {
79088 +               IMG_UINT32 ui32EventStatus, ui32EventEnable;
79089 +               IMG_UINT32 ui32EventClear = 0;
79090 +               PVRSRV_DEVICE_NODE *psDeviceNode;
79091 +               PVRSRV_SGXDEV_INFO *psDevInfo;
79092 +
79093 +
79094 +               if(pvData == IMG_NULL)
79095 +               {
79096 +                       PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
79097 +                       return bInterruptProcessed;
79098 +               }
79099 +
79100 +               psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
79101 +               psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
79102 +
79103 +               ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
79104 +               ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
79105 +
79106 +
79107 +
79108 +               gui32EventStatusServicesByISR = ui32EventStatus;
79109 +
79110 +
79111 +               ui32EventStatus &= ui32EventEnable;
79112 +
79113 +               if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
79114 +               {
79115 +                       ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
79116 +               }
79117 +
79118 +               if (ui32EventClear)
79119 +               {
79120 +                       bInterruptProcessed = IMG_TRUE;
79121 +
79122 +
79123 +                       ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
79124 +
79125 +
79126 +                       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
79127 +               }
79128 +       }
79129 +
79130 +       return bInterruptProcessed;
79131 +}
79132 +
79133 +
79134 +IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
79135 +{
79136 +       PVRSRV_DEVICE_NODE      *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
79137 +       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
79138 +       SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
79139 +
79140 +       if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
79141 +               ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
79142 +       {
79143 +               HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
79144 +       }
79145 +
79146 +#if defined(OS_SUPPORTS_IN_LISR)
79147 +       if (psDeviceNode->bReProcessDeviceCommandComplete)
79148 +       {
79149 +               SGXScheduleProcessQueuesKM(psDeviceNode);
79150 +       }
79151 +#endif
79152 +
79153 +       SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
79154 +}
79155 +#endif
79156 +
79157 +
79158 +PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
79159 +{
79160 +       DEVICE_MEMORY_INFO *psDevMemoryInfo;
79161 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
79162 +
79163 +
79164 +       psDeviceNode->sDevId.eDeviceType        = DEV_DEVICE_TYPE;
79165 +       psDeviceNode->sDevId.eDeviceClass       = DEV_DEVICE_CLASS;
79166 +
79167 +       psDeviceNode->pfnInitDevice             = DevInitSGXPart1;
79168 +       psDeviceNode->pfnDeInitDevice           = DevDeInitSGX;
79169 +
79170 +       psDeviceNode->pfnInitDeviceCompatCheck  = SGXDevInitCompatCheck;
79171 +
79172 +
79173 +
79174 +       psDeviceNode->pfnMMUInitialise = MMU_Initialise;
79175 +       psDeviceNode->pfnMMUFinalise = MMU_Finalise;
79176 +       psDeviceNode->pfnMMUInsertHeap = MMU_InsertHeap;
79177 +       psDeviceNode->pfnMMUCreate = MMU_Create;
79178 +       psDeviceNode->pfnMMUDelete = MMU_Delete;
79179 +       psDeviceNode->pfnMMUAlloc = MMU_Alloc;
79180 +       psDeviceNode->pfnMMUFree = MMU_Free;
79181 +       psDeviceNode->pfnMMUMapPages = MMU_MapPages;
79182 +       psDeviceNode->pfnMMUMapShadow = MMU_MapShadow;
79183 +       psDeviceNode->pfnMMUUnmapPages = MMU_UnmapPages;
79184 +       psDeviceNode->pfnMMUMapScatter = MMU_MapScatter;
79185 +       psDeviceNode->pfnMMUGetPhysPageAddr = MMU_GetPhysPageAddr;
79186 +       psDeviceNode->pfnMMUGetPDDevPAddr = MMU_GetPDDevPAddr;
79187 +
79188 +#if defined (SYS_USING_INTERRUPTS)
79189 +
79190 +
79191 +       psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
79192 +       psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
79193 +#endif
79194 +
79195 +
79196 +
79197 +       psDeviceNode->pfnDeviceCommandComplete = SGXCommandComplete;
79198 +
79199 +
79200 +
79201 +       psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
79202 +
79203 +       psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
79204 +
79205 +
79206 +       psDevMemoryInfo->ui32Flags = 0;
79207 +
79208 +
79209 +       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
79210 +                                        sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
79211 +                                        (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
79212 +                                        "Array of Device Memory Heap Info") != PVRSRV_OK)
79213 +       {
79214 +               PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
79215 +               return (PVRSRV_ERROR_OUT_OF_MEMORY);
79216 +       }
79217 +       OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID);
79218 +
79219 +       psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
79220 +
79221 +
79222 +
79223 +
79224 +
79225 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
79226 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
79227 +       psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
79228 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79229 +                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79230 +                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79231 +       psDeviceMemoryHeap->pszName = "General";
79232 +       psDeviceMemoryHeap->pszBSName = "General BS";
79233 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79234 +
79235 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79236 +#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
79237 +
79238 +       psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
79239 +#endif
79240 +       psDeviceMemoryHeap++;
79241 +
79242 +
79243 +
79244 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
79245 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
79246 +       psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
79247 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79248 +                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79249 +                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;
79250 +       psDeviceMemoryHeap->pszName = "TA Data";
79251 +       psDeviceMemoryHeap->pszBSName = "TA Data BS";
79252 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79253 +
79254 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79255 +       psDeviceMemoryHeap++;
79256 +
79257 +
79258 +
79259 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
79260 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
79261 +       psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
79262 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79263 +                                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79264 +                                                                                                                       | PVRSRV_HAP_MULTI_PROCESS;
79265 +       psDeviceMemoryHeap->pszName = "Kernel Code";
79266 +       psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
79267 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79268 +
79269 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79270 +       psDeviceMemoryHeap++;
79271 +
79272 +
79273 +
79274 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
79275 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
79276 +       psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
79277 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79278 +                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79279 +                                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;
79280 +       psDeviceMemoryHeap->pszName = "KernelData";
79281 +       psDeviceMemoryHeap->pszBSName = "KernelData BS";
79282 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79283 +
79284 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79285 +       psDeviceMemoryHeap++;
79286 +
79287 +
79288 +
79289 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
79290 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
79291 +       psDeviceMemoryHeap->ui32HeapSize = SGX_PIXELSHADER_HEAP_SIZE;
79292 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79293 +                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79294 +                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79295 +       psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
79296 +       psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
79297 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79298 +
79299 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79300 +       psDeviceMemoryHeap++;
79301 +
79302 +
79303 +
79304 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
79305 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
79306 +       psDeviceMemoryHeap->ui32HeapSize = SGX_VERTEXSHADER_HEAP_SIZE;
79307 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79308 +                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79309 +                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79310 +       psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
79311 +       psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
79312 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79313 +
79314 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79315 +       psDeviceMemoryHeap++;
79316 +
79317 +
79318 +
79319 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
79320 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
79321 +       psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
79322 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79323 +                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79324 +                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79325 +       psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
79326 +       psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
79327 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79328 +
79329 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79330 +       psDeviceMemoryHeap++;
79331 +
79332 +
79333 +
79334 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
79335 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
79336 +       psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
79337 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79338 +                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79339 +                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79340 +       psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
79341 +       psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
79342 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79343 +
79344 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79345 +       psDeviceMemoryHeap++;
79346 +
79347 +
79348 +
79349 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
79350 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
79351 +       psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
79352 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79353 +                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79354 +                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;
79355 +       psDeviceMemoryHeap->pszName = "CacheCoherent";
79356 +       psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
79357 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79358 +
79359 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79360 +
79361 +       psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
79362 +       psDeviceMemoryHeap++;
79363 +
79364 +
79365 +
79366 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID);
79367 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE;
79368 +       psDeviceMemoryHeap->ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE;
79369 +       psDeviceMemoryHeap->pszName = "3DParameters";
79370 +       psDeviceMemoryHeap->pszBSName = "3DParameters BS";
79371 +#if defined(SUPPORT_PERCONTEXT_PB)
79372 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79373 +                                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79374 +                                                                                                                       | PVRSRV_HAP_SINGLE_PROCESS;
79375 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79376 +#else
79377 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79378 +                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79379 +                                                                                                       | PVRSRV_HAP_MULTI_PROCESS;
79380 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79381 +#endif
79382 +
79383 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79384 +       psDeviceMemoryHeap++;
79385 +
79386 +
79387 +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
79388 +
79389 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
79390 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
79391 +       psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
79392 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS;
79393 +       psDeviceMemoryHeap->pszName = "GeneralMapping";
79394 +       psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
79395 +       #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
79396 +
79397 +
79398 +
79399 +
79400 +
79401 +
79402 +
79403 +               psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79404 +#else
79405 +               psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79406 +#endif
79407 +
79408 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79409 +
79410 +       psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
79411 +       psDeviceMemoryHeap++;
79412 +#endif
79413 +
79414 +
79415 +#if defined(SGX_FEATURE_2D_HARDWARE)
79416 +
79417 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
79418 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
79419 +       psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
79420 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79421 +                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79422 +                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79423 +       psDeviceMemoryHeap->pszName = "2D";
79424 +       psDeviceMemoryHeap->pszBSName = "2D BS";
79425 +
79426 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
79427 +
79428 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79429 +       psDeviceMemoryHeap++;
79430 +#endif
79431 +
79432 +
79433 +#if defined(FIX_HW_BRN_26915)
79434 +
79435 +
79436 +       psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID);
79437 +       psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE;
79438 +       psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE;
79439 +       psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
79440 +                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION
79441 +                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;
79442 +       psDeviceMemoryHeap->pszName = "CGBuffer";
79443 +       psDeviceMemoryHeap->pszBSName = "CGBuffer BS";
79444 +
79445 +       psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
79446 +
79447 +       psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
79448 +       psDeviceMemoryHeap++;
79449 +#endif
79450 +
79451 +
79452 +       psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
79453 +
79454 +       return PVRSRV_OK;
79455 +}
79456 +
79457 +IMG_EXPORT
79458 +PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE                                     hDevCookie,
79459 +                                                               SGX_CLIENT_INFO*                psClientInfo)
79460 +{
79461 +       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
79462 +
79463 +
79464 +
79465 +       psDevInfo->ui32ClientRefCount++;
79466 +
79467 +#if defined(PDUMP)
79468 +
79469 +       psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
79470 +#endif
79471 +
79472 +
79473 +       psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
79474 +
79475 +
79476 +
79477 +       OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
79478 +
79479 +
79480 +       return PVRSRV_OK;
79481 +}
79482 +
79483 +
79484 +IMG_VOID SGXPanic(PVRSRV_DEVICE_NODE   *psDeviceNode)
79485 +{
79486 +       PVR_LOG(("SGX panic"));
79487 +       SGXDumpDebugInfo(psDeviceNode, IMG_FALSE);
79488 +       OSPanic();
79489 +}
79490 +
79491 +
79492 +PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
79493 +{
79494 +       PVRSRV_ERROR    eError;
79495 +       PVRSRV_SGXDEV_INFO                              *psDevInfo;
79496 +       IMG_UINT32                      ui32BuildOptions, ui32BuildOptionsMismatch;
79497 +#if !defined(NO_HARDWARE)
79498 +       PPVRSRV_KERNEL_MEM_INFO                 psMemInfo;
79499 +       PVRSRV_SGX_MISCINFO_INFO                *psSGXMiscInfoInt;
79500 +       PVRSRV_SGX_MISCINFO_FEATURES    *psSGXFeatures;
79501 +       SGX_MISCINFO_STRUCT_SIZES               *psSGXStructSizes;
79502 +       IMG_BOOL                                                bStructSizesFailed;
79503 +
79504 +
79505 +       IMG_BOOL        bCheckCoreRev;
79506 +       const IMG_UINT32        aui32CoreRevExceptions[] = {
79507 +                       0x10100, 0x10101
79508 +       };
79509 +       const IMG_UINT32        ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
79510 +       IMG_UINT        i;
79511 +#endif
79512 +
79513 +
79514 +       if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
79515 +       {
79516 +               PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
79517 +               eError = PVRSRV_ERROR_INVALID_PARAMS;
79518 +               goto chk_exit;
79519 +       }
79520 +
79521 +       psDevInfo = psDeviceNode->pvDevice;
79522 +
79523 +
79524 +
79525 +       ui32BuildOptions = (SGX_BUILD_OPTIONS);
79526 +       if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
79527 +       {
79528 +               ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
79529 +               if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
79530 +               {
79531 +                       PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
79532 +                               "extra options present in client-side driver: (0x%lx). Please check sgx_options.h",
79533 +                               psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
79534 +               }
79535 +
79536 +               if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
79537 +               {
79538 +                       PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
79539 +                               "extra options present in KM: (0x%lx). Please check sgx_options.h",
79540 +                               ui32BuildOptions & ui32BuildOptionsMismatch ));
79541 +               }
79542 +               eError = PVRSRV_ERROR_BUILD_MISMATCH;
79543 +               goto chk_exit;
79544 +       }
79545 +       else
79546 +       {
79547 +               PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
79548 +       }
79549 +
79550 +#if !defined (NO_HARDWARE)
79551 +       psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
79552 +
79553 +
79554 +       psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
79555 +       psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
79556 +       psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
79557 +       eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
79558 +
79559 +
79560 +       if(eError != PVRSRV_OK)
79561 +       {
79562 +               PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
79563 +               goto chk_exit;
79564 +       }
79565 +       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
79566 +       if( (psSGXFeatures->ui32DDKVersion !=
79567 +               ((PVRVERSION_MAJ << 16) |
79568 +                (PVRVERSION_MIN << 8) |
79569 +                 PVRVERSION_BRANCH) ) ||
79570 +               (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
79571 +       {
79572 +               PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%ld)/device DDK revision (%ld).",
79573 +                               PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
79574 +               eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
79575 +               PVR_DBG_BREAK;
79576 +               goto chk_exit;
79577 +       }
79578 +       else
79579 +       {
79580 +               PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%ld) and device DDK (%ld) match. [ OK ]",
79581 +                               PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
79582 +       }
79583 +
79584 +
79585 +       if (psSGXFeatures->ui32CoreRevSW == 0)
79586 +       {
79587 +
79588 +
79589 +               PVR_LOG(("SGXInit: HW core rev (%lx) check skipped.",
79590 +                               psSGXFeatures->ui32CoreRev));
79591 +       }
79592 +       else
79593 +       {
79594 +
79595 +               bCheckCoreRev = IMG_TRUE;
79596 +               for(i=0; i<ui32NumCoreExceptions; i+=2)
79597 +               {
79598 +                       if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
79599 +                               (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1])     )
79600 +                       {
79601 +                               PVR_LOG(("SGXInit: HW core rev (%lx), SW core rev (%lx) check skipped.",
79602 +                                               psSGXFeatures->ui32CoreRev,
79603 +                                               psSGXFeatures->ui32CoreRevSW));
79604 +                               bCheckCoreRev = IMG_FALSE;
79605 +                       }
79606 +               }
79607 +
79608 +               if (bCheckCoreRev)
79609 +               {
79610 +                       if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
79611 +                       {
79612 +                               PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%lx) and SW core rev (%lx).",
79613 +                                               psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
79614 +                                               eError = PVRSRV_ERROR_BUILD_MISMATCH;
79615 +                                               goto chk_exit;
79616 +                       }
79617 +                       else
79618 +                       {
79619 +                               PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%lx) and SW core rev (%lx) match. [ OK ]",
79620 +                                               psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
79621 +                       }
79622 +               }
79623 +       }
79624 +
79625 +
79626 +       psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
79627 +
79628 +       bStructSizesFailed = IMG_FALSE;
79629 +
79630 +       CHECK_SIZE(HOST_CTL);
79631 +       CHECK_SIZE(COMMAND);
79632 +#if defined(SGX_FEATURE_2D_HARDWARE)
79633 +       CHECK_SIZE(2DCMD);
79634 +       CHECK_SIZE(2DCMD_SHARED);
79635 +#endif
79636 +       CHECK_SIZE(CMDTA);
79637 +       CHECK_SIZE(CMDTA_SHARED);
79638 +       CHECK_SIZE(TRANSFERCMD);
79639 +       CHECK_SIZE(TRANSFERCMD_SHARED);
79640 +
79641 +       CHECK_SIZE(3DREGISTERS);
79642 +       CHECK_SIZE(HWPBDESC);
79643 +       CHECK_SIZE(HWRENDERCONTEXT);
79644 +       CHECK_SIZE(HWRENDERDETAILS);
79645 +       CHECK_SIZE(HWRTDATA);
79646 +       CHECK_SIZE(HWRTDATASET);
79647 +       CHECK_SIZE(HWTRANSFERCONTEXT);
79648 +
79649 +       if (bStructSizesFailed == IMG_TRUE)
79650 +       {
79651 +               PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
79652 +               eError = PVRSRV_ERROR_BUILD_MISMATCH;
79653 +               goto chk_exit;
79654 +       }
79655 +       else
79656 +       {
79657 +               PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
79658 +       }
79659 +
79660 +
79661 +       ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
79662 +       if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
79663 +       {
79664 +               ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
79665 +               if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
79666 +               {
79667 +                       PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
79668 +                               "extra options present in driver: (0x%lx). Please check sgx_options.h",
79669 +                               (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
79670 +               }
79671 +
79672 +               if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
79673 +               {
79674 +                       PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
79675 +                               "extra options present in microkernel: (0x%lx). Please check sgx_options.h",
79676 +                               ui32BuildOptions & ui32BuildOptionsMismatch ));
79677 +               }
79678 +               eError = PVRSRV_ERROR_BUILD_MISMATCH;
79679 +               goto chk_exit;
79680 +       }
79681 +       else
79682 +       {
79683 +               PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
79684 +       }
79685 +#endif
79686 +
79687 +       eError = PVRSRV_OK;
79688 +chk_exit:
79689 +#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
79690 +       return PVRSRV_OK;
79691 +#else
79692 +       return eError;
79693 +#endif
79694 +}
79695 +
79696 +static
79697 +PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO  *psDevInfo,
79698 +                                                                  PVRSRV_DEVICE_NODE   *psDeviceNode)
79699 +{
79700 +       PVRSRV_ERROR            eError;
79701 +       SGXMKIF_COMMAND         sCommandData;
79702 +       PVRSRV_SGX_MISCINFO_INFO                        *psSGXMiscInfoInt;
79703 +       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;
79704 +       SGX_MISCINFO_STRUCT_SIZES                       *psSGXStructSizes;
79705 +
79706 +       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
79707 +
79708 +       if (! psMemInfo->pvLinAddrKM)
79709 +       {
79710 +               PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
79711 +               return PVRSRV_ERROR_INVALID_PARAMS;
79712 +       }
79713 +       psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
79714 +       psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
79715 +       psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
79716 +
79717 +       psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
79718 +
79719 +
79720 +       OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
79721 +       OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
79722 +
79723 +
79724 +       sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr;
79725 +
79726 +       eError = SGXScheduleCCBCommandKM(psDeviceNode,
79727 +                                                                        SGXMKIF_CMD_GETMISCINFO,
79728 +                                                                        &sCommandData,
79729 +                                                                        KERNEL_ID,
79730 +                                                                        0);
79731 +
79732 +       if (eError != PVRSRV_OK)
79733 +       {
79734 +               PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
79735 +               return eError;
79736 +       }
79737 +
79738 +
79739 +#if !defined(NO_HARDWARE)
79740 +       {
79741 +               IMG_BOOL bExit;
79742 +
79743 +               bExit = IMG_FALSE;
79744 +               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
79745 +               {
79746 +                       if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
79747 +                       {
79748 +                               bExit = IMG_TRUE;
79749 +                               break;
79750 +                       }
79751 +               } END_LOOP_UNTIL_TIMEOUT();
79752 +
79753 +
79754 +               if (!bExit)
79755 +               {
79756 +                       PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
79757 +                       return PVRSRV_ERROR_TIMEOUT;
79758 +               }
79759 +       }
79760 +#endif
79761 +
79762 +       return PVRSRV_OK;
79763 +}
79764 +
79765 +
79766 +
79767 +IMG_EXPORT
79768 +PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO       *psDevInfo,
79769 +                                                         SGX_MISC_INFO                 *psMiscInfo,
79770 +                                                         PVRSRV_DEVICE_NODE    *psDeviceNode,
79771 +                                                         IMG_HANDLE                     hDevMemContext)
79772 +{
79773 +       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
79774 +       IMG_UINT32      *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
79775 +
79776 +
79777 +       *pui32MiscInfoFlags = 0;
79778 +
79779 +#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
79780 +       PVR_UNREFERENCED_PARAMETER(hDevMemContext);
79781 +#endif
79782 +
79783 +       switch(psMiscInfo->eRequest)
79784 +       {
79785 +#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
79786 +               case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
79787 +               {
79788 +                       IMG_UINT32 ui32RegOffset;
79789 +                       IMG_UINT32 ui32RegVal;
79790 +                       IMG_UINT32 ui32BaseRegOffset;
79791 +                       IMG_UINT32 ui32BaseRegVal;
79792 +                       IMG_UINT32 ui32MaskRegOffset;
79793 +                       IMG_UINT32 ui32MaskRegVal;
79794 +
79795 +                       switch(psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex)
79796 +                       {
79797 +                               case 0:
79798 +                                       ui32RegOffset = EUR_CR_BREAKPOINT0;
79799 +                                       ui32BaseRegOffset = EUR_CR_BREAKPOINT0_BASE;
79800 +                                       ui32MaskRegOffset = EUR_CR_BREAKPOINT0_MASK;
79801 +                                       break;
79802 +                               case 1:
79803 +                                       ui32RegOffset = EUR_CR_BREAKPOINT1;
79804 +                                       ui32BaseRegOffset = EUR_CR_BREAKPOINT1_BASE;
79805 +                                       ui32MaskRegOffset = EUR_CR_BREAKPOINT1_MASK;
79806 +                                       break;
79807 +                               case 2:
79808 +                                       ui32RegOffset = EUR_CR_BREAKPOINT2;
79809 +                                       ui32BaseRegOffset = EUR_CR_BREAKPOINT2_BASE;
79810 +                                       ui32MaskRegOffset = EUR_CR_BREAKPOINT2_MASK;
79811 +                                       break;
79812 +                               case 3:
79813 +                                       ui32RegOffset = EUR_CR_BREAKPOINT3;
79814 +                                       ui32BaseRegOffset = EUR_CR_BREAKPOINT3_BASE;
79815 +                                       ui32MaskRegOffset = EUR_CR_BREAKPOINT3_MASK;
79816 +                                       break;
79817 +                               default:
79818 +                                       PVR_DPF((PVR_DBG_ERROR,"SGXGetMiscInfoKM: SGX_MISC_INFO_REQUEST_SET_BREAKPOINT invalid BP idx %d", psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex));
79819 +                                       return PVRSRV_ERROR_INVALID_PARAMS;
79820 +                       }
79821 +
79822 +
79823 +                       if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
79824 +                       {
79825 +
79826 +                               IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
79827 +
79828 +
79829 +                               ui32MaskRegVal = EUR_CR_BREAKPOINT0_MASK_REGION_MASK | EUR_CR_BREAKPOINT0_MASK_DM_MASK;
79830 +
79831 +
79832 +                               ui32BaseRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_BASE_ADDRESS_MASK;
79833 +
79834 +
79835 +                               ui32RegVal =    EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK
79836 +                                                       |       EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK
79837 +                                                       |       EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK;
79838 +                       }
79839 +                       else
79840 +                       {
79841 +
79842 +                               ui32RegVal = ui32BaseRegVal = ui32MaskRegVal = 0;
79843 +                       }
79844 +
79845 +
79846 +
79847 +
79848 +
79849 +
79850 +
79851 +
79852 +
79853 +
79854 +                       return PVRSRV_OK;
79855 +               }
79856 +#endif
79857 +
79858 +               case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
79859 +               {
79860 +                       psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
79861 +                       return PVRSRV_OK;
79862 +               }
79863 +
79864 +               case SGX_MISC_INFO_REQUEST_SGXREV:
79865 +               {
79866 +                       PVRSRV_ERROR eError;
79867 +                       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;
79868 +
79869 +                       eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
79870 +                       if(eError != PVRSRV_OK)
79871 +                       {
79872 +                               PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
79873 +                                               eError));
79874 +                               return eError;
79875 +                       }
79876 +                       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
79877 +
79878 +
79879 +                       psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
79880 +
79881 +
79882 +                       PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%lx, sw ID 0x%lx, sw Rev 0x%lx\n",
79883 +                                       psSGXFeatures->ui32CoreRev,
79884 +                                       psSGXFeatures->ui32CoreIdSW,
79885 +                                       psSGXFeatures->ui32CoreRevSW));
79886 +                       PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%lx, DDK build 0x%lx\n",
79887 +                                       psSGXFeatures->ui32DDKVersion,
79888 +                                       psSGXFeatures->ui32DDKBuild));
79889 +
79890 +
79891 +                       return PVRSRV_OK;
79892 +               }
79893 +
79894 +               case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
79895 +               {
79896 +                       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;
79897 +
79898 +                       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
79899 +
79900 +
79901 +                       OSMemSet(psMemInfo->pvLinAddrKM, 0,
79902 +                                       sizeof(PVRSRV_SGX_MISCINFO_INFO));
79903 +
79904 +                       psSGXFeatures->ui32DDKVersion =
79905 +                               (PVRVERSION_MAJ << 16) |
79906 +                               (PVRVERSION_MIN << 8) |
79907 +                               PVRVERSION_BRANCH;
79908 +                       psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
79909 +
79910 +
79911 +                       psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
79912 +
79913 +
79914 +                       psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
79915 +                       return PVRSRV_OK;
79916 +               }
79917 +
79918 +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
79919 +               case SGX_MISC_INFO_REQUEST_MEMREAD:
79920 +               {
79921 +                       PVRSRV_ERROR eError;
79922 +                       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
79923 +                       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;
79924 +                       PVRSRV_SGX_MISCINFO_MEMREAD                     *psSGXMemReadData;
79925 +
79926 +                       psSGXMemReadData = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemReadData;
79927 +
79928 +
79929 +                       *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
79930 +
79931 +
79932 +                       if(psMiscInfo->hDevMemContext != IMG_NULL)
79933 +                       {
79934 +                               SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemReadData->sPDDevPAddr);
79935 +                       }
79936 +                       else
79937 +                       {
79938 +                               return PVRSRV_ERROR_INVALID_PARAMS;
79939 +                       }
79940 +
79941 +
79942 +                       if(psMiscInfo->sDevVAddr.uiAddr != 0)
79943 +                       {
79944 +                               psSGXMemReadData->sDevVAddr = psMiscInfo->sDevVAddr;
79945 +                       }
79946 +                       else
79947 +                       {
79948 +                               return PVRSRV_ERROR_INVALID_PARAMS;
79949 +                       }
79950 +
79951 +
79952 +                       eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
79953 +                       if(eError != PVRSRV_OK)
79954 +                       {
79955 +                               PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
79956 +                                               eError));
79957 +                               return eError;
79958 +                       }
79959 +                       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
79960 +
79961 +#if !defined SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
79962 +                       if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
79963 +                       {
79964 +                               return PVRSRV_ERROR_GENERIC;
79965 +                       }
79966 +#endif
79967 +
79968 +                       psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
79969 +                       return PVRSRV_OK;
79970 +               }
79971 +#endif
79972 +
79973 +#ifdef SUPPORT_SGX_HWPERF
79974 +               case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
79975 +               {
79976 +                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
79977 +                       IMG_UINT ui32MatchingFlags;
79978 +
79979 +
79980 +                       if ((psMiscInfo->uData.ui32NewHWPerfStatus & ~(PVRSRV_SGX_HWPERF_GRAPHICS_ON | PVRSRV_SGX_HWPERF_MK_EXECUTION_ON)) != 0)
79981 +                       {
79982 +                               return PVRSRV_ERROR_INVALID_PARAMS;
79983 +                       }
79984 +
79985 +
79986 +                       ui32MatchingFlags = psMiscInfo->uData.ui32NewHWPerfStatus & psDevInfo->psSGXHostCtl->ui32HWPerfFlags;
79987 +                       if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_GRAPHICS_ON) == 0UL)
79988 +                       {
79989 +                               psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffff;
79990 +                       }
79991 +                       if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_MK_EXECUTION_ON) == 0UL)
79992 +                       {
79993 +                               psHWPerfCB->ui32OrdinalMK_EXECUTION = 0xffffffffUL;
79994 +                       }
79995 +
79996 +
79997 +                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags = psMiscInfo->uData.ui32NewHWPerfStatus;
79998 +                       #if defined(PDUMP)
79999 +                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX ukernel HWPerf status %lu\n",
80000 +                                                                 psDevInfo->psSGXHostCtl->ui32HWPerfFlags);
80001 +                       PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
80002 +                                        offsetof(SGXMKIF_HOST_CTL, ui32HWPerfFlags),
80003 +                                        sizeof(psDevInfo->psSGXHostCtl->ui32HWPerfFlags), PDUMP_FLAGS_CONTINUOUS,
80004 +                                        MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
80005 +                       #endif
80006 +
80007 +                       return PVRSRV_OK;
80008 +               }
80009 +               case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON:
80010 +               {
80011 +
80012 +                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
80013 +                       psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffffUL;
80014 +
80015 +                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_GRAPHICS_ON;
80016 +                       return PVRSRV_OK;
80017 +               }
80018 +               case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF:
80019 +               {
80020 +
80021 +                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags = 0;
80022 +                       return PVRSRV_OK;
80023 +               }
80024 +               case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB:
80025 +               {
80026 +
80027 +                       SGX_MISC_INFO_HWPERF_RETRIEVE_CB *psRetrieve = &psMiscInfo->uData.sRetrieveCB;
80028 +                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
80029 +                       IMG_UINT i;
80030 +
80031 +                       for (i = 0; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++)
80032 +                       {
80033 +                               SGXMKIF_HWPERF_CB_ENTRY *psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
80034 +
80035 +
80036 +
80037 +                               psRetrieve->psHWPerfData[i].ui32FrameNo = psData->ui32FrameNo;
80038 +                               psRetrieve->psHWPerfData[i].ui32Type = (psData->ui32Type & PVRSRV_SGX_HWPERF_TYPE_OP_MASK);
80039 +                               psRetrieve->psHWPerfData[i].ui32StartTime = psData->ui32Time;
80040 +                               psRetrieve->psHWPerfData[i].ui32StartTimeWraps = psData->ui32TimeWraps;
80041 +                               psRetrieve->psHWPerfData[i].ui32EndTime = psData->ui32Time;
80042 +                               psRetrieve->psHWPerfData[i].ui32EndTimeWraps = psData->ui32TimeWraps;
80043 +                               psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
80044 +                               psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock;
80045 +                               psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
80046 +                       }
80047 +                       psRetrieve->ui32DataCount = i;
80048 +                       psRetrieve->ui32Time = OSClockus();
80049 +                       return PVRSRV_OK;
80050 +               }
80051 +#endif
80052 +               case SGX_MISC_INFO_DUMP_DEBUG_INFO:
80053 +               {
80054 +                       PVR_LOG(("User requested SGX debug info"));
80055 +
80056 +
80057 +                       SGXDumpDebugInfo(psDeviceNode, IMG_FALSE);
80058 +
80059 +                       return PVRSRV_OK;
80060 +               }
80061 +
80062 +               case SGX_MISC_INFO_PANIC:
80063 +               {
80064 +                       PVR_LOG(("User requested SGX panic"));
80065 +
80066 +                       SGXPanic(psDeviceNode);
80067 +
80068 +                       return PVRSRV_OK;
80069 +               }
80070 +
80071 +               default:
80072 +               {
80073 +
80074 +                       return PVRSRV_ERROR_INVALID_PARAMS;
80075 +               }
80076 +       }
80077 +}
80078 +
80079 +#if defined(SUPPORT_SGX_HWPERF)
80080 +IMG_EXPORT
80081 +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE                          hDevHandle,
80082 +                                                                  IMG_UINT32                           ui32Reg,
80083 +                                                                  IMG_UINT32                           *pui32Old,
80084 +                                                                  IMG_BOOL                                     bNew,
80085 +                                                                  IMG_UINT32                           ui32New,
80086 +                                                                  IMG_UINT32                           ui32NewReset,
80087 +                                                                  IMG_UINT32                           ui32CountersReg,
80088 +                                                                  IMG_UINT32                           ui32Reg2,
80089 +                                                                  IMG_BOOL                                     *pbActive,
80090 +                                                                  PVRSRV_SGXDEV_DIFF_INFO      *psDiffs)
80091 +{
80092 +       PVRSRV_ERROR            eError;
80093 +       SYS_DATA                        *psSysData;
80094 +       PVRSRV_POWER_DEV        *psPowerDevice;
80095 +       IMG_BOOL                        bPowered = IMG_FALSE;
80096 +       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
80097 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
80098 +
80099 +
80100 +       if(bNew)
80101 +       {
80102 +               psDevInfo->ui32HWGroupRequested = ui32New;
80103 +       }
80104 +       psDevInfo->ui32HWReset |= ui32NewReset;
80105 +
80106 +
80107 +       eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
80108 +       if (eError != PVRSRV_OK)
80109 +       {
80110 +               return eError;
80111 +       }
80112 +
80113 +       SysAcquireData(&psSysData);
80114 +
80115 +
80116 +       psPowerDevice = (PVRSRV_POWER_DEV*)
80117 +                               List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
80118 +                                                                                       MatchPowerDeviceIndex_AnyVaCb,
80119 +                                                                                       psDeviceNode->sDevId.ui32DeviceIndex);
80120 +
80121 +       if (psPowerDevice)
80122 +       {
80123 +               bPowered = (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON);
80124 +       }
80125 +
80126 +
80127 +
80128 +       *pbActive = bPowered;
80129 +
80130 +
80131 +
80132 +       {
80133 +               IMG_UINT32 ui32rval = 0;
80134 +
80135 +
80136 +               if(bPowered)
80137 +               {
80138 +                       IMG_UINT32 i;
80139 +
80140 +
80141 +                       *pui32Old = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg);
80142 +
80143 +                       for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i)
80144 +                       {
80145 +                               psDiffs->aui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32CountersReg + (i * 4));
80146 +                       }
80147 +
80148 +                       if(ui32Reg2)
80149 +                       {
80150 +                               ui32rval = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg2);
80151 +                       }
80152 +
80153 +
80154 +
80155 +                       if (psDevInfo->ui32HWGroupRequested != *pui32Old)
80156 +                       {
80157 +
80158 +                               if(psDevInfo->ui32HWReset != 0)
80159 +                               {
80160 +                                       OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested | psDevInfo->ui32HWReset);
80161 +                                       psDevInfo->ui32HWReset = 0;
80162 +                               }
80163 +
80164 +                               OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested);
80165 +                       }
80166 +               }
80167 +
80168 +               psDiffs->ui32Time[0] = OSClockus();
80169 +               psDiffs->ui32Time[1] = psDevInfo->psSGXHostCtl->ui32TimeWraps;
80170 +               psDiffs->ui32Time[2] = ui32rval;
80171 +
80172 +               psDiffs->ui32Marker[0] = psDevInfo->ui32KickTACounter;
80173 +               psDiffs->ui32Marker[1] = psDevInfo->ui32KickTARenderCounter;
80174 +       }
80175 +
80176 +
80177 +       PVRSRVPowerUnlock(KERNEL_ID);
80178 +
80179 +       SGXTestActivePowerEvent(psDeviceNode, KERNEL_ID);
80180 +
80181 +       return eError;
80182 +}
80183 +
80184 +
80185 +IMG_EXPORT
80186 +PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE                                      hDevHandle,
80187 +                                                          IMG_UINT32                                   ui32ArraySize,
80188 +                                                          PVRSRV_SGX_HWPERF_CB_ENTRY   *psClientHWPerfEntry,
80189 +                                                          IMG_UINT32                                   *pui32DataCount,
80190 +                                                          IMG_UINT32                                   *pui32ClockSpeed,
80191 +                                                          IMG_UINT32                                   *pui32HostTimeStamp)
80192 +{
80193 +       PVRSRV_ERROR            eError = PVRSRV_OK;
80194 +       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
80195 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
80196 +       SGXMKIF_HWPERF_CB       *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
80197 +       IMG_UINT                        i;
80198 +
80199 +       for (i = 0;
80200 +                psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
80201 +                i++)
80202 +       {
80203 +               SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
80204 +
80205 +               psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
80206 +               psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
80207 +               psClientHWPerfEntry[i].ui32Ordinal      = psMKPerfEntry->ui32Ordinal;
80208 +               psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
80209 +                                                                                                       psMKPerfEntry->ui32TimeWraps,
80210 +                                                                                                       psMKPerfEntry->ui32Time);
80211 +               OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0],
80212 +                                 &psMKPerfEntry->ui32Counters[0],
80213 +                                 sizeof(psMKPerfEntry->ui32Counters));
80214 +
80215 +               psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
80216 +       }
80217 +
80218 +       *pui32DataCount = i;
80219 +       *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
80220 +       *pui32HostTimeStamp = OSClockus();
80221 +
80222 +       return eError;
80223 +}
80224 +#else
80225 +#endif
80226 +
80227 +
80228 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
80229 new file mode 100644
80230 index 0000000..2848313
80231 --- /dev/null
80232 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
80233 @@ -0,0 +1,744 @@
80234 +/**********************************************************************
80235 + *
80236 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
80237 + * 
80238 + * This program is free software; you can redistribute it and/or modify it
80239 + * under the terms and conditions of the GNU General Public License,
80240 + * version 2, as published by the Free Software Foundation.
80241 + * 
80242 + * This program is distributed in the hope it will be useful but, except 
80243 + * as otherwise stated in writing, without any warranty; without even the 
80244 + * implied warranty of merchantability or fitness for a particular purpose. 
80245 + * See the GNU General Public License for more details.
80246 + * 
80247 + * You should have received a copy of the GNU General Public License along with
80248 + * this program; if not, write to the Free Software Foundation, Inc.,
80249 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
80250 + * 
80251 + * The full GNU General Public License is included in this distribution in
80252 + * the file called "COPYING".
80253 + *
80254 + * Contact Information:
80255 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
80256 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
80257 + *
80258 + ******************************************************************************/
80259 +
80260 +#include <stddef.h> 
80261 +#include "services_headers.h"
80262 +#include "sgxinfo.h"
80263 +#include "sgxinfokm.h"
80264 +#if defined (PDUMP)
80265 +#include "sgxapi_km.h"
80266 +#include "pdump_km.h"
80267 +#endif
80268 +#include "sgx_bridge_km.h"
80269 +#include "osfunc.h"
80270 +#include "pvr_debug.h"
80271 +#include "sgxutils.h"
80272 +
80273 +IMG_EXPORT
80274 +PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
80275 +{
80276 +       PVRSRV_ERROR eError;
80277 +       PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
80278 +       PVRSRV_KERNEL_MEM_INFO  *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo;
80279 +       SGXMKIF_CMDTA_SHARED *psTACmd;
80280 +       IMG_UINT32 i;
80281 +#if defined(SUPPORT_SGX_HWPERF)
80282 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
80283 +       PVRSRV_SGXDEV_INFO      *psDevInfo;
80284 +
80285 +       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
80286 +       psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
80287 +#endif
80288 +
80289 +#if defined(SUPPORT_SGX_HWPERF)
80290 +       if (psCCBKick->bKickRender)
80291 +       {
80292 +               ++psDevInfo->ui32KickTARenderCounter;
80293 +       }
80294 +       ++psDevInfo->ui32KickTACounter;
80295 +#endif
80296 +
80297 +       if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset))
80298 +       {
80299 +               PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
80300 +               return PVRSRV_ERROR_INVALID_PARAMS;
80301 +       }
80302 +       
80303 +       
80304 +       psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset);
80305 +
80306 +       
80307 +       if (psCCBKick->hTA3DSyncInfo)
80308 +       {
80309 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
80310 +               psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80311 +
80312 +               psTACmd->sTA3DDependency.ui32WriteOpsPendingVal   = psSyncInfo->psSyncData->ui32WriteOpsPending;
80313 +
80314 +               if (psCCBKick->bTADependency)
80315 +               {
80316 +                       psSyncInfo->psSyncData->ui32WriteOpsPending++;
80317 +               }
80318 +       }
80319 +
80320 +       if (psCCBKick->hTASyncInfo != IMG_NULL)
80321 +       {
80322 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
80323 +
80324 +               psTACmd->sTATQSyncReadOpsCompleteDevVAddr  = psSyncInfo->sReadOpsCompleteDevVAddr;
80325 +               psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80326 +
80327 +               psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80328 +               psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
80329 +       }
80330 +
80331 +       if (psCCBKick->h3DSyncInfo != IMG_NULL)
80332 +       {
80333 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
80334 +
80335 +               psTACmd->s3DTQSyncReadOpsCompleteDevVAddr  = psSyncInfo->sReadOpsCompleteDevVAddr;
80336 +               psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80337 +
80338 +               psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80339 +               psTACmd->ui323DTQSyncWriteOpsPendingVal  = psSyncInfo->psSyncData->ui32WriteOpsPending;
80340 +       }
80341 +
80342 +       psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals;
80343 +       if (psCCBKick->ui32NumTAStatusVals != 0)
80344 +       {
80345 +               
80346 +               for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
80347 +               {
80348 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80349 +                       psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus;
80350 +#else
80351 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
80352 +                       psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80353 +                       psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
80354 +#endif
80355 +               }
80356 +       }
80357 +
80358 +       psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
80359 +       if (psCCBKick->ui32Num3DStatusVals != 0)
80360 +       {
80361 +               
80362 +               for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
80363 +               {
80364 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80365 +                       psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus;
80366 +#else
80367 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
80368 +                       psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80369 +                       psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending;
80370 +#endif
80371 +               }
80372 +       }
80373 +
80374 +
80375 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
80376 +       
80377 +       psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs;
80378 +       for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
80379 +       {
80380 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
80381 +
80382 +               psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80383 +               psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80384 +
80385 +               
80386 +               psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80387 +               
80388 +               psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
80389 +       }
80390 +
80391 +       psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs;
80392 +       for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
80393 +       {
80394 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
80395 +
80396 +               psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80397 +               psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80398 +
80399 +               
80400 +               psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
80401 +               
80402 +               psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
80403 +       }
80404 +
80405 +       psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs;
80406 +       for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
80407 +       {
80408 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
80409 +
80410 +               psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80411 +               psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80412 +
80413 +               
80414 +               psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80415 +               
80416 +               psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
80417 +       }
80418 +#else 
80419 +       
80420 +       psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
80421 +       for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
80422 +       {
80423 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
80424 +
80425 +               psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80426 +               psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80427 +
80428 +               
80429 +               psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
80430 +               
80431 +               psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
80432 +       }
80433 +#endif
80434 +
80435 +       if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
80436 +       {
80437 +               PVRSRV_KERNEL_MEM_INFO  *psHWDstSyncListMemInfo =
80438 +                                                               (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
80439 +               SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
80440 +               IMG_UINT32      ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
80441 +
80442 +               PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->ui32AllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) +
80443 +                                                               (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs)));
80444 +
80445 +               psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
80446 +#if defined(PDUMP)
80447 +               if (PDumpIsCaptureFrameKM())
80448 +               {
80449 +                       PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
80450 +                       PDUMPMEM(IMG_NULL,
80451 +                                        psHWDstSyncListMemInfo,
80452 +                                        0,
80453 +                                        sizeof(SGXMKIF_HWDEVICE_SYNC_LIST),
80454 +                                        0,
80455 +                                        MAKEUNIQUETAG(psHWDstSyncListMemInfo));
80456 +               }
80457 +#endif
80458 +
80459 +               for (i=0; i<ui32NumDstSyncs; i++)
80460 +               {
80461 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
80462 +
80463 +                       if (psSyncInfo)
80464 +                       {
80465 +                               psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
80466 +                               psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
80467 +
80468 +                               psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
80469 +                               psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
80470 +
80471 +       #if defined(PDUMP)
80472 +                               if (PDumpIsCaptureFrameKM())
80473 +                               {
80474 +                                       IMG_UINT32 ui32ModifiedValue;
80475 +                                       IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData)
80476 +                                                                                               + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT));
80477 +                                       IMG_UINT32 ui32WOpsOffset = ui32SyncOffset
80478 +                                                                                               + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal);
80479 +                                       IMG_UINT32 ui32ROpsOffset = ui32SyncOffset
80480 +                                                                                               + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal);
80481 +
80482 +                                       PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i);
80483 +
80484 +                                       PDUMPMEM(IMG_NULL,
80485 +                                                        psHWDstSyncListMemInfo,
80486 +                                                        ui32SyncOffset,
80487 +                                                        sizeof(PVRSRV_DEVICE_SYNC_OBJECT),
80488 +                                                        0,
80489 +                                                        MAKEUNIQUETAG(psHWDstSyncListMemInfo));
80490 +
80491 +                                       if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
80492 +                                               (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
80493 +                                       {
80494 +                                               
80495 +                                               PDUMPCOMMENT("Init RT ROpsComplete\r\n", i);
80496 +                                               PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80497 +                                                       psSyncInfo->psSyncDataMemInfoKM,
80498 +                                                       offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
80499 +                                                       sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
80500 +                                                       0,
80501 +                                                       MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80502 +                                               
80503 +                                               PDUMPCOMMENT("Init RT WOpsComplete\r\n");
80504 +                                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80505 +                                                               psSyncInfo->psSyncDataMemInfoKM,
80506 +                                                               offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
80507 +                                                               sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
80508 +                                                               0,
80509 +                                                               MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80510 +                                       }
80511 +
80512 +                                       psSyncInfo->psSyncData->ui32LastOpDumpVal++;
80513 +
80514 +                                       ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
80515 +
80516 +                                       PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i);
80517 +
80518 +                                       PDUMPMEM(&ui32ModifiedValue,
80519 +                                               psHWDstSyncListMemInfo,
80520 +                                               ui32WOpsOffset,
80521 +                                               sizeof(IMG_UINT32),
80522 +                                               0,
80523 +                                               MAKEUNIQUETAG(psHWDstSyncListMemInfo));
80524 +
80525 +                                       ui32ModifiedValue = 0;
80526 +                                       PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i);
80527 +
80528 +                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80529 +                                                psHWDstSyncListMemInfo,
80530 +                                                ui32ROpsOffset,
80531 +                                                sizeof(IMG_UINT32),
80532 +                                                0,
80533 +                                               MAKEUNIQUETAG(psHWDstSyncListMemInfo));
80534 +                               }
80535 +       #endif  
80536 +                       }
80537 +                       else
80538 +                       {
80539 +                               psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0;
80540 +                               psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0;
80541 +
80542 +                               psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0;
80543 +                               psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0;
80544 +                       }
80545 +               }
80546 +       }
80547 +       
80548 +       
80549 +
80550 +
80551 +       psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY;
80552 +
80553 +#if defined(PDUMP)
80554 +       if (PDumpIsCaptureFrameKM())
80555 +       {
80556 +               PDUMPCOMMENT("Shared part of TA command\r\n");
80557 +
80558 +               PDUMPMEM(psTACmd,
80559 +                                psCCBMemInfo,
80560 +                                psCCBKick->ui32CCBDumpWOff,
80561 +                                sizeof(SGXMKIF_CMDTA_SHARED),
80562 +                                0,
80563 +                                MAKEUNIQUETAG(psCCBMemInfo));
80564 +
80565 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
80566 +               for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
80567 +               {
80568 +                       IMG_UINT32      ui32ModifiedValue;
80569 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
80570 +
80571 +                       if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
80572 +                               (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
80573 +                       {
80574 +                               
80575 +                               PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i);
80576 +                               PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80577 +                                       psSyncInfo->psSyncDataMemInfoKM,
80578 +                                       offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
80579 +                                       sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
80580 +                                       0,
80581 +                                       MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80582 +                               
80583 +                               PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n");
80584 +                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80585 +                                               psSyncInfo->psSyncDataMemInfoKM,
80586 +                                               offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
80587 +                                               sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
80588 +                                               0,
80589 +                                               MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80590 +                       }
80591 +
80592 +                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
80593 +
80594 +                       ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
80595 +
80596 +                       PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i);
80597 +
80598 +                       PDUMPMEM(&ui32ModifiedValue,
80599 +                                psCCBMemInfo,
80600 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
80601 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
80602 +                                sizeof(IMG_UINT32),
80603 +                                0,
80604 +                               MAKEUNIQUETAG(psCCBMemInfo));
80605 +
80606 +                       PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i);
80607 +
80608 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80609 +                               psCCBMemInfo,
80610 +                               psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
80611 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
80612 +                               sizeof(IMG_UINT32),
80613 +                               0,
80614 +                               MAKEUNIQUETAG(psCCBMemInfo));
80615 +               }
80616 +
80617 +               for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
80618 +               {
80619 +                       IMG_UINT32      ui32ModifiedValue;
80620 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
80621 +
80622 +                       if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
80623 +                               (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
80624 +                       {
80625 +                               
80626 +                               PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i);
80627 +                               PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80628 +                                       psSyncInfo->psSyncDataMemInfoKM,
80629 +                                       offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
80630 +                                       sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
80631 +                                       0,
80632 +                                       MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80633 +                               
80634 +                               PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n");
80635 +                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80636 +                                               psSyncInfo->psSyncDataMemInfoKM,
80637 +                                               offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
80638 +                                               sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
80639 +                                               0,
80640 +                                               MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80641 +                       }
80642 +
80643 +                       psSyncInfo->psSyncData->ui32LastOpDumpVal++;
80644 +
80645 +                       ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1;
80646 +
80647 +                       PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i);
80648 +
80649 +                       PDUMPMEM(&ui32ModifiedValue,
80650 +                                psCCBMemInfo,
80651 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
80652 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
80653 +                                sizeof(IMG_UINT32),
80654 +                                0,
80655 +                               MAKEUNIQUETAG(psCCBMemInfo));
80656 +
80657 +                       PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i);
80658 +
80659 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80660 +                               psCCBMemInfo,
80661 +                               psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
80662 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
80663 +                               sizeof(IMG_UINT32),
80664 +                               0,
80665 +                               MAKEUNIQUETAG(psCCBMemInfo));
80666 +               }
80667 +
80668 +               for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
80669 +               {
80670 +                       IMG_UINT32      ui32ModifiedValue;
80671 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
80672 +
80673 +                       if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
80674 +                               (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
80675 +                       {
80676 +                               
80677 +                               PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i);
80678 +                               PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80679 +                                       psSyncInfo->psSyncDataMemInfoKM,
80680 +                                       offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
80681 +                                       sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
80682 +                                       0,
80683 +                                       MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80684 +                               
80685 +                               PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n");
80686 +                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80687 +                                               psSyncInfo->psSyncDataMemInfoKM,
80688 +                                               offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
80689 +                                               sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
80690 +                                               0,
80691 +                                               MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80692 +                       }
80693 +
80694 +                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
80695 +
80696 +                       ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
80697 +
80698 +                       PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i);
80699 +
80700 +                       PDUMPMEM(&ui32ModifiedValue,
80701 +                                psCCBMemInfo,
80702 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
80703 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
80704 +                                sizeof(IMG_UINT32),
80705 +                                0,
80706 +                               MAKEUNIQUETAG(psCCBMemInfo));
80707 +
80708 +                       PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i);
80709 +
80710 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80711 +                               psCCBMemInfo,
80712 +                               psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
80713 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
80714 +                               sizeof(IMG_UINT32),
80715 +                               0,
80716 +                               MAKEUNIQUETAG(psCCBMemInfo));
80717 +               }
80718 +#else
80719 +               for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
80720 +               {
80721 +                       IMG_UINT32      ui32ModifiedValue;
80722 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
80723 +
80724 +                       if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
80725 +                               (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
80726 +                       {
80727 +                               
80728 +                               PDUMPCOMMENT("Init RT ROpsComplete\r\n", i);
80729 +                               PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
80730 +                                       psSyncInfo->psSyncDataMemInfoKM,
80731 +                                       offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
80732 +                                       sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
80733 +                                       0,
80734 +                                       MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80735 +                               
80736 +                               PDUMPCOMMENT("Init RT WOpsComplete\r\n");
80737 +                                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80738 +                                               psSyncInfo->psSyncDataMemInfoKM,
80739 +                                               offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
80740 +                                               sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete),
80741 +                                               0,
80742 +                                               MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
80743 +                       }
80744 +
80745 +                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
80746 +
80747 +                       ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
80748 +
80749 +                       PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
80750 +
80751 +                       PDUMPMEM(&ui32ModifiedValue,
80752 +                                psCCBMemInfo,
80753 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
80754 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
80755 +                                sizeof(IMG_UINT32),
80756 +                                0,
80757 +                               MAKEUNIQUETAG(psCCBMemInfo));
80758 +
80759 +                       PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
80760 +
80761 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80762 +                               psCCBMemInfo,
80763 +                               psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) +
80764 +                                       (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
80765 +                               sizeof(IMG_UINT32),
80766 +                               0,
80767 +                               MAKEUNIQUETAG(psCCBMemInfo));
80768 +               }
80769 +#endif
80770 +
80771 +               for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
80772 +               {
80773 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80774 +                       PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
80775 +                       PDUMPMEM(&psCCBKick->asTAStatusUpdate[i].ui32LastStatusUpdateDumpVal,
80776 +                                psCCBMemInfo,
80777 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue),
80778 +                                sizeof(IMG_UINT32),
80779 +                                0,
80780 +                               MAKEUNIQUETAG(psCCBMemInfo));
80781 +#else
80782 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
80783 +                       PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
80784 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80785 +                                psCCBMemInfo,
80786 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue),
80787 +                                sizeof(IMG_UINT32),
80788 +                                0,
80789 +                               MAKEUNIQUETAG(psCCBMemInfo));
80790 +#endif
80791 +               }
80792 +
80793 +               for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
80794 +               {
80795 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80796 +                       PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
80797 +                       PDUMPMEM(&psCCBKick->as3DStatusUpdate[i].ui32LastStatusUpdateDumpVal,
80798 +                                psCCBMemInfo,
80799 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
80800 +                                sizeof(IMG_UINT32),
80801 +                                0,
80802 +                               MAKEUNIQUETAG(psCCBMemInfo));
80803 +#else
80804 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
80805 +                       PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
80806 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
80807 +                                psCCBMemInfo,
80808 +                                psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
80809 +                                sizeof(IMG_UINT32),
80810 +                                0,
80811 +                               MAKEUNIQUETAG(psCCBMemInfo));
80812 +#endif
80813 +               }
80814 +       }
80815 +#endif 
80816 +
80817 +       eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0);
80818 +       if (eError == PVRSRV_ERROR_RETRY)
80819 +       {
80820 +               if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
80821 +               {
80822 +                       for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++)
80823 +                       {
80824 +                               
80825 +                               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
80826 +
80827 +                               if (psSyncInfo)
80828 +                               {
80829 +                                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
80830 +#if defined(PDUMP)
80831 +                                       if (PDumpIsCaptureFrameKM())
80832 +                                       {
80833 +                                               psSyncInfo->psSyncData->ui32LastOpDumpVal--;
80834 +                                       }
80835 +#endif
80836 +                               }
80837 +                       }
80838 +               }
80839 +
80840 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
80841 +               for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
80842 +               {
80843 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
80844 +                       psSyncInfo->psSyncData->ui32ReadOpsPending--;
80845 +               }
80846 +               for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
80847 +               {
80848 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
80849 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
80850 +               }
80851 +               for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
80852 +               {
80853 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
80854 +                       psSyncInfo->psSyncData->ui32ReadOpsPending--;
80855 +               }
80856 +#else
80857 +               for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
80858 +               {
80859 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
80860 +                       psSyncInfo->psSyncData->ui32ReadOpsPending--;
80861 +               }
80862 +#endif
80863 +
80864 +               return eError;
80865 +       }
80866 +       else if (PVRSRV_OK != eError)
80867 +       {
80868 +               PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed."));
80869 +               return eError;
80870 +       }
80871 +
80872 +
80873 +#if defined(NO_HARDWARE)
80874 +
80875 +
80876 +       
80877 +       if (psCCBKick->hTA3DSyncInfo)
80878 +       {
80879 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
80880 +
80881 +               if (psCCBKick->bTADependency)
80882 +               {
80883 +                       psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
80884 +               }
80885 +       }
80886 +
80887 +       if (psCCBKick->hTASyncInfo != IMG_NULL)
80888 +       {
80889 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
80890 +
80891 +               psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
80892 +       }
80893 +
80894 +       if (psCCBKick->h3DSyncInfo != IMG_NULL)
80895 +       {
80896 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
80897 +
80898 +               psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
80899 +       }
80900 +
80901 +       
80902 +       for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
80903 +       {
80904 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80905 +               PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo;
80906 +               
80907 +               *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
80908 +                                               + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr
80909 +                                               - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
80910 +#else
80911 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i];
80912 +               psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
80913 +#endif
80914 +       }
80915 +
80916 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
80917 +       
80918 +       for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
80919 +       {
80920 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
80921 +               psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
80922 +       }
80923 +       for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
80924 +       {
80925 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
80926 +               psSyncInfo->psSyncData->ui32WriteOpsComplete =  psSyncInfo->psSyncData->ui32WriteOpsPending;
80927 +       }
80928 +       for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
80929 +       {
80930 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
80931 +               psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
80932 +       }
80933 +#else
80934 +       
80935 +       for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
80936 +       {
80937 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
80938 +               psSyncInfo->psSyncData->ui32ReadOpsComplete =  psSyncInfo->psSyncData->ui32ReadOpsPending;
80939 +       }
80940 +#endif
80941 +
80942 +       if (psCCBKick->bTerminateOrAbort)
80943 +       {
80944 +               if (psCCBKick->ui32NumDstSyncObjects > 0)
80945 +               {
80946 +                       PVRSRV_KERNEL_MEM_INFO  *psHWDstSyncListMemInfo =
80947 +                                                               (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo;
80948 +                       SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM;
80949 +
80950 +                       for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++)
80951 +                       {
80952 +                               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
80953 +                               if (psSyncInfo)
80954 +                                       psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1;
80955 +                       }
80956 +               }
80957 +
80958 +               
80959 +               for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++)
80960 +               {
80961 +#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
80962 +                       PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo;
80963 +                       
80964 +                       *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM
80965 +                                                       + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr
80966 +                                                       - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
80967 +#else
80968 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i];
80969 +                       psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
80970 +#endif
80971 +               }
80972 +       }
80973 +#endif
80974 +
80975 +       return eError;
80976 +}
80977 +
80978 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxpower.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxpower.c
80979 new file mode 100644
80980 index 0000000..169ae20
80981 --- /dev/null
80982 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxpower.c
80983 @@ -0,0 +1,453 @@
80984 +/**********************************************************************
80985 + *
80986 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
80987 + *
80988 + * This program is free software; you can redistribute it and/or modify it
80989 + * under the terms and conditions of the GNU General Public License,
80990 + * version 2, as published by the Free Software Foundation.
80991 + *
80992 + * This program is distributed in the hope it will be useful but, except
80993 + * as otherwise stated in writing, without any warranty; without even the
80994 + * implied warranty of merchantability or fitness for a particular purpose.
80995 + * See the GNU General Public License for more details.
80996 + *
80997 + * You should have received a copy of the GNU General Public License along with
80998 + * this program; if not, write to the Free Software Foundation, Inc.,
80999 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
81000 + *
81001 + * The full GNU General Public License is included in this distribution in
81002 + * the file called "COPYING".
81003 + *
81004 + * Contact Information:
81005 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
81006 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
81007 + *
81008 + ******************************************************************************/
81009 +
81010 +#include <stddef.h>
81011 +
81012 +#include "sgxdefs.h"
81013 +#include "services_headers.h"
81014 +#include "sgxapi_km.h"
81015 +#include "sgx_mkif_km.h"
81016 +#include "sgxutils.h"
81017 +#include "pdump_km.h"
81018 +
81019 +
81020 +#if defined(SUPPORT_HW_RECOVERY)
81021 +static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE             *psDeviceNode,
81022 +                                                               SGX_TIMING_INFORMATION  *psSGXTimingInfo,
81023 +                                                               IMG_HANDLE                              *phTimer)
81024 +{
81025 +       *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode,
81026 +                                                 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq);
81027 +       if(*phTimer == IMG_NULL)
81028 +       {
81029 +               PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function"));
81030 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
81031 +       }
81032 +
81033 +       return PVRSRV_OK;
81034 +}
81035 +#endif 
81036 +
81037 +static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE     *psDeviceNode)
81038 +{
81039 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
81040 +#if defined(SGX_DYNAMIC_TIMING_INFO)
81041 +       SGX_TIMING_INFORMATION  sSGXTimingInfo = {0};
81042 +#else
81043 +       SGX_DEVICE_MAP          *psSGXDeviceMap;
81044 +#endif
81045 +       IMG_UINT32              ui32ActivePowManSampleRate;
81046 +       SGX_TIMING_INFORMATION  *psSGXTimingInfo;
81047 +
81048 +
81049 +#if defined(SGX_DYNAMIC_TIMING_INFO)
81050 +       psSGXTimingInfo = &sSGXTimingInfo;
81051 +       SysGetSGXTimingInformation(psSGXTimingInfo);
81052 +#else
81053 +       SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
81054 +                                                 (IMG_VOID**)&psSGXDeviceMap);
81055 +       psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo;
81056 +#endif
81057 +
81058 +#if defined(SUPPORT_HW_RECOVERY)
81059 +       {
81060 +               PVRSRV_ERROR                    eError;
81061 +               IMG_UINT32      ui32OlduKernelFreq;
81062 +
81063 +               if (psDevInfo->hTimer != IMG_NULL)
81064 +               {
81065 +                       ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock;
81066 +                       if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq)
81067 +                       {
81068 +                               IMG_HANDLE hNewTimer;
81069 +                               
81070 +                               eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer);
81071 +                               if (eError == PVRSRV_OK)
81072 +                               {
81073 +                                       eError = OSRemoveTimer(psDevInfo->hTimer);
81074 +                                       if (eError != PVRSRV_OK)
81075 +                                       {
81076 +                                               PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer"));
81077 +                                       }
81078 +                                       psDevInfo->hTimer = hNewTimer;
81079 +                               }
81080 +                               else
81081 +                               {
81082 +
81083 +                               }
81084 +                       }
81085 +               }
81086 +               else
81087 +               {
81088 +                       eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer);
81089 +                       if (eError != PVRSRV_OK)
81090 +                       {
81091 +                               return eError;
81092 +                       }
81093 +               }
81094 +
81095 +               psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate =
81096 +                       psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq;
81097 +       }
81098 +#endif
81099 +
81100 +
81101 +       psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed;
81102 +       psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq;
81103 +
81104 +
81105 +       psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock;
81106 +#if defined(PDUMP)
81107 +       PDUMPCOMMENT("Host Control - Microkernel clock");
81108 +       PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
81109 +                        offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock),
81110 +                        sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
81111 +                        MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
81112 +#endif
81113 +
81114 +       if (psSGXTimingInfo->bEnableActivePM)
81115 +       {
81116 +               ui32ActivePowManSampleRate =
81117 +                       psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000;
81118 +
81119 +
81120 +
81121 +
81122 +
81123 +
81124 +
81125 +
81126 +               ui32ActivePowManSampleRate += 1;
81127 +       }
81128 +       else
81129 +       {
81130 +               ui32ActivePowManSampleRate = 0;
81131 +       }
81132 +
81133 +       psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate;
81134 +#if defined(PDUMP)
81135 +       PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
81136 +                        offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate),
81137 +                        sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
81138 +                        MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
81139 +#endif
81140 +
81141 +       return PVRSRV_OK;
81142 +}
81143 +
81144 +
81145 +static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO       *psDevInfo)
81146 +{
81147 +       #if defined(SUPPORT_HW_RECOVERY)
81148 +       PVRSRV_ERROR    eError;
81149 +
81150 +       eError = OSEnableTimer(psDevInfo->hTimer);
81151 +       if (eError != PVRSRV_OK)
81152 +       {
81153 +               PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer"));
81154 +       }
81155 +       #else
81156 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
81157 +       #endif
81158 +}
81159 +
81160 +
81161 +static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO      *psDevInfo,
81162 +                                                                          IMG_UINT32                   ui32Register,
81163 +                                                                          IMG_UINT32                   ui32RegisterValue,
81164 +                                                                          IMG_CHAR                             *pszComment)
81165 +{
81166 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
81167 +       PVR_UNREFERENCED_PARAMETER(ui32Register);
81168 +       PVR_UNREFERENCED_PARAMETER(ui32RegisterValue);
81169 +       PVR_UNREFERENCED_PARAMETER(pszComment);
81170 +
81171 +       #if !defined(NO_HARDWARE)
81172 +       PVR_ASSERT(psDevInfo != IMG_NULL);
81173 +
81174 +
81175 +       if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2),
81176 +                                               0,
81177 +                                               ui32RegisterValue,
81178 +                                               MAX_HW_TIME_US/WAIT_TRY_COUNT,
81179 +                                               WAIT_TRY_COUNT) != PVRSRV_OK)
81180 +       {
81181 +               PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: %s failed.", pszComment));
81182 +       }
81183 +       #endif
81184 +
81185 +       PDUMPCOMMENT(pszComment);
81186 +       PDUMPREGPOL(ui32Register, 0, ui32RegisterValue);
81187 +}
81188 +
81189 +
81190 +PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE                              hDevHandle,
81191 +                                                          PVRSRV_DEV_POWER_STATE       eNewPowerState,
81192 +                                                          PVRSRV_DEV_POWER_STATE       eCurrentPowerState)
81193 +{
81194 +       if ((eNewPowerState != eCurrentPowerState) &&
81195 +               (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
81196 +       {
81197 +               PVRSRV_ERROR            eError;
81198 +               PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
81199 +               PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
81200 +               IMG_UINT32                      ui32PowerCmd, ui32CompleteStatus;
81201 +               SGXMKIF_COMMAND         sCommand = {0};
81202 +               IMG_UINT32                      ui32Core;
81203 +
81204 +               #if defined(SUPPORT_HW_RECOVERY)
81205 +
81206 +               eError = OSDisableTimer(psDevInfo->hTimer);
81207 +               if (eError != PVRSRV_OK)
81208 +               {
81209 +                       PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer"));
81210 +                       return eError;
81211 +               }
81212 +               #endif
81213 +
81214 +               if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
81215 +               {
81216 +
81217 +                       ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF;
81218 +                       ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE;
81219 +                       PDUMPCOMMENT("SGX power off request");
81220 +               }
81221 +               else
81222 +               {
81223 +
81224 +                       ui32PowerCmd = PVRSRV_POWERCMD_IDLE;
81225 +                       ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE;
81226 +                       PDUMPCOMMENT("SGX idle request");
81227 +               }
81228 +
81229 +               sCommand.ui32Data[1] = ui32PowerCmd;
81230 +
81231 +               eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0);
81232 +               if (eError != PVRSRV_OK)
81233 +               {
81234 +                       PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command"));
81235 +                       return eError;
81236 +               }
81237 +
81238 +
81239 +               #if !defined(NO_HARDWARE)
81240 +               if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus,
81241 +                                                       ui32CompleteStatus,
81242 +                                                       ui32CompleteStatus,
81243 +                                                       MAX_HW_TIME_US/WAIT_TRY_COUNT,
81244 +                                                       WAIT_TRY_COUNT) != PVRSRV_OK)
81245 +               {
81246 +                       PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
81247 +                       PVR_DBG_BREAK;
81248 +               }
81249 +               #endif
81250 +
81251 +               #if defined(PDUMP)
81252 +               PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel.");
81253 +               PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo,
81254 +                                       offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
81255 +                                       ui32CompleteStatus,
81256 +                                       ui32CompleteStatus,
81257 +                                       PDUMP_POLL_OPERATOR_EQUAL,
81258 +                                       0,
81259 +                                       MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
81260 +               #endif
81261 +
81262 +               for (ui32Core = 0; ui32Core < SGX_FEATURE_MP_CORE_COUNT; ui32Core++)
81263 +               {
81264 +
81265 +                       SGXPollForClockGating(psDevInfo,
81266 +                                                                 SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core),
81267 +                                                                 psDevInfo->ui32ClkGateStatusMask,
81268 +                                                                 "Wait for SGX clock gating");
81269 +               }
81270 +
81271 +               #if defined(SGX_FEATURE_MP)
81272 +
81273 +               SGXPollForClockGating(psDevInfo,
81274 +                                                         psDevInfo->ui32MasterClkGateStatusReg,
81275 +                                                         psDevInfo->ui32MasterClkGateStatusMask,
81276 +                                                         "Wait for SGX master clock gating");
81277 +               #endif
81278 +
81279 +               if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
81280 +               {
81281 +
81282 +                       eError = SGXDeinitialise(psDevInfo);
81283 +                       if (eError != PVRSRV_OK)
81284 +                       {
81285 +                               PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %lu", eError));
81286 +                               return eError;
81287 +                       }
81288 +               }
81289 +       }
81290 +
81291 +       return PVRSRV_OK;
81292 +}
81293 +
81294 +
81295 +PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE                             hDevHandle,
81296 +                                                               PVRSRV_DEV_POWER_STATE  eNewPowerState,
81297 +                                                               PVRSRV_DEV_POWER_STATE  eCurrentPowerState)
81298 +{
81299 +       if ((eNewPowerState != eCurrentPowerState) &&
81300 +               (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
81301 +       {
81302 +               PVRSRV_ERROR            eError;
81303 +               PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
81304 +               PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
81305 +               SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
81306 +
81307 +
81308 +               psSGXHostCtl->ui32PowerStatus = 0;
81309 +               #if defined(PDUMP)
81310 +               PDUMPCOMMENT("TA/3D CCB Control - Reset power status");
81311 +               PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
81312 +                                offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
81313 +                                sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
81314 +                                MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
81315 +               #endif
81316 +
81317 +               if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
81318 +               {
81319 +                       eError = SGXUpdateTimingInfo(psDeviceNode);
81320 +                       if (eError != PVRSRV_OK)
81321 +                       {
81322 +                               PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
81323 +                               return eError;
81324 +                       }
81325 +
81326 +                       eError = SGXInitialise(psDevInfo);
81327 +                       if (eError != PVRSRV_OK)
81328 +                       {
81329 +                               PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed"));
81330 +                               return eError;
81331 +                       }
81332 +               }
81333 +               else
81334 +               {
81335 +
81336 +
81337 +                       SGXMKIF_COMMAND         sCommand = {0};
81338 +
81339 +                       sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME;
81340 +                       eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0);
81341 +                       if (eError != PVRSRV_OK)
81342 +                       {
81343 +                               PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %lu", eError));
81344 +                               return PVRSRV_ERROR_GENERIC;
81345 +                       }
81346 +               }
81347 +
81348 +               SGXStartTimer(psDevInfo);
81349 +       }
81350 +
81351 +       return PVRSRV_OK;
81352 +}
81353 +
81354 +
81355 +PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE                                hDevHandle,
81356 +                                                                        IMG_BOOL                               bIdleDevice,
81357 +                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState)
81358 +{
81359 +       PVRSRV_ERROR            eError;
81360 +       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
81361 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
81362 +
81363 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
81364 +
81365 +       if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
81366 +       {
81367 +               if (bIdleDevice)
81368 +               {
81369 +
81370 +                       PDUMPSUSPEND();
81371 +
81372 +                       eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE,
81373 +                                                                         PVRSRV_DEV_POWER_STATE_ON);
81374 +
81375 +                       if (eError != PVRSRV_OK)
81376 +                       {
81377 +                               PDUMPRESUME();
81378 +                               return eError;
81379 +                       }
81380 +               }
81381 +       }
81382 +
81383 +       PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %luHz",
81384 +                       psDevInfo->ui32CoreClockSpeed));
81385 +
81386 +       return PVRSRV_OK;
81387 +}
81388 +
81389 +
81390 +PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE                               hDevHandle,
81391 +                                                                         IMG_BOOL                                      bIdleDevice,
81392 +                                                                         PVRSRV_DEV_POWER_STATE        eCurrentPowerState)
81393 +{
81394 +       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;
81395 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
81396 +       IMG_UINT32                      ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed;
81397 +
81398 +       PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed);
81399 +
81400 +       if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
81401 +       {
81402 +               PVRSRV_ERROR eError;
81403 +
81404 +               eError = SGXUpdateTimingInfo(psDeviceNode);
81405 +               if (eError != PVRSRV_OK)
81406 +               {
81407 +                       PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
81408 +                       return eError;
81409 +               }
81410 +
81411 +               if (bIdleDevice)
81412 +               {
81413 +                       eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON,
81414 +                                                                          PVRSRV_DEV_POWER_STATE_IDLE);
81415 +
81416 +                       PDUMPRESUME();
81417 +
81418 +                       if (eError != PVRSRV_OK)
81419 +                       {
81420 +                               return eError;
81421 +                       }
81422 +               }
81423 +               else
81424 +               {
81425 +                       SGXStartTimer(psDevInfo);
81426 +               }
81427 +
81428 +       }
81429 +
81430 +       PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %luHz to %luHz",
81431 +                       ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed));
81432 +
81433 +       return PVRSRV_OK;
81434 +}
81435 +
81436 +
81437 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxreset.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxreset.c
81438 new file mode 100644
81439 index 0000000..5cf2519
81440 --- /dev/null
81441 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxreset.c
81442 @@ -0,0 +1,489 @@
81443 +/**********************************************************************
81444 + *
81445 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
81446 + *
81447 + * This program is free software; you can redistribute it and/or modify it
81448 + * under the terms and conditions of the GNU General Public License,
81449 + * version 2, as published by the Free Software Foundation.
81450 + *
81451 + * This program is distributed in the hope it will be useful but, except
81452 + * as otherwise stated in writing, without any warranty; without even the
81453 + * implied warranty of merchantability or fitness for a particular purpose.
81454 + * See the GNU General Public License for more details.
81455 + *
81456 + * You should have received a copy of the GNU General Public License along with
81457 + * this program; if not, write to the Free Software Foundation, Inc.,
81458 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
81459 + *
81460 + * The full GNU General Public License is included in this distribution in
81461 + * the file called "COPYING".
81462 + *
81463 + * Contact Information:
81464 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
81465 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
81466 + *
81467 + ******************************************************************************/
81468 +
81469 +#include "sgxdefs.h"
81470 +#include "sgxmmu.h"
81471 +#include "services_headers.h"
81472 +#include "sgxinfokm.h"
81473 +#include "sgxconfig.h"
81474 +
81475 +#include "pdump_km.h"
81476 +
81477 +
81478 +static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO   *psDevInfo,
81479 +                                                                 IMG_BOOL                              bResetBIF,
81480 +                                                                 IMG_UINT32                    ui32PDUMPFlags,
81481 +                                                                 IMG_BOOL                              bPDump)
81482 +{
81483 +       IMG_UINT32 ui32SoftResetRegVal;
81484 +
81485 +#if defined(SGX_FEATURE_MP)
81486 +       ui32SoftResetRegVal =
81487 +                                       EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK |
81488 +                                       EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK  |
81489 +                                       EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
81490 +
81491 +#if defined(SGX_FEATURE_SYSTEM_CACHE)
81492 +       ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK;
81493 +#endif
81494 +
81495 +       if (bResetBIF)
81496 +       {
81497 +               ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK;
81498 +       }
81499 +
81500 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal);
81501 +       if (bPDump)
81502 +       {
81503 +               PDUMPREGWITHFLAGS(EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
81504 +       }
81505 +#endif
81506 +
81507 +       ui32SoftResetRegVal =
81508 +
81509 +                                       EUR_CR_SOFT_RESET_DPM_RESET_MASK |
81510 +                                       EUR_CR_SOFT_RESET_TA_RESET_MASK  |
81511 +                                       EUR_CR_SOFT_RESET_USE_RESET_MASK |
81512 +                                       EUR_CR_SOFT_RESET_ISP_RESET_MASK |
81513 +                                       EUR_CR_SOFT_RESET_TSP_RESET_MASK;
81514 +
81515 +#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK
81516 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK;
81517 +#endif
81518 +#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK)
81519 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK;
81520 +#endif
81521 +#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK)
81522 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK;
81523 +#endif
81524 +#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK)
81525 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK;
81526 +#endif
81527 +#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK)
81528 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK;
81529 +#endif
81530 +#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK)
81531 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK;
81532 +#endif
81533 +#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK)
81534 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK;
81535 +#endif
81536 +#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK)
81537 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK;
81538 +#endif
81539 +#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK)
81540 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK;
81541 +#endif
81542 +#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK)
81543 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK;
81544 +#endif
81545 +#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK)
81546 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK;
81547 +#endif
81548 +#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK)
81549 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK;
81550 +#endif
81551 +#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK)
81552 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK;
81553 +#endif
81554 +#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK)
81555 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK;
81556 +#endif
81557 +#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK)
81558 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK;
81559 +#endif
81560 +#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK)
81561 +       ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK;
81562 +#endif
81563 +
81564 +#if !defined(PDUMP)
81565 +       PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
81566 +#endif
81567 +
81568 +       if (bResetBIF)
81569 +       {
81570 +               ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK;
81571 +       }
81572 +
81573 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal);
81574 +       if (bPDump)
81575 +       {
81576 +               PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
81577 +       }
81578 +}
81579 +
81580 +
81581 +static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO       *psDevInfo,
81582 +                                                         IMG_UINT32                    ui32PDUMPFlags,
81583 +                                                         IMG_BOOL                              bPDump)
81584 +{
81585 +#if !defined(PDUMP)
81586 +       PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
81587 +#endif
81588 +
81589 +
81590 +       OSWaitus(1000 * 1000000 / psDevInfo->ui32CoreClockSpeed);
81591 +       if (bPDump)
81592 +       {
81593 +               PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
81594 +#if defined(PDUMP)
81595 +               PDumpRegRead(EUR_CR_SOFT_RESET, ui32PDUMPFlags);
81596 +#endif
81597 +       }
81598 +
81599 +
81600 +
81601 +}
81602 +
81603 +
81604 +static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO     *psDevInfo,
81605 +                                                           IMG_UINT32                  ui32PDUMPFlags,
81606 +                                                               IMG_BOOL                        bPDump)
81607 +{
81608 +       IMG_UINT32 ui32RegVal;
81609 +
81610 +
81611 +#if defined(EUR_CR_BIF_CTRL_INVAL)
81612 +       ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK;
81613 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal);
81614 +       if (bPDump)
81615 +       {
81616 +               PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags);
81617 +       }
81618 +#else
81619 +       ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
81620 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81621 +       if (bPDump)
81622 +       {
81623 +               PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81624 +       }
81625 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
81626 +
81627 +       ui32RegVal = 0;
81628 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81629 +       if (bPDump)
81630 +       {
81631 +               PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81632 +       }
81633 +#endif
81634 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
81635 +
81636 +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
81637 +       {
81638 +
81639 +
81640 +
81641 +               if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT),
81642 +                                                       0,
81643 +                                                       EUR_CR_BIF_MEM_REQ_STAT_READS_MASK,
81644 +                                                       MAX_HW_TIME_US/WAIT_TRY_COUNT,
81645 +                                                       WAIT_TRY_COUNT) != PVRSRV_OK)
81646 +               {
81647 +                       PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed."));
81648 +                       PVR_DBG_BREAK;
81649 +               }
81650 +
81651 +               if (bPDump)
81652 +               {
81653 +                       PDUMPREGPOLWITHFLAGS(EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags);
81654 +               }
81655 +       }
81656 +#endif
81657 +}
81658 +
81659 +
81660 +IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO   *psDevInfo,
81661 +                                 IMG_UINT32                     ui32PDUMPFlags)
81662 +{
81663 +       IMG_UINT32 ui32RegVal;
81664 +#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK)
81665 +       const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK;
81666 +#else
81667 +       const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK;
81668 +#endif
81669 +
81670 +#ifndef PDUMP
81671 +       PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
81672 +#endif
81673 +
81674 +       psDevInfo->ui32NumResets++;
81675 +
81676 +       PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n");
81677 +
81678 +#if defined(FIX_HW_BRN_23944)
81679 +
81680 +       ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
81681 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81682 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81683 +
81684 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81685 +
81686 +       ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
81687 +       if (ui32RegVal & ui32BifFaultMask)
81688 +       {
81689 +
81690 +               ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK;
81691 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81692 +               PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81693 +
81694 +               SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81695 +
81696 +               ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
81697 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81698 +               PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81699 +
81700 +               SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81701 +       }
81702 +#endif
81703 +
81704 +
81705 +       SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE);
81706 +
81707 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81708 +
81709 +
81710 +
81711 +#if defined(SGX_FEATURE_36BIT_MMU)
81712 +
81713 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK);
81714 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags);
81715 +#endif
81716 +
81717 +       ui32RegVal = 0;
81718 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
81719 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81720 +#if defined(SGX_FEATURE_MP)
81721 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal);
81722 +       PDUMPREGWITHFLAGS(EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
81723 +#endif
81724 +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
81725 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal);
81726 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags);
81727 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
81728 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
81729 +#endif
81730 +
81731 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
81732 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags);
81733 +
81734 +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
81735 +       {
81736 +               IMG_UINT32      ui32DirList, ui32DirListReg;
81737 +
81738 +               for (ui32DirList = 1;
81739 +                        ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS;
81740 +                        ui32DirList++)
81741 +               {
81742 +                       ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1);
81743 +                       OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal);
81744 +                       PDUMPREGWITHFLAGS(ui32DirListReg, ui32RegVal, ui32PDUMPFlags);
81745 +               }
81746 +       }
81747 +#endif
81748 +
81749 +#if defined(EUR_CR_BIF_MEM_ARB_CONFIG)
81750 +
81751 +
81752 +       ui32RegVal      = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) |
81753 +                                 (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) |
81754 +                                 (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT);
81755 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal);
81756 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags);
81757 +#endif
81758 +
81759 +#if defined(SGX_FEATURE_SYSTEM_CACHE)
81760 +#if defined(SGX_FEATURE_MP)
81761 +       #if defined(SGX_BYPASS_SYSTEM_CACHE)
81762 +               #error SGX_BYPASS_SYSTEM_CACHE not supported
81763 +       #else
81764 +               ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
81765 +                                               (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT);
81766 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
81767 +               PDUMPREG(EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
81768 +
81769 +               ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK;
81770 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
81771 +               PDUMPREG(EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
81772 +       #endif
81773 +#else
81774 +       #if defined(SGX_BYPASS_SYSTEM_CACHE)
81775 +
81776 +               ui32RegVal = EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK;
81777 +       #else
81778 +               #if defined(FIX_HW_BRN_26620)
81779 +                       ui32RegVal = 0;
81780 +               #else
81781 +
81782 +                       ui32RegVal = EUR_CR_MNE_CR_CTRL_BYP_CC_MASK;
81783 +               #endif
81784 +       #endif
81785 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MNE_CR_CTRL, ui32RegVal);
81786 +       PDUMPREG(EUR_CR_MNE_CR_CTRL, ui32RegVal);
81787 +#endif
81788 +#endif
81789 +
81790 +
81791 +
81792 +
81793 +
81794 +
81795 +       ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr;
81796 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
81797 +
81798 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81799 +
81800 +
81801 +       SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
81802 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81803 +
81804 +       SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81805 +
81806 +
81807 +
81808 +       for (;;)
81809 +       {
81810 +               IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
81811 +               IMG_DEV_VIRTADDR sBifFault;
81812 +               IMG_UINT32 ui32PDIndex, ui32PTIndex;
81813 +
81814 +               if ((ui32BifIntStat & ui32BifFaultMask) == 0)
81815 +               {
81816 +                       break;
81817 +               }
81818 +
81819 +
81820 +
81821 +
81822 +               sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
81823 +               PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr));
81824 +               ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
81825 +               ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
81826 +
81827 +
81828 +               SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE);
81829 +
81830 +
81831 +               psDevInfo->pui32BIFResetPD[ui32PDIndex] = (psDevInfo->sBIFResetPTDevPAddr.uiAddr
81832 +                                                                                               >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
81833 +                                                                                               | SGX_MMU_PDE_PAGE_SIZE_4K
81834 +                                                                                               | SGX_MMU_PDE_VALID;
81835 +               psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr
81836 +                                                                                               >>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
81837 +                                                                                               | SGX_MMU_PTE_VALID;
81838 +
81839 +
81840 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
81841 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal);
81842 +               ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
81843 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal);
81844 +
81845 +               SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81846 +
81847 +
81848 +               SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE);
81849 +               SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81850 +
81851 +
81852 +               SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
81853 +
81854 +
81855 +               psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0;
81856 +               psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0;
81857 +       }
81858 +
81859 +
81860 +
81861 +
81862 +       #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
81863 +
81864 +       ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT);
81865 +
81866 +       #if defined(SGX_FEATURE_2D_HARDWARE)
81867 +
81868 +       ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT);
81869 +       #endif
81870 +
81871 +       #if defined(FIX_HW_BRN_23410)
81872 +
81873 +       ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT);
81874 +       #endif
81875 +
81876 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
81877 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
81878 +       #endif
81879 +
81880 +       {
81881 +               IMG_UINT32      ui32EDMDirListReg;
81882 +
81883 +
81884 +               #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
81885 +               ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
81886 +               #else
81887 +
81888 +               ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
81889 +               #endif
81890 +
81891 +#if defined(FIX_HW_BRN_28011)
81892 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT);
81893 +               PDUMPPDREGWITHFLAGS(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
81894 +#endif
81895 +
81896 +               OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT);
81897 +               PDUMPPDREGWITHFLAGS(ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
81898 +       }
81899 +
81900 +#ifdef SGX_FEATURE_2D_HARDWARE
81901 +
81902 +       #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0)
81903 +               #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment"
81904 +       #endif
81905 +
81906 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE);
81907 +       PDUMPREGWITHFLAGS(EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags);
81908 +#endif
81909 +
81910 +
81911 +       SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81912 +
81913 +       PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX"));
81914 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81915 +
81916 +
81917 +       ui32RegVal = 0;
81918 +#if defined(SGX_FEATURE_MP)
81919 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
81920 +       PDUMPREGWITHFLAGS(EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
81921 +#endif
81922 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
81923 +       PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
81924 +
81925 +
81926 +       SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
81927 +
81928 +       PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");
81929 +}
81930 +
81931 +
81932 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxtransfer.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxtransfer.c
81933 new file mode 100644
81934 index 0000000..f851b75
81935 --- /dev/null
81936 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxtransfer.c
81937 @@ -0,0 +1,543 @@
81938 +/**********************************************************************
81939 + *
81940 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
81941 + *
81942 + * This program is free software; you can redistribute it and/or modify it
81943 + * under the terms and conditions of the GNU General Public License,
81944 + * version 2, as published by the Free Software Foundation.
81945 + *
81946 + * This program is distributed in the hope it will be useful but, except
81947 + * as otherwise stated in writing, without any warranty; without even the
81948 + * implied warranty of merchantability or fitness for a particular purpose.
81949 + * See the GNU General Public License for more details.
81950 + *
81951 + * You should have received a copy of the GNU General Public License along with
81952 + * this program; if not, write to the Free Software Foundation, Inc.,
81953 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
81954 + *
81955 + * The full GNU General Public License is included in this distribution in
81956 + * the file called "COPYING".
81957 + *
81958 + * Contact Information:
81959 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
81960 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
81961 + *
81962 + ******************************************************************************/
81963 +
81964 +#if defined(TRANSFER_QUEUE)
81965 +
81966 +#include <stddef.h>
81967 +
81968 +#include "sgxdefs.h"
81969 +#include "services_headers.h"
81970 +#include "buffer_manager.h"
81971 +#include "sgxinfo.h"
81972 +#include "sysconfig.h"
81973 +#include "regpaths.h"
81974 +#include "pdump_km.h"
81975 +#include "mmu.h"
81976 +#include "pvr_bridge.h"
81977 +#include "sgx_bridge_km.h"
81978 +#include "sgxinfokm.h"
81979 +#include "osfunc.h"
81980 +#include "pvr_debug.h"
81981 +#include "sgxutils.h"
81982 +
81983 +IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick)
81984 +{
81985 +       PVRSRV_KERNEL_MEM_INFO  *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
81986 +       SGXMKIF_COMMAND sCommand = {0};
81987 +       SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd;
81988 +       PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
81989 +       PVRSRV_ERROR eError;
81990 +
81991 +
81992 +       if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
81993 +       {
81994 +               PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset"));
81995 +               return PVRSRV_ERROR_INVALID_PARAMS;
81996 +       }
81997 +
81998 +
81999 +       psSharedTransferCmd =  CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
82000 +
82001 +       if (psKick->hTASyncInfo != IMG_NULL)
82002 +       {
82003 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82004 +
82005 +               psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
82006 +               psSharedTransferCmd->ui32TASyncReadOpsPendingVal  = psSyncInfo->psSyncData->ui32ReadOpsPending;
82007 +
82008 +               psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82009 +               psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82010 +       }
82011 +       else
82012 +       {
82013 +               psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0;
82014 +               psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0;
82015 +       }
82016 +
82017 +       if (psKick->h3DSyncInfo != IMG_NULL)
82018 +       {
82019 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82020 +
82021 +               psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
82022 +               psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82023 +
82024 +               psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82025 +               psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82026 +       }
82027 +       else
82028 +       {
82029 +               psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0;
82030 +               psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0;
82031 +       }
82032 +
82033 +       if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
82034 +       {
82035 +               if (psKick->ui32NumSrcSync > 0)
82036 +               {
82037 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
82038 +
82039 +                       psSharedTransferCmd->ui32SrcWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
82040 +                       psSharedTransferCmd->ui32SrcReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82041 +
82042 +                       psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82043 +                       psSharedTransferCmd->sSrcReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82044 +
82045 +               }
82046 +
82047 +               if (psKick->ui32NumDstSync > 0)
82048 +               {
82049 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
82050 +
82051 +                       psSharedTransferCmd->ui32DstWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
82052 +                       psSharedTransferCmd->ui32DstReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82053 +
82054 +                       psSharedTransferCmd->sDstWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82055 +                       psSharedTransferCmd->sDstReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82056 +
82057 +               }
82058 +
82059 +
82060 +               if (psKick->ui32NumSrcSync > 0)
82061 +               {
82062 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
82063 +                       psSyncInfo->psSyncData->ui32ReadOpsPending++;
82064 +               }
82065 +               if (psKick->ui32NumDstSync > 0)
82066 +               {
82067 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
82068 +                       psSyncInfo->psSyncData->ui32WriteOpsPending++;
82069 +               }
82070 +       }
82071 +
82072 +
82073 +       if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync  > 1)
82074 +       {
82075 +               PVR_DPF((PVR_DBG_ERROR,
82076 +                                       "Transfer command doesn't support more than 1 sync object per src/dst\ndst: %d, src: %d",
82077 +                                       psKick->ui32NumDstSync, psKick->ui32NumSrcSync));
82078 +       }
82079 +
82080 +#if defined(PDUMP)
82081 +       if (PDumpIsCaptureFrameKM()
82082 +       || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
82083 +       {
82084 +               PDUMPCOMMENT("Shared part of transfer command\r\n");
82085 +               PDUMPMEM(psSharedTransferCmd,
82086 +                               psCCBMemInfo,
82087 +                               psKick->ui32CCBDumpWOff,
82088 +                               sizeof(SGXMKIF_TRANSFERCMD_SHARED),
82089 +                               psKick->ui32PDumpFlags,
82090 +                               MAKEUNIQUETAG(psCCBMemInfo));
82091 +
82092 +               if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
82093 +               {
82094 +                       psSyncInfo = psKick->ahSrcSyncInfo[0];
82095 +
82096 +                       PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n");
82097 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
82098 +                                       psCCBMemInfo,
82099 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcWriteOpPendingVal),
82100 +                                       sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
82101 +                                       psKick->ui32PDumpFlags,
82102 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82103 +
82104 +                       PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n");
82105 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
82106 +                                       psCCBMemInfo,
82107 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcReadOpPendingVal),
82108 +                                       sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
82109 +                                       psKick->ui32PDumpFlags,
82110 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82111 +
82112 +               }
82113 +               if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
82114 +               {
82115 +                       psSyncInfo = psKick->ahDstSyncInfo[0];
82116 +
82117 +                       PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n");
82118 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
82119 +                                       psCCBMemInfo,
82120 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstWriteOpPendingVal),
82121 +                                       sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
82122 +                                       psKick->ui32PDumpFlags,
82123 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82124 +
82125 +                       PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n");
82126 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
82127 +                                       psCCBMemInfo,
82128 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstReadOpPendingVal),
82129 +                                       sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
82130 +                                       psKick->ui32PDumpFlags,
82131 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82132 +
82133 +               }
82134 +
82135 +
82136 +               if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING)== 0UL))
82137 +               {
82138 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
82139 +                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
82140 +               }
82141 +
82142 +               if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL))
82143 +               {
82144 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
82145 +                       psSyncInfo->psSyncData->ui32LastOpDumpVal++;
82146 +               }
82147 +       }
82148 +#endif
82149 +
82150 +       sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
82151 +
82152 +       eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags);
82153 +
82154 +       if (eError == PVRSRV_ERROR_RETRY)
82155 +       {
82156 +
82157 +               if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
82158 +               {
82159 +                       if (psKick->ui32NumSrcSync > 0)
82160 +                       {
82161 +                               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
82162 +                               psSyncInfo->psSyncData->ui32ReadOpsPending--;
82163 +                       }
82164 +                       if (psKick->ui32NumDstSync > 0)
82165 +                       {
82166 +                               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
82167 +                               psSyncInfo->psSyncData->ui32WriteOpsPending--;
82168 +                       }
82169 +#if defined(PDUMP)
82170 +                       if (PDumpIsCaptureFrameKM()
82171 +                       || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
82172 +                       {
82173 +                               if (psKick->ui32NumSrcSync > 0)
82174 +                               {
82175 +                                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0];
82176 +                                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
82177 +                               }
82178 +                               if (psKick->ui32NumDstSync > 0)
82179 +                               {
82180 +                                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
82181 +                                       psSyncInfo->psSyncData->ui32LastOpDumpVal--;
82182 +                               }
82183 +                       }
82184 +#endif
82185 +               }
82186 +
82187 +               
82188 +               if (psKick->hTASyncInfo != IMG_NULL)
82189 +               {
82190 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82191 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
82192 +               }
82193 +
82194 +               
82195 +               if (psKick->h3DSyncInfo != IMG_NULL)
82196 +               {
82197 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82198 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
82199 +               }
82200 +       }
82201 +       else if (PVRSRV_OK != eError)
82202 +       {
82203 +               PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed."));
82204 +               return eError;
82205 +       }
82206 +
82207 +
82208 +#if defined(NO_HARDWARE)
82209 +       if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0)
82210 +       {
82211 +               IMG_UINT32 i;
82212 +
82213 +
82214 +               for(i = 0; i < psKick->ui32NumSrcSync; i++)
82215 +               {
82216 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
82217 +                       psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
82218 +               }
82219 +
82220 +               for(i = 0; i < psKick->ui32NumDstSync; i++)
82221 +               {
82222 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i];
82223 +                       psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82224 +
82225 +               }
82226 +
82227 +               if (psKick->hTASyncInfo != IMG_NULL)
82228 +               {
82229 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82230 +
82231 +                       psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82232 +               }
82233 +
82234 +               if (psKick->h3DSyncInfo != IMG_NULL)
82235 +               {
82236 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82237 +
82238 +                       psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82239 +               }
82240 +       }
82241 +#endif
82242 +
82243 +       return eError;
82244 +}
82245 +
82246 +#if defined(SGX_FEATURE_2D_HARDWARE)
82247 +IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick)
82248 +
82249 +{
82250 +       PVRSRV_KERNEL_MEM_INFO  *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo;
82251 +       SGXMKIF_COMMAND sCommand = {0};
82252 +       SGXMKIF_2DCMD_SHARED *ps2DCmd;
82253 +       PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
82254 +       PVRSRV_ERROR eError;
82255 +       IMG_UINT32 i;
82256 +
82257 +       if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
82258 +       {
82259 +               PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset"));
82260 +               return PVRSRV_ERROR_INVALID_PARAMS;
82261 +       }
82262 +
82263 +
82264 +       ps2DCmd =  CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
82265 +
82266 +       OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
82267 +
82268 +
82269 +       if (psKick->hTASyncInfo != IMG_NULL)
82270 +       {
82271 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82272 +
82273 +               ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
82274 +               ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82275 +
82276 +               ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr  = psSyncInfo->sWriteOpsCompleteDevVAddr;
82277 +               ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr   = psSyncInfo->sReadOpsCompleteDevVAddr;
82278 +       }
82279 +
82280 +
82281 +       if (psKick->h3DSyncInfo != IMG_NULL)
82282 +       {
82283 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82284 +
82285 +               ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
82286 +               ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82287 +
82288 +               ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82289 +               ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82290 +       }
82291 +
82292 +
82293 +       ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync;
82294 +       for (i = 0; i < psKick->ui32NumSrcSync; i++)
82295 +       {
82296 +               psSyncInfo = psKick->ahSrcSyncInfo[i];
82297 +
82298 +               ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
82299 +               ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82300 +
82301 +               ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82302 +               ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82303 +       }
82304 +
82305 +       if (psKick->hDstSyncInfo != IMG_NULL)
82306 +       {
82307 +               psSyncInfo = psKick->hDstSyncInfo;
82308 +
82309 +               ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
82310 +               ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
82311 +
82312 +               ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
82313 +               ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
82314 +       }
82315 +
82316 +
82317 +       for (i = 0; i < psKick->ui32NumSrcSync; i++)
82318 +       {
82319 +               psSyncInfo = psKick->ahSrcSyncInfo[i];
82320 +               psSyncInfo->psSyncData->ui32ReadOpsPending++;
82321 +       }
82322 +
82323 +       if (psKick->hDstSyncInfo != IMG_NULL)
82324 +       {
82325 +               psSyncInfo = psKick->hDstSyncInfo;
82326 +               psSyncInfo->psSyncData->ui32WriteOpsPending++;
82327 +       }
82328 +
82329 +#if defined(PDUMP)
82330 +       if (PDumpIsCaptureFrameKM()
82331 +       || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
82332 +       {
82333 +
82334 +               PDUMPCOMMENT("Shared part of 2D command\r\n");
82335 +               PDUMPMEM(ps2DCmd,
82336 +                               psCCBMemInfo,
82337 +                               psKick->ui32CCBDumpWOff,
82338 +                               sizeof(SGXMKIF_2DCMD_SHARED),
82339 +                               psKick->ui32PDumpFlags,
82340 +                               MAKEUNIQUETAG(psCCBMemInfo));
82341 +
82342 +               for (i = 0; i < psKick->ui32NumSrcSync; i++)
82343 +               {
82344 +                       psSyncInfo = psKick->ahSrcSyncInfo[i];
82345 +
82346 +                       PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n");
82347 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
82348 +                                       psCCBMemInfo,
82349 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal),
82350 +                                       sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
82351 +                                       psKick->ui32PDumpFlags,
82352 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82353 +
82354 +                       PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n");
82355 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
82356 +                                       psCCBMemInfo,
82357 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal),
82358 +                                       sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
82359 +                                       psKick->ui32PDumpFlags,
82360 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82361 +               }
82362 +
82363 +               if (psKick->hDstSyncInfo != IMG_NULL)
82364 +               {
82365 +                       psSyncInfo = psKick->hDstSyncInfo;
82366 +
82367 +                       PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n");
82368 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
82369 +                                       psCCBMemInfo,
82370 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal),
82371 +                                       sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
82372 +                                       psKick->ui32PDumpFlags,
82373 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82374 +
82375 +                       PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n");
82376 +                       PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
82377 +                                       psCCBMemInfo,
82378 +                                       psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal),
82379 +                                       sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
82380 +                                       psKick->ui32PDumpFlags,
82381 +                                       MAKEUNIQUETAG(psCCBMemInfo));
82382 +               }
82383 +
82384 +
82385 +               for (i = 0; i < psKick->ui32NumSrcSync; i++)
82386 +               {
82387 +                       psSyncInfo = psKick->ahSrcSyncInfo[i];
82388 +                       psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
82389 +               }
82390 +
82391 +               if (psKick->hDstSyncInfo != IMG_NULL)
82392 +               {
82393 +                       psSyncInfo = psKick->hDstSyncInfo;
82394 +                       psSyncInfo->psSyncData->ui32LastOpDumpVal++;
82395 +               }
82396 +       }
82397 +#endif
82398 +
82399 +       sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr;
82400 +
82401 +       eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags);
82402 +
82403 +       if (eError == PVRSRV_ERROR_RETRY)
82404 +       {
82405 +#if defined(PDUMP)
82406 +               if (PDumpIsCaptureFrameKM())
82407 +               {
82408 +                       for (i = 0; i < psKick->ui32NumSrcSync; i++)
82409 +                       {
82410 +                               psSyncInfo = psKick->ahSrcSyncInfo[i];
82411 +                               psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
82412 +                       }
82413 +
82414 +                       if (psKick->hDstSyncInfo != IMG_NULL)
82415 +                       {
82416 +                               psSyncInfo = psKick->hDstSyncInfo;
82417 +                               psSyncInfo->psSyncData->ui32LastOpDumpVal--;
82418 +                       }
82419 +               }
82420 +#endif
82421 +
82422 +               for (i = 0; i < psKick->ui32NumSrcSync; i++)
82423 +               {
82424 +                       psSyncInfo = psKick->ahSrcSyncInfo[i];
82425 +                       psSyncInfo->psSyncData->ui32ReadOpsPending--;
82426 +               }
82427 +
82428 +               if (psKick->hDstSyncInfo != IMG_NULL)
82429 +               {
82430 +                       psSyncInfo = psKick->hDstSyncInfo;
82431 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
82432 +               }
82433 +
82434 +               
82435 +               if (psKick->hTASyncInfo != IMG_NULL)
82436 +               {
82437 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82438 +
82439 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
82440 +               }
82441 +
82442 +               
82443 +               if (psKick->h3DSyncInfo != IMG_NULL)
82444 +               {
82445 +                       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82446 +
82447 +                       psSyncInfo->psSyncData->ui32WriteOpsPending--;
82448 +               }
82449 +       }
82450 +
82451 +#if defined(NO_HARDWARE)
82452 +
82453 +       for(i = 0; i < psKick->ui32NumSrcSync; i++)
82454 +       {
82455 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
82456 +               psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
82457 +       }
82458 +
82459 +       psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo;
82460 +       psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82461 +
82462 +       if (psKick->hTASyncInfo != IMG_NULL)
82463 +       {
82464 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
82465 +
82466 +               psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82467 +       }
82468 +
82469 +       if (psKick->h3DSyncInfo != IMG_NULL)
82470 +       {
82471 +               psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
82472 +
82473 +               psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
82474 +       }
82475 +#endif
82476 +
82477 +       return eError;
82478 +}
82479 +#endif
82480 +#endif
82481 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.c
82482 new file mode 100644
82483 index 0000000..2c31d22
82484 --- /dev/null
82485 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.c
82486 @@ -0,0 +1,928 @@
82487 +/**********************************************************************
82488 + *
82489 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
82490 + *
82491 + * This program is free software; you can redistribute it and/or modify it
82492 + * under the terms and conditions of the GNU General Public License,
82493 + * version 2, as published by the Free Software Foundation.
82494 + *
82495 + * This program is distributed in the hope it will be useful but, except
82496 + * as otherwise stated in writing, without any warranty; without even the
82497 + * implied warranty of merchantability or fitness for a particular purpose.
82498 + * See the GNU General Public License for more details.
82499 + *
82500 + * You should have received a copy of the GNU General Public License along with
82501 + * this program; if not, write to the Free Software Foundation, Inc.,
82502 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
82503 + *
82504 + * The full GNU General Public License is included in this distribution in
82505 + * the file called "COPYING".
82506 + *
82507 + * Contact Information:
82508 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
82509 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
82510 + *
82511 + ******************************************************************************/
82512 +
82513 +#include <stddef.h>
82514 +
82515 +#include "sgxdefs.h"
82516 +#include "services_headers.h"
82517 +#include "buffer_manager.h"
82518 +#include "sgxapi_km.h"
82519 +#include "sgxinfo.h"
82520 +#include "sgx_mkif_km.h"
82521 +#include "sysconfig.h"
82522 +#include "pdump_km.h"
82523 +#include "mmu.h"
82524 +#include "pvr_bridge_km.h"
82525 +#include "osfunc.h"
82526 +#include "pvr_debug.h"
82527 +#include "sgxutils.h"
82528 +
82529 +#ifdef __linux__
82530 +#include <linux/tty.h>
82531 +#else
82532 +#include <stdio.h>
82533 +#endif
82534 +#include "ospm_power.h"
82535 +
82536 +#if defined(SYS_CUSTOM_POWERDOWN)
82537 +PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE       * psDeviceNode, IMG_UINT32 ui32CallerID);
82538 +#endif
82539 +
82540 +
82541 +
82542 +IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE    * psDeviceNode,
82543 +                                 IMG_UINT32           ui32CallerID)
82544 +{
82545 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
82546 +       SGXMKIF_HOST_CTL        *psSGXHostCtl = psDevInfo->psSGXHostCtl;
82547 +
82548 +
82549 +       psSGXHostCtl->ui32NumActivePowerEvents++;
82550 +
82551 +       if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0)
82552 +       {
82553 +
82554 +
82555 +
82556 +               if (ui32CallerID == ISR_ID)
82557 +               {
82558 +                       psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
82559 +               }
82560 +               else
82561 +               {
82562 +                       SGXScheduleProcessQueuesKM(psDeviceNode);
82563 +               }
82564 +       }
82565 +}
82566 +
82567 +
82568 +IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE   *psDeviceNode,
82569 +                                                                 IMG_UINT32                    ui32CallerID)
82570 +{
82571 +       PVRSRV_ERROR            eError = PVRSRV_OK;
82572 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
82573 +       SGXMKIF_HOST_CTL        *psSGXHostCtl = psDevInfo->psSGXHostCtl;
82574 +
82575 +       if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) &&
82576 +               ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0))
82577 +       {
82578 +
82579 +               psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
82580 +
82581 +
82582 +               PDUMPSUSPEND();
82583 +
82584 +#if defined(SYS_CUSTOM_POWERDOWN)
82585 +
82586 +
82587 +
82588 +               eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
82589 +#else
82590 +               eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
82591 +                                                                                        PVRSRV_DEV_POWER_STATE_OFF,
82592 +                                                                                        ui32CallerID, IMG_FALSE);
82593 +               if (eError == PVRSRV_OK)
82594 +               {
82595 +                       SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
82596 +               }
82597 +#endif
82598 +               if (eError == PVRSRV_ERROR_RETRY)
82599 +               {
82600 +
82601 +
82602 +                       psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
82603 +                       eError = PVRSRV_OK;
82604 +               }
82605 +
82606 +
82607 +               PDUMPRESUME();
82608 +       }
82609 +
82610 +       if (eError != PVRSRV_OK)
82611 +       {
82612 +               PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%lu", eError));
82613 +       }
82614 +}
82615 +
82616 +
82617 +#ifdef INLINE_IS_PRAGMA
82618 +#pragma inline(SGXAcquireKernelCCBSlot)
82619 +#endif
82620 +static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB)
82621 +{
82622 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
82623 +       {
82624 +               if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset)
82625 +               {
82626 +                       return &psCCB->psCommands[*psCCB->pui32WriteOffset];
82627 +               }
82628 +
82629 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
82630 +       } END_LOOP_UNTIL_TIMEOUT();
82631 +
82632 +
82633 +       return IMG_NULL;
82634 +}
82635 +
82636 +PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO  *psDevInfo,
82637 +                                                                  SGXMKIF_CMD_TYPE             eCmdType,
82638 +                                                                  SGXMKIF_COMMAND              *psCommandData,
82639 +                                                                  IMG_UINT32                   ui32CallerID,
82640 +                                                                  IMG_UINT32                   ui32PDumpFlags)
82641 +{
82642 +       PVRSRV_SGX_CCB_INFO *psKernelCCB;
82643 +       PVRSRV_ERROR eError = PVRSRV_OK;
82644 +       SGXMKIF_COMMAND *psSGXCommand;
82645 +#if defined(PDUMP)
82646 +       IMG_VOID *pvDumpCommand;
82647 +       IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
82648 +#else
82649 +       PVR_UNREFERENCED_PARAMETER(ui32CallerID);
82650 +       PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
82651 +#endif
82652 +
82653 +       psKernelCCB = psDevInfo->psKernelCCBInfo;
82654 +
82655 +       psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB);
82656 +
82657 +
82658 +       if(!psSGXCommand)
82659 +       {
82660 +               eError = PVRSRV_ERROR_TIMEOUT;
82661 +               goto Exit;
82662 +       }
82663 +
82664 +
82665 +       psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl;
82666 +
82667 +#if defined(PDUMP)
82668 +
82669 +       psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl;
82670 +#endif
82671 +
82672 +
82673 +       psDevInfo->ui32CacheControl = 0;
82674 +
82675 +
82676 +       *psSGXCommand = *psCommandData;
82677 +
82678 +       if (eCmdType >= SGXMKIF_CMD_MAX)
82679 +       {
82680 +               PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCmdType)) ;
82681 +               eError = PVRSRV_ERROR_GENERIC;
82682 +               goto Exit;
82683 +       }
82684 +
82685 +#if defined(SUPPORT_CPU_CACHED_BUFFERS)
82686 +       {
82687 +               SYS_DATA *psSysData;
82688 +
82689 +               SysAcquireData(&psSysData);
82690 +
82691 +               if (psSysData->bFlushAll)
82692 +               {
82693 +                       OSFlushCPUCacheKM();
82694 +                       
82695 +                       psSysData->bFlushAll = IMG_FALSE;
82696 +               }
82697 +       }
82698 +#endif
82699 +
82700 +       psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType];
82701 +
82702 +#if defined(PDUMP)
82703 +       if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE))
82704 +       {
82705 +
82706 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n");
82707 +               PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
82708 +                                       offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
82709 +                                       (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff,
82710 +                                       0xff,
82711 +                                       PDUMP_POLL_OPERATOR_NOTEQUAL,
82712 +                                       ui32PDumpFlags,
82713 +                                       MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
82714 +
82715 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command\r\n");
82716 +               pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND)));
82717 +
82718 +               PDUMPMEM(pvDumpCommand,
82719 +                                       psKernelCCB->psCCBMemInfo,
82720 +                                       psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND),
82721 +                                       sizeof(SGXMKIF_COMMAND),
82722 +                                       ui32PDumpFlags,
82723 +                                       MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
82724 +
82725 +
82726 +               PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl,
82727 +                                       psKernelCCB->psCCBMemInfo,
82728 +                                       psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) +
82729 +                                       offsetof(SGXMKIF_COMMAND, ui32CacheControl),
82730 +                                       sizeof(IMG_UINT32),
82731 +                                       ui32PDumpFlags,
82732 +                                       MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
82733 +
82734 +               if (PDumpIsCaptureFrameKM()
82735 +               || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
82736 +               {
82737 +
82738 +                       psDevInfo->sPDContext.ui32CacheControl = 0;
82739 +               }
82740 +       }
82741 +#endif
82742 +
82743 +#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
82744 +
82745 +       eError = PollForValueKM (psKernelCCB->pui32ReadOffset,
82746 +                                                               *psKernelCCB->pui32WriteOffset,
82747 +                                                               0xFF,
82748 +                                                               MAX_HW_TIME_US/WAIT_TRY_COUNT,
82749 +                                                               WAIT_TRY_COUNT);
82750 +       if (eError != PVRSRV_OK)
82751 +       {
82752 +               eError = PVRSRV_ERROR_TIMEOUT;
82753 +               goto Exit;
82754 +       }
82755 +#endif
82756 +
82757 +
82758 +
82759 +       *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255;
82760 +
82761 +#if defined(PDUMP)
82762 +       if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE))
82763 +       {
82764 +       #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
82765 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n");
82766 +               PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
82767 +                                       offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
82768 +                                       (psKernelCCB->ui32CCBDumpWOff),
82769 +                                       0xFF,
82770 +                                       PDUMP_POLL_OPERATOR_EQUAL,
82771 +                                       ui32PDumpFlags,
82772 +                                       MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
82773 +       #endif
82774 +
82775 +               if (PDumpIsCaptureFrameKM()
82776 +               || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
82777 +               {
82778 +                       psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF;
82779 +                       psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF;
82780 +               }
82781 +
82782 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n");
82783 +               PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff,
82784 +                                psKernelCCB->psCCBCtlMemInfo,
82785 +                                offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset),
82786 +                                sizeof(IMG_UINT32),
82787 +                                ui32PDumpFlags,
82788 +                                MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
82789 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n");
82790 +               PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
82791 +                                psDevInfo->psKernelCCBEventKickerMemInfo,
82792 +                                0,
82793 +                                sizeof(IMG_UINT32),
82794 +                                ui32PDumpFlags,
82795 +                                MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
82796 +               PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n");
82797 +       #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
82798 +               PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags);
82799 +       #else
82800 +               PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags);
82801 +       #endif
82802 +       }
82803 +#endif
82804 +
82805 +       *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
82806 +#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
82807 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM,
82808 +                               SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
82809 +                               EUR_CR_EVENT_KICK2_NOW_MASK);
82810 +#else
82811 +       OSWriteHWReg(psDevInfo->pvRegsBaseKM,
82812 +                               SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
82813 +                               EUR_CR_EVENT_KICK_NOW_MASK);
82814 +#endif
82815 +
82816 +#if defined(NO_HARDWARE)
82817 +
82818 +       *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
82819 +#endif
82820 +
82821 +Exit:
82822 +       return eError;
82823 +}
82824 +
82825 +
82826 +PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE                *psDeviceNode,
82827 +                                                                        SGXMKIF_CMD_TYPE               eCmdType,
82828 +                                                                        SGXMKIF_COMMAND                *psCommandData,
82829 +                                                                        IMG_UINT32                             ui32CallerID,
82830 +                                                                        IMG_UINT32                             ui32PDumpFlags)
82831 +{
82832 +       PVRSRV_ERROR            eError;
82833 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
82834 +
82835 +
82836 +       PDUMPSUSPEND();
82837 +
82838 +       ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, OSPM_UHB_IGNORE_POWER_OFF);
82839 +
82840 +       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
82841 +                                                                                PVRSRV_DEV_POWER_STATE_ON,
82842 +                                                                                ui32CallerID,
82843 +                                                                                IMG_TRUE);
82844 +
82845 +       PDUMPRESUME();
82846 +
82847 +       if (eError == PVRSRV_OK)
82848 +       {
82849 +               psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
82850 +       }
82851 +       else
82852 +       {
82853 +               if (eError == PVRSRV_ERROR_RETRY)
82854 +               {
82855 +                       if (ui32CallerID == ISR_ID)
82856 +                       {
82857 +
82858 +
82859 +
82860 +                               psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
82861 +                               eError = PVRSRV_OK;
82862 +                       }
82863 +                       else
82864 +                       {
82865 +
82866 +
82867 +                       }
82868 +               }
82869 +               else
82870 +               {
82871 +                       PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
82872 +                                        "ui32CallerID:%ld eError:%lu", ui32CallerID, eError));
82873 +               }
82874 +
82875 +               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
82876 +               return eError;
82877 +       }
82878 +
82879 +       eError = SGXScheduleCCBCommand(psDevInfo, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags);
82880 +
82881 +       PVRSRVPowerUnlock(ui32CallerID);
82882 +
82883 +       ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
82884 +
82885 +       if (ui32CallerID != ISR_ID)
82886 +       {
82887 +
82888 +
82889 +
82890 +               SGXTestActivePowerEvent(psDeviceNode, ui32CallerID);
82891 +       }
82892 +
82893 +       return eError;
82894 +}
82895 +
82896 +
82897 +PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode)
82898 +{
82899 +       PVRSRV_ERROR            eError;
82900 +       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;
82901 +       SGXMKIF_HOST_CTL        *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
82902 +       IMG_UINT32              ui32PowerStatus;
82903 +       SGXMKIF_COMMAND         sCommand = {0};
82904 +
82905 +       ui32PowerStatus = psHostCtl->ui32PowerStatus;
82906 +       if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
82907 +       {
82908 +
82909 +               return PVRSRV_OK;
82910 +       }
82911 +
82912 +       eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0);
82913 +       if (eError != PVRSRV_OK)
82914 +       {
82915 +               PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %lu", eError));
82916 +               return PVRSRV_ERROR_GENERIC;
82917 +       }
82918 +
82919 +       return PVRSRV_OK;
82920 +}
82921 +
82922 +
82923 +IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode)
82924 +{
82925 +       return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
82926 +}
82927 +
82928 +IMG_EXPORT
82929 +PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
82930 +                                                                       SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo)
82931 +{
82932 +       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
82933 +
82934 +       psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags;
82935 +       psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff;
82936 +
82937 +
82938 +       psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle =
82939 +               (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo;
82940 +
82941 +       return PVRSRV_OK;
82942 +}
82943 +
82944 +
82945 +IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE  *psDeviceNode,
82946 +                                                  IMG_DEV_VIRTADDR             *psHWDataDevVAddr,
82947 +                                                  IMG_UINT32                   ui32CleanupType)
82948 +{
82949 +       PVRSRV_ERROR                    eError;
82950 +       PVRSRV_SGXDEV_INFO              *psSGXDevInfo = psDeviceNode->pvDevice;
82951 +       PVRSRV_KERNEL_MEM_INFO  *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo;
82952 +       SGXMKIF_HOST_CTL                *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
82953 +
82954 +       if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
82955 +       {
82956 +
82957 +       }
82958 +       else
82959 +       {
82960 +               SGXMKIF_COMMAND         sCommand = {0};
82961 +
82962 +               PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resouce clean-up");
82963 +               sCommand.ui32Data[0] = ui32CleanupType;
82964 +               sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr;
82965 +
82966 +               eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0);
82967 +               if (eError != PVRSRV_OK)
82968 +               {
82969 +                       PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
82970 +                       PVR_DBG_BREAK;
82971 +               }
82972 +
82973 +
82974 +               #if !defined(NO_HARDWARE)
82975 +               if(PollForValueKM(&psSGXHostCtl->ui32CleanupStatus,
82976 +                                                 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
82977 +                                                 PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
82978 +                                                 MAX_HW_TIME_US/WAIT_TRY_COUNT,
82979 +                                                 WAIT_TRY_COUNT) != PVRSRV_OK)
82980 +               {
82981 +                       PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up failed"));
82982 +                       PVR_DBG_BREAK;
82983 +               }
82984 +               #endif
82985 +
82986 +               #if defined(PDUMP)
82987 +
82988 +               PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
82989 +               PDUMPMEMPOL(psSGXHostCtlMemInfo,
82990 +                                       offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
82991 +                                       PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
82992 +                                       PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
82993 +                                       PDUMP_POLL_OPERATOR_EQUAL,
82994 +                                       0,
82995 +                                       MAKEUNIQUETAG(psSGXHostCtlMemInfo));
82996 +               #endif
82997 +
82998 +               psSGXHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
82999 +               PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo));
83000 +       }
83001 +}
83002 +
83003 +
83004 +typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
83005 +{
83006 +       PVRSRV_DEVICE_NODE *psDeviceNode;
83007 +       IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
83008 +       IMG_HANDLE hBlockAlloc;
83009 +       PRESMAN_ITEM psResItem;
83010 +} SGX_HW_RENDER_CONTEXT_CLEANUP;
83011 +
83012 +
83013 +static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID                pvParam,
83014 +                                                                                                         IMG_UINT32    ui32Param)
83015 +{
83016 +       SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam;
83017 +
83018 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
83019 +
83020 +       SGXCleanupRequest(psCleanup->psDeviceNode,
83021 +                                         &psCleanup->sHWRenderContextDevVAddr,
83022 +                                         PVRSRV_CLEANUPCMD_RC);
83023 +
83024 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83025 +                         sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
83026 +                         psCleanup,
83027 +                         psCleanup->hBlockAlloc);
83028 +
83029 +
83030 +       return PVRSRV_OK;
83031 +}
83032 +
83033 +typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
83034 +{
83035 +       PVRSRV_DEVICE_NODE *psDeviceNode;
83036 +       IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
83037 +       IMG_HANDLE hBlockAlloc;
83038 +       PRESMAN_ITEM psResItem;
83039 +} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
83040 +
83041 +
83042 +static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID      pvParam,
83043 +                                                                                                               IMG_UINT32      ui32Param)
83044 +{
83045 +       SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam;
83046 +
83047 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
83048 +
83049 +       SGXCleanupRequest(psCleanup->psDeviceNode,
83050 +                                         &psCleanup->sHWTransferContextDevVAddr,
83051 +                                         PVRSRV_CLEANUPCMD_TC);
83052 +
83053 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83054 +                         sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
83055 +                         psCleanup,
83056 +                         psCleanup->hBlockAlloc);
83057 +
83058 +
83059 +       return PVRSRV_OK;
83060 +}
83061 +
83062 +IMG_EXPORT
83063 +IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE                             psDeviceNode,
83064 +                                                                               IMG_DEV_VIRTADDR                *psHWRenderContextDevVAddr,
83065 +                                                                               PVRSRV_PER_PROCESS_DATA *psPerProc)
83066 +{
83067 +       PVRSRV_ERROR eError;
83068 +       IMG_HANDLE hBlockAlloc;
83069 +       SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
83070 +       PRESMAN_ITEM psResItem;
83071 +
83072 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
83073 +                                               sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
83074 +                                               (IMG_VOID **)&psCleanup,
83075 +                                               &hBlockAlloc,
83076 +                                               "SGX Hardware Render Context Cleanup");
83077 +
83078 +       if (eError != PVRSRV_OK)
83079 +       {
83080 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
83081 +               return IMG_NULL;
83082 +       }
83083 +
83084 +       psCleanup->hBlockAlloc = hBlockAlloc;
83085 +       psCleanup->psDeviceNode = psDeviceNode;
83086 +       psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr;
83087 +
83088 +       psResItem = ResManRegisterRes(psPerProc->hResManContext,
83089 +                                                                 RESMAN_TYPE_HW_RENDER_CONTEXT,
83090 +                                                                 (IMG_VOID *)psCleanup,
83091 +                                                                 0,
83092 +                                                                 &SGXCleanupHWRenderContextCallback);
83093 +
83094 +       if (psResItem == IMG_NULL)
83095 +       {
83096 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
83097 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83098 +                                 sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
83099 +                                 psCleanup,
83100 +                                 psCleanup->hBlockAlloc);
83101 +
83102 +
83103 +               return IMG_NULL;
83104 +       }
83105 +
83106 +       psCleanup->psResItem = psResItem;
83107 +
83108 +       return (IMG_HANDLE)psCleanup;
83109 +}
83110 +
83111 +IMG_EXPORT
83112 +PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext)
83113 +{
83114 +       PVRSRV_ERROR eError;
83115 +       SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
83116 +
83117 +       PVR_ASSERT(hHWRenderContext != IMG_NULL);
83118 +
83119 +       psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
83120 +
83121 +       if (psCleanup == IMG_NULL)
83122 +       {
83123 +               PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter"));
83124 +               return PVRSRV_ERROR_INVALID_PARAMS;
83125 +       }
83126 +
83127 +       eError = ResManFreeResByPtr(psCleanup->psResItem);
83128 +
83129 +       return eError;
83130 +}
83131 +
83132 +
83133 +IMG_EXPORT
83134 +IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE                           psDeviceNode,
83135 +                                                                                 IMG_DEV_VIRTADDR                      *psHWTransferContextDevVAddr,
83136 +                                                                                 PVRSRV_PER_PROCESS_DATA       *psPerProc)
83137 +{
83138 +       PVRSRV_ERROR eError;
83139 +       IMG_HANDLE hBlockAlloc;
83140 +       SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
83141 +       PRESMAN_ITEM psResItem;
83142 +
83143 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
83144 +                                               sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
83145 +                                               (IMG_VOID **)&psCleanup,
83146 +                                               &hBlockAlloc,
83147 +                                               "SGX Hardware Transfer Context Cleanup");
83148 +
83149 +       if (eError != PVRSRV_OK)
83150 +       {
83151 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
83152 +               return IMG_NULL;
83153 +       }
83154 +
83155 +       psCleanup->hBlockAlloc = hBlockAlloc;
83156 +       psCleanup->psDeviceNode = psDeviceNode;
83157 +       psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr;
83158 +
83159 +       psResItem = ResManRegisterRes(psPerProc->hResManContext,
83160 +                                                                 RESMAN_TYPE_HW_TRANSFER_CONTEXT,
83161 +                                                                 psCleanup,
83162 +                                                                 0,
83163 +                                                                 &SGXCleanupHWTransferContextCallback);
83164 +
83165 +       if (psResItem == IMG_NULL)
83166 +       {
83167 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
83168 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83169 +                                 sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
83170 +                                 psCleanup,
83171 +                                 psCleanup->hBlockAlloc);
83172 +
83173 +
83174 +               return IMG_NULL;
83175 +       }
83176 +
83177 +       psCleanup->psResItem = psResItem;
83178 +
83179 +       return (IMG_HANDLE)psCleanup;
83180 +}
83181 +
83182 +IMG_EXPORT
83183 +PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext)
83184 +{
83185 +       PVRSRV_ERROR eError;
83186 +       SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
83187 +
83188 +       PVR_ASSERT(hHWTransferContext != IMG_NULL);
83189 +
83190 +       psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
83191 +
83192 +       if (psCleanup == IMG_NULL)
83193 +       {
83194 +               PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter"));
83195 +               return PVRSRV_ERROR_INVALID_PARAMS;
83196 +       }
83197 +
83198 +       eError = ResManFreeResByPtr(psCleanup->psResItem);
83199 +
83200 +       return eError;
83201 +}
83202 +
83203 +#if defined(SGX_FEATURE_2D_HARDWARE)
83204 +typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
83205 +{
83206 +       PVRSRV_DEVICE_NODE *psDeviceNode;
83207 +       IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
83208 +       IMG_HANDLE hBlockAlloc;
83209 +       PRESMAN_ITEM psResItem;
83210 +} SGX_HW_2D_CONTEXT_CLEANUP;
83211 +
83212 +static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
83213 +{
83214 +       SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam;
83215 +
83216 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
83217 +
83218 +       SGXCleanupRequest(psCleanup->psDeviceNode,
83219 +                                         &psCleanup->sHW2DContextDevVAddr,
83220 +                                         PVRSRV_CLEANUPCMD_2DC);
83221 +
83222 +       OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83223 +                         sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
83224 +                         psCleanup,
83225 +                         psCleanup->hBlockAlloc);
83226 +
83227 +
83228 +       return PVRSRV_OK;
83229 +}
83230 +
83231 +IMG_EXPORT
83232 +IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE                         psDeviceNode,
83233 +                                                                       IMG_DEV_VIRTADDR                *psHW2DContextDevVAddr,
83234 +                                                                       PVRSRV_PER_PROCESS_DATA *psPerProc)
83235 +{
83236 +       PVRSRV_ERROR eError;
83237 +       IMG_HANDLE hBlockAlloc;
83238 +       SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
83239 +       PRESMAN_ITEM psResItem;
83240 +
83241 +       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
83242 +                                               sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
83243 +                                               (IMG_VOID **)&psCleanup,
83244 +                                               &hBlockAlloc,
83245 +                                               "SGX Hardware 2D Context Cleanup");
83246 +
83247 +       if (eError != PVRSRV_OK)
83248 +       {
83249 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
83250 +               return IMG_NULL;
83251 +       }
83252 +
83253 +       psCleanup->hBlockAlloc = hBlockAlloc;
83254 +       psCleanup->psDeviceNode = psDeviceNode;
83255 +       psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr;
83256 +
83257 +       psResItem = ResManRegisterRes(psPerProc->hResManContext,
83258 +                                                                 RESMAN_TYPE_HW_2D_CONTEXT,
83259 +                                                                 psCleanup,
83260 +                                                                 0,
83261 +                                                                 &SGXCleanupHW2DContextCallback);
83262 +
83263 +       if (psResItem == IMG_NULL)
83264 +       {
83265 +               PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
83266 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
83267 +                                 sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
83268 +                                 psCleanup,
83269 +                                 psCleanup->hBlockAlloc);
83270 +
83271 +
83272 +               return IMG_NULL;
83273 +       }
83274 +
83275 +       psCleanup->psResItem = psResItem;
83276 +
83277 +       return (IMG_HANDLE)psCleanup;
83278 +}
83279 +
83280 +IMG_EXPORT
83281 +PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext)
83282 +{
83283 +       PVRSRV_ERROR eError;
83284 +       SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
83285 +
83286 +       PVR_ASSERT(hHW2DContext != IMG_NULL);
83287 +
83288 +       if (hHW2DContext == IMG_NULL)
83289 +       {
83290 +               return (PVRSRV_ERROR_INVALID_PARAMS);
83291 +       }
83292 +
83293 +       psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext;
83294 +
83295 +       eError = ResManFreeResByPtr(psCleanup->psResItem);
83296 +
83297 +       return eError;
83298 +}
83299 +#endif
83300 +
83301 +#ifdef INLINE_IS_PRAGMA
83302 +#pragma inline(SGX2DQuerySyncOpsComplete)
83303 +#endif
83304 +static INLINE
83305 +IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO     *psSyncInfo,
83306 +                                                                  IMG_UINT32                           ui32ReadOpsPending,
83307 +                                                                  IMG_UINT32                           ui32WriteOpsPending)
83308 +{
83309 +       PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
83310 +
83311 +       return (IMG_BOOL)(
83312 +                                         (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) &&
83313 +                                         (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending)
83314 +                                        );
83315 +}
83316 +
83317 +IMG_EXPORT
83318 +PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO      *psDevInfo,
83319 +                                                                          PVRSRV_KERNEL_SYNC_INFO *psSyncInfo,
83320 +                                                                          IMG_BOOL bWaitForComplete)
83321 +{
83322 +       IMG_UINT32      ui32ReadOpsPending, ui32WriteOpsPending;
83323 +
83324 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
83325 +
83326 +       PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start"));
83327 +
83328 +       ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending;
83329 +       ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending;
83330 +
83331 +       if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
83332 +       {
83333 +
83334 +               PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete."));
83335 +               return PVRSRV_OK;
83336 +       }
83337 +
83338 +
83339 +       if (!bWaitForComplete)
83340 +       {
83341 +
83342 +               PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending."));
83343 +               return PVRSRV_ERROR_CMD_NOT_PROCESSED;
83344 +       }
83345 +
83346 +
83347 +       PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling."));
83348 +
83349 +       LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
83350 +       {
83351 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
83352 +
83353 +               if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
83354 +               {
83355 +
83356 +                       PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over.  Blits complete."));
83357 +                       return PVRSRV_OK;
83358 +               }
83359 +
83360 +               OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
83361 +       } END_LOOP_UNTIL_TIMEOUT();
83362 +
83363 +
83364 +       PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending."));
83365 +
83366 +#if defined(DEBUG)
83367 +       {
83368 +               PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
83369 +
83370 +               PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: %p, Syncdata: %p", psSyncInfo, psSyncData));
83371 +
83372 +               PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending));
83373 +               PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending));
83374 +
83375 +       }
83376 +#endif
83377 +
83378 +       return PVRSRV_ERROR_TIMEOUT;
83379 +}
83380 +
83381 +
83382 +IMG_EXPORT
83383 +IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr)
83384 +{
83385 +       PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL);
83386 +
83387 +       SGXCleanupRequest(psDeviceNode,
83388 +                                         &sHWRTDataSetDevVAddr,
83389 +                                         PVRSRV_CLEANUPCMD_RT);
83390 +}
83391 +
83392 +
83393 +IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO      *psDevInfo,
83394 +                                                          IMG_UINT32                   ui32TimeWraps,
83395 +                                                          IMG_UINT32                   ui32Time)
83396 +{
83397 +#if defined(EUR_CR_TIMER)
83398 +       PVR_UNREFERENCED_PARAMETER(psDevInfo);
83399 +       PVR_UNREFERENCED_PARAMETER(ui32TimeWraps);
83400 +       return ui32Time;
83401 +#else
83402 +       IMG_UINT64      ui64Clocks;
83403 +       IMG_UINT32      ui32Clocksx16;
83404 +
83405 +       ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) +
83406 +                                       (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK));
83407 +       ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16);
83408 +
83409 +       return ui32Clocksx16;
83410 +#endif
83411 +}
83412 +
83413 +
83414 +
83415 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.h
83416 new file mode 100644
83417 index 0000000..bc4c053
83418 --- /dev/null
83419 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/devices/sgx/sgxutils.h
83420 @@ -0,0 +1,99 @@
83421 +/**********************************************************************
83422 + *
83423 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83424 + * 
83425 + * This program is free software; you can redistribute it and/or modify it
83426 + * under the terms and conditions of the GNU General Public License,
83427 + * version 2, as published by the Free Software Foundation.
83428 + * 
83429 + * This program is distributed in the hope it will be useful but, except 
83430 + * as otherwise stated in writing, without any warranty; without even the 
83431 + * implied warranty of merchantability or fitness for a particular purpose. 
83432 + * See the GNU General Public License for more details.
83433 + * 
83434 + * You should have received a copy of the GNU General Public License along with
83435 + * this program; if not, write to the Free Software Foundation, Inc.,
83436 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
83437 + * 
83438 + * The full GNU General Public License is included in this distribution in
83439 + * the file called "COPYING".
83440 + *
83441 + * Contact Information:
83442 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
83443 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
83444 + *
83445 + ******************************************************************************/
83446 +
83447 +#include "perproc.h"
83448 +#include "sgxinfokm.h"
83449 +
83450 +#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \
83451 +       ((sizeof(type) <= (psCCBMemInfo)->ui32AllocSize) && \
83452 +       ((psCCBKick)->offset <= (psCCBMemInfo)->ui32AllocSize - sizeof(type)))
83453 +
83454 +#define        CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \
83455 +       ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
83456 +               (psCCBKick)->offset))
83457 +
83458 +
83459 +IMG_IMPORT
83460 +IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE    *psDeviceNode,
83461 +                                                                IMG_UINT32                     ui32CallerID);
83462 +
83463 +IMG_IMPORT
83464 +PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO  *psDevInfo,
83465 +                                                                  SGXMKIF_CMD_TYPE             eCommandType,
83466 +                                                                  SGXMKIF_COMMAND              *psCommandData,
83467 +                                                                  IMG_UINT32                   ui32CallerID,
83468 +                                                                  IMG_UINT32                   ui32PDumpFlags);
83469 +IMG_IMPORT
83470 +PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE                *psDeviceNode,
83471 +                                                                        SGXMKIF_CMD_TYPE               eCommandType,
83472 +                                                                        SGXMKIF_COMMAND                *psCommandData,
83473 +                                                                        IMG_UINT32                             ui32CallerID,
83474 +                                                                        IMG_UINT32                             ui32PDumpFlags);
83475 +
83476 +IMG_IMPORT
83477 +PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode);
83478 +
83479 +IMG_IMPORT
83480 +IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode);
83481 +
83482 +IMG_IMPORT
83483 +IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE                             psDeviceNode,
83484 +                                                                               IMG_DEV_VIRTADDR                *psHWRenderContextDevVAddr,
83485 +                                                                               PVRSRV_PER_PROCESS_DATA *psPerProc);
83486 +
83487 +IMG_IMPORT
83488 +IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE                           psDeviceNode,
83489 +                                                                                 IMG_DEV_VIRTADDR                      *psHWTransferContextDevVAddr,
83490 +                                                                                 PVRSRV_PER_PROCESS_DATA       *psPerProc);
83491 +
83492 +IMG_IMPORT
83493 +IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr);
83494 +
83495 +IMG_IMPORT
83496 +PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext);
83497 +
83498 +IMG_IMPORT
83499 +PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext);
83500 +
83501 +#if defined(SGX_FEATURE_2D_HARDWARE)
83502 +IMG_IMPORT
83503 +IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE                         psDeviceNode,
83504 +                                                                       IMG_DEV_VIRTADDR                *psHW2DContextDevVAddr,
83505 +                                                                       PVRSRV_PER_PROCESS_DATA *psPerProc);
83506 +
83507 +IMG_IMPORT
83508 +PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext);
83509 +#endif
83510 +
83511 +IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO      *psDevInfo,
83512 +                                                          IMG_UINT32                   ui32TimeWraps,
83513 +                                                          IMG_UINT32                   ui32Time);
83514 +
83515 +IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE  *psDeviceNode,
83516 +                                                       IMG_DEV_VIRTADDR        *psHWDataDevVAddr,
83517 +                                                       IMG_UINT32                      ui32CleanupType);
83518 +                                                          
83519 +
83520 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/.gitignore
83521 new file mode 100644
83522 index 0000000..2f89523
83523 --- /dev/null
83524 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/.gitignore
83525 @@ -0,0 +1,5 @@
83526 +bin_pc_i686*
83527 +tmp_pc_i686*
83528 +host_pc_i686*
83529 +*.o
83530 +*.o.cmd
83531 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_data.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_data.h
83532 new file mode 100644
83533 index 0000000..3d41219
83534 --- /dev/null
83535 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_data.h
83536 @@ -0,0 +1,66 @@
83537 +/**********************************************************************
83538 + *
83539 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83540 + * 
83541 + * This program is free software; you can redistribute it and/or modify it
83542 + * under the terms and conditions of the GNU General Public License,
83543 + * version 2, as published by the Free Software Foundation.
83544 + * 
83545 + * This program is distributed in the hope it will be useful but, except 
83546 + * as otherwise stated in writing, without any warranty; without even the 
83547 + * implied warranty of merchantability or fitness for a particular purpose. 
83548 + * See the GNU General Public License for more details.
83549 + * 
83550 + * You should have received a copy of the GNU General Public License along with
83551 + * this program; if not, write to the Free Software Foundation, Inc.,
83552 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
83553 + * 
83554 + * The full GNU General Public License is included in this distribution in
83555 + * the file called "COPYING".
83556 + *
83557 + * Contact Information:
83558 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
83559 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
83560 + *
83561 + ******************************************************************************/
83562 +
83563 +#ifndef _ENV_DATA_
83564 +#define _ENV_DATA_
83565 +
83566 +#include <linux/interrupt.h>
83567 +#include <linux/pci.h>
83568 +
83569 +#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
83570 +#include <linux/workqueue.h>
83571 +#endif
83572 +
83573 +#define PVRSRV_MAX_BRIDGE_IN_SIZE      0x1000
83574 +#define PVRSRV_MAX_BRIDGE_OUT_SIZE     0x1000
83575 +
83576 +typedef        struct _PVR_PCI_DEV_TAG
83577 +{
83578 +       struct pci_dev          *psPCIDev;
83579 +       HOST_PCI_INIT_FLAGS     ePCIFlags;
83580 +       IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE];
83581 +} PVR_PCI_DEV;
83582 +
83583 +typedef struct _ENV_DATA_TAG
83584 +{
83585 +       IMG_VOID                *pvBridgeData;
83586 +       struct pm_dev           *psPowerDevice;
83587 +       IMG_BOOL                bLISRInstalled;
83588 +       IMG_BOOL                bMISRInstalled;
83589 +       IMG_UINT32              ui32IRQ;
83590 +       IMG_VOID                *pvISRCookie;
83591 +#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
83592 +       struct workqueue_struct *psWorkQueue;
83593 +#endif
83594 +#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
83595 +       struct work_struct      sMISRWork;
83596 +       IMG_VOID                *pvMISRData;
83597 +#else
83598 +       struct tasklet_struct   sMISRTasklet;
83599 +#endif
83600 +} ENV_DATA;
83601 +
83602 +#endif 
83603 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_perproc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_perproc.h
83604 new file mode 100644
83605 index 0000000..a6e49db
83606 --- /dev/null
83607 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/env_perproc.h
83608 @@ -0,0 +1,56 @@
83609 +/**********************************************************************
83610 + *
83611 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83612 + * 
83613 + * This program is free software; you can redistribute it and/or modify it
83614 + * under the terms and conditions of the GNU General Public License,
83615 + * version 2, as published by the Free Software Foundation.
83616 + * 
83617 + * This program is distributed in the hope it will be useful but, except 
83618 + * as otherwise stated in writing, without any warranty; without even the 
83619 + * implied warranty of merchantability or fitness for a particular purpose. 
83620 + * See the GNU General Public License for more details.
83621 + * 
83622 + * You should have received a copy of the GNU General Public License along with
83623 + * this program; if not, write to the Free Software Foundation, Inc.,
83624 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
83625 + * 
83626 + * The full GNU General Public License is included in this distribution in
83627 + * the file called "COPYING".
83628 + *
83629 + * Contact Information:
83630 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
83631 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
83632 + *
83633 + ******************************************************************************/
83634 +
83635 +#ifndef __ENV_PERPROC_H__
83636 +#define __ENV_PERPROC_H__
83637 +
83638 +#include <linux/list.h>
83639 +#include <linux/proc_fs.h>
83640 +
83641 +#include "services.h"
83642 +#include "handle.h"
83643 +
83644 +typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_
83645 +{
83646 +       IMG_HANDLE hBlockAlloc;
83647 +       struct proc_dir_entry *psProcDir;
83648 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
83649 +       struct list_head sDRMAuthListHead;
83650 +#endif
83651 +} PVRSRV_ENV_PER_PROCESS_DATA;
83652 +
83653 +IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
83654 +
83655 +PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
83656 +
83657 +IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc);
83658
83659 +PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
83660 +
83661 +IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID);
83662 +
83663 +#endif 
83664 +
83665 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.c
83666 new file mode 100644
83667 index 0000000..33eca49
83668 --- /dev/null
83669 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.c
83670 @@ -0,0 +1,273 @@
83671 +/**********************************************************************
83672 + *
83673 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83674 + *
83675 + * This program is free software; you can redistribute it and/or modify it
83676 + * under the terms and conditions of the GNU General Public License,
83677 + * version 2, as published by the Free Software Foundation.
83678 + *
83679 + * This program is distributed in the hope it will be useful but, except
83680 + * as otherwise stated in writing, without any warranty; without even the
83681 + * implied warranty of merchantability or fitness for a particular purpose.
83682 + * See the GNU General Public License for more details.
83683 + *
83684 + * You should have received a copy of the GNU General Public License along with
83685 + * this program; if not, write to the Free Software Foundation, Inc.,
83686 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
83687 + *
83688 + * The full GNU General Public License is included in this distribution in
83689 + * the file called "COPYING".
83690 + *
83691 + * Contact Information:
83692 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
83693 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
83694 + *
83695 + ******************************************************************************/
83696 +
83697 +#ifndef AUTOCONF_INCLUDED
83698 + #include <linux/config.h>
83699 +#endif
83700 +
83701 +#include <linux/version.h>
83702 +#include <asm/io.h>
83703 +#include <asm/page.h>
83704 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
83705 +#include <asm/system.h>
83706 +#endif
83707 +#include <linux/mm.h>
83708 +#include <linux/slab.h>
83709 +#include <linux/vmalloc.h>
83710 +#include <linux/delay.h>
83711 +#include <linux/pci.h>
83712 +
83713 +#include <linux/string.h>
83714 +#include <linux/sched.h>
83715 +#include <linux/interrupt.h>
83716 +#include <asm/hardirq.h>
83717 +#include <linux/timer.h>
83718 +#include <linux/capability.h>
83719 +#include <linux/sched.h>
83720 +#include <asm/uaccess.h>
83721 +
83722 +#include "img_types.h"
83723 +#include "services_headers.h"
83724 +#include "mm.h"
83725 +#include "pvrmmap.h"
83726 +#include "mmap.h"
83727 +#include "env_data.h"
83728 +#include "proc.h"
83729 +#include "mutex.h"
83730 +#include "lock.h"
83731 +
83732 +typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG
83733 +{
83734 +   rwlock_t                       sLock;
83735 +   struct list_head        sList;
83736 +
83737 +} PVRSRV_LINUX_EVENT_OBJECT_LIST;
83738 +
83739 +
83740 +typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG
83741 +{
83742 +       atomic_t        sTimeStamp;
83743 +       IMG_UINT32  ui32TimeStampPrevious;
83744 +#if defined(DEBUG)
83745 +       IMG_UINT        ui32Stats;
83746 +#endif
83747 +    wait_queue_head_t sWait;
83748 +       struct list_head        sList;
83749 +       IMG_HANDLE                              hResItem;
83750 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList;
83751 +} PVRSRV_LINUX_EVENT_OBJECT;
83752 +
83753 +PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
83754 +{
83755 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList;
83756 +
83757 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST),
83758 +               (IMG_VOID **)&psEvenObjectList, IMG_NULL,
83759 +               "Linux Event Object List") != PVRSRV_OK)
83760 +       {
83761 +               PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
83762 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
83763 +       }
83764 +
83765 +    INIT_LIST_HEAD(&psEvenObjectList->sList);
83766 +
83767 +       rwlock_init(&psEvenObjectList->sLock);
83768 +
83769 +       *phEventObjectList = (IMG_HANDLE *) psEvenObjectList;
83770 +
83771 +       return PVRSRV_OK;
83772 +}
83773 +
83774 +PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
83775 +{
83776 +
83777 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
83778 +
83779 +       if(psEvenObjectList)
83780 +       {
83781 +               if (!list_empty(&psEvenObjectList->sList))
83782 +               {
83783 +                        PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
83784 +                        return PVRSRV_ERROR_GENERIC;
83785 +               }
83786 +               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEvenObjectList, IMG_NULL);
83787 +
83788 +       }
83789 +       return PVRSRV_OK;
83790 +}
83791 +
83792 +
83793 +PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject)
83794 +{
83795 +       if(hOSEventObjectList)
83796 +       {
83797 +               if(hOSEventObject)
83798 +               {
83799 +                       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
83800 +#if defined(DEBUG)
83801 +                       PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %lu", psLinuxEventObject->ui32Stats));
83802 +#endif
83803 +                       if(ResManFreeResByPtr(psLinuxEventObject->hResItem) != PVRSRV_OK)
83804 +                       {
83805 +                               return PVRSRV_ERROR_GENERIC;
83806 +                       }
83807 +
83808 +                       return PVRSRV_OK;
83809 +               }
83810 +       }
83811 +       return PVRSRV_ERROR_GENERIC;
83812 +
83813 +}
83814 +
83815 +static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
83816 +{
83817 +       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam;
83818 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
83819 +
83820 +       PVR_UNREFERENCED_PARAMETER(ui32Param);
83821 +
83822 +       write_lock_bh(&psLinuxEventObjectList->sLock);
83823 +       list_del(&psLinuxEventObject->sList);
83824 +       write_unlock_bh(&psLinuxEventObjectList->sLock);
83825 +
83826 +#if defined(DEBUG)
83827 +       PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %lu", psLinuxEventObject->ui32Stats));
83828 +#endif
83829 +
83830 +       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL);
83831 +
83832 +
83833 +       return PVRSRV_OK;
83834 +}
83835 +PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject)
83836 + {
83837 +       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
83838 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
83839 +       IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
83840 +       PVRSRV_PER_PROCESS_DATA *psPerProc;
83841 +
83842 +       psPerProc = PVRSRVPerProcessData(ui32PID);
83843 +       if (psPerProc == IMG_NULL)
83844 +       {
83845 +               PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data"));
83846 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
83847 +       }
83848 +
83849 +
83850 +       if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT),
83851 +               (IMG_VOID **)&psLinuxEventObject, IMG_NULL,
83852 +               "Linux Event Object") != PVRSRV_OK)
83853 +       {
83854 +               PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));
83855 +               return PVRSRV_ERROR_OUT_OF_MEMORY;
83856 +       }
83857 +
83858 +       INIT_LIST_HEAD(&psLinuxEventObject->sList);
83859 +
83860 +       atomic_set(&psLinuxEventObject->sTimeStamp, 0);
83861 +       psLinuxEventObject->ui32TimeStampPrevious = 0;
83862 +
83863 +#if defined(DEBUG)
83864 +       psLinuxEventObject->ui32Stats = 0;
83865 +#endif
83866 +    init_waitqueue_head(&psLinuxEventObject->sWait);
83867 +
83868 +       psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;
83869 +
83870 +       psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext,
83871 +                                                                                                        RESMAN_TYPE_EVENT_OBJECT,
83872 +                                                                                                        psLinuxEventObject,
83873 +                                                                                                        0,
83874 +                                                                                                        &LinuxEventObjectDeleteCallback);
83875 +
83876 +       write_lock_bh(&psLinuxEventObjectList->sLock);
83877 +       list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
83878 +    write_unlock_bh(&psLinuxEventObjectList->sLock);
83879 +
83880 +       *phOSEventObject = psLinuxEventObject;
83881 +
83882 +       return PVRSRV_OK;
83883 +}
83884 +
83885 +PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList)
83886 +{
83887 +       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
83888 +       PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
83889 +       struct list_head *psListEntry, *psListEntryTemp, *psList;
83890 +       psList = &psLinuxEventObjectList->sList;
83891 +
83892 +       list_for_each_safe(psListEntry, psListEntryTemp, psList)
83893 +       {
83894 +
83895 +               psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);
83896 +
83897 +               atomic_inc(&psLinuxEventObject->sTimeStamp);
83898 +               wake_up_interruptible(&psLinuxEventObject->sWait);
83899 +       }
83900 +
83901 +       return  PVRSRV_OK;
83902 +
83903 +}
83904 +
83905 +PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout)
83906 +{
83907 +       IMG_UINT32 ui32TimeStamp;
83908 +       DEFINE_WAIT(sWait);
83909 +
83910 +       PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
83911 +
83912 +       IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
83913 +
83914 +       do
83915 +       {
83916 +               prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
83917 +               ui32TimeStamp = atomic_read(&psLinuxEventObject->sTimeStamp);
83918 +
83919 +               if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp)
83920 +               {
83921 +                       break;
83922 +               }
83923 +
83924 +               LinuxUnLockMutex(&gPVRSRVLock);
83925 +
83926 +               ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
83927 +
83928 +               LinuxLockMutex(&gPVRSRVLock);
83929 +#if defined(DEBUG)
83930 +               psLinuxEventObject->ui32Stats++;
83931 +#endif
83932 +
83933 +
83934 +       } while (ui32TimeOutJiffies);
83935 +
83936 +       finish_wait(&psLinuxEventObject->sWait, &sWait);
83937 +
83938 +       psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp;
83939 +
83940 +       return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
83941 +
83942 +}
83943 +
83944 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.h
83945 new file mode 100644
83946 index 0000000..d07bc97
83947 --- /dev/null
83948 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/event.h
83949 @@ -0,0 +1,32 @@
83950 +/**********************************************************************
83951 + *
83952 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83953 + * 
83954 + * This program is free software; you can redistribute it and/or modify it
83955 + * under the terms and conditions of the GNU General Public License,
83956 + * version 2, as published by the Free Software Foundation.
83957 + * 
83958 + * This program is distributed in the hope it will be useful but, except 
83959 + * as otherwise stated in writing, without any warranty; without even the 
83960 + * implied warranty of merchantability or fitness for a particular purpose. 
83961 + * See the GNU General Public License for more details.
83962 + * 
83963 + * You should have received a copy of the GNU General Public License along with
83964 + * this program; if not, write to the Free Software Foundation, Inc.,
83965 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
83966 + * 
83967 + * The full GNU General Public License is included in this distribution in
83968 + * the file called "COPYING".
83969 + *
83970 + * Contact Information:
83971 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
83972 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
83973 + *
83974 + ******************************************************************************/
83975 +
83976 +PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList);
83977 +PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList);
83978 +PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject);
83979 +PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject);
83980 +PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
83981 +PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout);
83982 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/linkage.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/linkage.h
83983 new file mode 100644
83984 index 0000000..1ec2696
83985 --- /dev/null
83986 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/linkage.h
83987 @@ -0,0 +1,61 @@
83988 +/**********************************************************************
83989 + *
83990 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
83991 + *
83992 + * This program is free software; you can redistribute it and/or modify it
83993 + * under the terms and conditions of the GNU General Public License,
83994 + * version 2, as published by the Free Software Foundation.
83995 + *
83996 + * This program is distributed in the hope it will be useful but, except
83997 + * as otherwise stated in writing, without any warranty; without even the
83998 + * implied warranty of merchantability or fitness for a particular purpose.
83999 + * See the GNU General Public License for more details.
84000 + *
84001 + * You should have received a copy of the GNU General Public License along with
84002 + * this program; if not, write to the Free Software Foundation, Inc.,
84003 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
84004 + *
84005 + * The full GNU General Public License is included in this distribution in
84006 + * the file called "COPYING".
84007 + *
84008 + * Contact Information:
84009 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
84010 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
84011 + *
84012 + ******************************************************************************/
84013 +
84014 +#ifndef __LINKAGE_H__
84015 +#define __LINKAGE_H__
84016 +
84017 +#if !defined(SUPPORT_DRI_DRM)
84018 +IMG_INT32 PVRSRV_BridgeDispatchKM(struct file *file, IMG_UINT cmd, IMG_UINT32 arg);
84019 +#endif
84020 +
84021 +IMG_VOID PVRDPFInit(IMG_VOID);
84022 +PVRSRV_ERROR PVROSFuncInit(IMG_VOID);
84023 +IMG_VOID PVROSFuncDeInit(IMG_VOID);
84024 +
84025 +#ifdef DEBUG
84026 +IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
84027 +IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel);
84028 +
84029 +#ifdef PVR_PROC_USE_SEQ_FILE
84030 +void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el);
84031 +#else
84032 +IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data);
84033 +#endif
84034 +
84035 +#ifdef PVR_MANUAL_POWER_CONTROL
84036 +IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
84037 +
84038 +#ifdef PVR_PROC_USE_SEQ_FILE
84039 +void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el);
84040 +#else
84041 +IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data);
84042 +#endif
84043 +
84044 +
84045 +#endif
84046 +#endif
84047 +
84048 +#endif
84049 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/lock.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/lock.h
84050 new file mode 100644
84051 index 0000000..e0bf5ee
84052 --- /dev/null
84053 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/lock.h
84054 @@ -0,0 +1,32 @@
84055 +/**********************************************************************
84056 + *
84057 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
84058 + * 
84059 + * This program is free software; you can redistribute it and/or modify it
84060 + * under the terms and conditions of the GNU General Public License,
84061 + * version 2, as published by the Free Software Foundation.
84062 + * 
84063 + * This program is distributed in the hope it will be useful but, except 
84064 + * as otherwise stated in writing, without any warranty; without even the 
84065 + * implied warranty of merchantability or fitness for a particular purpose. 
84066 + * See the GNU General Public License for more details.
84067 + * 
84068 + * You should have received a copy of the GNU General Public License along with
84069 + * this program; if not, write to the Free Software Foundation, Inc.,
84070 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
84071 + * 
84072 + * The full GNU General Public License is included in this distribution in
84073 + * the file called "COPYING".
84074 + *
84075 + * Contact Information:
84076 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
84077 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
84078 + *
84079 + ******************************************************************************/
84080 +
84081 +#ifndef __LOCK_H__
84082 +#define __LOCK_H__
84083 +
84084 +extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
84085 +
84086 +#endif 
84087 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.c
84088 new file mode 100644
84089 index 0000000..97a4750
84090 --- /dev/null
84091 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.c
84092 @@ -0,0 +1,2360 @@
84093 +/**********************************************************************
84094 + *
84095 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
84096 + *
84097 + * This program is free software; you can redistribute it and/or modify it
84098 + * under the terms and conditions of the GNU General Public License,
84099 + * version 2, as published by the Free Software Foundation.
84100 + *
84101 + * This program is distributed in the hope it will be useful but, except
84102 + * as otherwise stated in writing, without any warranty; without even the
84103 + * implied warranty of merchantability or fitness for a particular purpose.
84104 + * See the GNU General Public License for more details.
84105 + *
84106 + * You should have received a copy of the GNU General Public License along with
84107 + * this program; if not, write to the Free Software Foundation, Inc.,
84108 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
84109 + *
84110 + * The full GNU General Public License is included in this distribution in
84111 + * the file called "COPYING".
84112 + *
84113 + * Contact Information:
84114 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
84115 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
84116 + *
84117 + ******************************************************************************/
84118 +
84119 +#ifndef AUTOCONF_INCLUDED
84120 + #include <linux/config.h>
84121 +#endif
84122 +
84123 +#include <linux/version.h>
84124 +#include <linux/mm.h>
84125 +#include <linux/vmalloc.h>
84126 +#include <asm/io.h>
84127 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
84128 +#include <linux/wrapper.h>
84129 +#endif
84130 +#include <linux/slab.h>
84131 +#include <linux/highmem.h>
84132 +#include <linux/sched.h>
84133 +
84134 +#include "img_defs.h"
84135 +#include "services.h"
84136 +#include "servicesint.h"
84137 +#include "syscommon.h"
84138 +#include "mutils.h"
84139 +#include "mm.h"
84140 +#include "pvrmmap.h"
84141 +#include "mmap.h"
84142 +#include "osfunc.h"
84143 +#include "pvr_debug.h"
84144 +#include "proc.h"
84145 +#include "mutex.h"
84146 +#include "lock.h"
84147 +
84148 +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84149 +       #include "lists.h"
84150 +#endif
84151 +
84152 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84153 +typedef enum {
84154 +    DEBUG_MEM_ALLOC_TYPE_KMALLOC,
84155 +    DEBUG_MEM_ALLOC_TYPE_VMALLOC,
84156 +    DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
84157 +    DEBUG_MEM_ALLOC_TYPE_IOREMAP,
84158 +    DEBUG_MEM_ALLOC_TYPE_IO,
84159 +    DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
84160 +    DEBUG_MEM_ALLOC_TYPE_COUNT
84161 +}DEBUG_MEM_ALLOC_TYPE;
84162 +
84163 +typedef struct _DEBUG_MEM_ALLOC_REC
84164 +{
84165 +    DEBUG_MEM_ALLOC_TYPE    eAllocType;
84166 +       IMG_VOID                                *pvKey;
84167 +    IMG_VOID                *pvCpuVAddr;
84168 +    IMG_UINT32              ulCpuPAddr;
84169 +    IMG_VOID                *pvPrivateData;
84170 +       IMG_UINT32                              ui32Bytes;
84171 +       pid_t                                   pid;
84172 +    IMG_CHAR                *pszFileName;
84173 +    IMG_UINT32              ui32Line;
84174 +
84175 +    struct _DEBUG_MEM_ALLOC_REC   *psNext;
84176 +       struct _DEBUG_MEM_ALLOC_REC   **ppsThis;
84177 +}DEBUG_MEM_ALLOC_REC;
84178 +
84179 +static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
84180 +static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
84181 +static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC)
84182 +static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC)
84183 +static IMPLEMENT_LIST_REMOVE(DEBUG_MEM_ALLOC_REC)
84184 +
84185 +
84186 +static DEBUG_MEM_ALLOC_REC *g_MemoryRecords;
84187 +
84188 +static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
84189 +static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
84190 +
84191 +static IMG_UINT32 g_SysRAMWaterMark;
84192 +static IMG_UINT32 g_SysRAMHighWaterMark;
84193 +
84194 +static IMG_UINT32 g_IOMemWaterMark;
84195 +static IMG_UINT32 g_IOMemHighWaterMark;
84196 +
84197 +static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
84198 +                                       IMG_VOID *pvKey,
84199 +                                       IMG_VOID *pvCpuVAddr,
84200 +                                       IMG_UINT32 ulCpuPAddr,
84201 +                                       IMG_VOID *pvPrivateData,
84202 +                                       IMG_UINT32 ui32Bytes,
84203 +                                       IMG_CHAR *pszFileName,
84204 +                                       IMG_UINT32 ui32Line);
84205 +
84206 +static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
84207 +
84208 +static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType);
84209 +
84210 +
84211 +#ifdef PVR_PROC_USE_SEQ_FILE
84212 +static struct proc_dir_entry *g_SeqFileMemoryRecords =0;
84213 +static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
84214 +static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
84215 +static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off);
84216 +
84217 +#else
84218 +static off_t printMemoryRecords(IMG_CHAR * buffer, size_t size, off_t off);
84219 +#endif
84220 +
84221 +#endif
84222 +
84223 +
84224 +#if defined(DEBUG_LINUX_MEM_AREAS)
84225 +typedef struct _DEBUG_LINUX_MEM_AREA_REC
84226 +{
84227 +       LinuxMemArea                *psLinuxMemArea;
84228 +    IMG_UINT32                  ui32Flags;
84229 +       pid_t                                       pid;
84230 +
84231 +       struct _DEBUG_LINUX_MEM_AREA_REC  *psNext;
84232 +       struct _DEBUG_LINUX_MEM_AREA_REC  **ppsThis;
84233 +}DEBUG_LINUX_MEM_AREA_REC;
84234 +
84235 +
84236 +static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC)
84237 +static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC)
84238 +static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC)
84239 +static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC)
84240 +
84241 +
84242 +
84243 +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84244 +static PVRSRV_LINUX_MUTEX g_sDebugMutex;
84245 +#endif
84246 +
84247 +static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords;
84248 +static IMG_UINT32 g_LinuxMemAreaCount;
84249 +static IMG_UINT32 g_LinuxMemAreaWaterMark;
84250 +static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
84251 +
84252 +
84253 +#ifdef PVR_PROC_USE_SEQ_FILE
84254 +static struct proc_dir_entry *g_SeqFileMemArea=0;
84255 +
84256 +static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
84257 +static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
84258 +static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off);
84259 +
84260 +#else
84261 +static off_t printLinuxMemAreaRecords(IMG_CHAR * buffer, size_t size, off_t off);
84262 +#endif
84263 +
84264 +#endif
84265 +
84266 +#ifdef PVR_PROC_USE_SEQ_FILE
84267 +#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS))
84268 +static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
84269 +#endif
84270 +#endif
84271 +
84272 +static LinuxKMemCache *psLinuxMemAreaCache;
84273 +
84274 +
84275 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
84276 +static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
84277 +static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
84278 +#endif
84279 +
84280 +static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID);
84281 +static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea);
84282 +#if defined(DEBUG_LINUX_MEM_AREAS)
84283 +static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags);
84284 +static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea);
84285 +static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea);
84286 +#endif
84287 +
84288 +PVRSRV_ERROR
84289 +LinuxMMInit(IMG_VOID)
84290 +{
84291 +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84292 +       LinuxInitMutex(&g_sDebugMutex);
84293 +#endif
84294 +
84295 +#if defined(DEBUG_LINUX_MEM_AREAS)
84296 +    {
84297 +        IMG_INT iStatus;
84298 +#ifdef PVR_PROC_USE_SEQ_FILE
84299 +               g_SeqFileMemArea = CreateProcReadEntrySeq(
84300 +                                                                       "mem_areas",
84301 +                                                                       NULL,
84302 +                                                                       ProcSeqNextMemArea,
84303 +                                                                       ProcSeqShowMemArea,
84304 +                                                                       ProcSeqOff2ElementMemArea,
84305 +                                                                       ProcSeqStartstopDebugMutex
84306 +                                                                  );
84307 +               iStatus = !g_SeqFileMemArea ? -1 : 0;
84308 +#else
84309 +   iStatus = CreateProcReadEntry("mem_areas", printLinuxMemAreaRecords);
84310 +#endif
84311 +        if(iStatus!=0)
84312 +        {
84313 +            return PVRSRV_ERROR_OUT_OF_MEMORY;
84314 +        }
84315 +    }
84316 +#endif
84317 +
84318 +
84319 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84320 +    {
84321 +        IMG_INT iStatus;
84322 +#ifdef PVR_PROC_USE_SEQ_FILE
84323 +               g_SeqFileMemoryRecords =CreateProcReadEntrySeq(
84324 +                                                                       "meminfo",
84325 +                                                                       NULL,
84326 +                                                                       ProcSeqNextMemoryRecords,
84327 +                                                                       ProcSeqShowMemoryRecords,
84328 +                                                                       ProcSeqOff2ElementMemoryRecords,
84329 +                                                                       ProcSeqStartstopDebugMutex
84330 +                                                                  );
84331 +
84332 +               iStatus = !g_SeqFileMemoryRecords ? -1 : 0;
84333 +#else
84334 +        iStatus = CreateProcReadEntry("meminfo", printMemoryRecords);
84335 +#endif
84336 +        if(iStatus!=0)
84337 +        {
84338 +            return PVRSRV_ERROR_OUT_OF_MEMORY;
84339 +        }
84340 +    }
84341 +#endif
84342 +
84343 +    psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
84344 +    if(!psLinuxMemAreaCache)
84345 +    {
84346 +        PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
84347 +        return PVRSRV_ERROR_OUT_OF_MEMORY;
84348 +    }
84349 +
84350 +    return PVRSRV_OK;
84351 +}
84352 +
84353 +#if defined(DEBUG_LINUX_MEM_AREAS)
84354 +IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
84355 +{
84356 +       LinuxMemArea *psLinuxMemArea;
84357 +
84358 +       psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
84359 +       PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%ld bytes",
84360 +                               __FUNCTION__,
84361 +                               psCurrentRecord->psLinuxMemArea,
84362 +                               LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
84363 +                               psCurrentRecord->psLinuxMemArea->ui32ByteSize));
84364 +
84365 +       LinuxMemAreaDeepFree(psLinuxMemArea);
84366 +}
84367 +#endif
84368 +
84369 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84370 +IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
84371 +
84372 +{
84373 +
84374 +       PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
84375 +                                                       "type=%s "
84376 +                                                       "CpuVAddr=%p "
84377 +                                                       "CpuPAddr=0x%08lx, "
84378 +                                                       "allocated @ file=%s,line=%d",
84379 +                       __FUNCTION__,
84380 +                       DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
84381 +                       psCurrentRecord->pvCpuVAddr,
84382 +                       psCurrentRecord->ulCpuPAddr,
84383 +                       psCurrentRecord->pszFileName,
84384 +                       psCurrentRecord->ui32Line));
84385 +       switch(psCurrentRecord->eAllocType)
84386 +       {
84387 +               case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
84388 +                       KFreeWrapper(psCurrentRecord->pvCpuVAddr);
84389 +                       break;
84390 +               case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
84391 +                       IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
84392 +                       break;
84393 +               case DEBUG_MEM_ALLOC_TYPE_IO:
84394 +
84395 +                       DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
84396 +                       break;
84397 +               case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
84398 +                       VFreeWrapper(psCurrentRecord->pvCpuVAddr);
84399 +                       break;
84400 +               case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
84401 +
84402 +                       DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
84403 +                       break;
84404 +               case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
84405 +                       KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
84406 +                       break;
84407 +               default:
84408 +                       PVR_ASSERT(0);
84409 +       }
84410 +}
84411 +#endif
84412 +
84413 +
84414 +IMG_VOID
84415 +LinuxMMCleanup(IMG_VOID)
84416 +{
84417 +
84418 +#if defined(DEBUG_LINUX_MEM_AREAS)
84419 +    {
84420 +        if(g_LinuxMemAreaCount)
84421 +        {
84422 +            PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%ld bytes)",
84423 +                    __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
84424 +        }
84425 +
84426 +               List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords,
84427 +                                                                                       LinuxMMCleanup_MemAreas_ForEachCb);
84428 +
84429 +#ifdef PVR_PROC_USE_SEQ_FILE
84430 +               RemoveProcEntrySeq( g_SeqFileMemArea );
84431 +#else
84432 +        RemoveProcEntry("mem_areas");
84433 +#endif
84434 +    }
84435 +#endif
84436 +
84437 +
84438 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84439 +    {
84440 +
84441 +
84442 +               List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords,
84443 +                                                                               LinuxMMCleanup_MemRecords_ForEachVa);
84444 +
84445 +#ifdef PVR_PROC_USE_SEQ_FILE
84446 +               RemoveProcEntrySeq( g_SeqFileMemoryRecords );
84447 +#else
84448 +        RemoveProcEntry("meminfo");
84449 +#endif
84450 +
84451 +    }
84452 +#endif
84453 +
84454 +    if(psLinuxMemAreaCache)
84455 +    {
84456 +        KMemCacheDestroyWrapper(psLinuxMemAreaCache);
84457 +        psLinuxMemAreaCache=NULL;
84458 +    }
84459 +}
84460 +
84461 +
84462 +IMG_VOID *
84463 +_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
84464 +{
84465 +    IMG_VOID *pvRet;
84466 +    pvRet = kmalloc(ui32ByteSize, GFP_KERNEL);
84467 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84468 +    if(pvRet)
84469 +    {
84470 +        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
84471 +                               pvRet,
84472 +                               pvRet,
84473 +                               0,
84474 +                               NULL,
84475 +                               ui32ByteSize,
84476 +                               pszFileName,
84477 +                               ui32Line
84478 +                               );
84479 +    }
84480 +#else
84481 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84482 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84483 +#endif
84484 +    return pvRet;
84485 +}
84486 +
84487 +
84488 +IMG_VOID
84489 +_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
84490 +{
84491 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84492 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMALLOC, pvCpuVAddr, pszFileName,  ui32Line);
84493 +#else
84494 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84495 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84496 +#endif
84497 +    kfree(pvCpuVAddr);
84498 +}
84499 +
84500 +
84501 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84502 +static IMG_VOID
84503 +DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
84504 +                       IMG_VOID *pvKey,
84505 +                       IMG_VOID *pvCpuVAddr,
84506 +                       IMG_UINT32 ulCpuPAddr,
84507 +                       IMG_VOID *pvPrivateData,
84508 +                       IMG_UINT32 ui32Bytes,
84509 +                       IMG_CHAR *pszFileName,
84510 +                       IMG_UINT32 ui32Line)
84511 +{
84512 +    DEBUG_MEM_ALLOC_REC *psRecord;
84513 +
84514 +    LinuxLockMutex(&g_sDebugMutex);
84515 +
84516 +    psRecord = kmalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL);
84517 +
84518 +    psRecord->eAllocType = eAllocType;
84519 +    psRecord->pvKey = pvKey;
84520 +    psRecord->pvCpuVAddr = pvCpuVAddr;
84521 +    psRecord->ulCpuPAddr = ulCpuPAddr;
84522 +    psRecord->pvPrivateData = pvPrivateData;
84523 +    psRecord->pid = current->pid;
84524 +    psRecord->ui32Bytes = ui32Bytes;
84525 +    psRecord->pszFileName = pszFileName;
84526 +    psRecord->ui32Line = ui32Line;
84527 +
84528 +       List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord);
84529 +
84530 +    g_WaterMarkData[eAllocType] += ui32Bytes;
84531 +    if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
84532 +    {
84533 +        g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType];
84534 +    }
84535 +
84536 +    if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
84537 +       || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
84538 +       || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
84539 +       || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
84540 +    {
84541 +        g_SysRAMWaterMark += ui32Bytes;
84542 +        if(g_SysRAMWaterMark > g_SysRAMHighWaterMark)
84543 +        {
84544 +            g_SysRAMHighWaterMark = g_SysRAMWaterMark;
84545 +        }
84546 +    }
84547 +    else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
84548 +            || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
84549 +    {
84550 +        g_IOMemWaterMark += ui32Bytes;
84551 +        if(g_IOMemWaterMark > g_IOMemHighWaterMark)
84552 +        {
84553 +            g_IOMemHighWaterMark = g_IOMemWaterMark;
84554 +        }
84555 +    }
84556 +
84557 +    LinuxUnLockMutex(&g_sDebugMutex);
84558 +}
84559 +
84560 +
84561 +IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va)
84562 +{
84563 +       DEBUG_MEM_ALLOC_TYPE eAllocType;
84564 +       IMG_VOID *pvKey;
84565 +
84566 +       eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
84567 +       pvKey = va_arg(va, IMG_VOID*);
84568 +
84569 +       if(psCurrentRecord->eAllocType == eAllocType
84570 +               && psCurrentRecord->pvKey == pvKey)
84571 +       {
84572 +               eAllocType = psCurrentRecord->eAllocType;
84573 +               g_WaterMarkData[eAllocType] -= psCurrentRecord->ui32Bytes;
84574 +
84575 +               if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
84576 +                  || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
84577 +                  || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
84578 +                  || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
84579 +               {
84580 +                       g_SysRAMWaterMark -= psCurrentRecord->ui32Bytes;
84581 +               }
84582 +               else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
84583 +                               || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
84584 +               {
84585 +                       g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
84586 +               }
84587 +
84588 +               List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord);
84589 +               kfree(psCurrentRecord);
84590 +
84591 +               return IMG_TRUE;
84592 +       }
84593 +       else
84594 +       {
84595 +               return IMG_FALSE;
84596 +       }
84597 +}
84598 +
84599 +
84600 +static IMG_VOID
84601 +DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
84602 +{
84603 +    LinuxLockMutex(&g_sDebugMutex);
84604 +
84605 +
84606 +       if(!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
84607 +                                                                                               DebugMemAllocRecordRemove_AnyVaCb,
84608 +                                                                                               eAllocType,
84609 +                                                                                               pvKey))
84610 +       {
84611 +               PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with pvKey=%p (called from %s, line %d\n",
84612 +               __FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), pvKey,
84613 +               pszFileName, ui32Line));
84614 +       }
84615 +
84616 +    LinuxUnLockMutex(&g_sDebugMutex);
84617 +}
84618 +
84619 +
84620 +static IMG_CHAR *
84621 +DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
84622 +{
84623 +    IMG_CHAR *apszDebugMemoryRecordTypes[] = {
84624 +        "KMALLOC",
84625 +        "VMALLOC",
84626 +        "ALLOC_PAGES",
84627 +        "IOREMAP",
84628 +        "IO",
84629 +        "KMEM_CACHE_ALLOC"
84630 +    };
84631 +    return apszDebugMemoryRecordTypes[eAllocType];
84632 +}
84633 +#endif
84634 +
84635 +
84636 +
84637 +IMG_VOID *
84638 +_VMallocWrapper(IMG_UINT32 ui32Bytes,
84639 +                IMG_UINT32 ui32AllocFlags,
84640 +                IMG_CHAR *pszFileName,
84641 +                IMG_UINT32 ui32Line)
84642 +{
84643 +    pgprot_t PGProtFlags;
84644 +    IMG_VOID *pvRet;
84645 +
84646 +    switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
84647 +    {
84648 +        case PVRSRV_HAP_CACHED:
84649 +            PGProtFlags = PAGE_KERNEL;
84650 +            break;
84651 +        case PVRSRV_HAP_WRITECOMBINE:
84652 +            PGProtFlags = PGPROT_WC(PAGE_KERNEL);
84653 +            break;
84654 +        case PVRSRV_HAP_UNCACHED:
84655 +            PGProtFlags = PGPROT_UC(PAGE_KERNEL);
84656 +            break;
84657 +        default:
84658 +            PVR_DPF((PVR_DBG_ERROR,
84659 +                     "VMAllocWrapper: unknown mapping flags=0x%08lx",
84660 +                     ui32AllocFlags));
84661 +            dump_stack();
84662 +            return NULL;
84663 +    }
84664 +
84665 +
84666 +    pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
84667 +
84668 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84669 +    if(pvRet)
84670 +    {
84671 +        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC,
84672 +                               pvRet,
84673 +                               pvRet,
84674 +                               0,
84675 +                               NULL,
84676 +                               PAGE_ALIGN(ui32Bytes),
84677 +                               pszFileName,
84678 +                               ui32Line
84679 +                               );
84680 +    }
84681 +#else
84682 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84683 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84684 +#endif
84685 +
84686 +    return pvRet;
84687 +}
84688 +
84689 +
84690 +IMG_VOID
84691 +_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
84692 +{
84693 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84694 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, pszFileName, ui32Line);
84695 +#else
84696 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84697 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84698 +#endif
84699 +    vfree(pvCpuVAddr);
84700 +}
84701 +
84702 +
84703 +LinuxMemArea *
84704 +NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
84705 +{
84706 +    LinuxMemArea *psLinuxMemArea;
84707 +    IMG_VOID *pvCpuVAddr;
84708 +
84709 +    psLinuxMemArea = LinuxMemAreaStructAlloc();
84710 +    if(!psLinuxMemArea)
84711 +    {
84712 +        goto failed;
84713 +    }
84714 +
84715 +    pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
84716 +    if(!pvCpuVAddr)
84717 +    {
84718 +        goto failed;
84719 +    }
84720 +
84721 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
84722 +
84723 +    ReservePages(pvCpuVAddr, ui32Bytes);
84724 +#endif
84725 +
84726 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
84727 +    psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
84728 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
84729 +    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
84730 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
84731 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
84732 +
84733 +#if defined(DEBUG_LINUX_MEM_AREAS)
84734 +    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
84735 +#endif
84736 +
84737 +    return psLinuxMemArea;
84738 +
84739 +failed:
84740 +    PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
84741 +    if(psLinuxMemArea)
84742 +        LinuxMemAreaStructFree(psLinuxMemArea);
84743 +    return NULL;
84744 +}
84745 +
84746 +
84747 +IMG_VOID
84748 +FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
84749 +{
84750 +    PVR_ASSERT(psLinuxMemArea);
84751 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC);
84752 +    PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
84753 +
84754 +#if defined(DEBUG_LINUX_MEM_AREAS)
84755 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
84756 +#endif
84757 +
84758 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
84759 +       UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
84760 +                    psLinuxMemArea->ui32ByteSize);
84761 +#endif
84762 +
84763 +    PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
84764 +             __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
84765 +    VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
84766 +
84767 +    LinuxMemAreaStructFree(psLinuxMemArea);
84768 +}
84769 +
84770 +
84771 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
84772 +static IMG_VOID
84773 +ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
84774 +{
84775 +       IMG_VOID *pvPage;
84776 +       IMG_VOID *pvEnd = pvAddress + ui32Length;
84777 +
84778 +       for(pvPage = pvAddress; pvPage < pvEnd;  pvPage += PAGE_SIZE)
84779 +       {
84780 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
84781 +               SetPageReserved(vmalloc_to_page(pvPage));
84782 +#else
84783 +               mem_map_reserve(vmalloc_to_page(pvPage));
84784 +#endif
84785 +       }
84786 +}
84787 +
84788 +
84789 +static IMG_VOID
84790 +UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length)
84791 +{
84792 +       IMG_VOID *pvPage;
84793 +       IMG_VOID *pvEnd = pvAddress + ui32Length;
84794 +
84795 +       for(pvPage = pvAddress; pvPage < pvEnd;  pvPage += PAGE_SIZE)
84796 +       {
84797 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
84798 +               ClearPageReserved(vmalloc_to_page(pvPage));
84799 +#else
84800 +               mem_map_unreserve(vmalloc_to_page(pvPage));
84801 +#endif
84802 +       }
84803 +}
84804 +#endif
84805 +
84806 +
84807 +IMG_VOID *
84808 +_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
84809 +               IMG_UINT32 ui32Bytes,
84810 +               IMG_UINT32 ui32MappingFlags,
84811 +               IMG_CHAR *pszFileName,
84812 +               IMG_UINT32 ui32Line)
84813 +{
84814 +    IMG_VOID *pvIORemapCookie;
84815 +
84816 +    switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
84817 +    {
84818 +        case PVRSRV_HAP_CACHED:
84819 +           pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes);
84820 +            break;
84821 +        case PVRSRV_HAP_WRITECOMBINE:
84822 +           pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes);
84823 +            break;
84824 +        case PVRSRV_HAP_UNCACHED:
84825 +            pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes);
84826 +            break;
84827 +        default:
84828 +            PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags"));
84829 +            return NULL;
84830 +    }
84831 +
84832 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84833 +    if(pvIORemapCookie)
84834 +    {
84835 +        DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
84836 +                               pvIORemapCookie,
84837 +                               pvIORemapCookie,
84838 +                               BasePAddr.uiAddr,
84839 +                               NULL,
84840 +                               ui32Bytes,
84841 +                               pszFileName,
84842 +                               ui32Line
84843 +                               );
84844 +    }
84845 +#else
84846 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84847 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84848 +#endif
84849 +
84850 +    return pvIORemapCookie;
84851 +}
84852 +
84853 +
84854 +IMG_VOID
84855 +_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
84856 +{
84857 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
84858 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, pvIORemapCookie, pszFileName, ui32Line);
84859 +#else
84860 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
84861 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
84862 +#endif
84863 +    iounmap(pvIORemapCookie);
84864 +}
84865 +
84866 +
84867 +LinuxMemArea *
84868 +NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
84869 +                       IMG_UINT32 ui32Bytes,
84870 +                       IMG_UINT32 ui32AreaFlags)
84871 +{
84872 +    LinuxMemArea *psLinuxMemArea;
84873 +    IMG_VOID *pvIORemapCookie;
84874 +
84875 +    psLinuxMemArea = LinuxMemAreaStructAlloc();
84876 +    if(!psLinuxMemArea)
84877 +    {
84878 +        return NULL;
84879 +    }
84880 +
84881 +    pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags);
84882 +    if(!pvIORemapCookie)
84883 +    {
84884 +        LinuxMemAreaStructFree(psLinuxMemArea);
84885 +        return NULL;
84886 +    }
84887 +
84888 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP;
84889 +    psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie;
84890 +    psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr;
84891 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
84892 +    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
84893 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
84894 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
84895 +
84896 +#if defined(DEBUG_LINUX_MEM_AREAS)
84897 +    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
84898 +#endif
84899 +
84900 +    return psLinuxMemArea;
84901 +}
84902 +
84903 +
84904 +IMG_VOID
84905 +FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea)
84906 +{
84907 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP);
84908 +
84909 +#if defined(DEBUG_LINUX_MEM_AREAS)
84910 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
84911 +#endif
84912 +
84913 +    IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie);
84914 +
84915 +    LinuxMemAreaStructFree(psLinuxMemArea);
84916 +}
84917 +
84918 +
84919 +static IMG_BOOL
84920 +TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig)
84921 +{
84922 +       IMG_UINT32 ui32;
84923 +       IMG_UINT32 ui32AddrChk;
84924 +       IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
84925 +
84926 +       for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
84927 +               ui32 < ui32NumPages;
84928 +               ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr)
84929 +       {
84930 +               if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk)))
84931 +               {
84932 +                       break;
84933 +               }
84934 +       }
84935 +       if (ui32 == ui32NumPages)
84936 +       {
84937 +               return IMG_FALSE;
84938 +       }
84939 +
84940 +       if (!bPhysContig)
84941 +       {
84942 +               for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
84943 +                       ui32 < ui32NumPages;
84944 +                       ui32++, ui32AddrChk += PAGE_SIZE)
84945 +               {
84946 +                       if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
84947 +                       {
84948 +                               return IMG_FALSE;
84949 +                       }
84950 +               }
84951 +       }
84952 +
84953 +       return IMG_TRUE;
84954 +}
84955 +
84956 +LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags)
84957 +{
84958 +    LinuxMemArea *psLinuxMemArea;
84959 +
84960 +    psLinuxMemArea = LinuxMemAreaStructAlloc();
84961 +    if(!psLinuxMemArea)
84962 +    {
84963 +        return NULL;
84964 +    }
84965 +
84966 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV;
84967 +    psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr;
84968 +    psLinuxMemArea->uData.sExternalKV.bPhysContig = (IMG_BOOL)(bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, ui32Bytes, bPhysContig));
84969 +
84970 +    if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
84971 +    {
84972 +       psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr;
84973 +    }
84974 +    else
84975 +    {
84976 +       psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr;
84977 +    }
84978 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
84979 +    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
84980 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
84981 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
84982 +
84983 +#if defined(DEBUG_LINUX_MEM_AREAS)
84984 +    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
84985 +#endif
84986 +
84987 +    return psLinuxMemArea;
84988 +}
84989 +
84990 +
84991 +IMG_VOID
84992 +FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea)
84993 +{
84994 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV);
84995 +
84996 +#if defined(DEBUG_LINUX_MEM_AREAS)
84997 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
84998 +#endif
84999 +
85000 +    LinuxMemAreaStructFree(psLinuxMemArea);
85001 +}
85002 +
85003 +
85004 +LinuxMemArea *
85005 +NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
85006 +                  IMG_UINT32 ui32Bytes,
85007 +                  IMG_UINT32 ui32AreaFlags)
85008 +{
85009 +    LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc();
85010 +    if(!psLinuxMemArea)
85011 +    {
85012 +        return NULL;
85013 +    }
85014 +
85015 +
85016 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO;
85017 +    psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr;
85018 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
85019 +    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
85020 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
85021 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
85022 +
85023 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85024 +    DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO,
85025 +                           (IMG_VOID *)BasePAddr.uiAddr,
85026 +                           0,
85027 +                           BasePAddr.uiAddr,
85028 +                           NULL,
85029 +                           ui32Bytes,
85030 +                           "unknown",
85031 +                           0
85032 +                           );
85033 +#endif
85034 +
85035 +#if defined(DEBUG_LINUX_MEM_AREAS)
85036 +    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
85037 +#endif
85038 +
85039 +    return psLinuxMemArea;
85040 +}
85041 +
85042 +
85043 +IMG_VOID
85044 +FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea)
85045 +{
85046 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO);
85047 +
85048 +#if defined(DEBUG_LINUX_MEM_AREAS)
85049 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
85050 +#endif
85051 +
85052 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85053 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO,
85054 +                              (IMG_VOID *)psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, __FILE__, __LINE__);
85055 +#endif
85056 +
85057 +
85058 +
85059 +    LinuxMemAreaStructFree(psLinuxMemArea);
85060 +}
85061 +
85062 +
85063 +LinuxMemArea *
85064 +NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
85065 +{
85066 +    LinuxMemArea *psLinuxMemArea;
85067 +    IMG_UINT32 ui32PageCount;
85068 +    struct page **pvPageList;
85069 +    IMG_HANDLE hBlockPageList;
85070 +    IMG_INT32 i;
85071 +    PVRSRV_ERROR eError;
85072 +
85073 +    psLinuxMemArea = LinuxMemAreaStructAlloc();
85074 +    if(!psLinuxMemArea)
85075 +    {
85076 +        goto failed_area_alloc;
85077 +    }
85078 +
85079 +    ui32PageCount = RANGE_TO_PAGES(ui32Bytes);
85080 +    eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList,
85081 +                                                       "Array of pages");
85082 +    if(eError != PVRSRV_OK)
85083 +    {
85084 +        goto failed_page_list_alloc;
85085 +    }
85086 +
85087 +    for(i=0; i<(IMG_INT32)ui32PageCount; i++)
85088 +    {
85089 +        pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
85090 +        if(!pvPageList[i])
85091 +        {
85092 +            goto failed_alloc_pages;
85093 +        }
85094 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
85095 +
85096 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
85097 +       SetPageReserved(pvPageList[i]);
85098 +#else
85099 +        mem_map_reserve(pvPageList[i]);
85100 +#endif
85101 +#endif
85102 +
85103 +    }
85104 +
85105 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85106 +    DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
85107 +                           pvPageList,
85108 +                           0,
85109 +                           0,
85110 +                           NULL,
85111 +                           PAGE_ALIGN(ui32Bytes),
85112 +                           "unknown",
85113 +                           0
85114 +                           );
85115 +#endif
85116 +
85117 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
85118 +    psLinuxMemArea->uData.sPageList.pvPageList = pvPageList;
85119 +    psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
85120 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
85121 +    psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
85122 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
85123 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
85124 +
85125 +#if defined(DEBUG_LINUX_MEM_AREAS)
85126 +    DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
85127 +#endif
85128 +
85129 +    return psLinuxMemArea;
85130 +
85131 +failed_alloc_pages:
85132 +    for(i--; i >= 0; i--)
85133 +    {
85134 +        __free_pages(pvPageList[i], 0);
85135 +    }
85136 +    (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
85137 +       psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
85138 +failed_page_list_alloc:
85139 +    LinuxMemAreaStructFree(psLinuxMemArea);
85140 +failed_area_alloc:
85141 +    PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
85142 +
85143 +    return NULL;
85144 +}
85145 +
85146 +
85147 +IMG_VOID
85148 +FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
85149 +{
85150 +    IMG_UINT32 ui32PageCount;
85151 +    struct page **pvPageList;
85152 +    IMG_HANDLE hBlockPageList;
85153 +    IMG_INT32 i;
85154 +
85155 +    PVR_ASSERT(psLinuxMemArea);
85156 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
85157 +
85158 +#if defined(DEBUG_LINUX_MEM_AREAS)
85159 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
85160 +#endif
85161 +
85162 +    ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
85163 +    pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
85164 +    hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
85165 +
85166 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85167 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__);
85168 +#endif
85169 +
85170 +    for(i=0;i<(IMG_INT32)ui32PageCount;i++)
85171 +    {
85172 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
85173 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
85174 +        ClearPageReserved(pvPageList[i]);
85175 +#else
85176 +        mem_map_reserve(pvPageList[i]);
85177 +#endif
85178 +#endif
85179 +        __free_pages(pvPageList[i], 0);
85180 +    }
85181 +
85182 +    (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
85183 +       psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
85184 +
85185 +    LinuxMemAreaStructFree(psLinuxMemArea);
85186 +}
85187 +
85188 +
85189 +struct page*
85190 +LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea,
85191 +                         IMG_UINT32 ui32ByteOffset)
85192 +{
85193 +    IMG_UINT32 ui32PageIndex;
85194 +    IMG_CHAR *pui8Addr;
85195 +
85196 +    switch(psLinuxMemArea->eAreaType)
85197 +    {
85198 +        case LINUX_MEM_AREA_ALLOC_PAGES:
85199 +            ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
85200 +            return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
85201 +
85202 +        case LINUX_MEM_AREA_VMALLOC:
85203 +            pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
85204 +            pui8Addr += ui32ByteOffset;
85205 +            return vmalloc_to_page(pui8Addr);
85206 +
85207 +        case LINUX_MEM_AREA_SUB_ALLOC:
85208 +
85209 +            return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
85210 +                                            psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
85211 +                                             + ui32ByteOffset);
85212 +        default:
85213 +            PVR_DPF((PVR_DBG_ERROR,
85214 +                    "%s: Unsupported request for struct page from LinuxMemArea with type=%s",
85215 +                    __FUNCTION__, LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType)));
85216 +            return NULL;
85217 +    }
85218 +}
85219 +
85220 +
85221 +LinuxKMemCache *
85222 +KMemCacheCreateWrapper(IMG_CHAR *pszName,
85223 +                       size_t Size,
85224 +                       size_t Align,
85225 +                       IMG_UINT32 ui32Flags)
85226 +{
85227 +#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS)
85228 +    ui32Flags |= SLAB_POISON|SLAB_RED_ZONE;
85229 +#endif
85230 +    return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL
85231 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
85232 +                               , NULL
85233 +#endif
85234 +                           );
85235 +}
85236 +
85237 +
85238 +IMG_VOID
85239 +KMemCacheDestroyWrapper(LinuxKMemCache *psCache)
85240 +{
85241 +    kmem_cache_destroy(psCache);
85242 +}
85243 +
85244 +
85245 +IMG_VOID *
85246 +_KMemCacheAllocWrapper(LinuxKMemCache *psCache,
85247 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
85248 +                      gfp_t Flags,
85249 +#else
85250 +                      IMG_INT Flags,
85251 +#endif
85252 +                      IMG_CHAR *pszFileName,
85253 +                      IMG_UINT32 ui32Line)
85254 +{
85255 +    IMG_VOID *pvRet;
85256 +
85257 +    pvRet = kmem_cache_alloc(psCache, Flags);
85258 +
85259 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85260 +    DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
85261 +                           pvRet,
85262 +                           pvRet,
85263 +                           0,
85264 +                           psCache,
85265 +                           kmem_cache_size(psCache),
85266 +                           pszFileName,
85267 +                           ui32Line
85268 +                           );
85269 +#else
85270 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
85271 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
85272 +#endif
85273 +
85274 +    return pvRet;
85275 +}
85276 +
85277 +
85278 +IMG_VOID
85279 +_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
85280 +{
85281 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85282 +    DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
85283 +#else
85284 +    PVR_UNREFERENCED_PARAMETER(pszFileName);
85285 +    PVR_UNREFERENCED_PARAMETER(ui32Line);
85286 +#endif
85287 +
85288 +    kmem_cache_free(psCache, pvObject);
85289 +}
85290 +
85291 +
85292 +const IMG_CHAR *
85293 +KMemCacheNameWrapper(LinuxKMemCache *psCache)
85294 +{
85295 +    PVR_UNREFERENCED_PARAMETER(psCache);
85296 +
85297 +
85298 +    return "";
85299 +}
85300 +
85301 +
85302 +LinuxMemArea *
85303 +NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
85304 +                   IMG_UINT32 ui32ByteOffset,
85305 +                   IMG_UINT32 ui32Bytes)
85306 +{
85307 +    LinuxMemArea *psLinuxMemArea;
85308 +
85309 +    PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize);
85310 +
85311 +    psLinuxMemArea = LinuxMemAreaStructAlloc();
85312 +    if(!psLinuxMemArea)
85313 +    {
85314 +        return NULL;
85315 +    }
85316 +
85317 +    psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC;
85318 +    psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea;
85319 +    psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset;
85320 +    psLinuxMemArea->ui32ByteSize = ui32Bytes;
85321 +    psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags;
85322 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
85323 +    INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
85324 +
85325 +#if defined(DEBUG_LINUX_MEM_AREAS)
85326 +    {
85327 +        DEBUG_LINUX_MEM_AREA_REC *psParentRecord;
85328 +        psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea);
85329 +        DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags);
85330 +    }
85331 +#endif
85332 +
85333 +    return psLinuxMemArea;
85334 +}
85335 +
85336 +
85337 +IMG_VOID
85338 +FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea)
85339 +{
85340 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
85341 +
85342 +#if defined(DEBUG_LINUX_MEM_AREAS)
85343 +    DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
85344 +#endif
85345 +
85346 +
85347 +
85348 +    LinuxMemAreaStructFree(psLinuxMemArea);
85349 +}
85350 +
85351 +
85352 +static LinuxMemArea *
85353 +LinuxMemAreaStructAlloc(IMG_VOID)
85354 +{
85355 +#if 0
85356 +    LinuxMemArea *psLinuxMemArea;
85357 +    psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL);
85358 +    printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
85359 +    dump_stack();
85360 +    return psLinuxMemArea;
85361 +#else
85362 +    return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL);
85363 +#endif
85364 +}
85365 +
85366 +
85367 +static IMG_VOID
85368 +LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
85369 +{
85370 +    KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea);
85371 +
85372 +
85373 +}
85374 +
85375 +
85376 +IMG_VOID
85377 +LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea)
85378 +{
85379 +    switch(psLinuxMemArea->eAreaType)
85380 +    {
85381 +        case LINUX_MEM_AREA_VMALLOC:
85382 +            FreeVMallocLinuxMemArea(psLinuxMemArea);
85383 +            break;
85384 +        case LINUX_MEM_AREA_ALLOC_PAGES:
85385 +            FreeAllocPagesLinuxMemArea(psLinuxMemArea);
85386 +            break;
85387 +        case LINUX_MEM_AREA_IOREMAP:
85388 +            FreeIORemapLinuxMemArea(psLinuxMemArea);
85389 +            break;
85390 +       case LINUX_MEM_AREA_EXTERNAL_KV:
85391 +           FreeExternalKVLinuxMemArea(psLinuxMemArea);
85392 +           break;
85393 +        case LINUX_MEM_AREA_IO:
85394 +            FreeIOLinuxMemArea(psLinuxMemArea);
85395 +            break;
85396 +        case LINUX_MEM_AREA_SUB_ALLOC:
85397 +            FreeSubLinuxMemArea(psLinuxMemArea);
85398 +            break;
85399 +        default:
85400 +            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n",
85401 +                     __FUNCTION__, psLinuxMemArea->eAreaType));
85402 +            break;
85403 +    }
85404 +}
85405 +
85406 +
85407 +#if defined(DEBUG_LINUX_MEM_AREAS)
85408 +static IMG_VOID
85409 +DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
85410 +{
85411 +    DEBUG_LINUX_MEM_AREA_REC *psNewRecord;
85412 +    const IMG_CHAR *pi8FlagsString;
85413 +
85414 +    LinuxLockMutex(&g_sDebugMutex);
85415 +
85416 +    if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
85417 +    {
85418 +        g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize;
85419 +        if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
85420 +        {
85421 +            g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark;
85422 +        }
85423 +    }
85424 +    g_LinuxMemAreaCount++;
85425 +
85426 +
85427 +    psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
85428 +    if(psNewRecord)
85429 +    {
85430 +
85431 +        psNewRecord->psLinuxMemArea = psLinuxMemArea;
85432 +        psNewRecord->ui32Flags = ui32Flags;
85433 +        psNewRecord->pid = current->pid;
85434 +
85435 +               List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord);
85436 +    }
85437 +    else
85438 +    {
85439 +        PVR_DPF((PVR_DBG_ERROR,
85440 +                 "%s: failed to allocate linux memory area record.",
85441 +                 __FUNCTION__));
85442 +    }
85443 +
85444 +
85445 +    pi8FlagsString = HAPFlagsToString(ui32Flags);
85446 +    if(strstr(pi8FlagsString, "UNKNOWN"))
85447 +    {
85448 +        PVR_DPF((PVR_DBG_ERROR,
85449 +                 "%s: Unexpected flags (0x%08lx) associated with psLinuxMemArea @ 0x%08lx",
85450 +                 __FUNCTION__,
85451 +                 ui32Flags,
85452 +                 psLinuxMemArea));
85453 +
85454 +    }
85455 +
85456 +    LinuxUnLockMutex(&g_sDebugMutex);
85457 +}
85458 +
85459 +
85460 +
85461 +IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord,
85462 +                                                                                               va_list va)
85463 +{
85464 +       LinuxMemArea *psLinuxMemArea;
85465 +
85466 +       psLinuxMemArea = va_arg(va, LinuxMemArea*);
85467 +       if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
85468 +       {
85469 +               return psCurrentRecord;
85470 +       }
85471 +       else
85472 +       {
85473 +               return IMG_NULL;
85474 +       }
85475 +}
85476 +
85477 +
85478 +static DEBUG_LINUX_MEM_AREA_REC *
85479 +DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea)
85480 +{
85481 +    DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
85482 +
85483 +    LinuxLockMutex(&g_sDebugMutex);
85484 +       psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
85485 +                                                                                                               MatchLinuxMemArea_AnyVaCb,
85486 +                                                                                                               psLinuxMemArea);
85487 +
85488 +    LinuxUnLockMutex(&g_sDebugMutex);
85489 +
85490 +    return psCurrentRecord;
85491 +}
85492 +
85493 +
85494 +static IMG_VOID
85495 +DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
85496 +{
85497 +    DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
85498 +
85499 +    LinuxLockMutex(&g_sDebugMutex);
85500 +
85501 +    if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
85502 +    {
85503 +        g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
85504 +    }
85505 +    g_LinuxMemAreaCount--;
85506 +
85507 +
85508 +       psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
85509 +                                                                                                               MatchLinuxMemArea_AnyVaCb,
85510 +                                                                                                               psLinuxMemArea);
85511 +       if(psCurrentRecord)
85512 +       {
85513 +
85514 +               List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
85515 +               kfree(psCurrentRecord);
85516 +       }
85517 +       else
85518 +       {
85519 +               PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n",
85520 +                    __FUNCTION__, psLinuxMemArea));
85521 +       }
85522 +
85523 +    LinuxUnLockMutex(&g_sDebugMutex);
85524 +}
85525 +#endif
85526 +
85527 +
85528 +IMG_VOID *
85529 +LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
85530 +{
85531 +    switch(psLinuxMemArea->eAreaType)
85532 +    {
85533 +        case LINUX_MEM_AREA_VMALLOC:
85534 +            return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
85535 +        case LINUX_MEM_AREA_IOREMAP:
85536 +            return psLinuxMemArea->uData.sIORemap.pvIORemapCookie;
85537 +       case LINUX_MEM_AREA_EXTERNAL_KV:
85538 +           return psLinuxMemArea->uData.sExternalKV.pvExternalKV;
85539 +        case LINUX_MEM_AREA_SUB_ALLOC:
85540 +        {
85541 +            IMG_CHAR *pAddr =
85542 +                LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
85543 +            if(!pAddr)
85544 +            {
85545 +                return NULL;
85546 +            }
85547 +            return pAddr + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
85548 +        }
85549 +        default:
85550 +            return NULL;
85551 +    }
85552 +}
85553 +
85554 +
85555 +IMG_CPU_PHYADDR
85556 +LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
85557 +{
85558 +    IMG_CPU_PHYADDR CpuPAddr;
85559 +
85560 +    CpuPAddr.uiAddr = 0;
85561 +
85562 +    switch(psLinuxMemArea->eAreaType)
85563 +    {
85564 +        case LINUX_MEM_AREA_IOREMAP:
85565 +        {
85566 +            CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr;
85567 +            CpuPAddr.uiAddr += ui32ByteOffset;
85568 +            break;
85569 +        }
85570 +       case LINUX_MEM_AREA_EXTERNAL_KV:
85571 +       {
85572 +           if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
85573 +           {
85574 +               CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr);
85575 +               CpuPAddr.uiAddr += ui32ByteOffset;
85576 +           }
85577 +           else
85578 +           {
85579 +               IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
85580 +               IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageIndex];
85581 +
85582 +               CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
85583 +                CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
85584 +           }
85585 +            break;
85586 +       }
85587 +        case LINUX_MEM_AREA_IO:
85588 +        {
85589 +            CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr;
85590 +            CpuPAddr.uiAddr += ui32ByteOffset;
85591 +            break;
85592 +        }
85593 +        case LINUX_MEM_AREA_VMALLOC:
85594 +        {
85595 +            IMG_CHAR *pCpuVAddr;
85596 +            pCpuVAddr =
85597 +                (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
85598 +            pCpuVAddr += ui32ByteOffset;
85599 +            CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr);
85600 +            break;
85601 +        }
85602 +        case LINUX_MEM_AREA_ALLOC_PAGES:
85603 +        {
85604 +            struct page *page;
85605 +            IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
85606 +            page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
85607 +            CpuPAddr.uiAddr = page_to_phys(page);
85608 +            CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
85609 +            break;
85610 +        }
85611 +        case LINUX_MEM_AREA_SUB_ALLOC:
85612 +        {
85613 +            CpuPAddr =
85614 +                OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea,
85615 +                                      psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset
85616 +                                        + ui32ByteOffset);
85617 +            break;
85618 +        }
85619 +        default:
85620 +            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
85621 +                     __FUNCTION__, psLinuxMemArea->eAreaType));
85622 +            break;
85623 +   }
85624 +
85625 +    PVR_ASSERT(CpuPAddr.uiAddr);
85626 +    return CpuPAddr;
85627 +}
85628 +
85629 +
85630 +IMG_BOOL
85631 +LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
85632 +{
85633 +    switch(psLinuxMemArea->eAreaType)
85634 +    {
85635 +        case LINUX_MEM_AREA_IOREMAP:
85636 +        case LINUX_MEM_AREA_IO:
85637 +            return IMG_TRUE;
85638 +
85639 +       case LINUX_MEM_AREA_EXTERNAL_KV:
85640 +           return psLinuxMemArea->uData.sExternalKV.bPhysContig;
85641 +
85642 +        case LINUX_MEM_AREA_VMALLOC:
85643 +        case LINUX_MEM_AREA_ALLOC_PAGES:
85644 +           return IMG_FALSE;
85645 +
85646 +        case LINUX_MEM_AREA_SUB_ALLOC:
85647 +
85648 +           return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
85649 +
85650 +        default:
85651 +            PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
85652 +                     __FUNCTION__, psLinuxMemArea->eAreaType));
85653 +           break;
85654 +    }
85655 +    return IMG_FALSE;
85656 +}
85657 +
85658 +
85659 +const IMG_CHAR *
85660 +LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
85661 +{
85662 +
85663 +    switch(eMemAreaType)
85664 +    {
85665 +        case LINUX_MEM_AREA_IOREMAP:
85666 +            return "LINUX_MEM_AREA_IOREMAP";
85667 +       case LINUX_MEM_AREA_EXTERNAL_KV:
85668 +           return "LINUX_MEM_AREA_EXTERNAL_KV";
85669 +        case LINUX_MEM_AREA_IO:
85670 +            return "LINUX_MEM_AREA_IO";
85671 +        case LINUX_MEM_AREA_VMALLOC:
85672 +            return "LINUX_MEM_AREA_VMALLOC";
85673 +        case LINUX_MEM_AREA_SUB_ALLOC:
85674 +            return "LINUX_MEM_AREA_SUB_ALLOC";
85675 +        case LINUX_MEM_AREA_ALLOC_PAGES:
85676 +            return "LINUX_MEM_AREA_ALLOC_PAGES";
85677 +        default:
85678 +            PVR_ASSERT(0);
85679 +    }
85680 +
85681 +    return "";
85682 +}
85683 +
85684 +
85685 +#ifdef PVR_PROC_USE_SEQ_FILE
85686 +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85687 +static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start)
85688 +{
85689 +       if(start)
85690 +       {
85691 +           LinuxLockMutex(&g_sDebugMutex);
85692 +       }
85693 +       else
85694 +       {
85695 +           LinuxUnLockMutex(&g_sDebugMutex);
85696 +       }
85697 +}
85698 +#endif
85699 +#endif
85700 +
85701 +#if defined(DEBUG_LINUX_MEM_AREAS)
85702 +
85703 +IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va)
85704 +{
85705 +       off_t *pOff = va_arg(va, off_t*);
85706 +       if (--(*pOff))
85707 +       {
85708 +               return IMG_NULL;
85709 +       }
85710 +       else
85711 +       {
85712 +               return psNode;
85713 +       }
85714 +}
85715 +
85716 +#ifdef PVR_PROC_USE_SEQ_FILE
85717 +
85718 +static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off)
85719 +{
85720 +    DEBUG_LINUX_MEM_AREA_REC *psRecord;
85721 +       psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
85722 +                               List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
85723 +                                                                                                       DecOffMemAreaRec_AnyVaCb,
85724 +                                                                                                       &off);
85725 +       return (void*)psRecord;
85726 +}
85727 +
85728 +static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
85729 +{
85730 +    DEBUG_LINUX_MEM_AREA_REC *psRecord;
85731 +       if(!off)
85732 +       {
85733 +               return PVR_PROC_SEQ_START_TOKEN;
85734 +       }
85735 +
85736 +       psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
85737 +                               List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
85738 +                                                                                                       DecOffMemAreaRec_AnyVaCb,
85739 +                                                                                                       &off);
85740 +       return (void*)psRecord;
85741 +}
85742 +
85743 +
85744 +static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
85745 +{
85746 +    DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el;
85747 +       if(el == PVR_PROC_SEQ_START_TOKEN)
85748 +       {
85749 +
85750 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
85751 +        seq_printf( sfile,
85752 +                                 "Number of Linux Memory Areas: %lu\n"
85753 +                          "At the current water mark these areas correspond to %lu bytes (excluding SUB areas)\n"
85754 +                          "At the highest water mark these areas corresponded to %lu bytes (excluding SUB areas)\n"
85755 +                          "\nDetails for all Linux Memory Areas:\n"
85756 +                          "%s %-24s %s %s %-8s %-5s %s\n",
85757 +                          g_LinuxMemAreaCount,
85758 +                          g_LinuxMemAreaWaterMark,
85759 +                          g_LinuxMemAreaHighWaterMark,
85760 +                          "psLinuxMemArea",
85761 +                          "LinuxMemType",
85762 +                          "CpuVAddr",
85763 +                          "CpuPAddr",
85764 +                          "Bytes",
85765 +                          "Pid",
85766 +                          "Flags"
85767 +                         );
85768 +#else
85769 +        seq_printf( sfile,
85770 +                          "<mem_areas_header>\n"
85771 +                          "\t<count>%lu</count>\n"
85772 +                          "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%lu\"/>\n"
85773 +                          "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%lu\"/>\n"
85774 +                          "</mem_areas_header>\n",
85775 +                          g_LinuxMemAreaCount,
85776 +                          g_LinuxMemAreaWaterMark,
85777 +                          g_LinuxMemAreaHighWaterMark
85778 +                         );
85779 +#endif
85780 +               return;
85781 +       }
85782 +
85783 +        seq_printf( sfile,
85784 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
85785 +                       "%8p       %-24s %8p %08lx %-8ld %-5u %08lx=(%s)\n",
85786 +#else
85787 +                       "<linux_mem_area>\n"
85788 +                       "\t<pointer>%8p</pointer>\n"
85789 +                       "\t<type>%s</type>\n"
85790 +                       "\t<cpu_virtual>%8p</cpu_virtual>\n"
85791 +                       "\t<cpu_physical>%08lx</cpu_physical>\n"
85792 +                       "\t<bytes>%ld</bytes>\n"
85793 +                       "\t<pid>%u</pid>\n"
85794 +                       "\t<flags>%08lx</flags>\n"
85795 +                       "\t<flags_string>%s</flags_string>\n"
85796 +                       "</linux_mem_area>\n",
85797 +#endif
85798 +                       psRecord->psLinuxMemArea,
85799 +                       LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType),
85800 +                       LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea),
85801 +                       LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr,
85802 +                       psRecord->psLinuxMemArea->ui32ByteSize,
85803 +                       psRecord->pid,
85804 +                       psRecord->ui32Flags,
85805 +                       HAPFlagsToString(psRecord->ui32Flags)
85806 +                      );
85807 +
85808 +}
85809 +
85810 +#else
85811 +
85812 +static off_t
85813 +printLinuxMemAreaRecords(IMG_CHAR * buffer, size_t count, off_t off)
85814 +{
85815 +    DEBUG_LINUX_MEM_AREA_REC *psRecord;
85816 +    off_t Ret;
85817 +
85818 +    LinuxLockMutex(&g_sDebugMutex);
85819 +
85820 +    if(!off)
85821 +    {
85822 +        if(count < 500)
85823 +        {
85824 +            Ret = 0;
85825 +            goto unlock_and_return;
85826 +        }
85827 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
85828 +        Ret = printAppend(buffer, count, 0,
85829 +                          "Number of Linux Memory Areas: %lu\n"
85830 +                          "At the current water mark these areas correspond to %lu bytes (excluding SUB areas)\n"
85831 +                          "At the highest water mark these areas corresponded to %lu bytes (excluding SUB areas)\n"
85832 +                          "\nDetails for all Linux Memory Areas:\n"
85833 +                          "%s %-24s %s %s %-8s %-5s %s\n",
85834 +                          g_LinuxMemAreaCount,
85835 +                          g_LinuxMemAreaWaterMark,
85836 +                          g_LinuxMemAreaHighWaterMark,
85837 +                          "psLinuxMemArea",
85838 +                          "LinuxMemType",
85839 +                          "CpuVAddr",
85840 +                          "CpuPAddr",
85841 +                          "Bytes",
85842 +                          "Pid",
85843 +                          "Flags"
85844 +                         );
85845 +#else
85846 +        Ret = printAppend(buffer, count, 0,
85847 +                          "<mem_areas_header>\n"
85848 +                          "\t<count>%lu</count>\n"
85849 +                          "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%lu\"/>\n"
85850 +                          "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%lu\"/>\n"
85851 +                          "</mem_areas_header>\n",
85852 +                          g_LinuxMemAreaCount,
85853 +                          g_LinuxMemAreaWaterMark,
85854 +                          g_LinuxMemAreaHighWaterMark
85855 +                         );
85856 +#endif
85857 +        goto unlock_and_return;
85858 +    }
85859 +
85860 +       psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
85861 +                               List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
85862 +                                                                                                       DecOffMemAreaRec_AnyVaCb,
85863 +                                                                                                       &off);
85864 +
85865 +    if(!psRecord)
85866 +    {
85867 +        Ret = END_OF_FILE;
85868 +        goto unlock_and_return;
85869 +    }
85870 +
85871 +    if(count < 500)
85872 +    {
85873 +        Ret = 0;
85874 +        goto unlock_and_return;
85875 +    }
85876 +
85877 +    Ret =  printAppend(buffer, count, 0,
85878 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
85879 +                       "%8p       %-24s %8p %08lx %-8ld %-5u %08lx=(%s)\n",
85880 +#else
85881 +                       "<linux_mem_area>\n"
85882 +                       "\t<pointer>%8p</pointer>\n"
85883 +                       "\t<type>%s</type>\n"
85884 +                       "\t<cpu_virtual>%8p</cpu_virtual>\n"
85885 +                       "\t<cpu_physical>%08lx</cpu_physical>\n"
85886 +                       "\t<bytes>%ld</bytes>\n"
85887 +                       "\t<pid>%u</pid>\n"
85888 +                       "\t<flags>%08lx</flags>\n"
85889 +                       "\t<flags_string>%s</flags_string>\n"
85890 +                       "</linux_mem_area>\n",
85891 +#endif
85892 +                       psRecord->psLinuxMemArea,
85893 +                       LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType),
85894 +                       LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea),
85895 +                       LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr,
85896 +                       psRecord->psLinuxMemArea->ui32ByteSize,
85897 +                       psRecord->pid,
85898 +                       psRecord->ui32Flags,
85899 +                       HAPFlagsToString(psRecord->ui32Flags)
85900 +                      );
85901 +
85902 +unlock_and_return:
85903 +    LinuxUnLockMutex(&g_sDebugMutex);
85904 +    return Ret;
85905 +}
85906 +#endif
85907 +
85908 +#endif
85909 +
85910 +
85911 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
85912 +
85913 +IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va)
85914 +{
85915 +       off_t *pOff = va_arg(va, off_t*);
85916 +       if (--(*pOff))
85917 +       {
85918 +               return IMG_NULL;
85919 +       }
85920 +       else
85921 +       {
85922 +               return psNode;
85923 +       }
85924 +}
85925 +
85926 +
85927 +#ifdef PVR_PROC_USE_SEQ_FILE
85928 +
85929 +static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off)
85930 +{
85931 +    DEBUG_MEM_ALLOC_REC *psRecord;
85932 +       psRecord = (DEBUG_MEM_ALLOC_REC*)
85933 +               List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
85934 +                                                                               DecOffMemAllocRec_AnyVaCb,
85935 +                                                                               &off);
85936 +#if defined(DEBUG_LINUX_XML_PROC_FILES)
85937 +       if(!psRecord)
85938 +       {
85939 +               seq_printf( sfile, "</meminfo>\n");
85940 +       }
85941 +#endif
85942 +
85943 +       return (void*)psRecord;
85944 +}
85945 +
85946 +static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
85947 +{
85948 +    DEBUG_MEM_ALLOC_REC *psRecord;
85949 +       if(!off)
85950 +       {
85951 +               return PVR_PROC_SEQ_START_TOKEN;
85952 +       }
85953 +
85954 +       psRecord = (DEBUG_MEM_ALLOC_REC*)
85955 +               List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
85956 +                                                                               DecOffMemAllocRec_AnyVaCb,
85957 +                                                                               &off);
85958 +
85959 +#if defined(DEBUG_LINUX_XML_PROC_FILES)
85960 +       if(!psRecord)
85961 +       {
85962 +               seq_printf( sfile, "</meminfo>\n");
85963 +       }
85964 +#endif
85965 +
85966 +       return (void*)psRecord;
85967 +}
85968 +
85969 +static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
85970 +{
85971 +    DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
85972 +       if(el == PVR_PROC_SEQ_START_TOKEN)
85973 +       {
85974 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
85975 +
85976 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85977 +                           "Current Water Mark of bytes allocated via kmalloc",
85978 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
85979 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85980 +                           "Highest Water Mark of bytes allocated via kmalloc",
85981 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
85982 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85983 +                           "Current Water Mark of bytes allocated via vmalloc",
85984 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
85985 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85986 +                           "Highest Water Mark of bytes allocated via vmalloc",
85987 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
85988 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85989 +                           "Current Water Mark of bytes allocated via alloc_pages",
85990 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
85991 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85992 +                           "Highest Water Mark of bytes allocated via alloc_pages",
85993 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
85994 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85995 +                           "Current Water Mark of bytes allocated via ioremap",
85996 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
85997 +        seq_printf( sfile, "%-60s: %ld bytes\n",
85998 +                           "Highest Water Mark of bytes allocated via ioremap",
85999 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86000 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86001 +                           "Current Water Mark of bytes reserved for \"IO\" memory areas",
86002 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86003 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86004 +                           "Highest Water Mark of bytes allocated for \"IO\" memory areas",
86005 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86006 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86007 +                           "Current Water Mark of bytes allocated via kmem_cache_alloc",
86008 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86009 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86010 +                           "Highest Water Mark of bytes allocated via kmem_cache_alloc",
86011 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86012 +        seq_printf( sfile, "\n");
86013 +
86014 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86015 +                           "The Current Water Mark for memory allocated from system RAM",
86016 +                           g_SysRAMWaterMark);
86017 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86018 +                           "The Highest Water Mark for memory allocated from system RAM",
86019 +                           g_SysRAMHighWaterMark);
86020 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86021 +                           "The Current Water Mark for memory allocated from IO memory",
86022 +                           g_IOMemWaterMark);
86023 +        seq_printf( sfile, "%-60s: %ld bytes\n",
86024 +                           "The Highest Water Mark for memory allocated from IO memory",
86025 +                           g_IOMemHighWaterMark);
86026 +
86027 +        seq_printf( sfile, "\n");
86028 +
86029 +               seq_printf( sfile, "Details for all known allocations:\n"
86030 +                           "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
86031 +                           "Type",
86032 +                           "CpuVAddr",
86033 +                           "CpuPAddr",
86034 +                           "Bytes",
86035 +                           "PID",
86036 +                           "PrivateData",
86037 +                           "Filename:Line");
86038 +
86039 +#else
86040 +
86041 +
86042 +               seq_printf( sfile, "<meminfo>\n<meminfo_header>\n");
86043 +               seq_printf( sfile,
86044 +                           "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%ld\"/>\n",
86045 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86046 +               seq_printf( sfile,
86047 +                           "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%ld\"/>\n",
86048 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86049 +               seq_printf( sfile,
86050 +                           "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%ld\"/>\n",
86051 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86052 +               seq_printf( sfile,
86053 +                           "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%ld\"/>\n",
86054 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86055 +               seq_printf( sfile,
86056 +                           "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%ld\"/>\n",
86057 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86058 +               seq_printf( sfile,
86059 +                           "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%ld\"/>\n",
86060 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86061 +               seq_printf( sfile,
86062 +                           "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%ld\"/>\n",
86063 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86064 +               seq_printf( sfile,
86065 +                           "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%ld\"/>\n",
86066 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86067 +               seq_printf( sfile,
86068 +                           "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%ld\"/>\n",
86069 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86070 +               seq_printf( sfile,
86071 +                           "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%ld\"/>\n",
86072 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86073 +               seq_printf( sfile,
86074 +                           "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%ld\"/>\n",
86075 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86076 +               seq_printf( sfile,
86077 +                           "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%ld\"/>\n",
86078 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86079 +               seq_printf( sfile,"\n" );
86080 +
86081 +               seq_printf( sfile,
86082 +                           "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%ld\"/>\n",
86083 +                           g_SysRAMWaterMark);
86084 +               seq_printf( sfile,
86085 +                           "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%ld\"/>\n",
86086 +                           g_SysRAMHighWaterMark);
86087 +               seq_printf( sfile,
86088 +                           "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%ld\"/>\n",
86089 +                           g_IOMemWaterMark);
86090 +               seq_printf( sfile,
86091 +                           "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%ld\"/>\n",
86092 +                           g_IOMemHighWaterMark);
86093 +
86094 +               seq_printf( sfile, "</meminfo_header>\n");
86095 +
86096 +#endif
86097 +               return;
86098 +       }
86099 +
86100 +    if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
86101 +    {
86102 +               seq_printf( sfile,
86103 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
86104 +                           "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n",
86105 +#else
86106 +                           "<allocation>\n"
86107 +                           "\t<type>%s</type>\n"
86108 +                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
86109 +                           "\t<cpu_physical>%08lx</cpu_physical>\n"
86110 +                           "\t<bytes>%ld</bytes>\n"
86111 +                           "\t<pid>%d</pid>\n"
86112 +                           "\t<private>%s</private>\n"
86113 +                           "\t<filename>%s</filename>\n"
86114 +                           "\t<line>%ld</line>\n"
86115 +                           "</allocation>\n",
86116 +#endif
86117 +                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
86118 +                           psRecord->pvCpuVAddr,
86119 +                           psRecord->ulCpuPAddr,
86120 +                           psRecord->ui32Bytes,
86121 +                           psRecord->pid,
86122 +                           "NULL",
86123 +                           psRecord->pszFileName,
86124 +                           psRecord->ui32Line);
86125 +    }
86126 +    else
86127 +    {
86128 +               seq_printf( sfile,
86129 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
86130 +                           "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n",
86131 +#else
86132 +                           "<allocation>\n"
86133 +                           "\t<type>%s</type>\n"
86134 +                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
86135 +                           "\t<cpu_physical>%08lx</cpu_physical>\n"
86136 +                           "\t<bytes>%ld</bytes>\n"
86137 +                           "\t<pid>%d</pid>\n"
86138 +                           "\t<private>%s</private>\n"
86139 +                           "\t<filename>%s</filename>\n"
86140 +                           "\t<line>%ld</line>\n"
86141 +                           "</allocation>\n",
86142 +#endif
86143 +                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
86144 +                           psRecord->pvCpuVAddr,
86145 +                           psRecord->ulCpuPAddr,
86146 +                           psRecord->ui32Bytes,
86147 +                           psRecord->pid,
86148 +                           KMemCacheNameWrapper(psRecord->pvPrivateData),
86149 +                           psRecord->pszFileName,
86150 +                           psRecord->ui32Line);
86151 +    }
86152 +}
86153 +
86154 +
86155 +
86156 +#else
86157 +
86158 +static off_t
86159 +printMemoryRecords(IMG_CHAR * buffer, size_t count, off_t off)
86160 +{
86161 +    DEBUG_MEM_ALLOC_REC *psRecord;
86162 +    off_t Ret;
86163 +
86164 +    LinuxLockMutex(&g_sDebugMutex);
86165 +
86166 +    if(!off)
86167 +    {
86168 +        if(count < 1000)
86169 +        {
86170 +            Ret = 0;
86171 +            goto unlock_and_return;
86172 +        }
86173 +
86174 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
86175 +
86176 +        Ret =  printAppend(buffer, count, 0, "%-60s: %ld bytes\n",
86177 +                           "Current Water Mark of bytes allocated via kmalloc",
86178 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86179 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86180 +                           "Highest Water Mark of bytes allocated via kmalloc",
86181 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86182 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86183 +                           "Current Water Mark of bytes allocated via vmalloc",
86184 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86185 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86186 +                           "Highest Water Mark of bytes allocated via vmalloc",
86187 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86188 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86189 +                           "Current Water Mark of bytes allocated via alloc_pages",
86190 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86191 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86192 +                           "Highest Water Mark of bytes allocated via alloc_pages",
86193 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86194 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86195 +                           "Current Water Mark of bytes allocated via ioremap",
86196 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86197 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86198 +                           "Highest Water Mark of bytes allocated via ioremap",
86199 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86200 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86201 +                           "Current Water Mark of bytes reserved for \"IO\" memory areas",
86202 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86203 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86204 +                           "Highest Water Mark of bytes allocated for \"IO\" memory areas",
86205 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86206 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86207 +                           "Current Water Mark of bytes allocated via kmem_cache_alloc",
86208 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86209 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86210 +                           "Highest Water Mark of bytes allocated via kmem_cache_alloc",
86211 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86212 +        Ret =  printAppend(buffer, count, Ret, "\n");
86213 +
86214 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86215 +                           "The Current Water Mark for memory allocated from system RAM",
86216 +                           g_SysRAMWaterMark);
86217 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86218 +                           "The Highest Water Mark for memory allocated from system RAM",
86219 +                           g_SysRAMHighWaterMark);
86220 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86221 +                           "The Current Water Mark for memory allocated from IO memory",
86222 +                           g_IOMemWaterMark);
86223 +        Ret =  printAppend(buffer, count, Ret, "%-60s: %ld bytes\n",
86224 +                           "The Highest Water Mark for memory allocated from IO memory",
86225 +                           g_IOMemHighWaterMark);
86226 +
86227 +        Ret =  printAppend(buffer, count, Ret, "\n");
86228 +
86229 +        Ret =  printAppend(buffer, count, Ret, "Details for all known allocations:\n"
86230 +                           "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
86231 +                           "Type",
86232 +                           "CpuVAddr",
86233 +                           "CpuPAddr",
86234 +                           "Bytes",
86235 +                           "PID",
86236 +                           "PrivateData",
86237 +                           "Filename:Line");
86238 +
86239 +#else
86240 +
86241 +
86242 +        Ret =  printAppend(buffer, count, 0, "<meminfo>\n<meminfo_header>\n");
86243 +        Ret =  printAppend(buffer, count, Ret,
86244 +                           "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%ld\"/>\n",
86245 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86246 +        Ret =  printAppend(buffer, count, Ret,
86247 +                           "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%ld\"/>\n",
86248 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
86249 +        Ret =  printAppend(buffer, count, Ret,
86250 +                           "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%ld\"/>\n",
86251 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86252 +        Ret =  printAppend(buffer, count, Ret,
86253 +                           "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%ld\"/>\n",
86254 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
86255 +        Ret =  printAppend(buffer, count, Ret,
86256 +                           "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%ld\"/>\n",
86257 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86258 +        Ret =  printAppend(buffer, count, Ret,
86259 +                           "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%ld\"/>\n",
86260 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
86261 +        Ret =  printAppend(buffer, count, Ret,
86262 +                           "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%ld\"/>\n",
86263 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86264 +        Ret =  printAppend(buffer, count, Ret,
86265 +                           "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%ld\"/>\n",
86266 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
86267 +        Ret =  printAppend(buffer, count, Ret,
86268 +                           "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%ld\"/>\n",
86269 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86270 +        Ret =  printAppend(buffer, count, Ret,
86271 +                           "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%ld\"/>\n",
86272 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
86273 +        Ret =  printAppend(buffer, count, Ret,
86274 +                           "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%ld\"/>\n",
86275 +                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86276 +        Ret =  printAppend(buffer, count, Ret,
86277 +                           "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%ld\"/>\n",
86278 +                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
86279 +        Ret =  printAppend(buffer, count, Ret, "\n");
86280 +
86281 +        Ret =  printAppend(buffer, count, Ret,
86282 +                           "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%ld\"/>\n",
86283 +                           g_SysRAMWaterMark);
86284 +        Ret =  printAppend(buffer, count, Ret,
86285 +                           "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%ld\"/>\n",
86286 +                           g_SysRAMHighWaterMark);
86287 +        Ret =  printAppend(buffer, count, Ret,
86288 +                           "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%ld\"/>\n",
86289 +                           g_IOMemWaterMark);
86290 +        Ret =  printAppend(buffer, count, Ret,
86291 +                           "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%ld\"/>\n",
86292 +                           g_IOMemHighWaterMark);
86293 +
86294 +        Ret =  printAppend(buffer, count, Ret, "</meminfo_header>\n");
86295 +
86296 +#endif
86297 +
86298 +        goto unlock_and_return;
86299 +    }
86300 +
86301 +    if(count < 1000)
86302 +    {
86303 +        Ret = 0;
86304 +        goto unlock_and_return;
86305 +    }
86306 +
86307 +       psRecord = (DEBUG_MEM_ALLOC_REC*)
86308 +               List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
86309 +                                                                               DecOffMemAllocRec_AnyVaCb,
86310 +                                                                               &off);
86311 +    if(!psRecord)
86312 +    {
86313 +#if defined(DEBUG_LINUX_XML_PROC_FILES)
86314 +               if(off == 0)
86315 +               {
86316 +                       Ret =  printAppend(buffer, count, 0, "</meminfo>\n");
86317 +                       goto unlock_and_return;
86318 +               }
86319 +#endif
86320 +        Ret = END_OF_FILE;
86321 +        goto unlock_and_return;
86322 +    }
86323 +
86324 +    if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
86325 +    {
86326 +        Ret =  printAppend(buffer, count, 0,
86327 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
86328 +                           "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n",
86329 +#else
86330 +                           "<allocation>\n"
86331 +                           "\t<type>%s</type>\n"
86332 +                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
86333 +                           "\t<cpu_physical>%08lx</cpu_physical>\n"
86334 +                           "\t<bytes>%ld</bytes>\n"
86335 +                           "\t<pid>%d</pid>\n"
86336 +                           "\t<private>%s</private>\n"
86337 +                           "\t<filename>%s</filename>\n"
86338 +                           "\t<line>%ld</line>\n"
86339 +                           "</allocation>\n",
86340 +#endif
86341 +                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
86342 +                           psRecord->pvCpuVAddr,
86343 +                           psRecord->ulCpuPAddr,
86344 +                           psRecord->ui32Bytes,
86345 +                           psRecord->pid,
86346 +                           "NULL",
86347 +                           psRecord->pszFileName,
86348 +                           psRecord->ui32Line);
86349 +    }
86350 +    else
86351 +    {
86352 +        Ret =  printAppend(buffer, count, 0,
86353 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
86354 +                           "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n",
86355 +#else
86356 +                           "<allocation>\n"
86357 +                           "\t<type>%s</type>\n"
86358 +                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
86359 +                           "\t<cpu_physical>%08lx</cpu_physical>\n"
86360 +                           "\t<bytes>%ld</bytes>\n"
86361 +                           "\t<pid>%d</pid>\n"
86362 +                           "\t<private>%s</private>\n"
86363 +                           "\t<filename>%s</filename>\n"
86364 +                           "\t<line>%ld</line>\n"
86365 +                           "</allocation>\n",
86366 +#endif
86367 +                           DebugMemAllocRecordTypeToString(psRecord->eAllocType),
86368 +                           psRecord->pvCpuVAddr,
86369 +                           psRecord->ulCpuPAddr,
86370 +                           psRecord->ui32Bytes,
86371 +                           psRecord->pid,
86372 +                           KMemCacheNameWrapper(psRecord->pvPrivateData),
86373 +                           psRecord->pszFileName,
86374 +                           psRecord->ui32Line);
86375 +    }
86376 +
86377 +unlock_and_return:
86378 +    LinuxUnLockMutex(&g_sDebugMutex);
86379 +    return Ret;
86380 +}
86381 +#endif
86382 +#endif
86383 +
86384 +
86385 +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS)
86386 +const IMG_CHAR *
86387 +HAPFlagsToString(IMG_UINT32 ui32Flags)
86388 +{
86389 +    static IMG_CHAR szFlags[50];
86390 +    IMG_INT32 i32Pos = 0;
86391 +    IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex;
86392 +    IMG_CHAR *apszCacheTypes[] = {
86393 +        "UNCACHED",
86394 +        "CACHED",
86395 +        "WRITECOMBINE",
86396 +        "UNKNOWN"
86397 +    };
86398 +    IMG_CHAR *apszMapType[] = {
86399 +        "KERNEL_ONLY",
86400 +        "SINGLE_PROCESS",
86401 +        "MULTI_PROCESS",
86402 +        "FROM_EXISTING_PROCESS",
86403 +        "NO_CPU_VIRTUAL",
86404 +        "UNKNOWN"
86405 +    };
86406 +
86407 +
86408 +    if(ui32Flags & PVRSRV_HAP_UNCACHED){
86409 +        ui32CacheTypeIndex=0;
86410 +    }else if(ui32Flags & PVRSRV_HAP_CACHED){
86411 +        ui32CacheTypeIndex=1;
86412 +    }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){
86413 +        ui32CacheTypeIndex=2;
86414 +    }else{
86415 +        ui32CacheTypeIndex=3;
86416 +        PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)",
86417 +                 __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)));
86418 +    }
86419 +
86420 +
86421 +    if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){
86422 +        ui32MapTypeIndex = 0;
86423 +    }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){
86424 +        ui32MapTypeIndex = 1;
86425 +    }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){
86426 +        ui32MapTypeIndex = 2;
86427 +    }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){
86428 +        ui32MapTypeIndex = 3;
86429 +    }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){
86430 +        ui32MapTypeIndex = 4;
86431 +    }else{
86432 +        ui32MapTypeIndex = 5;
86433 +        PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)",
86434 +                 __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)));
86435 +    }
86436 +
86437 +    i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]);
86438 +    if (i32Pos <= 0)
86439 +    {
86440 +       PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)",
86441 +               __FUNCTION__, ui32CacheTypeIndex, i32Pos));
86442 +       szFlags[0] = 0;
86443 +    }
86444 +    else
86445 +    {
86446 +        sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]);
86447 +    }
86448 +
86449 +    return szFlags;
86450 +}
86451 +#endif
86452 +
86453 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.h
86454 new file mode 100644
86455 index 0000000..7d2da4e
86456 --- /dev/null
86457 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mm.h
86458 @@ -0,0 +1,331 @@
86459 +/**********************************************************************
86460 + *
86461 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
86462 + * 
86463 + * This program is free software; you can redistribute it and/or modify it
86464 + * under the terms and conditions of the GNU General Public License,
86465 + * version 2, as published by the Free Software Foundation.
86466 + * 
86467 + * This program is distributed in the hope it will be useful but, except 
86468 + * as otherwise stated in writing, without any warranty; without even the 
86469 + * implied warranty of merchantability or fitness for a particular purpose. 
86470 + * See the GNU General Public License for more details.
86471 + * 
86472 + * You should have received a copy of the GNU General Public License along with
86473 + * this program; if not, write to the Free Software Foundation, Inc.,
86474 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
86475 + * 
86476 + * The full GNU General Public License is included in this distribution in
86477 + * the file called "COPYING".
86478 + *
86479 + * Contact Information:
86480 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
86481 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
86482 + *
86483 + ******************************************************************************/
86484 +
86485 +#ifndef __IMG_LINUX_MM_H__
86486 +#define __IMG_LINUX_MM_H__
86487 +
86488 +#ifndef AUTOCONF_INCLUDED
86489 + #include <linux/config.h>
86490 +#endif
86491 +
86492 +#include <linux/version.h>
86493 +#include <linux/slab.h>
86494 +#include <linux/mm.h>
86495 +#include <linux/list.h>
86496 +
86497 +#include <asm/io.h>
86498 +
86499 +#define        PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT)
86500 +#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT)
86501 +
86502 +#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
86503 +
86504 +#define        ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
86505 +
86506 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
86507 +#define        REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot)
86508 +#else
86509 +#define        REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
86510 +#endif
86511 +
86512 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
86513 +#define        IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot)
86514 +#else
86515 +#define        IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot)
86516 +#endif
86517 +
86518 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
86519 +#define        VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page)
86520 +#else
86521 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
86522 +#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot);
86523 +#else
86524 +#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot);
86525 +#endif
86526 +#endif
86527 +
86528 +static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr)
86529 +{
86530 +       return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr));
86531 +               
86532 +}
86533 +
86534 +typedef enum {
86535 +    LINUX_MEM_AREA_IOREMAP,
86536 +       LINUX_MEM_AREA_EXTERNAL_KV,
86537 +    LINUX_MEM_AREA_IO,
86538 +    LINUX_MEM_AREA_VMALLOC,
86539 +    LINUX_MEM_AREA_ALLOC_PAGES,
86540 +    LINUX_MEM_AREA_SUB_ALLOC,
86541 +    LINUX_MEM_AREA_TYPE_COUNT
86542 +}LINUX_MEM_AREA_TYPE;
86543 +
86544 +typedef struct _LinuxMemArea LinuxMemArea;
86545 +
86546 +
86547 +struct _LinuxMemArea {
86548 +    LINUX_MEM_AREA_TYPE eAreaType;
86549 +    union _uData
86550 +    {
86551 +        struct _sIORemap
86552 +        {
86553 +            
86554 +            IMG_CPU_PHYADDR CPUPhysAddr;
86555 +            IMG_VOID *pvIORemapCookie;
86556 +        }sIORemap;
86557 +        struct _sExternalKV
86558 +        {
86559 +            
86560 +           IMG_BOOL bPhysContig;
86561 +           union {
86562 +                   
86563 +                   IMG_SYS_PHYADDR SysPhysAddr;
86564 +                   IMG_SYS_PHYADDR *pSysPhysAddr;
86565 +           } uPhysAddr;
86566 +            IMG_VOID *pvExternalKV;
86567 +        }sExternalKV;
86568 +        struct _sIO
86569 +        {
86570 +            
86571 +            IMG_CPU_PHYADDR CPUPhysAddr;
86572 +        }sIO;
86573 +        struct _sVmalloc
86574 +        {
86575 +            
86576 +            IMG_VOID *pvVmallocAddress;
86577 +        }sVmalloc;
86578 +        struct _sPageList
86579 +        {
86580 +            
86581 +            struct page **pvPageList;
86582 +           IMG_HANDLE hBlockPageList;
86583 +        }sPageList;
86584 +        struct _sSubAlloc
86585 +        {
86586 +            
86587 +            LinuxMemArea *psParentLinuxMemArea;
86588 +            IMG_UINT32 ui32ByteOffset;
86589 +        }sSubAlloc;
86590 +    }uData;
86591 +
86592 +    IMG_UINT32 ui32ByteSize;           
86593 +
86594 +    IMG_UINT32 ui32AreaFlags;          
86595 +
86596 +    IMG_BOOL bMMapRegistered;          
86597 +
86598 +    
86599 +    struct list_head   sMMapItem;
86600 +
86601 +    
86602 +    struct list_head   sMMapOffsetStructList;
86603 +};
86604 +
86605 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
86606 +typedef kmem_cache_t LinuxKMemCache;
86607 +#else
86608 +typedef struct kmem_cache LinuxKMemCache;
86609 +#endif
86610 +
86611 +
86612 +PVRSRV_ERROR LinuxMMInit(IMG_VOID);
86613 +
86614 +
86615 +IMG_VOID LinuxMMCleanup(IMG_VOID);
86616 +
86617 +
86618 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86619 +#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, __FILE__, __LINE__)
86620 +#else
86621 +#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, NULL, 0)
86622 +#endif
86623 +IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *szFileName, IMG_UINT32 ui32Line);
86624 +
86625 +
86626 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86627 +#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
86628 +#else
86629 +#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0)
86630 +#endif
86631 +IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86632 +
86633 +
86634 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86635 +#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
86636 +#else
86637 +#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0)
86638 +#endif
86639 +IMG_VOID *_VMallocWrapper(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86640 +
86641 +
86642 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86643 +#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
86644 +#else
86645 +#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0)
86646 +#endif
86647 +IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86648 +
86649 +
86650 +LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
86651 +
86652 +
86653 +IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea);
86654 +
86655 +
86656 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86657 +#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
86658 +    _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
86659 +#else
86660 +#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
86661 +    _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
86662 +#endif
86663 +IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
86664 +                          IMG_UINT32 ui32Bytes,
86665 +                          IMG_UINT32 ui32MappingFlags,
86666 +                          IMG_CHAR *pszFileName,
86667 +                          IMG_UINT32 ui32Line);
86668 +
86669 +
86670 +LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
86671 +
86672 +
86673 +IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea);
86674 +
86675 +LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags);
86676 +
86677 +
86678 +IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea);
86679 +
86680 +
86681 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86682 +#define IOUnmapWrapper(pvIORemapCookie) \
86683 +    _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
86684 +#else
86685 +#define IOUnmapWrapper(pvIORemapCookie) \
86686 +    _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
86687 +#endif
86688 +IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86689 +
86690 +
86691 +struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
86692 +
86693 +
86694 +LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags);
86695 +
86696 +
86697 +IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache);
86698 +
86699 +
86700 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86701 +#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__)
86702 +#else
86703 +#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0)
86704 +#endif
86705 +
86706 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
86707 +IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86708 +#else
86709 +IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86710 +#endif
86711 +
86712 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
86713 +#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__)
86714 +#else
86715 +#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0)
86716 +#endif
86717 +IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
86718 +
86719 +
86720 +const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache);
86721 +
86722 +
86723 +LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
86724 +
86725 +
86726 +IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea);
86727 +
86728 +
86729 +LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
86730 +
86731 +
86732 +IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea);
86733 +
86734 +
86735 +LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
86736 +                                 IMG_UINT32 ui32ByteOffset,
86737 +                                 IMG_UINT32 ui32Bytes);
86738 +
86739 +
86740 +IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea);
86741 +
86742 +
86743 +#if defined(LINUX_MEM_AREAS_DEBUG)
86744 +IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea);
86745 +#else
86746 +#define LinuxMemAreaRegister(X)
86747 +#endif
86748 +
86749 +
86750 +IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea);
86751 +
86752 +
86753 +IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
86754 +
86755 +
86756 +#define         LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr)
86757 +
86758 +IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea);
86759 +
86760 +static inline LinuxMemArea *
86761 +LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea)
86762 +{
86763 +    if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
86764 +    {
86765 +        return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
86766 +    }
86767 +    else
86768 +    {
86769 +        return psLinuxMemArea;
86770 +    }
86771 +}
86772 +
86773 +
86774 +static inline LINUX_MEM_AREA_TYPE
86775 +LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea)
86776 +{
86777 +    return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
86778 +}
86779 +
86780 +
86781 +const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType);
86782 +
86783 +
86784 +#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS)
86785 +const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags);
86786 +#endif
86787 +
86788 +#endif 
86789 +
86790 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.c
86791 new file mode 100644
86792 index 0000000..1689bd4
86793 --- /dev/null
86794 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.c
86795 @@ -0,0 +1,1148 @@
86796 +/**********************************************************************
86797 + *
86798 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
86799 + *
86800 + * This program is free software; you can redistribute it and/or modify it
86801 + * under the terms and conditions of the GNU General Public License,
86802 + * version 2, as published by the Free Software Foundation.
86803 + *
86804 + * This program is distributed in the hope it will be useful but, except
86805 + * as otherwise stated in writing, without any warranty; without even the
86806 + * implied warranty of merchantability or fitness for a particular purpose.
86807 + * See the GNU General Public License for more details.
86808 + *
86809 + * You should have received a copy of the GNU General Public License along with
86810 + * this program; if not, write to the Free Software Foundation, Inc.,
86811 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
86812 + *
86813 + * The full GNU General Public License is included in this distribution in
86814 + * the file called "COPYING".
86815 + *
86816 + * Contact Information:
86817 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
86818 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
86819 + *
86820 + ******************************************************************************/
86821 +
86822 +#ifndef AUTOCONF_INCLUDED
86823 + #include <linux/config.h>
86824 +#endif
86825 +
86826 +#include <linux/version.h>
86827 +#include <linux/mm.h>
86828 +#include <linux/module.h>
86829 +#include <linux/vmalloc.h>
86830 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
86831 +#include <linux/wrapper.h>
86832 +#endif
86833 +#include <linux/slab.h>
86834 +#include <asm/io.h>
86835 +#include <asm/page.h>
86836 +#include <asm/shmparam.h>
86837 +#include <asm/pgtable.h>
86838 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
86839 +#include <linux/sched.h>
86840 +#include <asm/current.h>
86841 +#endif
86842 +#if defined(SUPPORT_DRI_DRM)
86843 +#include <drm/drmP.h>
86844 +#endif
86845 +
86846 +#include "img_defs.h"
86847 +#include "services.h"
86848 +#include "servicesint.h"
86849 +#include "pvrmmap.h"
86850 +#include "mutils.h"
86851 +#include "mmap.h"
86852 +#include "mm.h"
86853 +#include "pvr_debug.h"
86854 +#include "osfunc.h"
86855 +#include "proc.h"
86856 +#include "mutex.h"
86857 +#include "handle.h"
86858 +#include "perproc.h"
86859 +#include "env_perproc.h"
86860 +#include "bridged_support.h"
86861 +#if defined(SUPPORT_DRI_DRM)
86862 +#include "pvr_drm.h"
86863 +#endif
86864 +
86865 +#if !defined(PVR_SECURE_HANDLES)
86866 +#error "The mmap code requires PVR_SECURE_HANDLES"
86867 +#endif
86868 +
86869 +static PVRSRV_LINUX_MUTEX g_sMMapMutex;
86870 +
86871 +static LinuxKMemCache *g_psMemmapCache = NULL;
86872 +static LIST_HEAD(g_sMMapAreaList);
86873 +static LIST_HEAD(g_sMMapOffsetStructList);
86874 +#if defined(DEBUG_LINUX_MMAP_AREAS)
86875 +static IMG_UINT32 g_ui32RegisteredAreas = 0;
86876 +static IMG_UINT32 g_ui32TotalByteSize = 0;
86877 +#endif
86878 +
86879 +
86880 +#if defined(PVR_PROC_USE_SEQ_FILE) && defined(DEBUG_LINUX_MMAP_AREAS)
86881 +static struct proc_dir_entry *g_ProcMMap;
86882 +#endif
86883 +
86884 +#define        FIRST_PHYSICAL_PFN      0
86885 +#define        LAST_PHYSICAL_PFN       0x7fffffffUL
86886 +#define        FIRST_SPECIAL_PFN       (LAST_PHYSICAL_PFN + 1)
86887 +#define        LAST_SPECIAL_PFN        0xffffffffUL
86888 +
86889 +#define        MAX_MMAP_HANDLE         0x7fffffffUL
86890 +
86891 +static inline IMG_BOOL
86892 +PFNIsPhysical(IMG_UINT32 pfn)
86893 +{
86894 +
86895 +       return ((pfn >= FIRST_PHYSICAL_PFN) && (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE;
86896 +}
86897 +
86898 +static inline IMG_BOOL
86899 +PFNIsSpecial(IMG_UINT32 pfn)
86900 +{
86901 +
86902 +       return ((pfn >= FIRST_SPECIAL_PFN) && (pfn <= LAST_SPECIAL_PFN)) ? IMG_TRUE : IMG_FALSE;
86903 +}
86904 +
86905 +static inline IMG_HANDLE
86906 +MMapOffsetToHandle(IMG_UINT32 pfn)
86907 +{
86908 +       if (PFNIsPhysical(pfn))
86909 +       {
86910 +               PVR_ASSERT(PFNIsPhysical(pfn));
86911 +               return IMG_NULL;
86912 +       }
86913 +
86914 +       return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN);
86915 +}
86916 +
86917 +static inline IMG_UINT32
86918 +HandleToMMapOffset(IMG_HANDLE hHandle)
86919 +{
86920 +       IMG_UINT32 ulHandle = (IMG_UINT32)hHandle;
86921 +
86922 +       if (PFNIsSpecial(ulHandle))
86923 +       {
86924 +               PVR_ASSERT(PFNIsSpecial(ulHandle));
86925 +               return 0;
86926 +       }
86927 +
86928 +       return ulHandle + FIRST_SPECIAL_PFN;
86929 +}
86930 +
86931 +static inline IMG_BOOL
86932 +LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea)
86933 +{
86934 +    return LinuxMemAreaPhysIsContig(psLinuxMemArea);
86935 +}
86936 +
86937 +static inline IMG_UINT32
86938 +GetCurrentThreadID(IMG_VOID)
86939 +{
86940 +
86941 +       return (IMG_UINT32)current->pid;
86942 +}
86943 +
86944 +static PKV_OFFSET_STRUCT
86945 +CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
86946 +{
86947 +    PKV_OFFSET_STRUCT psOffsetStruct;
86948 +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
86949 +    const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
86950 +#endif
86951 +
86952 +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
86953 +    PVR_DPF((PVR_DBG_MESSAGE,
86954 +             "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8lx)",
86955 +             __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
86956 +#endif
86957 +
86958 +    PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
86959 +
86960 +    PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
86961 +
86962 +    psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL);
86963 +    if(psOffsetStruct == IMG_NULL)
86964 +    {
86965 +        PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache"));
86966 +        return IMG_NULL;
86967 +    }
86968 +
86969 +    psOffsetStruct->ui32MMapOffset = ui32Offset;
86970 +
86971 +    psOffsetStruct->psLinuxMemArea = psLinuxMemArea;
86972 +
86973 +    psOffsetStruct->ui32Mapped = 0;
86974 +
86975 +    psOffsetStruct->ui32RealByteSize = ui32RealByteSize;
86976 +
86977 +
86978 +    psOffsetStruct->ui32TID = GetCurrentThreadID();
86979 +
86980 +    psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM();
86981 +
86982 +    psOffsetStruct->bOnMMapList = IMG_FALSE;
86983 +
86984 +    psOffsetStruct->ui32RefCount = 0;
86985 +
86986 +    psOffsetStruct->ui32UserVAddr = 0;
86987 +
86988 +#if defined(DEBUG_LINUX_MMAP_AREAS)
86989 +
86990 +    psOffsetStruct->pszName = pszName;
86991 +#endif
86992 +
86993 +    list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList);
86994 +
86995 +    return psOffsetStruct;
86996 +}
86997 +
86998 +
86999 +static IMG_VOID
87000 +DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct)
87001 +{
87002 +    list_del(&psOffsetStruct->sAreaItem);
87003 +
87004 +    if (psOffsetStruct->bOnMMapList)
87005 +    {
87006 +        list_del(&psOffsetStruct->sMMapItem);
87007 +    }
87008 +
87009 +    PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: "
87010 +             "psLinuxMemArea=0x%08lX, CpuPAddr=0x%08lX", __FUNCTION__,
87011 +             psOffsetStruct->psLinuxMemArea,
87012 +             LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0)));
87013 +
87014 +    KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct);
87015 +}
87016 +
87017 +
87018 +static inline IMG_VOID
87019 +DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea,
87020 +                               IMG_UINT32 *pui32RealByteSize,
87021 +                               IMG_UINT32 *pui32ByteOffset)
87022 +{
87023 +    IMG_UINT32 ui32PageAlignmentOffset;
87024 +    IMG_CPU_PHYADDR CpuPAddr;
87025 +
87026 +    CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0);
87027 +    ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr);
87028 +
87029 +    *pui32ByteOffset = ui32PageAlignmentOffset;
87030 +
87031 +    *pui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset);
87032 +}
87033 +
87034 +
87035 +PVRSRV_ERROR
87036 +PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
87037 +                               IMG_HANDLE hMHandle,
87038 +                                IMG_UINT32 *pui32MMapOffset,
87039 +                                IMG_UINT32 *pui32ByteOffset,
87040 +                                IMG_UINT32 *pui32RealByteSize,
87041 +                               IMG_UINT32 *pui32UserVAddr)
87042 +{
87043 +    LinuxMemArea *psLinuxMemArea;
87044 +    PKV_OFFSET_STRUCT psOffsetStruct;
87045 +    IMG_HANDLE hOSMemHandle;
87046 +    PVRSRV_ERROR eError;
87047 +
87048 +    LinuxLockMutex(&g_sMMapMutex);
87049 +
87050 +    PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
87051 +
87052 +    eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
87053 +    if (eError != PVRSRV_OK)
87054 +    {
87055 +       PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", __FUNCTION__, hMHandle));
87056 +
87057 +       goto exit_unlock;
87058 +    }
87059 +
87060 +    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
87061 +
87062 +    DetermineUsersSizeAndByteOffset(psLinuxMemArea,
87063 +                                   pui32RealByteSize,
87064 +                                   pui32ByteOffset);
87065 +
87066 +
87067 +    list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
87068 +    {
87069 +        if (psPerProc->ui32PID == psOffsetStruct->ui32PID)
87070 +        {
87071 +
87072 +          PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize);
87073 +
87074 +          *pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
87075 +          *pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
87076 +          psOffsetStruct->ui32RefCount++;
87077 +
87078 +          eError = PVRSRV_OK;
87079 +          goto exit_unlock;
87080 +        }
87081 +    }
87082 +
87083 +
87084 +    *pui32UserVAddr = 0;
87085 +
87086 +    if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea))
87087 +    {
87088 +        *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0);
87089 +        PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset));
87090 +    }
87091 +    else
87092 +    {
87093 +        *pui32MMapOffset = HandleToMMapOffset(hMHandle);
87094 +        PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset));
87095 +    }
87096 +
87097 +    psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize);
87098 +    if (psOffsetStruct == IMG_NULL)
87099 +    {
87100 +        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
87101 +       goto exit_unlock;
87102 +    }
87103 +
87104 +
87105 +    list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList);
87106 +
87107 +    psOffsetStruct->bOnMMapList = IMG_TRUE;
87108 +
87109 +    psOffsetStruct->ui32RefCount++;
87110 +
87111 +    eError = PVRSRV_OK;
87112 +
87113 +exit_unlock:
87114 +    LinuxUnLockMutex(&g_sMMapMutex);
87115 +
87116 +    return eError;
87117 +}
87118 +
87119 +
87120 +PVRSRV_ERROR
87121 +PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
87122 +                               IMG_HANDLE hMHandle,
87123 +                               IMG_BOOL *pbMUnmap,
87124 +                               IMG_UINT32 *pui32RealByteSize,
87125 +                                IMG_UINT32 *pui32UserVAddr)
87126 +{
87127 +    LinuxMemArea *psLinuxMemArea;
87128 +    PKV_OFFSET_STRUCT psOffsetStruct;
87129 +    IMG_HANDLE hOSMemHandle;
87130 +    PVRSRV_ERROR eError;
87131 +    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
87132 +
87133 +    LinuxLockMutex(&g_sMMapMutex);
87134 +
87135 +    PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
87136 +
87137 +    eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
87138 +    if (eError != PVRSRV_OK)
87139 +    {
87140 +       PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", __FUNCTION__, hMHandle));
87141 +
87142 +       goto exit_unlock;
87143 +    }
87144 +
87145 +    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
87146 +
87147 +
87148 +    list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
87149 +    {
87150 +        if (psOffsetStruct->ui32PID == ui32PID)
87151 +        {
87152 +           if (psOffsetStruct->ui32RefCount == 0)
87153 +           {
87154 +               PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area 0x%p", __FUNCTION__, psOffsetStruct, psLinuxMemArea));
87155 +               eError = PVRSRV_ERROR_GENERIC;
87156 +               goto exit_unlock;
87157 +           }
87158 +
87159 +           psOffsetStruct->ui32RefCount--;
87160 +
87161 +           *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
87162 +
87163 +           *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0;
87164 +           *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0;
87165 +
87166 +           eError = PVRSRV_OK;
87167 +           goto exit_unlock;
87168 +        }
87169 +    }
87170 +
87171 +
87172 +    PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle 0x%lx (memory area 0x%p)", __FUNCTION__, hMHandle, psLinuxMemArea));
87173 +
87174 +    eError =  PVRSRV_ERROR_GENERIC;
87175 +
87176 +exit_unlock:
87177 +    LinuxUnLockMutex(&g_sMMapMutex);
87178 +
87179 +    return eError;
87180 +}
87181 +
87182 +static inline PKV_OFFSET_STRUCT
87183 +FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
87184 +{
87185 +    PKV_OFFSET_STRUCT psOffsetStruct;
87186 +    IMG_UINT32 ui32TID = GetCurrentThreadID();
87187 +    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
87188 +
87189 +    list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
87190 +    {
87191 +        if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID)
87192 +        {
87193 +
87194 +           if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID)
87195 +           {
87196 +               return psOffsetStruct;
87197 +           }
87198 +        }
87199 +    }
87200 +
87201 +    return IMG_NULL;
87202 +}
87203 +
87204 +
87205 +static IMG_BOOL
87206 +DoMapToUser(LinuxMemArea *psLinuxMemArea,
87207 +            struct vm_area_struct* ps_vma,
87208 +            IMG_UINT32 ui32ByteOffset)
87209 +{
87210 +    IMG_UINT32 ui32ByteSize;
87211 +
87212 +    if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
87213 +    {
87214 +        return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea),
87215 +                    ps_vma,
87216 +                    psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset);
87217 +    }
87218 +
87219 +
87220 +    ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
87221 +    PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0);
87222 +
87223 +#if defined (__sparc__)
87224 +
87225 +#error "SPARC not supported"
87226 +#endif
87227 +
87228 +    if (PFNIsPhysical(ps_vma->vm_pgoff))
87229 +    {
87230 +       IMG_INT result;
87231 +
87232 +       PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea));
87233 +       PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff);
87234 +
87235 +
87236 +       result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, ui32ByteSize, ps_vma->vm_page_prot);
87237 +
87238 +        if(result == 0)
87239 +        {
87240 +            return IMG_TRUE;
87241 +        }
87242 +
87243 +        PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result));
87244 +    }
87245 +
87246 +    {
87247 +
87248 +        IMG_UINT32 ulVMAPos;
87249 +       IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize;
87250 +       IMG_UINT32 ui32PA;
87251 +
87252 +
87253 +       for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
87254 +       {
87255 +           IMG_UINT32 pfn =  LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
87256 +
87257 +           if (!pfn_valid(pfn))
87258 +           {
87259 +                PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%lx", __FUNCTION__, pfn));
87260 +                return IMG_FALSE;
87261 +           }
87262 +       }
87263 +
87264 +
87265 +        ulVMAPos = ps_vma->vm_start;
87266 +       for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
87267 +       {
87268 +           IMG_UINT32 pfn;
87269 +           struct page *psPage;
87270 +           IMG_INT result;
87271 +
87272 +           pfn =  LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA);
87273 +           PVR_ASSERT(pfn_valid(pfn));
87274 +
87275 +           psPage = pfn_to_page(pfn);
87276 +
87277 +           result = VM_INSERT_PAGE(ps_vma,  ulVMAPos, psPage);
87278 +            if(result != 0)
87279 +            {
87280 +                PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result));
87281 +                return IMG_FALSE;
87282 +            }
87283 +            ulVMAPos += PAGE_SIZE;
87284 +        }
87285 +    }
87286 +
87287 +    return IMG_TRUE;
87288 +}
87289 +
87290 +
87291 +static IMG_VOID
87292 +MMapVOpenNoLock(struct vm_area_struct* ps_vma)
87293 +{
87294 +    PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
87295 +    PVR_ASSERT(psOffsetStruct != IMG_NULL)
87296 +    psOffsetStruct->ui32Mapped++;
87297 +    PVR_ASSERT(!psOffsetStruct->bOnMMapList);
87298 +
87299 +    if (psOffsetStruct->ui32Mapped > 1)
87300 +    {
87301 +       PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %lu)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped));
87302 +        PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0);
87303 +    }
87304 +
87305 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87306 +
87307 +    PVR_DPF((PVR_DBG_MESSAGE,
87308 +             "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %ld, ui32Mapped %d",
87309 +             __FUNCTION__,
87310 +             psOffsetStruct->psLinuxMemArea,
87311 +             LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
87312 +             psOffsetStruct->ui32MMapOffset,
87313 +             psOffsetStruct->ui32Mapped));
87314 +#endif
87315 +
87316 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
87317 +    MOD_INC_USE_COUNT;
87318 +#endif
87319 +}
87320 +
87321 +
87322 +static void
87323 +MMapVOpen(struct vm_area_struct* ps_vma)
87324 +{
87325 +    LinuxLockMutex(&g_sMMapMutex);
87326 +
87327 +    MMapVOpenNoLock(ps_vma);
87328 +
87329 +    LinuxUnLockMutex(&g_sMMapMutex);
87330 +}
87331 +
87332 +
87333 +static IMG_VOID
87334 +MMapVCloseNoLock(struct vm_area_struct* ps_vma)
87335 +{
87336 +    PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
87337 +    PVR_ASSERT(psOffsetStruct != IMG_NULL)
87338 +
87339 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87340 +    PVR_DPF((PVR_DBG_MESSAGE,
87341 +             "%s: psLinuxMemArea 0x%p, CpuVAddr 0x%p ui32MMapOffset %ld, ui32Mapped %d",
87342 +             __FUNCTION__,
87343 +             psOffsetStruct->psLinuxMemArea,
87344 +             LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
87345 +             psOffsetStruct->ui32MMapOffset,
87346 +             psOffsetStruct->ui32Mapped));
87347 +#endif
87348 +
87349 +    PVR_ASSERT(!psOffsetStruct->bOnMMapList);
87350 +    psOffsetStruct->ui32Mapped--;
87351 +    if (psOffsetStruct->ui32Mapped == 0)
87352 +    {
87353 +       if (psOffsetStruct->ui32RefCount != 0)
87354 +       {
87355 +               PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct 0x%p has non-zero reference count (ui32RefCount = %lu). User mode address of start of mapping: 0x%lx", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr));
87356 +       }
87357 +
87358 +       DestroyOffsetStruct(psOffsetStruct);
87359 +    }
87360 +
87361 +    ps_vma->vm_private_data = NULL;
87362 +
87363 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
87364 +    MOD_DEC_USE_COUNT;
87365 +#endif
87366 +}
87367 +
87368 +static void
87369 +MMapVClose(struct vm_area_struct* ps_vma)
87370 +{
87371 +    LinuxLockMutex(&g_sMMapMutex);
87372 +
87373 +    MMapVCloseNoLock(ps_vma);
87374 +
87375 +    LinuxUnLockMutex(&g_sMMapMutex);
87376 +}
87377 +
87378 +
87379 +static struct vm_operations_struct MMapIOOps =
87380 +{
87381 +       .open=MMapVOpen,
87382 +       .close=MMapVClose
87383 +};
87384 +
87385 +
87386 +int
87387 +PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
87388 +{
87389 +    IMG_UINT32 ui32ByteSize;
87390 +    PKV_OFFSET_STRUCT psOffsetStruct;
87391 +    int iRetVal = 0;
87392 +
87393 +    PVR_UNREFERENCED_PARAMETER(pFile);
87394 +
87395 +    LinuxLockMutex(&g_sMMapMutex);
87396 +
87397 +    ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
87398 +
87399 +    PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx,"
87400 +                              " and ui32ByteSize %ld(0x%08lx)",
87401 +            __FUNCTION__,
87402 +            ps_vma->vm_pgoff,
87403 +            ui32ByteSize, ui32ByteSize));
87404 +
87405 +    psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize);
87406 +    if (psOffsetStruct == IMG_NULL)
87407 +    {
87408 +#if defined(SUPPORT_DRI_DRM)
87409 +        LinuxUnLockMutex(&g_sMMapMutex);
87410 +
87411 +
87412 +        return drm_mmap(pFile, ps_vma);
87413 +#else
87414 +        PVR_UNREFERENCED_PARAMETER(pFile);
87415 +
87416 +        PVR_DPF((PVR_DBG_ERROR,
87417 +             "%s: Attempted to mmap unregistered area at vm_pgoff %ld",
87418 +             __FUNCTION__, ps_vma->vm_pgoff));
87419 +        iRetVal = -EINVAL;
87420 +#endif
87421 +        goto unlock_and_return;
87422 +    }
87423 +    list_del(&psOffsetStruct->sMMapItem);
87424 +    psOffsetStruct->bOnMMapList = IMG_FALSE;
87425 +
87426 +
87427 +    if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
87428 +        ((ps_vma->vm_flags & VM_SHARED) == 0))
87429 +    {
87430 +        PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__));
87431 +        iRetVal = -EINVAL;
87432 +        goto unlock_and_return;
87433 +    }
87434 +
87435 +    PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n",
87436 +         __FUNCTION__, psOffsetStruct->psLinuxMemArea));
87437 +
87438 +    ps_vma->vm_flags |= VM_RESERVED;
87439 +    ps_vma->vm_flags |= VM_IO;
87440 +
87441 +
87442 +    ps_vma->vm_flags |= VM_DONTEXPAND;
87443 +
87444 +
87445 +    ps_vma->vm_flags |= VM_DONTCOPY;
87446 +
87447 +    ps_vma->vm_private_data = (void *)psOffsetStruct;
87448 +
87449 +    switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK)
87450 +    {
87451 +        case PVRSRV_HAP_CACHED:
87452 +
87453 +            break;
87454 +        case PVRSRV_HAP_WRITECOMBINE:
87455 +           ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot);
87456 +            break;
87457 +        case PVRSRV_HAP_UNCACHED:
87458 +            ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot);
87459 +            break;
87460 +        default:
87461 +            PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__));
87462 +           iRetVal = -EINVAL;
87463 +           goto unlock_and_return;
87464 +    }
87465 +
87466 +
87467 +    ps_vma->vm_ops = &MMapIOOps;
87468 +
87469 +    if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0))
87470 +    {
87471 +        iRetVal = -EAGAIN;
87472 +        goto unlock_and_return;
87473 +    }
87474 +
87475 +    PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0)
87476 +
87477 +    psOffsetStruct->ui32UserVAddr = ps_vma->vm_start;
87478 +
87479 +
87480 +    MMapVOpenNoLock(ps_vma);
87481 +
87482 +    PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n",
87483 +             __FUNCTION__, ps_vma->vm_pgoff));
87484 +
87485 +unlock_and_return:
87486 +    if (iRetVal != 0 && psOffsetStruct != IMG_NULL)
87487 +    {
87488 +       DestroyOffsetStruct(psOffsetStruct);
87489 +    }
87490 +
87491 +    LinuxUnLockMutex(&g_sMMapMutex);
87492 +
87493 +    return iRetVal;
87494 +}
87495 +
87496 +
87497 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87498 +
87499 +#ifdef PVR_PROC_USE_SEQ_FILE
87500 +
87501 +static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start)
87502 +{
87503 +       if(start)
87504 +       {
87505 +           LinuxLockMutex(&g_sMMapMutex);
87506 +       }
87507 +       else
87508 +       {
87509 +           LinuxUnLockMutex(&g_sMMapMutex);
87510 +       }
87511 +}
87512 +
87513 +
87514 +static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off)
87515 +{
87516 +    LinuxMemArea *psLinuxMemArea;
87517 +       if(!off)
87518 +       {
87519 +               return PVR_PROC_SEQ_START_TOKEN;
87520 +       }
87521 +
87522 +    list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
87523 +    {
87524 +        PKV_OFFSET_STRUCT psOffsetStruct;
87525 +
87526 +               list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
87527 +        {
87528 +               off--;
87529 +               if (off == 0)
87530 +               {
87531 +                               PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
87532 +                               return (void*)psOffsetStruct;
87533 +                   }
87534 +        }
87535 +    }
87536 +       return (void*)0;
87537 +}
87538 +
87539 +static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off)
87540 +{
87541 +       return ProcSeqOff2ElementMMapRegistrations(sfile,off);
87542 +}
87543 +
87544 +
87545 +static void ProcSeqShowMMapRegistrations(struct seq_file *sfile,void* el)
87546 +{
87547 +       KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el;
87548 +    LinuxMemArea *psLinuxMemArea;
87549 +       IMG_UINT32 ui32RealByteSize;
87550 +       IMG_UINT32 ui32ByteOffset;
87551 +
87552 +       if(el == PVR_PROC_SEQ_START_TOKEN)
87553 +       {
87554 +        seq_printf( sfile,
87555 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
87556 +                                                 "Allocations registered for mmap: %lu\n"
87557 +                          "In total these areas correspond to %lu bytes\n"
87558 +                          "psLinuxMemArea "
87559 +                                                 "UserVAddr "
87560 +                                                 "KernelVAddr "
87561 +                                                 "CpuPAddr "
87562 +                          "MMapOffset "
87563 +                          "ByteLength "
87564 +                          "LinuxMemType             "
87565 +                                                 "Pid   Name     Flags\n",
87566 +#else
87567 +                          "<mmap_header>\n"
87568 +                          "\t<count>%lu</count>\n"
87569 +                          "\t<bytes>%lu</bytes>\n"
87570 +                          "</mmap_header>\n",
87571 +#endif
87572 +                                                 g_ui32RegisteredAreas,
87573 +                          g_ui32TotalByteSize
87574 +                          );
87575 +               return;
87576 +       }
87577 +
87578 +       psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
87579 +
87580 +       DetermineUsersSizeAndByteOffset(psLinuxMemArea,
87581 +                                                                       &ui32RealByteSize,
87582 +                                                                       &ui32ByteOffset);
87583 +
87584 +       seq_printf( sfile,
87585 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
87586 +                                               "%-8p       %08lx %-8p %08lx %08lx   %-8ld   %-24s %-5lu %-8s %08lx(%s)\n",
87587 +#else
87588 +                        "<mmap_record>\n"
87589 +                                               "\t<pointer>%-8p</pointer>\n"
87590 +                        "\t<user_virtual>%-8lx</user_virtual>\n"
87591 +                        "\t<kernel_virtual>%-8p</kernel_virtual>\n"
87592 +                        "\t<cpu_physical>%08lx</cpu_physical>\n"
87593 +                        "\t<mmap_offset>%08lx</mmap_offset>\n"
87594 +                        "\t<bytes>%-8ld</bytes>\n"
87595 +                        "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
87596 +                        "\t<pid>%-5lu</pid>\n"
87597 +                        "\t<name>%-8s</name>\n"
87598 +                        "\t<flags>%08lx</flags>\n"
87599 +                        "\t<flags_string>%s</flags_string>\n"
87600 +                        "</mmap_record>\n",
87601 +#endif
87602 +                        psLinuxMemArea,
87603 +                                               psOffsetStruct->ui32UserVAddr + ui32ByteOffset,
87604 +                                               LinuxMemAreaToCpuVAddr(psLinuxMemArea),
87605 +                        LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr,
87606 +                                               psOffsetStruct->ui32MMapOffset,
87607 +                                               psLinuxMemArea->ui32ByteSize,
87608 +                        LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType),
87609 +                                               psOffsetStruct->ui32PID,
87610 +                                               psOffsetStruct->pszName,
87611 +                                               psLinuxMemArea->ui32AreaFlags,
87612 +                        HAPFlagsToString(psLinuxMemArea->ui32AreaFlags));
87613 +}
87614 +
87615 +#else
87616 +
87617 +static off_t
87618 +PrintMMapRegistrations(IMG_CHAR *buffer, size_t size, off_t off)
87619 +{
87620 +    LinuxMemArea *psLinuxMemArea;
87621 +    off_t Ret;
87622 +
87623 +    LinuxLockMutex(&g_sMMapMutex);
87624 +
87625 +    if(!off)
87626 +    {
87627 +               Ret = printAppend(buffer, size, 0,
87628 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
87629 +                                                 "Allocations registered for mmap: %lu\n"
87630 +                          "In total these areas correspond to %lu bytes\n"
87631 +                          "psLinuxMemArea "
87632 +                                                 "UserVAddr "
87633 +                                                 "KernelVAddr "
87634 +                                                 "CpuPAddr "
87635 +                          "MMapOffset "
87636 +                          "ByteLength "
87637 +                          "LinuxMemType             "
87638 +                                                 "Pid   Name     Flags\n",
87639 +#else
87640 +                          "<mmap_header>\n"
87641 +                          "\t<count>%lu</count>\n"
87642 +                          "\t<bytes>%lu</bytes>\n"
87643 +                          "</mmap_header>\n",
87644 +#endif
87645 +                                                 g_ui32RegisteredAreas,
87646 +                          g_ui32TotalByteSize
87647 +                          );
87648 +
87649 +        goto unlock_and_return;
87650 +    }
87651 +
87652 +    if (size < 135)
87653 +    {
87654 +               Ret = 0;
87655 +        goto unlock_and_return;
87656 +    }
87657 +
87658 +    PVR_ASSERT(off != 0);
87659 +    list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
87660 +    {
87661 +        PKV_OFFSET_STRUCT psOffsetStruct;
87662 +
87663 +       list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
87664 +        {
87665 +           off--;
87666 +           if (off == 0)
87667 +           {
87668 +               IMG_UINT32 ui32RealByteSize;
87669 +               IMG_UINT32 ui32ByteOffset;
87670 +
87671 +               PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
87672 +
87673 +               DetermineUsersSizeAndByteOffset(psLinuxMemArea,
87674 +                                   &ui32RealByteSize,
87675 +                                   &ui32ByteOffset);
87676 +
87677 +                Ret =  printAppend (buffer, size, 0,
87678 +#if !defined(DEBUG_LINUX_XML_PROC_FILES)
87679 +                                               "%-8p       %08lx %-8p %08lx %08lx   %-8ld   %-24s %-5lu %-8s %08lx(%s)\n",
87680 +#else
87681 +                        "<mmap_record>\n"
87682 +                                               "\t<pointer>%-8p</pointer>\n"
87683 +                        "\t<user_virtual>%-8lx</user_virtual>\n"
87684 +                        "\t<kernel_virtual>%-8p</kernel_virtual>\n"
87685 +                        "\t<cpu_physical>%08lx</cpu_physical>\n"
87686 +                        "\t<mmap_offset>%08lx</mmap_offset>\n"
87687 +                        "\t<bytes>%-8ld</bytes>\n"
87688 +                        "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
87689 +                        "\t<pid>%-5lu</pid>\n"
87690 +                        "\t<name>%-8s</name>\n"
87691 +                        "\t<flags>%08lx</flags>\n"
87692 +                        "\t<flags_string>%s</flags_string>\n"
87693 +                        "</mmap_record>\n",
87694 +#endif
87695 +                        psLinuxMemArea,
87696 +                       psOffsetStruct->ui32UserVAddr + ui32ByteOffset,
87697 +                                               LinuxMemAreaToCpuVAddr(psLinuxMemArea),
87698 +                        LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr,
87699 +                                               psOffsetStruct->ui32MMapOffset,
87700 +                                               psLinuxMemArea->ui32ByteSize,
87701 +                        LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType),
87702 +                                               psOffsetStruct->ui32PID,
87703 +                                               psOffsetStruct->pszName,
87704 +                                               psLinuxMemArea->ui32AreaFlags,
87705 +                        HAPFlagsToString(psLinuxMemArea->ui32AreaFlags));
87706 +               goto unlock_and_return;
87707 +           }
87708 +        }
87709 +    }
87710 +    Ret = END_OF_FILE;
87711 +
87712 +unlock_and_return:
87713 +    LinuxUnLockMutex(&g_sMMapMutex);
87714 +    return Ret;
87715 +}
87716 +#endif
87717 +#endif
87718 +
87719 +
87720 +PVRSRV_ERROR
87721 +PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea)
87722 +{
87723 +    PVRSRV_ERROR eError;
87724 +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
87725 +    const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
87726 +#endif
87727 +
87728 +    LinuxLockMutex(&g_sMMapMutex);
87729 +
87730 +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
87731 +    PVR_DPF((PVR_DBG_MESSAGE,
87732 +             "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8lx)",
87733 +             __FUNCTION__, pszName, psLinuxMemArea,  psLinuxMemArea->ui32AreaFlags));
87734 +#endif
87735 +
87736 +    PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
87737 +
87738 +
87739 +    if(psLinuxMemArea->bMMapRegistered)
87740 +    {
87741 +        PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered",
87742 +                __FUNCTION__, psLinuxMemArea));
87743 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
87744 +       goto exit_unlock;
87745 +    }
87746 +
87747 +    list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList);
87748 +
87749 +    psLinuxMemArea->bMMapRegistered = IMG_TRUE;
87750 +
87751 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87752 +    g_ui32RegisteredAreas++;
87753 +
87754 +    if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
87755 +    {
87756 +        g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize;
87757 +    }
87758 +#endif
87759 +
87760 +    eError = PVRSRV_OK;
87761 +
87762 +exit_unlock:
87763 +    LinuxUnLockMutex(&g_sMMapMutex);
87764 +
87765 +    return eError;
87766 +}
87767 +
87768 +
87769 +PVRSRV_ERROR
87770 +PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
87771 +{
87772 +    PVRSRV_ERROR eError;
87773 +    PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
87774 +
87775 +    LinuxLockMutex(&g_sMMapMutex);
87776 +
87777 +    PVR_ASSERT(psLinuxMemArea->bMMapRegistered);
87778 +
87779 +    list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
87780 +    {
87781 +       if (psOffsetStruct->ui32Mapped != 0)
87782 +       {
87783 +            PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %lu",  __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
87784 +               eError = PVRSRV_ERROR_GENERIC;
87785 +               goto exit_unlock;
87786 +       }
87787 +       else
87788 +       {
87789 +
87790 +            PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped",  __FUNCTION__, psOffsetStruct));
87791 +       }
87792 +
87793 +       PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList);
87794 +
87795 +       DestroyOffsetStruct(psOffsetStruct);
87796 +    }
87797 +
87798 +    list_del(&psLinuxMemArea->sMMapItem);
87799 +
87800 +    psLinuxMemArea->bMMapRegistered = IMG_FALSE;
87801 +
87802 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87803 +    g_ui32RegisteredAreas--;
87804 +    if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
87805 +    {
87806 +        g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize;
87807 +    }
87808 +#endif
87809 +
87810 +    eError = PVRSRV_OK;
87811 +
87812 +exit_unlock:
87813 +    LinuxUnLockMutex(&g_sMMapMutex);
87814 +    return eError;
87815 +}
87816 +
87817 +
87818 +PVRSRV_ERROR
87819 +LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
87820 +{
87821 +    PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
87822 +
87823 +    return PVRSRV_OK;
87824 +}
87825 +
87826 +IMG_VOID
87827 +LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
87828 +{
87829 +    PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct;
87830 +    IMG_BOOL bWarn = IMG_FALSE;
87831 +    IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
87832 +
87833 +    PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
87834 +
87835 +    LinuxLockMutex(&g_sMMapMutex);
87836 +
87837 +    list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
87838 +    {
87839 +       if (psOffsetStruct->ui32PID == ui32PID)
87840 +       {
87841 +           if (!bWarn)
87842 +           {
87843 +               PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__));
87844 +               bWarn = IMG_TRUE;
87845 +           }
87846 +           PVR_ASSERT(psOffsetStruct->ui32Mapped == 0);
87847 +           PVR_ASSERT(psOffsetStruct->bOnMMapList);
87848 +
87849 +           DestroyOffsetStruct(psOffsetStruct);
87850 +       }
87851 +    }
87852 +
87853 +    LinuxUnLockMutex(&g_sMMapMutex);
87854 +}
87855 +
87856 +
87857 +PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
87858 +{
87859 +    PVRSRV_ERROR eError;
87860 +
87861 +    eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE);
87862 +    if (eError != PVRSRV_OK)
87863 +    {
87864 +       PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError));
87865 +       return eError;
87866 +    }
87867 +
87868 +    return eError;
87869 +}
87870 +
87871 +
87872 +IMG_VOID
87873 +PVRMMapInit(IMG_VOID)
87874 +{
87875 +    LinuxInitMutex(&g_sMMapMutex);
87876 +
87877 +    g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0);
87878 +    if (!g_psMemmapCache)
87879 +    {
87880 +        PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
87881 +       goto error;
87882 +    }
87883 +
87884 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87885 +#ifdef PVR_PROC_USE_SEQ_FILE
87886 +       g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL,
87887 +                                                 ProcSeqNextMMapRegistrations,
87888 +                                                 ProcSeqShowMMapRegistrations,
87889 +                                                 ProcSeqOff2ElementMMapRegistrations,
87890 +                                                 ProcSeqStartstopMMapRegistations
87891 +                                                );
87892 +#else
87893 +    CreateProcReadEntry("mmap", PrintMMapRegistrations);
87894 +#endif
87895 +#endif
87896 +    return;
87897 +
87898 +error:
87899 +    PVRMMapCleanup();
87900 +    return;
87901 +}
87902 +
87903 +
87904 +IMG_VOID
87905 +PVRMMapCleanup(IMG_VOID)
87906 +{
87907 +    PVRSRV_ERROR eError;
87908 +
87909 +    if (!list_empty(&g_sMMapAreaList))
87910 +    {
87911 +       LinuxMemArea *psLinuxMemArea, *psTmpMemArea;
87912 +
87913 +       PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__));
87914 +
87915 +       PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__));
87916 +       list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem)
87917 +       {
87918 +               eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
87919 +               if (eError != PVRSRV_OK)
87920 +               {
87921 +                       PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError));
87922 +               }
87923 +               PVR_ASSERT(eError == PVRSRV_OK);
87924 +
87925 +               LinuxMemAreaDeepFree(psLinuxMemArea);
87926 +       }
87927 +    }
87928 +    PVR_ASSERT(list_empty((&g_sMMapAreaList)));
87929 +
87930 +#if defined(DEBUG_LINUX_MMAP_AREAS)
87931 +#ifdef PVR_PROC_USE_SEQ_FILE
87932 +    RemoveProcEntrySeq(g_ProcMMap);
87933 +#else
87934 +    RemoveProcEntry("mmap");
87935 +#endif
87936 +#endif
87937 +
87938 +    if(g_psMemmapCache)
87939 +    {
87940 +        KMemCacheDestroyWrapper(g_psMemmapCache);
87941 +        g_psMemmapCache = NULL;
87942 +    }
87943 +}
87944 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.h
87945 new file mode 100644
87946 index 0000000..5c9f2b2
87947 --- /dev/null
87948 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mmap.h
87949 @@ -0,0 +1,107 @@
87950 +/**********************************************************************
87951 + *
87952 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
87953 + * 
87954 + * This program is free software; you can redistribute it and/or modify it
87955 + * under the terms and conditions of the GNU General Public License,
87956 + * version 2, as published by the Free Software Foundation.
87957 + * 
87958 + * This program is distributed in the hope it will be useful but, except 
87959 + * as otherwise stated in writing, without any warranty; without even the 
87960 + * implied warranty of merchantability or fitness for a particular purpose. 
87961 + * See the GNU General Public License for more details.
87962 + * 
87963 + * You should have received a copy of the GNU General Public License along with
87964 + * this program; if not, write to the Free Software Foundation, Inc.,
87965 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
87966 + * 
87967 + * The full GNU General Public License is included in this distribution in
87968 + * the file called "COPYING".
87969 + *
87970 + * Contact Information:
87971 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
87972 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
87973 + *
87974 + ******************************************************************************/
87975 +
87976 +#if !defined(__MMAP_H__)
87977 +#define __MMAP_H__
87978 +
87979 +#include <linux/mm.h>
87980 +#include <linux/list.h>
87981 +
87982 +#include "perproc.h"
87983 +#include "mm.h"
87984 +
87985 +typedef struct KV_OFFSET_STRUCT_TAG
87986 +{
87987 +    
87988 +    IMG_UINT32                 ui32Mapped;
87989 +
87990 +    
87991 +    IMG_UINT32                  ui32MMapOffset;
87992 +    
87993 +    IMG_UINT32                 ui32RealByteSize;
87994 +
87995 +    
87996 +    LinuxMemArea                *psLinuxMemArea;
87997 +    
87998 +    
87999 +    IMG_UINT32                 ui32TID;
88000 +
88001 +    
88002 +    IMG_UINT32                 ui32PID;
88003 +
88004 +    
88005 +    IMG_BOOL                   bOnMMapList;
88006 +
88007 +    
88008 +    IMG_UINT32                 ui32RefCount;
88009 +
88010 +    
88011 +    IMG_UINT32                 ui32UserVAddr;
88012 +
88013 +    
88014 +#if defined(DEBUG_LINUX_MMAP_AREAS)
88015 +    const IMG_CHAR             *pszName;
88016 +#endif
88017 +    
88018 +   
88019 +   struct list_head            sMMapItem;
88020 +
88021 +   
88022 +   struct list_head            sAreaItem;
88023 +}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT;
88024 +
88025 +
88026 +
88027 +IMG_VOID PVRMMapInit(IMG_VOID);
88028 +
88029 +
88030 +IMG_VOID PVRMMapCleanup(IMG_VOID);
88031 +
88032 +
88033 +PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea);
88034 +
88035 +
88036 +PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea);
88037 +
88038 +
88039 +PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
88040 +                                            IMG_HANDLE hMHandle,
88041 +                                             IMG_UINT32 *pui32MMapOffset,
88042 +                                             IMG_UINT32 *pui32ByteOffset,
88043 +                                             IMG_UINT32 *pui32RealByteSize,                                                 IMG_UINT32 *pui32UserVAddr);
88044 +
88045 +PVRSRV_ERROR
88046 +PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
88047 +                               IMG_HANDLE hMHandle,
88048 +                               IMG_BOOL *pbMUnmap,
88049 +                               IMG_UINT32 *pui32RealByteSize,
88050 +                                IMG_UINT32 *pui32UserVAddr);
88051 +
88052 +int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
88053 +
88054 +
88055 +#endif 
88056 +
88057 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/module.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/module.c
88058 new file mode 100644
88059 index 0000000..150fea5
88060 --- /dev/null
88061 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/module.c
88062 @@ -0,0 +1,765 @@
88063 +/**********************************************************************
88064 + *
88065 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
88066 + * 
88067 + * This program is free software; you can redistribute it and/or modify it
88068 + * under the terms and conditions of the GNU General Public License,
88069 + * version 2, as published by the Free Software Foundation.
88070 + * 
88071 + * This program is distributed in the hope it will be useful but, except 
88072 + * as otherwise stated in writing, without any warranty; without even the 
88073 + * implied warranty of merchantability or fitness for a particular purpose. 
88074 + * See the GNU General Public License for more details.
88075 + * 
88076 + * You should have received a copy of the GNU General Public License along with
88077 + * this program; if not, write to the Free Software Foundation, Inc.,
88078 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
88079 + * 
88080 + * The full GNU General Public License is included in this distribution in
88081 + * the file called "COPYING".
88082 + *
88083 + * Contact Information:
88084 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
88085 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
88086 + *
88087 + ******************************************************************************/
88088 +
88089 +#ifndef AUTOCONF_INCLUDED
88090 + #include <linux/config.h>
88091 +#endif
88092 +
88093 +#if !defined(SUPPORT_DRI_DRM)
88094 +       
88095 +       #if defined(LDM_PLATFORM)
88096 +               #define PVR_LDM_PLATFORM_MODULE
88097 +               #define PVR_LDM_MODULE
88098 +       #else
88099 +               #if defined(LDM_PCI)
88100 +                       #define PVR_LDM_PCI_MODULE
88101 +                       #define PVR_LDM_MODULE
88102 +               #endif
88103 +       #endif
88104 +#endif
88105 +
88106 +#include <linux/init.h>
88107 +#include <linux/kernel.h>
88108 +#include <linux/module.h>
88109 +#include <linux/version.h>
88110 +#include <linux/fs.h>
88111 +#include <linux/proc_fs.h>
88112 +
88113 +#if defined(SUPPORT_DRI_DRM)
88114 +#include <drm/drmP.h>
88115 +#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
88116 +#include "env_perproc.h"
88117 +#endif
88118 +#endif
88119 +
88120 +#if defined(PVR_LDM_PLATFORM_MODULE)
88121 +#include <linux/platform_device.h>
88122 +#endif 
88123 +
88124 +#if defined(PVR_LDM_PCI_MODULE)
88125 +#include <linux/pci.h>
88126 +#endif 
88127 +
88128 +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
88129 +#include <asm/uaccess.h>
88130 +#endif
88131 +
88132 +#include "img_defs.h"
88133 +#include "services.h"
88134 +#include "kerneldisplay.h"
88135 +#include "kernelbuffer.h"
88136 +#include "syscommon.h"
88137 +#include "pvrmmap.h"
88138 +#include "mutils.h"
88139 +#include "mm.h"
88140 +#include "mmap.h"
88141 +#include "mutex.h"
88142 +#include "pvr_debug.h"
88143 +#include "srvkm.h"
88144 +#include "perproc.h"
88145 +#include "handle.h"
88146 +#include "pvr_bridge_km.h"
88147 +#include "proc.h"
88148 +#include "pvrmodule.h"
88149 +#include "private_data.h"
88150 +#include "lock.h"
88151 +#include "linkage.h"
88152 +
88153 +#if defined(SUPPORT_DRI_DRM)
88154 +#include "pvr_drm.h"
88155 +#endif
88156 +#define DRVNAME                "pvrsrvkm"
88157 +#define DEVNAME                "pvrsrvkm"
88158 +
88159 +#if defined(SUPPORT_DRI_DRM)
88160 +#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
88161 +#else
88162 +#define PRIVATE_DATA(pFile) ((pFile)->private_data)
88163 +#endif
88164 +
88165 +MODULE_SUPPORTED_DEVICE(DEVNAME);
88166 +#ifdef DEBUG
88167 +static IMG_INT debug = DBGPRIV_WARNING;
88168 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
88169 +#include <linux/moduleparam.h>
88170 +module_param(debug, int, 0);
88171 +#else
88172 +MODULE_PARM(debug, "i");
88173 +MODULE_PARM_DESC(debug, "Sets the level of debug output (default=0x4)");
88174 +#endif
88175 +#endif
88176 +
88177 +
88178 +extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
88179 +extern IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
88180
88181 +EXPORT_SYMBOL(PVRGetDisplayClassJTable);
88182 +EXPORT_SYMBOL(PVRGetBufferClassJTable);
88183 +
88184 +
88185 +#if defined(PVR_LDM_MODULE)
88186 +static struct class *psPvrClass;
88187 +#endif
88188 +
88189 +#if !defined(SUPPORT_DRI_DRM)
88190 +static IMG_INT AssignedMajorNumber;
88191 +
88192 +static IMG_INT PVRSRVOpen(struct inode* pInode, struct file* pFile);
88193 +static IMG_INT PVRSRVRelease(struct inode* pInode, struct file* pFile);
88194 +
88195 +static struct file_operations pvrsrv_fops = {
88196 +       .owner=THIS_MODULE,
88197 +       .unlocked_ioctl=PVRSRV_BridgeDispatchKM,
88198 +       .open=PVRSRVOpen,
88199 +       .release=PVRSRVRelease,
88200 +       .mmap=PVRMMap,
88201 +};
88202 +#endif
88203 +
88204 +PVRSRV_LINUX_MUTEX gPVRSRVLock;
88205 +
88206 +IMG_UINT32 gui32ReleasePID;
88207 +
88208 +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
88209 +static IMG_UINT32 gPVRPowerLevel;
88210 +#endif
88211 +
88212 +#if defined(PVR_LDM_MODULE)
88213 +
88214 +#if defined(PVR_LDM_PLATFORM_MODULE)
88215 +#define        LDM_DEV struct platform_device
88216 +#define        LDM_DRV struct platform_driver
88217 +#endif 
88218 +
88219 +#if defined(PVR_LDM_PCI_MODULE)
88220 +#define        LDM_DEV struct pci_dev
88221 +#define        LDM_DRV struct pci_driver
88222 +#endif 
88223 +
88224 +#if defined(PVR_LDM_PLATFORM_MODULE)
88225 +static IMG_INT PVRSRVDriverRemove(LDM_DEV *device);
88226 +static IMG_INT PVRSRVDriverProbe(LDM_DEV *device);
88227 +#endif
88228 +#if defined(PVR_LDM_PCI_MODULE)
88229 +static IMG_VOID PVRSRVDriverRemove(LDM_DEV *device);
88230 +static IMG_INT PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
88231 +#endif
88232 +static IMG_INT PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
88233 +static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *device);
88234 +static IMG_INT PVRSRVDriverResume(LDM_DEV *device);
88235 +
88236 +#if defined(PVR_LDM_PCI_MODULE)
88237 +struct pci_device_id powervr_id_table[] __devinitdata = {
88238 +       { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID) },
88239 +       { 0 }
88240 +};
88241 +
88242 +MODULE_DEVICE_TABLE(pci, powervr_id_table);
88243 +#endif
88244 +
88245 +static LDM_DRV powervr_driver = {
88246 +#if defined(PVR_LDM_PLATFORM_MODULE)
88247 +       .driver = {
88248 +               .name           = DRVNAME,
88249 +       },
88250 +#endif
88251 +#if defined(PVR_LDM_PCI_MODULE)
88252 +       .name           = DRVNAME,
88253 +       .id_table = powervr_id_table,
88254 +#endif
88255 +       .probe          = PVRSRVDriverProbe,
88256 +#if defined(PVR_LDM_PLATFORM_MODULE)
88257 +       .remove         = PVRSRVDriverRemove,
88258 +#endif
88259 +#if defined(PVR_LDM_PCI_MODULE)
88260 +       .remove         = __devexit_p(PVRSRVDriverRemove),
88261 +#endif
88262 +       .suspend        = PVRSRVDriverSuspend,
88263 +       .resume         = PVRSRVDriverResume,
88264 +       .shutdown       = PVRSRVDriverShutdown,
88265 +};
88266 +
88267 +LDM_DEV *gpsPVRLDMDev;
88268 +
88269 +#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE)
88270 +
88271 +static IMG_VOID PVRSRVDeviceRelease(struct device *pDevice)
88272 +{
88273 +       PVR_UNREFERENCED_PARAMETER(pDevice);
88274 +}
88275 +
88276 +static struct platform_device powervr_device = {
88277 +       .name                   = DEVNAME,
88278 +       .id                             = -1,
88279 +       .dev                    = {
88280 +               .release        = PVRSRVDeviceRelease
88281 +       }
88282 +};
88283 +
88284 +#endif 
88285 +
88286 +#if defined(PVR_LDM_PLATFORM_MODULE)
88287 +static IMG_INT PVRSRVDriverProbe(LDM_DEV *pDevice)
88288 +#endif
88289 +#if defined(PVR_LDM_PCI_MODULE)
88290 +static IMG_INT __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
88291 +#endif
88292 +{
88293 +       SYS_DATA *psSysData;
88294 +
88295 +       PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
88296 +
88297 +#if 0
88298 +       
88299 +       if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
88300 +       {
88301 +               return -EINVAL;
88302 +       }
88303 +#endif 
88304 +       
88305 +       if (SysAcquireData(&psSysData) != PVRSRV_OK)
88306 +       {
88307 +               gpsPVRLDMDev = pDevice;
88308 +
88309 +               if (SysInitialise() != PVRSRV_OK)
88310 +               {
88311 +                       return -ENODEV;
88312 +               }
88313 +       }
88314 +
88315 +       return 0;
88316 +}
88317 +
88318 +
88319 +#if defined (PVR_LDM_PLATFORM_MODULE)
88320 +static IMG_INT PVRSRVDriverRemove(LDM_DEV *pDevice)
88321 +#endif
88322 +#if defined(PVR_LDM_PCI_MODULE)
88323 +static IMG_VOID __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
88324 +#endif
88325 +{
88326 +       SYS_DATA *psSysData;
88327 +
88328 +       PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
88329 +
88330 +       if (SysAcquireData(&psSysData) == PVRSRV_OK)
88331 +       {
88332 +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
88333 +               if (gPVRPowerLevel != 0)
88334 +               {
88335 +                       if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
88336 +                       {
88337 +                               gPVRPowerLevel = 0;
88338 +                       }
88339 +               }
88340 +#endif
88341 +               SysDeinitialise(psSysData);
88342 +
88343 +               gpsPVRLDMDev = IMG_NULL;
88344 +       }
88345 +
88346 +#if 0
88347 +       if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
88348 +       {
88349 +               return -EINVAL;
88350 +       }
88351 +#endif
88352 +
88353 +#if defined (PVR_LDM_PLATFORM_MODULE)
88354 +       return 0;
88355 +#endif
88356 +#if defined (PVR_LDM_PCI_MODULE)
88357 +       return;
88358 +#endif
88359 +}
88360 +
88361 +
88362 +static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *pDevice)
88363 +{
88364 +       PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
88365 +
88366 +       (IMG_VOID) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
88367 +}
88368 +
88369 +#endif 
88370 +
88371 +
88372 +#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
88373 +#if defined(SUPPORT_DRI_DRM)
88374 +IMG_INT PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
88375 +#else
88376 +static IMG_INT PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
88377 +#endif
88378 +{
88379 +#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
88380 +       PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
88381 +
88382 +       if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
88383 +       {
88384 +               return -EINVAL;
88385 +       }
88386 +#endif
88387 +       return 0;
88388 +}
88389 +
88390 +
88391 +#if defined(SUPPORT_DRI_DRM)
88392 +IMG_INT PVRSRVDriverResume(struct drm_device *pDevice)
88393 +#else
88394 +static IMG_INT PVRSRVDriverResume(LDM_DEV *pDevice)
88395 +#endif
88396 +{
88397 +#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
88398 +       PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
88399 +
88400 +       if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
88401 +       {
88402 +               return -EINVAL;
88403 +       }
88404 +#endif
88405 +       return 0;
88406 +}
88407 +#endif 
88408 +
88409 +
88410 +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
88411 +IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
88412 +{
88413 +       IMG_CHAR data_buffer[2];
88414 +       IMG_UINT32 PVRPowerLevel;
88415 +
88416 +       if (count != sizeof(data_buffer))
88417 +       {
88418 +               return -EINVAL;
88419 +       }
88420 +       else
88421 +       {
88422 +               if (copy_from_user(data_buffer, buffer, count))
88423 +                       return -EINVAL;
88424 +               if (data_buffer[count - 1] != '\n')
88425 +                       return -EINVAL;
88426 +               PVRPowerLevel = data_buffer[0] - '0';
88427 +               if (PVRPowerLevel != gPVRPowerLevel)
88428 +               {
88429 +                       if (PVRPowerLevel != 0)
88430 +                       {
88431 +                               if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
88432 +                               {
88433 +                                       return -EINVAL;
88434 +                               }
88435 +                       }
88436 +                       else
88437 +                       {
88438 +                               if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
88439 +                               {
88440 +                                       return -EINVAL;
88441 +                               }
88442 +                       }
88443 +
88444 +                       gPVRPowerLevel = PVRPowerLevel;
88445 +               }
88446 +       }
88447 +       return (count);
88448 +}
88449 +
88450 +#ifdef PVR_PROC_USE_SEQ_FILE
88451 +void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)    
88452 +{
88453 +       seq_printf(sfile, "%lu\n", gPVRPowerLevel);
88454 +}
88455 +
88456 +#else 
88457 +IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
88458 +{
88459 +       if (off == 0) {
88460 +               *start = (IMG_CHAR *)1;
88461 +               return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel);
88462 +       }
88463 +       *eof = 1;
88464 +       return 0;
88465 +}
88466 +#endif 
88467 +
88468 +#endif
88469 +
88470 +#if defined(SUPPORT_DRI_DRM)
88471 +IMG_INT PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
88472 +#else
88473 +static IMG_INT PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
88474 +#endif
88475 +{
88476 +       PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
88477 +       IMG_HANDLE hBlockAlloc;
88478 +       IMG_INT iRet = -ENOMEM;
88479 +       PVRSRV_ERROR eError;
88480 +       IMG_UINT32 ui32PID;
88481 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
88482 +       PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
88483 +#endif
88484 +
88485 +#if defined(SUPPORT_DRI_DRM)
88486 +       PVR_UNREFERENCED_PARAMETER(dev);
88487 +#else
88488 +       PVR_UNREFERENCED_PARAMETER(pInode);
88489 +#endif
88490 +
88491 +       LinuxLockMutex(&gPVRSRVLock);
88492 +
88493 +       ui32PID = OSGetCurrentProcessIDKM();
88494 +
88495 +       if (PVRSRVProcessConnect(ui32PID) != PVRSRV_OK)
88496 +               goto err_unlock;
88497 +
88498 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
88499 +       psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
88500 +       if (psEnvPerProc == IMG_NULL)
88501 +       {
88502 +               PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
88503 +               goto err_unlock;
88504 +       }
88505 +#endif
88506 +
88507 +       eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
88508 +                                               sizeof(PVRSRV_FILE_PRIVATE_DATA),
88509 +                                               (IMG_PVOID *)&psPrivateData,
88510 +                                               &hBlockAlloc,
88511 +                                               "File Private Data");
88512 +
88513 +       if(eError != PVRSRV_OK)
88514 +               goto err_unlock;
88515 +
88516 +#if defined(PVR_SECURE_FD_EXPORT)
88517 +       psPrivateData->hKernelMemInfo = NULL;
88518 +#endif
88519 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
88520 +       psPrivateData->psDRMFile = pFile;
88521 +
88522 +       list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
88523 +#endif
88524 +       psPrivateData->ui32OpenPID = ui32PID;
88525 +       psPrivateData->hBlockAlloc = hBlockAlloc;
88526 +       PRIVATE_DATA(pFile) = psPrivateData;
88527 +       iRet = 0;
88528 +err_unlock:    
88529 +       LinuxUnLockMutex(&gPVRSRVLock);
88530 +       return iRet;
88531 +}
88532 +
88533 +
88534 +#if defined(SUPPORT_DRI_DRM)
88535 +IMG_INT PVRSRVRelease(struct drm_device unref__ *dev, struct drm_file *pFile)
88536 +#else
88537 +static IMG_INT PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
88538 +#endif
88539 +{
88540 +       PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
88541 +
88542 +#if defined(SUPPORT_DRI_DRM)
88543 +       PVR_UNREFERENCED_PARAMETER(dev);
88544 +#else
88545 +       PVR_UNREFERENCED_PARAMETER(pInode);
88546 +#endif
88547 +
88548 +       LinuxLockMutex(&gPVRSRVLock);
88549 +
88550 +       psPrivateData = PRIVATE_DATA(pFile);
88551 +
88552 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
88553 +       list_del(&psPrivateData->sDRMAuthListItem);
88554 +#endif
88555 +
88556 +       
88557 +       gui32ReleasePID = psPrivateData->ui32OpenPID;
88558 +       PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
88559 +       gui32ReleasePID = 0;
88560 +
88561 +       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
88562 +                         sizeof(PVRSRV_FILE_PRIVATE_DATA),
88563 +                         psPrivateData, psPrivateData->hBlockAlloc);
88564 +       PRIVATE_DATA(pFile) = NULL; 
88565 +
88566 +       LinuxUnLockMutex(&gPVRSRVLock);
88567 +       return 0;
88568 +}
88569 +
88570 +
88571 +#if defined(SUPPORT_DRI_DRM)
88572 +IMG_INT PVRCore_Init(IMG_VOID)
88573 +#else
88574 +static IMG_INT __init PVRCore_Init(IMG_VOID)
88575 +#endif
88576 +{
88577 +       IMG_INT error;
88578 +#if !defined(PVR_LDM_MODULE)
88579 +       PVRSRV_ERROR eError;
88580 +#else
88581 +       struct device *psDev;
88582 +#endif
88583 +
88584 +#if !defined(SUPPORT_DRI_DRM)
88585 +       
88586 +       PVRDPFInit();
88587 +#endif
88588 +       PVR_TRACE(("PVRCore_Init"));
88589 +
88590 +       LinuxInitMutex(&gPVRSRVLock);
88591 +
88592 +#ifdef DEBUG
88593 +       PVRDebugSetLevel(debug);
88594 +#endif
88595 +
88596 +       if (CreateProcEntries ())
88597 +       {
88598 +               error = -ENOMEM;
88599 +               return error;
88600 +       }
88601 +
88602 +       if (PVROSFuncInit() != PVRSRV_OK)
88603 +       {
88604 +               error = -ENOMEM;
88605 +               goto init_failed;
88606 +       }
88607 +
88608 +       PVRLinuxMUtilsInit();
88609 +
88610 +       if(LinuxMMInit() != PVRSRV_OK)
88611 +       {
88612 +               error = -ENOMEM;
88613 +               goto init_failed;
88614 +       }
88615 +
88616 +       LinuxBridgeInit();
88617 +
88618 +       PVRMMapInit();
88619 +
88620 +#if defined(PVR_LDM_MODULE)
88621 +
88622 +#if defined(PVR_LDM_PLATFORM_MODULE)
88623 +       if ((error = platform_driver_register(&powervr_driver)) != 0)
88624 +       {
88625 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
88626 +
88627 +               goto init_failed;
88628 +       }
88629 +
88630 +#if defined(MODULE)
88631 +       if ((error = platform_device_register(&powervr_device)) != 0)
88632 +       {
88633 +               platform_driver_unregister(&powervr_driver);
88634 +
88635 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
88636 +
88637 +               goto init_failed;
88638 +       }
88639 +#endif
88640 +#endif 
88641 +
88642 +#if defined(PVR_LDM_PCI_MODULE)
88643 +       if ((error = pci_register_driver(&powervr_driver)) != 0)
88644 +       {
88645 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
88646 +
88647 +               goto init_failed;
88648 +       }
88649 +#endif 
88650 +
88651 +#else 
88652 +       
88653 +       if ((eError = SysInitialise()) != PVRSRV_OK)
88654 +       {
88655 +               error = -ENODEV;
88656 +#if defined(TCF_REV) && (TCF_REV == 110)
88657 +               if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
88658 +               {
88659 +                       printk("\nAtlas wrapper (FPGA image) version mismatch");
88660 +                       error = -ENODEV;
88661 +               }
88662 +#endif
88663 +               goto init_failed;
88664 +       }
88665 +#endif 
88666 +
88667 +#if !defined(SUPPORT_DRI_DRM)
88668 +       AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
88669 +
88670 +       if (AssignedMajorNumber <= 0)
88671 +       {
88672 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
88673 +
88674 +               error = -EBUSY;
88675 +               goto sys_deinit;
88676 +       }
88677 +
88678 +       PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
88679 +#endif 
88680 +
88681 +#if defined(PVR_LDM_MODULE)
88682 +       
88683 +       psPvrClass = class_create(THIS_MODULE, "pvr");
88684 +
88685 +       if (IS_ERR(psPvrClass))
88686 +       {
88687 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
88688 +               error = -EBUSY;
88689 +               goto unregister_device;
88690 +       }
88691 +
88692 +       psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
88693 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
88694 +                                 NULL,
88695 +#endif 
88696 +                                 DEVNAME);
88697 +       if (IS_ERR(psDev))
88698 +       {
88699 +               PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
88700 +               error = -EBUSY;
88701 +               goto destroy_class;
88702 +       }
88703 +#endif 
88704 +
88705 +       return 0;
88706 +
88707 +#if defined(PVR_LDM_MODULE)
88708 +destroy_class:
88709 +       class_destroy(psPvrClass);
88710 +unregister_device:
88711 +       unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME);
88712 +#endif
88713 +#if !defined(SUPPORT_DRI_DRM)
88714 +sys_deinit:
88715 +#endif
88716 +#if defined(PVR_LDM_MODULE)
88717 +#if defined(PVR_LDM_PCI_MODULE)
88718 +       pci_unregister_driver(&powervr_driver);
88719 +#endif
88720 +
88721 +#if defined (PVR_LDM_PLATFORM_MODULE)
88722 +#if defined (MODULE)
88723 +       platform_device_unregister(&powervr_device);
88724 +#endif
88725 +       platform_driver_unregister(&powervr_driver);
88726 +#endif
88727 +
88728 +#else  
88729 +       
88730 +       {
88731 +               SYS_DATA *psSysData;
88732 +
88733 +               SysAcquireData(&psSysData);
88734 +               if (psSysData != IMG_NULL)
88735 +               {
88736 +                       SysDeinitialise(psSysData);
88737 +               }
88738 +       }
88739 +#endif 
88740 +init_failed:
88741 +       PVRMMapCleanup();
88742 +       LinuxMMCleanup();
88743 +       LinuxBridgeDeInit();
88744 +       PVROSFuncDeInit();
88745 +       RemoveProcEntries();
88746 +
88747 +       return error;
88748 +
88749 +} 
88750 +
88751 +
88752 +#if defined(SUPPORT_DRI_DRM)
88753 +IMG_VOID PVRCore_Cleanup(IMG_VOID)
88754 +#else
88755 +static IMG_VOID __exit PVRCore_Cleanup(IMG_VOID)
88756 +#endif
88757 +{
88758 +       SYS_DATA *psSysData;
88759 +
88760 +       PVR_TRACE(("PVRCore_Cleanup"));
88761 +
88762 +       SysAcquireData(&psSysData);
88763 +
88764 +#if defined(PVR_LDM_MODULE)
88765 +       device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
88766 +       class_destroy(psPvrClass);
88767 +#endif
88768 +
88769 +#if !defined(SUPPORT_DRI_DRM)
88770 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
88771 +       if (
88772 +#endif 
88773 +               unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME)
88774 +#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
88775 +                                                               ;
88776 +#else  
88777 +                                                               )
88778 +       {
88779 +               PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
88780 +       }
88781 +#endif 
88782 +#endif 
88783 +
88784 +#if defined(PVR_LDM_MODULE)
88785 +
88786 +#if defined(PVR_LDM_PCI_MODULE)
88787 +       pci_unregister_driver(&powervr_driver);
88788 +#endif
88789 +
88790 +#if defined (PVR_LDM_PLATFORM_MODULE)
88791 +#if defined (MODULE)
88792 +       platform_device_unregister(&powervr_device);
88793 +#endif
88794 +       platform_driver_unregister(&powervr_driver);
88795 +#endif
88796 +
88797 +#else 
88798 +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
88799 +       if (gPVRPowerLevel != 0)
88800 +       {
88801 +               if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
88802 +               {
88803 +                       gPVRPowerLevel = 0;
88804 +               }
88805 +       }
88806 +#endif
88807 +       
88808 +       SysDeinitialise(psSysData);
88809 +#endif 
88810 +
88811 +       PVRMMapCleanup();
88812 +
88813 +       LinuxMMCleanup();
88814 +
88815 +       LinuxBridgeDeInit();
88816 +
88817 +       PVROSFuncDeInit();
88818 +
88819 +       RemoveProcEntries();
88820 +
88821 +       PVR_TRACE(("PVRCore_Cleanup: unloading"));
88822 +}
88823 +
88824 +#if !defined(SUPPORT_DRI_DRM)
88825 +module_init(PVRCore_Init);
88826 +module_exit(PVRCore_Cleanup);
88827 +#endif
88828 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.c
88829 new file mode 100644
88830 index 0000000..d66e697
88831 --- /dev/null
88832 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.c
88833 @@ -0,0 +1,136 @@
88834 +/**********************************************************************
88835 + *
88836 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
88837 + * 
88838 + * This program is free software; you can redistribute it and/or modify it
88839 + * under the terms and conditions of the GNU General Public License,
88840 + * version 2, as published by the Free Software Foundation.
88841 + * 
88842 + * This program is distributed in the hope it will be useful but, except 
88843 + * as otherwise stated in writing, without any warranty; without even the 
88844 + * implied warranty of merchantability or fitness for a particular purpose. 
88845 + * See the GNU General Public License for more details.
88846 + * 
88847 + * You should have received a copy of the GNU General Public License along with
88848 + * this program; if not, write to the Free Software Foundation, Inc.,
88849 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
88850 + * 
88851 + * The full GNU General Public License is included in this distribution in
88852 + * the file called "COPYING".
88853 + *
88854 + * Contact Information:
88855 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
88856 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
88857 + *
88858 + ******************************************************************************/
88859 +
88860 +#include <linux/version.h>
88861 +#include <linux/errno.h>
88862 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
88863 +#include <linux/mutex.h>
88864 +#else
88865 +#include <asm/semaphore.h>
88866 +#endif
88867 +#include <linux/module.h>
88868 +
88869 +#include <img_defs.h>
88870 +#include <services.h>
88871 +
88872 +#include "mutex.h"
88873 +
88874 +
88875 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
88876 +
88877 +IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88878 +{
88879 +    mutex_init(psPVRSRVMutex);
88880 +}
88881 +
88882 +IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88883 +{
88884 +    mutex_lock(psPVRSRVMutex);
88885 +}
88886 +
88887 +PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88888 +{
88889 +    if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR)
88890 +    {
88891 +        return PVRSRV_ERROR_GENERIC;
88892 +    }
88893 +    else
88894 +    {
88895 +        return PVRSRV_OK;
88896 +    }
88897 +}
88898 +
88899 +IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88900 +{
88901 +    return mutex_trylock(psPVRSRVMutex);
88902 +}
88903 +
88904 +IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88905 +{
88906 +    mutex_unlock(psPVRSRVMutex);
88907 +}
88908 +
88909 +IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88910 +{
88911 +    return (IMG_BOOL)mutex_is_locked(psPVRSRVMutex);
88912 +}
88913 +
88914 +
88915 +#else 
88916 +
88917 +
88918 +IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88919 +{
88920 +    init_MUTEX(&psPVRSRVMutex->sSemaphore);
88921 +    atomic_set(&psPVRSRVMutex->Count, 0);
88922 +}
88923 +
88924 +IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88925 +{
88926 +    down(&psPVRSRVMutex->sSemaphore);
88927 +    atomic_dec(&psPVRSRVMutex->Count);
88928 +}
88929 +
88930 +PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88931 +{
88932 +    if(down_interruptible(&psPVRSRVMutex->sSemaphore) == -EINTR)
88933 +    {
88934 +        
88935 +        return PVRSRV_ERROR_GENERIC;
88936 +    }else{
88937 +        atomic_dec(&psPVRSRVMutex->Count);
88938 +        return PVRSRV_OK;
88939 +    }
88940 +}
88941 +
88942 +IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88943 +{
88944 +    IMG_INT32 Status = down_trylock(&psPVRSRVMutex->sSemaphore);
88945 +    if(Status == 0)
88946 +    {
88947 +        atomic_dec(&psPVRSRVMutex->Count);
88948 +    }
88949 +
88950 +    return Status;
88951 +}
88952 +
88953 +IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88954 +{
88955 +    atomic_inc(&psPVRSRVMutex->Count);
88956 +    up(&psPVRSRVMutex->sSemaphore);
88957 +}
88958 +
88959 +IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex)
88960 +{
88961 +    IMG_INT32 iCount;
88962 +    
88963 +    iCount = atomic_read(&psPVRSRVMutex->Count);
88964 +
88965 +    return (IMG_BOOL)iCount;
88966 +}
88967 +
88968 +#endif 
88969 +
88970 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.h
88971 new file mode 100644
88972 index 0000000..b24a599
88973 --- /dev/null
88974 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutex.h
88975 @@ -0,0 +1,70 @@
88976 +/**********************************************************************
88977 + *
88978 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
88979 + * 
88980 + * This program is free software; you can redistribute it and/or modify it
88981 + * under the terms and conditions of the GNU General Public License,
88982 + * version 2, as published by the Free Software Foundation.
88983 + * 
88984 + * This program is distributed in the hope it will be useful but, except 
88985 + * as otherwise stated in writing, without any warranty; without even the 
88986 + * implied warranty of merchantability or fitness for a particular purpose. 
88987 + * See the GNU General Public License for more details.
88988 + * 
88989 + * You should have received a copy of the GNU General Public License along with
88990 + * this program; if not, write to the Free Software Foundation, Inc.,
88991 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
88992 + * 
88993 + * The full GNU General Public License is included in this distribution in
88994 + * the file called "COPYING".
88995 + *
88996 + * Contact Information:
88997 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
88998 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
88999 + *
89000 + ******************************************************************************/
89001 +
89002 +#ifndef __INCLUDED_LINUX_MUTEX_H_
89003 +#define __INCLUDED_LINUX_MUTEX_H_
89004 +
89005 +#include <linux/version.h>
89006 +
89007 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
89008 +#include <linux/mutex.h>
89009 +#else
89010 +#include <asm/semaphore.h>
89011 +#endif
89012 +
89013 +
89014 +
89015 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
89016 +
89017 +typedef struct mutex PVRSRV_LINUX_MUTEX;
89018 +
89019 +#else 
89020 +
89021 +
89022 +typedef struct {
89023 +    struct semaphore sSemaphore;
89024 +    
89025 +    atomic_t Count;
89026 +}PVRSRV_LINUX_MUTEX;
89027 +
89028 +#endif
89029 +
89030 +
89031 +extern IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89032 +
89033 +extern IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89034 +
89035 +extern PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89036 +
89037 +extern IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89038 +
89039 +extern IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89040 +
89041 +extern IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex);
89042 +
89043 +
89044 +#endif 
89045 +
89046 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.c
89047 new file mode 100644
89048 index 0000000..83eab51
89049 --- /dev/null
89050 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.c
89051 @@ -0,0 +1,133 @@
89052 +/**********************************************************************
89053 + *
89054 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
89055 + * 
89056 + * This program is free software; you can redistribute it and/or modify it
89057 + * under the terms and conditions of the GNU General Public License,
89058 + * version 2, as published by the Free Software Foundation.
89059 + * 
89060 + * This program is distributed in the hope it will be useful but, except 
89061 + * as otherwise stated in writing, without any warranty; without even the 
89062 + * implied warranty of merchantability or fitness for a particular purpose. 
89063 + * See the GNU General Public License for more details.
89064 + * 
89065 + * You should have received a copy of the GNU General Public License along with
89066 + * this program; if not, write to the Free Software Foundation, Inc.,
89067 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
89068 + * 
89069 + * The full GNU General Public License is included in this distribution in
89070 + * the file called "COPYING".
89071 + *
89072 + * Contact Information:
89073 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
89074 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
89075 + *
89076 + ******************************************************************************/
89077 +
89078 +#ifndef AUTOCONF_INCLUDED
89079 +#include <linux/config.h>
89080 +#endif
89081 +#include <linux/version.h>
89082 +
89083 +#include <linux/spinlock.h>
89084 +#include <linux/mm.h>
89085 +#include <asm/page.h>
89086 +#include <asm/pgtable.h>
89087 +
89088 +#include "img_defs.h"
89089 +#include "pvr_debug.h"
89090 +#include "mutils.h"
89091 +
89092 +#if defined(SUPPORT_LINUX_X86_PAT)
89093 +#define        PAT_LINUX_X86_WC        1
89094 +
89095 +#define        PAT_X86_ENTRY_BITS      8
89096 +
89097 +#define        PAT_X86_BIT_PWT         1U
89098 +#define        PAT_X86_BIT_PCD         2U
89099 +#define        PAT_X86_BIT_PAT         4U
89100 +#define        PAT_X86_BIT_MASK        (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)
89101 +
89102 +static IMG_BOOL g_write_combining_available = IMG_FALSE;
89103 +
89104 +#define        PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)
89105 +
89106 +static inline IMG_UINT
89107 +pvr_pat_index(pgprotval_t prot_val)
89108 +{
89109 +       IMG_UINT ret = 0;
89110 +       pgprotval_t val = prot_val & _PAGE_CACHE_MASK;
89111 +
89112 +       ret |= PROT_TO_PAT_INDEX(val, PAT);
89113 +       ret |= PROT_TO_PAT_INDEX(val, PCD);
89114 +       ret |= PROT_TO_PAT_INDEX(val, PWT);
89115 +
89116 +       return ret;
89117 +}
89118 +
89119 +static inline IMG_UINT
89120 +pvr_pat_entry(u64 pat, IMG_UINT index)
89121 +{
89122 +       return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;
89123 +}
89124 +
89125 +static IMG_VOID
89126 +PVRLinuxX86PATProbe(IMG_VOID)
89127 +{
89128 +       
89129 +       if (cpu_has_pat)         
89130 +       {
89131 +               u64 pat;
89132 +               IMG_UINT pat_index;
89133 +               IMG_UINT pat_entry;
89134 +
89135 +               PVR_TRACE(("%s: PAT available", __FUNCTION__));
89136 +               
89137 +               rdmsrl(MSR_IA32_CR_PAT, pat);
89138 +               PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));
89139 +               PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));
89140 +
89141 +               pat_index = pvr_pat_index(_PAGE_CACHE_WC);
89142 +               PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));
89143 +
89144 +               pat_entry = pvr_pat_entry(pat, pat_index);
89145 +               PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));
89146 +
89147 +#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
89148 +               g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);
89149 +#endif
89150 +       }
89151 +#if defined(DEBUG)
89152 +#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
89153 +       if (g_write_combining_available)
89154 +       {
89155 +               PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));
89156 +       }
89157 +       else
89158 +       {
89159 +               PVR_TRACE(("%s: Write combining not available", __FUNCTION__));
89160 +       }
89161 +#else  
89162 +       PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));
89163 +#endif 
89164 +#endif 
89165 +}
89166 +
89167 +pgprot_t
89168 +pvr_pgprot_writecombine(pgprot_t prot)
89169 +{
89170 +    
89171 +     
89172 +    return (g_write_combining_available) ?
89173 +               __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);
89174 +}
89175 +#endif 
89176 +
89177 +IMG_VOID
89178 +PVRLinuxMUtilsInit(IMG_VOID)
89179 +{
89180 +#if defined(SUPPORT_LINUX_X86_PAT)
89181 +       PVRLinuxX86PATProbe();
89182 +#endif
89183 +}
89184 +
89185 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.h
89186 new file mode 100644
89187 index 0000000..943c2bd
89188 --- /dev/null
89189 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/mutils.h
89190 @@ -0,0 +1,101 @@
89191 +/**********************************************************************
89192 + *
89193 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
89194 + * 
89195 + * This program is free software; you can redistribute it and/or modify it
89196 + * under the terms and conditions of the GNU General Public License,
89197 + * version 2, as published by the Free Software Foundation.
89198 + * 
89199 + * This program is distributed in the hope it will be useful but, except 
89200 + * as otherwise stated in writing, without any warranty; without even the 
89201 + * implied warranty of merchantability or fitness for a particular purpose. 
89202 + * See the GNU General Public License for more details.
89203 + * 
89204 + * You should have received a copy of the GNU General Public License along with
89205 + * this program; if not, write to the Free Software Foundation, Inc.,
89206 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
89207 + * 
89208 + * The full GNU General Public License is included in this distribution in
89209 + * the file called "COPYING".
89210 + *
89211 + * Contact Information:
89212 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
89213 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
89214 + *
89215 + ******************************************************************************/
89216 +
89217 +#ifndef __IMG_LINUX_MUTILS_H__
89218 +#define __IMG_LINUX_MUTILS_H__
89219 +
89220 +#ifndef AUTOCONF_INCLUDED
89221 +#include <linux/config.h>
89222 +#endif
89223 +
89224 +#include <linux/version.h>
89225 +
89226 +#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)))
89227 +#if defined(SUPPORT_LINUX_X86_PAT)
89228 +#undef SUPPORT_LINUX_X86_PAT
89229 +#endif
89230 +#endif
89231 +
89232 +#if defined(SUPPORT_LINUX_X86_PAT)
89233 +       pgprot_t pvr_pgprot_writecombine(pgprot_t prot);
89234 +       #define PGPROT_WC(pv)   pvr_pgprot_writecombine(pv)
89235 +#else
89236 +       #if defined(__arm__) || defined(__sh__)
89237 +               #define PGPROT_WC(pv)   pgprot_writecombine(pv)
89238 +       #else
89239 +               #if defined(__i386__)
89240 +                       #define PGPROT_WC(pv)   pgprot_noncached(pv)
89241 +               #else
89242 +                       #define PGPROT_WC(pv)   pgprot_noncached(pv)
89243 +                       #error  Unsupported architecture!
89244 +               #endif
89245 +       #endif
89246 +#endif
89247 +
89248 +#define        PGPROT_UC(pv)   pgprot_noncached(pv)
89249 +
89250 +#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
89251 +       #define IOREMAP(pa, bytes)      ioremap_cache(pa, bytes)
89252 +#else  
89253 +       #if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
89254 +               #define IOREMAP(pa, bytes)      ioremap_cached(pa, bytes)
89255 +       #else
89256 +               #define IOREMAP(pa, bytes)      ioremap(pa, bytes)
89257 +       #endif
89258 +#endif
89259 +
89260 +#if defined(SUPPORT_LINUX_X86_PAT)
89261 +       #if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
89262 +               #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
89263 +       #else
89264 +               #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes)
89265 +       #endif
89266 +#else
89267 +       #if defined(__arm__)
89268 +               #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
89269 +                       #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes)
89270 +               #else
89271 +                       #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
89272 +                               #define IOREMAP_WC(pa, bytes)   ioremap_nocache(pa, bytes)
89273 +                       #else
89274 +                               #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17))
89275 +                                       #define IOREMAP_WC(pa, bytes)   __ioremap(pa, bytes, L_PTE_BUFFERABLE)
89276 +                               #else
89277 +                                       #define IOREMAP_WC(pa, bytes)   __ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1)
89278 +                               #endif
89279 +                       #endif
89280 +               #endif
89281 +       #else
89282 +               #define IOREMAP_WC(pa, bytes)   ioremap_nocache(pa, bytes)
89283 +       #endif
89284 +#endif
89285 +
89286 +#define        IOREMAP_UC(pa, bytes)   ioremap_nocache(pa, bytes)
89287 +
89288 +IMG_VOID PVRLinuxMUtilsInit(IMG_VOID);
89289 +
89290 +#endif 
89291 +
89292 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osfunc.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osfunc.c
89293 new file mode 100644
89294 index 0000000..0e2b68c
89295 --- /dev/null
89296 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osfunc.c
89297 @@ -0,0 +1,2564 @@
89298 +/**********************************************************************
89299 + *
89300 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
89301 + * 
89302 + * This program is free software; you can redistribute it and/or modify it
89303 + * under the terms and conditions of the GNU General Public License,
89304 + * version 2, as published by the Free Software Foundation.
89305 + * 
89306 + * This program is distributed in the hope it will be useful but, except 
89307 + * as otherwise stated in writing, without any warranty; without even the 
89308 + * implied warranty of merchantability or fitness for a particular purpose. 
89309 + * See the GNU General Public License for more details.
89310 + * 
89311 + * You should have received a copy of the GNU General Public License along with
89312 + * this program; if not, write to the Free Software Foundation, Inc.,
89313 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
89314 + * 
89315 + * The full GNU General Public License is included in this distribution in
89316 + * the file called "COPYING".
89317 + *
89318 + * Contact Information:
89319 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
89320 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
89321 + *
89322 + ******************************************************************************/
89323 +
89324 +#ifndef AUTOCONF_INCLUDED
89325 + #include <linux/config.h>
89326 +#endif
89327 +
89328 +#include <linux/version.h>
89329 +#include <asm/io.h>
89330 +#include <asm/page.h>
89331 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
89332 +#include <asm/system.h>
89333 +#endif
89334 +#if defined(SUPPORT_CPU_CACHED_BUFFERS)
89335 +#include <asm/cacheflush.h>
89336 +#endif
89337 +#include <linux/mm.h>
89338 +#include <linux/pagemap.h>
89339 +#include <linux/hugetlb.h> 
89340 +#include <linux/slab.h>
89341 +#include <linux/vmalloc.h>
89342 +#include <linux/delay.h>
89343 +#include <linux/pci.h>
89344 +
89345 +#include <linux/string.h>
89346 +#include <linux/sched.h>
89347 +#include <linux/interrupt.h>
89348 +#include <asm/hardirq.h>
89349 +#include <linux/timer.h>
89350 +#include <linux/capability.h>
89351 +#include <asm/uaccess.h>
89352 +#include <linux/spinlock.h>
89353 +#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
89354 +       defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
89355 +       defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
89356 +       defined(PVR_LINUX_USING_WORKQUEUES)
89357 +#include <linux/workqueue.h>
89358 +#endif
89359 +
89360 +#include "img_types.h"
89361 +#include "services_headers.h"
89362 +#include "mm.h"
89363 +#include "pvrmmap.h"
89364 +#include "mmap.h"
89365 +#include "env_data.h"
89366 +#include "proc.h"
89367 +#include "mutex.h"
89368 +#include "event.h"
89369 +#include "linkage.h"
89370 +
89371 +#define EVENT_OBJECT_TIMEOUT_MS                (100)
89372 +
89373 +#if defined(SUPPORT_CPU_CACHED_BUFFERS) || \
89374 +       defined(SUPPORT_CACHEFLUSH_ON_ALLOC)
89375 +
89376 +#if defined(__i386__)
89377 +static void per_cpu_cache_flush(void *arg)
89378 +{
89379 +    PVR_UNREFERENCED_PARAMETER(arg);
89380 +    wbinvd();
89381 +}
89382 +#endif 
89383 +
89384 +#if !defined(SUPPORT_CPU_CACHED_BUFFERS)
89385 +static
89386 +#endif
89387 +IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
89388 +{
89389 +#if defined(__arm__)
89390 +    flush_cache_all();
89391 +#elif defined(__i386__)
89392 +    
89393 +    on_each_cpu(per_cpu_cache_flush, NULL, 1);
89394 +#else
89395 +#error "Implement full CPU cache flush for this CPU!"
89396 +#endif
89397 +}
89398 +
89399 +#endif 
89400 +#if defined(SUPPORT_CPU_CACHED_BUFFERS)
89401 +
89402 +IMG_VOID OSFlushCPUCacheRangeKM(IMG_VOID *pvRangeAddrStart,
89403 +                                                               IMG_VOID *pvRangeAddrEnd)
89404 +{
89405 +       PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
89406 +       PVR_UNREFERENCED_PARAMETER(pvRangeAddrEnd);
89407 +
89408 +       
89409 +       OSFlushCPUCacheKM();
89410 +}
89411 +
89412 +#endif 
89413 +
89414 +#define HOST_ALLOC_MEM_USING_KMALLOC ((IMG_HANDLE)0)
89415 +#define HOST_ALLOC_MEM_USING_VMALLOC ((IMG_HANDLE)1)
89416 +
89417 +#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89418 +PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
89419 +#else
89420 +PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
89421 +#endif
89422 +{
89423 +    PVR_UNREFERENCED_PARAMETER(ui32Flags);
89424 +
89425 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89426 +    *ppvCpuVAddr = _KMallocWrapper(ui32Size, pszFilename, ui32Line);
89427 +#else
89428 +    *ppvCpuVAddr = KMallocWrapper(ui32Size);
89429 +#endif
89430 +    if(*ppvCpuVAddr)
89431 +    {
89432 +    if (phBlockAlloc)
89433 +    {
89434 +        
89435 +        *phBlockAlloc = HOST_ALLOC_MEM_USING_KMALLOC;
89436 +    }
89437 +    }
89438 +    else
89439 +    {
89440 +    if (!phBlockAlloc)
89441 +    {
89442 +        return PVRSRV_ERROR_OUT_OF_MEMORY;
89443 +    }
89444 +
89445 +    
89446 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89447 +    *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line);
89448 +#else
89449 +    *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED);
89450 +#endif
89451 +    if (!*ppvCpuVAddr)
89452 +    {
89453 +         return PVRSRV_ERROR_OUT_OF_MEMORY;
89454 +    }
89455 +
89456 +    
89457 +    *phBlockAlloc = HOST_ALLOC_MEM_USING_VMALLOC;
89458 +    }
89459 +
89460 +    return PVRSRV_OK;
89461 +}
89462 +
89463 +
89464 +#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89465 +PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
89466 +#else
89467 +PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
89468 +#endif
89469 +{      
89470 +    PVR_UNREFERENCED_PARAMETER(ui32Flags);
89471 +    PVR_UNREFERENCED_PARAMETER(ui32Size);
89472 +
89473 +    if (hBlockAlloc == HOST_ALLOC_MEM_USING_VMALLOC)
89474 +    {
89475 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89476 +    _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
89477 +#else
89478 +    VFreeWrapper(pvCpuVAddr);
89479 +#endif
89480 +    }
89481 +    else
89482 +    {
89483 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
89484 +    _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line);
89485 +#else
89486 +        KFreeWrapper(pvCpuVAddr);
89487 +#endif
89488 +    }
89489 +
89490 +    return PVRSRV_OK;
89491 +}
89492 +
89493 +
89494 +PVRSRV_ERROR
89495 +OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags,
89496 +                IMG_UINT32 ui32Size,
89497 +                IMG_UINT32 ui32PageSize,
89498 +                IMG_VOID **ppvCpuVAddr,
89499 +                IMG_HANDLE *phOSMemHandle)
89500 +{
89501 +    LinuxMemArea *psLinuxMemArea;
89502 +
89503 +    PVR_UNREFERENCED_PARAMETER(ui32PageSize);
89504 +
89505 +#if 0
89506 +    
89507 +    if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
89508 +    {
89509 +        ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
89510 +        ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
89511 +    }
89512 +#endif
89513 +
89514 +    switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
89515 +    {
89516 +        case PVRSRV_HAP_KERNEL_ONLY:
89517 +        {
89518 +            psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
89519 +            if(!psLinuxMemArea)
89520 +            {
89521 +                return PVRSRV_ERROR_OUT_OF_MEMORY;
89522 +            }
89523 +            break;
89524 +        }
89525 +        case PVRSRV_HAP_SINGLE_PROCESS:
89526 +        {
89527 +            
89528 +            
89529 +            psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
89530 +            if(!psLinuxMemArea)
89531 +            {
89532 +                return PVRSRV_ERROR_OUT_OF_MEMORY;
89533 +            }
89534 +            PVRMMapRegisterArea(psLinuxMemArea);
89535 +            break;
89536 +        }
89537 +
89538 +        case PVRSRV_HAP_MULTI_PROCESS:
89539 +        {
89540 +            
89541 +#if defined(VIVT_CACHE) || defined(__sh__)
89542 +            
89543 +            ui32AllocFlags &= ~PVRSRV_HAP_CACHED;
89544 +#endif
89545 +            psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags);
89546 +            if(!psLinuxMemArea)
89547 +            {
89548 +                return PVRSRV_ERROR_OUT_OF_MEMORY;
89549 +            }
89550 +            PVRMMapRegisterArea(psLinuxMemArea);
89551 +            break;
89552 +        }
89553 +        default:
89554 +            PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags));
89555 +            *ppvCpuVAddr = NULL;
89556 +            *phOSMemHandle = (IMG_HANDLE)0;
89557 +            return PVRSRV_ERROR_INVALID_PARAMS;
89558 +    }
89559 +
89560 +#if defined(SUPPORT_CACHEFLUSH_ON_ALLOC)
89561 +    
89562 +    if(ui32AllocFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
89563 +    {
89564 +        OSFlushCPUCacheKM();
89565 +    }
89566 +#endif 
89567 +
89568 +    *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
89569 +    *phOSMemHandle = psLinuxMemArea;
89570 +    
89571 +    LinuxMemAreaRegister(psLinuxMemArea);
89572 +
89573 +    return PVRSRV_OK;
89574 +}
89575 +
89576 +
89577 +PVRSRV_ERROR
89578 +OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle)
89579 +{   
89580 +    LinuxMemArea *psLinuxMemArea;
89581 +    PVR_UNREFERENCED_PARAMETER(ui32Bytes);
89582 +    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
89583 +    
89584 +    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
89585 +
89586 +    switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK)
89587 +    {
89588 +        case PVRSRV_HAP_KERNEL_ONLY:
89589 +            break;
89590 +        case PVRSRV_HAP_SINGLE_PROCESS:
89591 +        case PVRSRV_HAP_MULTI_PROCESS:
89592 +            if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
89593 +            {
89594 +                PVR_DPF((PVR_DBG_ERROR,
89595 +                         "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%ld, "
89596 +                                        "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
89597 +                         ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
89598 +                return PVRSRV_ERROR_GENERIC;
89599 +            }
89600 +            break;
89601 +        default:
89602 +            PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n",
89603 +                    __FUNCTION__, ui32AllocFlags));
89604 +            return PVRSRV_ERROR_INVALID_PARAMS;
89605 +    }
89606 +
89607 +    LinuxMemAreaDeepFree(psLinuxMemArea);
89608 +
89609 +    return PVRSRV_OK;
89610 +}
89611 +
89612 +
89613 +PVRSRV_ERROR
89614 +OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
89615 +                  IMG_UINT32 ui32ByteOffset,
89616 +                  IMG_UINT32 ui32Bytes,
89617 +                  IMG_UINT32 ui32Flags,
89618 +                  IMG_HANDLE *phOSMemHandleRet)
89619 +{
89620 +    LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea;
89621 +    PVRSRV_ERROR eError;
89622 +
89623 +    psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
89624 +    
89625 +    psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes);
89626 +    if(!psLinuxMemArea)
89627 +    {
89628 +        *phOSMemHandleRet = NULL;
89629 +        return PVRSRV_ERROR_OUT_OF_MEMORY;
89630 +    }
89631 +    *phOSMemHandleRet = psLinuxMemArea;
89632 +
89633 +    
89634 +    if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY)
89635 +    {
89636 +        return PVRSRV_OK;
89637 +    }
89638 +
89639 +    eError = PVRMMapRegisterArea(psLinuxMemArea);
89640 +    if(eError != PVRSRV_OK)
89641 +     {
89642 +        goto failed_register_area;
89643 +    }
89644 +
89645 +    return PVRSRV_OK;
89646 +
89647 +failed_register_area:
89648 +    *phOSMemHandleRet = NULL;
89649 +    LinuxMemAreaDeepFree(psLinuxMemArea);
89650 +    return eError;
89651 +}
89652 +
89653 +PVRSRV_ERROR
89654 +OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags)
89655 +{
89656 +    LinuxMemArea *psLinuxMemArea;
89657 +    PVRSRV_ERROR eError;
89658 +    
89659 +    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
89660 +    PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
89661 +    
89662 +    if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0)
89663 +    {
89664 +        eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
89665 +        if(eError != PVRSRV_OK)
89666 +        {
89667 +            return eError;
89668 +        }
89669 +    }
89670 +    LinuxMemAreaDeepFree(psLinuxMemArea);
89671 +
89672 +    return PVRSRV_OK;
89673 +}
89674 +
89675 +
89676 +IMG_CPU_PHYADDR
89677 +OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset)
89678 +{
89679 +    PVR_ASSERT(hOSMemHandle);
89680 +
89681 +    return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
89682 +}
89683 +
89684 +
89685 +
89686 +IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
89687 +{
89688 +#if defined(USE_UNOPTIMISED_MEMCPY)
89689 +    IMG_UINT8 *Src,*Dst;
89690 +    IMG_INT i;
89691 +
89692 +    Src=(IMG_UINT8 *)pvSrc;
89693 +    Dst=(IMG_UINT8 *)pvDst;
89694 +    for(i=0;i<ui32Size;i++)
89695 +    {
89696 +        Dst[i]=Src[i];
89697 +    }
89698 +#else
89699 +    memcpy(pvDst, pvSrc, ui32Size);
89700 +#endif
89701 +}
89702 +
89703 +
89704 +IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
89705 +{
89706 +#if defined(USE_UNOPTIMISED_MEMSET)
89707 +    IMG_UINT8 *Buff;
89708 +    IMG_INT i;
89709 +
89710 +    Buff=(IMG_UINT8 *)pvDest;
89711 +    for(i=0;i<ui32Size;i++)
89712 +    {
89713 +        Buff[i]=ui8Value;
89714 +    }
89715 +#else
89716 +    memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
89717 +#endif
89718 +}
89719 +
89720 +
89721 +IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
89722 +{
89723 +    return (strcpy(pszDest, pszSrc));
89724 +}
89725 +
89726 +IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
89727 +{
89728 +    va_list argList;
89729 +    IMG_INT32 iCount;
89730 +
89731 +    va_start(argList, pszFormat);
89732 +    iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
89733 +    va_end(argList);
89734 +
89735 +    return iCount;
89736 +}
89737 +
89738 +IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
89739 +{
89740 +    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
89741 +
89742 +    if(*pui32Access)
89743 +    {
89744 +        if(psResource->ui32ID == ui32ID)
89745 +        {
89746 +            psResource->ui32ID = 0;
89747 +            *pui32Access = 0;
89748 +        }
89749 +        else
89750 +        {
89751 +            PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process.")); 
89752 +        }
89753 +    }
89754 +    else
89755 +    {
89756 +        PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked"));
89757 +    }
89758 +}
89759 +
89760 +
89761 +PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
89762 +{
89763 +    psResource->ui32ID = 0;
89764 +    psResource->ui32Lock = 0;
89765 +
89766 +    return PVRSRV_OK;
89767 +}
89768 +
89769 +
89770 +PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
89771 +{
89772 +    OSBreakResourceLock (psResource, psResource->ui32ID);
89773 +
89774 +    return PVRSRV_OK;
89775 +}
89776 +
89777 +
89778 +PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
89779 +{
89780 +    ENV_DATA           *psEnvData;
89781 +    
89782 +    
89783 +    if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
89784 +        "Environment Data") != PVRSRV_OK)
89785 +    {
89786 +        return PVRSRV_ERROR_GENERIC;
89787 +    }
89788 +
89789 +    if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, 
89790 +                    &psEnvData->pvBridgeData, IMG_NULL,
89791 +                    "Bridge Data") != PVRSRV_OK)
89792 +    {
89793 +        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
89794 +               
89795 +        return PVRSRV_ERROR_GENERIC;
89796 +    }
89797 +
89798 +
89799 +    
89800 +    psEnvData->bMISRInstalled = IMG_FALSE;
89801 +    psEnvData->bLISRInstalled = IMG_FALSE;
89802 +
89803 +    
89804 +    *ppvEnvSpecificData = psEnvData;
89805 +
89806 +    return PVRSRV_OK;
89807 +}
89808 +
89809 +
89810 +PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData)
89811 +{
89812 +    ENV_DATA           *psEnvData = (ENV_DATA*)pvEnvSpecificData;
89813 +
89814 +    PVR_ASSERT(!psEnvData->bMISRInstalled);
89815 +    PVR_ASSERT(!psEnvData->bLISRInstalled);
89816 +
89817 +    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
89818 +    psEnvData->pvBridgeData = IMG_NULL;
89819 +
89820 +    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
89821 +       
89822 +
89823 +    return PVRSRV_OK;
89824 +}
89825 +
89826 +
89827
89828 +IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
89829 +{
89830 +    schedule();
89831 +}
89832 +
89833 +
89834
89835 +IMG_UINT32 OSClockus(IMG_VOID)
89836 +{
89837 +    IMG_UINT32 time, j = jiffies;
89838 +
89839 +    time = j * (1000000 / HZ);
89840 +
89841 +    return time;
89842 +}
89843 +
89844 +
89845
89846 +IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus)
89847 +{
89848 +    udelay(ui32Timeus);
89849 +}
89850 +
89851 +
89852 +IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID)
89853 +{
89854 +    if (in_interrupt())
89855 +    {
89856 +        return KERNEL_ID;
89857 +    }
89858 +
89859 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
89860 +    return (IMG_UINT32)current->pgrp;
89861 +#else
89862 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
89863 +    return (IMG_UINT32)task_tgid_nr(current);
89864 +#else
89865 +    return (IMG_UINT32)current->tgid;
89866 +#endif
89867 +#endif
89868 +}
89869 +
89870 +
89871 +IMG_UINT32 OSGetPageSize(IMG_VOID)
89872 +{
89873 +#if defined(__sh__)
89874 +    IMG_UINT32 ui32ReturnValue = PAGE_SIZE;
89875 +
89876 +    return (ui32ReturnValue);
89877 +#else
89878 +    return PAGE_SIZE;
89879 +#endif
89880 +}
89881 +
89882 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
89883 +static irqreturn_t DeviceISRWrapper(int irq, void *dev_id
89884 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
89885 +        , struct pt_regs *regs
89886 +#endif
89887 +        )
89888 +{
89889 +    PVRSRV_DEVICE_NODE *psDeviceNode;
89890 +    IMG_BOOL bStatus = IMG_FALSE;
89891 +
89892 +    PVR_UNREFERENCED_PARAMETER(irq);
89893 +
89894 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
89895 +    PVR_UNREFERENCED_PARAMETER(regs);
89896 +#endif 
89897 +    psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id;
89898 +    if(!psDeviceNode)
89899 +    {
89900 +        PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n"));
89901 +        goto out;
89902 +    }
89903 +
89904 +    bStatus = PVRSRVDeviceLISR(psDeviceNode);
89905 +
89906 +    if (bStatus)
89907 +    {
89908 +               OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
89909 +    }
89910 +
89911 +out:
89912 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
89913 +    return bStatus ? IRQ_HANDLED : IRQ_NONE;
89914 +#endif
89915 +}
89916 +
89917 +
89918 +
89919 +static irqreturn_t SystemISRWrapper(int irq, void *dev_id
89920 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
89921 +        , struct pt_regs *regs
89922 +#endif
89923 +        )
89924 +{
89925 +    SYS_DATA *psSysData;
89926 +    IMG_BOOL bStatus = IMG_FALSE;
89927 +
89928 +    PVR_UNREFERENCED_PARAMETER(irq);
89929 +
89930 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
89931 +    PVR_UNREFERENCED_PARAMETER(regs);
89932 +#endif
89933 +    psSysData = (SYS_DATA *)dev_id;
89934 +    if(!psSysData)
89935 +    {
89936 +        PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n"));
89937 +        goto out;
89938 +    }
89939 +
89940 +    bStatus = PVRSRVSystemLISR(psSysData);
89941 +
89942 +    if (bStatus)
89943 +    {
89944 +        OSScheduleMISR((IMG_VOID *)psSysData);
89945 +    }
89946 +
89947 +out:
89948 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
89949 +    return bStatus ? IRQ_HANDLED : IRQ_NONE;
89950 +#endif
89951 +}
89952 +PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
89953 +                                    IMG_UINT32 ui32Irq,
89954 +                                    IMG_CHAR *pszISRName,
89955 +                                    IMG_VOID *pvDeviceNode)
89956 +{
89957 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
89958 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
89959 +
89960 +    if (psEnvData->bLISRInstalled)
89961 +    {
89962 +        PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
89963 +        return PVRSRV_ERROR_GENERIC;
89964 +    }
89965 +
89966 +    PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %x", pszISRName, ui32Irq, pvDeviceNode));
89967 +
89968 +    if(request_irq(ui32Irq, DeviceISRWrapper,
89969 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
89970 +        SA_SHIRQ
89971 +#else
89972 +        IRQF_SHARED
89973 +#endif
89974 +        , pszISRName, pvDeviceNode))
89975 +    {
89976 +        PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq));
89977 +
89978 +        return PVRSRV_ERROR_GENERIC;
89979 +    }
89980 +
89981 +    psEnvData->ui32IRQ = ui32Irq;
89982 +    psEnvData->pvISRCookie = pvDeviceNode;
89983 +    psEnvData->bLISRInstalled = IMG_TRUE;
89984 +
89985 +    return PVRSRV_OK;  
89986 +}
89987 +
89988 +PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData)
89989 +{
89990 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
89991 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
89992 +
89993 +    if (!psEnvData->bLISRInstalled)
89994 +    {
89995 +        PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed"));
89996 +        return PVRSRV_ERROR_GENERIC;
89997 +    }
89998 +        
89999 +    PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ,  psEnvData->pvISRCookie));
90000 +
90001 +    free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
90002 +
90003 +    psEnvData->bLISRInstalled = IMG_FALSE;
90004 +
90005 +    return PVRSRV_OK;
90006 +}
90007 +
90008 +
90009 +PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq)
90010 +{
90011 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90012 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90013 +
90014 +    if (psEnvData->bLISRInstalled)
90015 +    {
90016 +        PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
90017 +        return PVRSRV_ERROR_GENERIC;
90018 +    }
90019 +
90020 +    PVR_TRACE(("Installing system LISR on IRQ %d with cookie %x", ui32Irq, pvSysData));
90021 +
90022 +    if(request_irq(ui32Irq, SystemISRWrapper,
90023 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
90024 +        SA_SHIRQ
90025 +#else
90026 +        IRQF_SHARED
90027 +#endif
90028 +        , "PowerVR", pvSysData))
90029 +    {
90030 +        PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
90031 +
90032 +        return PVRSRV_ERROR_GENERIC;
90033 +    }
90034 +
90035 +    psEnvData->ui32IRQ = ui32Irq;
90036 +    psEnvData->pvISRCookie = pvSysData;
90037 +    psEnvData->bLISRInstalled = IMG_TRUE;
90038 +
90039 +    return PVRSRV_OK;  
90040 +}
90041 +
90042 +
90043 +PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData)
90044 +{
90045 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90046 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90047 +
90048 +    if (!psEnvData->bLISRInstalled)
90049 +    {
90050 +        PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed"));
90051 +        return PVRSRV_ERROR_GENERIC;
90052 +    }
90053 +
90054 +    PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
90055 +
90056 +    free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
90057 +
90058 +    psEnvData->bLISRInstalled = IMG_FALSE;
90059 +
90060 +    return PVRSRV_OK;
90061 +}
90062 +
90063 +#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
90064 +static void MISRWrapper(
90065 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
90066 +                       void *data
90067 +#else
90068 +                       struct work_struct *data
90069 +#endif
90070 +)
90071 +{
90072 +       ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
90073 +       SYS_DATA *psSysData  = (SYS_DATA *)psEnvData->pvMISRData;
90074 +
90075 +       PVRSRVMISR(psSysData);
90076 +}
90077 +
90078 +
90079 +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
90080 +{
90081 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90082 +       ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90083 +
90084 +       if (psEnvData->bMISRInstalled)
90085 +       {
90086 +               PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
90087 +               return PVRSRV_ERROR_GENERIC;
90088 +       }
90089 +
90090 +       PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
90091 +
90092 +       psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
90093 +
90094 +       if (psEnvData->psWorkQueue == IMG_NULL)
90095 +       {
90096 +               PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
90097 +               return PVRSRV_ERROR_GENERIC;
90098 +       }
90099 +
90100 +       INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
90101 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
90102 +               , (void *)&psEnvData->sMISRWork
90103 +#endif
90104 +                               );
90105 +
90106 +       psEnvData->pvMISRData = pvSysData;
90107 +       psEnvData->bMISRInstalled = IMG_TRUE;
90108 +
90109 +       return PVRSRV_OK;
90110 +}
90111 +
90112 +
90113 +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
90114 +{
90115 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90116 +       ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90117 +
90118 +       if (!psEnvData->bMISRInstalled)
90119 +       {
90120 +               PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
90121 +               return PVRSRV_ERROR_GENERIC;
90122 +       }
90123 +
90124 +       PVR_TRACE(("Uninstalling MISR"));
90125 +
90126 +       destroy_workqueue(psEnvData->psWorkQueue);
90127 +
90128 +       psEnvData->bMISRInstalled = IMG_FALSE;
90129 +
90130 +       return PVRSRV_OK;
90131 +}
90132 +
90133 +
90134 +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
90135 +{
90136 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90137 +       ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
90138 +
90139 +       if (psEnvData->bMISRInstalled)
90140 +       {
90141 +               queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
90142 +       }
90143 +
90144 +       return PVRSRV_OK;       
90145 +}
90146 +#else  
90147 +#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
90148 +static void MISRWrapper(
90149 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
90150 +                       void *data
90151 +#else
90152 +                       struct work_struct *data
90153 +#endif
90154 +)
90155 +{
90156 +       ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
90157 +       SYS_DATA *psSysData  = (SYS_DATA *)psEnvData->pvMISRData;
90158 +
90159 +       PVRSRVMISR(psSysData);
90160 +}
90161 +
90162 +
90163 +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
90164 +{
90165 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90166 +       ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90167 +
90168 +       if (psEnvData->bMISRInstalled)
90169 +       {
90170 +               PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
90171 +               return PVRSRV_ERROR_GENERIC;
90172 +       }
90173 +
90174 +       PVR_TRACE(("Installing MISR with cookie %x", pvSysData));
90175 +
90176 +       INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
90177 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
90178 +               , (void *)&psEnvData->sMISRWork
90179 +#endif
90180 +                               );
90181 +
90182 +       psEnvData->pvMISRData = pvSysData;
90183 +       psEnvData->bMISRInstalled = IMG_TRUE;
90184 +
90185 +       return PVRSRV_OK;
90186 +}
90187 +
90188 +
90189 +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
90190 +{
90191 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90192 +       ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90193 +
90194 +       if (!psEnvData->bMISRInstalled)
90195 +       {
90196 +               PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
90197 +               return PVRSRV_ERROR_GENERIC;
90198 +       }
90199 +
90200 +       PVR_TRACE(("Uninstalling MISR"));
90201 +
90202 +       flush_scheduled_work();
90203 +
90204 +       psEnvData->bMISRInstalled = IMG_FALSE;
90205 +
90206 +       return PVRSRV_OK;
90207 +}
90208 +
90209 +
90210 +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
90211 +{
90212 +       SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90213 +       ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
90214 +
90215 +       if (psEnvData->bMISRInstalled)
90216 +       {
90217 +               schedule_work(&psEnvData->sMISRWork);
90218 +       }
90219 +
90220 +       return PVRSRV_OK;       
90221 +}
90222 +
90223 +#else  
90224 +
90225 +
90226 +static void MISRWrapper(unsigned long data)
90227 +{
90228 +    SYS_DATA *psSysData;
90229 +
90230 +    psSysData = (SYS_DATA *)data;
90231 +    
90232 +    PVRSRVMISR(psSysData);
90233 +}
90234 +
90235 +
90236 +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData)
90237 +{
90238 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90239 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90240 +
90241 +    if (psEnvData->bMISRInstalled)
90242 +    {
90243 +        PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed"));
90244 +        return PVRSRV_ERROR_GENERIC;
90245 +    }
90246 +
90247 +    PVR_TRACE(("Installing MISR with cookie %x", pvSysData));
90248 +
90249 +    tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
90250 +
90251 +    psEnvData->bMISRInstalled = IMG_TRUE;
90252 +
90253 +    return PVRSRV_OK;
90254 +}
90255 +
90256 +
90257 +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData)
90258 +{
90259 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90260 +    ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData;
90261 +
90262 +    if (!psEnvData->bMISRInstalled)
90263 +    {
90264 +        PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed"));
90265 +        return PVRSRV_ERROR_GENERIC;
90266 +    }
90267 +
90268 +    PVR_TRACE(("Uninstalling MISR"));
90269 +
90270 +    tasklet_kill(&psEnvData->sMISRTasklet);
90271 +
90272 +    psEnvData->bMISRInstalled = IMG_FALSE;
90273 +
90274 +    return PVRSRV_OK;
90275 +}
90276 +
90277 +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
90278 +{
90279 +    SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
90280 +    ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
90281 +
90282 +    if (psEnvData->bMISRInstalled)
90283 +    {
90284 +        tasklet_schedule(&psEnvData->sMISRTasklet);
90285 +    }
90286 +
90287 +    return PVRSRV_OK;  
90288 +}
90289 +
90290 +#endif 
90291 +#endif 
90292 +
90293 +#endif 
90294 +
90295 +IMG_VOID OSPanic(IMG_VOID)
90296 +{
90297 +       BUG();
90298 +}
90299 +
90300 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
90301 +#define        OS_TAS(p)       xchg((p), 1)
90302 +#else
90303 +#define        OS_TAS(p)       tas(p)
90304 +#endif
90305 +PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE  *psResource,
90306 +                                IMG_UINT32                     ui32ID)
90307 +
90308 +{
90309 +    PVRSRV_ERROR eError = PVRSRV_OK;
90310 +
90311 +    if(!OS_TAS(&psResource->ui32Lock))
90312 +        psResource->ui32ID = ui32ID;
90313 +    else
90314 +        eError = PVRSRV_ERROR_GENERIC;
90315 +
90316 +    return eError;
90317 +}
90318 +
90319 +
90320 +PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
90321 +{
90322 +    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
90323 +    PVRSRV_ERROR eError = PVRSRV_OK;
90324 +
90325 +    if(*pui32Access)
90326 +    {
90327 +        if(psResource->ui32ID == ui32ID)
90328 +        {
90329 +            psResource->ui32ID = 0;
90330 +            *pui32Access = 0;
90331 +        }
90332 +        else
90333 +        {
90334 +            PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource)); 
90335 +            PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID));
90336 +            eError = PVRSRV_ERROR_GENERIC;
90337 +        }
90338 +    }
90339 +    else
90340 +    {
90341 +        PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
90342 +        eError = PVRSRV_ERROR_GENERIC;
90343 +    }
90344 +    
90345 +    return eError;
90346 +}
90347 +
90348 +
90349 +IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
90350 +{
90351 +    volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
90352 +
90353 +    return     (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID)
90354 +            ?  IMG_TRUE
90355 +            :  IMG_FALSE;
90356 +}
90357 +
90358 +
90359 +IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_VOID *pvLinAddr)
90360 +{
90361 +    IMG_CPU_PHYADDR CpuPAddr;
90362 +
90363 +    CpuPAddr.uiAddr = (IMG_UINTPTR_T)VMallocToPhys(pvLinAddr);
90364 +
90365 +    return CpuPAddr;
90366 +}
90367 +
90368 +
90369 +IMG_VOID *
90370 +OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
90371 +               IMG_UINT32 ui32Bytes,
90372 +               IMG_UINT32 ui32MappingFlags,
90373 +               IMG_HANDLE *phOSMemHandle)
90374 +{
90375 +    if(phOSMemHandle)
90376 +    {
90377 +        *phOSMemHandle = (IMG_HANDLE)0;
90378 +    }
90379 +
90380 +    if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
90381 +    {
90382 +        IMG_VOID *pvIORemapCookie;
90383 +        pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
90384 +        if(pvIORemapCookie == IMG_NULL)
90385 +        {
90386 +            return NULL;
90387 +        }
90388 +        return pvIORemapCookie;
90389 +    }
90390 +    else
90391 +    {
90392 +        PVR_DPF((PVR_DBG_ERROR,
90393 +                 "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
90394 +                 " (Use OSReservePhys otherwise)"));
90395 +        return NULL;
90396 +    }
90397 +}
90398 +
90399 +IMG_BOOL
90400 +OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hPageAlloc)
90401 +{
90402 +    PVR_TRACE(("%s: unmapping %d bytes from 0x%08x", __FUNCTION__, ui32Bytes, pvLinAddr));
90403 +
90404 +    PVR_UNREFERENCED_PARAMETER(hPageAlloc);    
90405 +    PVR_UNREFERENCED_PARAMETER(ui32Bytes);     
90406 +
90407 +    if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
90408 +    {
90409 +        IOUnmapWrapper(pvLinAddr);
90410 +        return IMG_TRUE;
90411 +    }
90412 +    else
90413 +    {
90414 +        PVR_DPF((PVR_DBG_ERROR,
90415 +                     "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
90416 +                     " (Use OSUnReservePhys otherwise)"));
90417 +        return IMG_FALSE;
90418 +    }
90419 +}
90420 +
90421 +static PVRSRV_ERROR
90422 +RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr,
90423 +          IMG_VOID *pvCPUVAddr,
90424 +              IMG_UINT32 ui32Bytes,
90425 +          IMG_BOOL bPhysContig,
90426 +              IMG_UINT32 ui32MappingFlags,
90427 +              IMG_HANDLE *phOSMemHandle)
90428 +{
90429 +    LinuxMemArea *psLinuxMemArea;
90430 +
90431 +    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
90432 +    {
90433 +        case PVRSRV_HAP_KERNEL_ONLY:
90434 +        {
90435 +        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
90436 +        
90437 +            if(!psLinuxMemArea)
90438 +            {
90439 +                return PVRSRV_ERROR_GENERIC;
90440 +            }
90441 +            break;
90442 +        }
90443 +        case PVRSRV_HAP_SINGLE_PROCESS:
90444 +        {
90445 +        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
90446 +
90447 +            if(!psLinuxMemArea)
90448 +            {
90449 +                return PVRSRV_ERROR_GENERIC;
90450 +            }
90451 +            PVRMMapRegisterArea(psLinuxMemArea);
90452 +            break;
90453 +        }
90454 +        case PVRSRV_HAP_MULTI_PROCESS:
90455 +        {
90456 +            
90457 +#if defined(VIVT_CACHE) || defined(__sh__)
90458 +            
90459 +            ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
90460 +#endif
90461 +        psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
90462 +
90463 +            if(!psLinuxMemArea)
90464 +            {
90465 +                return PVRSRV_ERROR_GENERIC;
90466 +            }
90467 +            PVRMMapRegisterArea(psLinuxMemArea);
90468 +            break;
90469 +        }
90470 +        default:
90471 +            PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
90472 +            *phOSMemHandle = (IMG_HANDLE)0;
90473 +            return PVRSRV_ERROR_GENERIC;
90474 +    }
90475 +    
90476 +    *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
90477 +
90478 +    LinuxMemAreaRegister(psLinuxMemArea);
90479 +
90480 +    return PVRSRV_OK;
90481 +}
90482 +
90483 +
90484 +PVRSRV_ERROR
90485 +OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
90486 +              IMG_VOID *pvCPUVAddr,
90487 +              IMG_UINT32 ui32Bytes,
90488 +              IMG_UINT32 ui32MappingFlags,
90489 +              IMG_HANDLE *phOSMemHandle)
90490 +{
90491 +    IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr);
90492 +
90493 +    return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle);
90494 +}
90495 +
90496 +
90497 +PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle)
90498 +{
90499 +    return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle);
90500 +}
90501 +
90502 +
90503 +PVRSRV_ERROR
90504 +OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
90505 +                IMG_UINT32 ui32Bytes,
90506 +                IMG_UINT32 ui32MappingFlags,
90507 +                IMG_HANDLE hOSMemHandle)
90508 +{
90509 +    LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
90510 +
90511 +    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
90512 +    PVR_UNREFERENCED_PARAMETER(ui32Bytes);
90513 +
90514 +    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
90515 +    {
90516 +        case PVRSRV_HAP_KERNEL_ONLY:
90517 +            break;
90518 +        case PVRSRV_HAP_SINGLE_PROCESS:
90519 +        case PVRSRV_HAP_MULTI_PROCESS:
90520 +        {
90521 +            if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
90522 +            {
90523 +                 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
90524 +                          __FUNCTION__, pvCpuVAddr, ui32Bytes,
90525 +                          ui32MappingFlags, hOSMemHandle));
90526 +                return PVRSRV_ERROR_GENERIC;
90527 +            }
90528 +            break;
90529 +        }
90530 +        default:
90531 +        {
90532 +            PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags));
90533 +            return PVRSRV_ERROR_INVALID_PARAMS;
90534 +        }
90535 +    }
90536 +
90537 +    LinuxMemAreaDeepFree(psLinuxMemArea);
90538 +
90539 +    return PVRSRV_OK;
90540 +}
90541 +
90542 +PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
90543 +{
90544 +    return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
90545 +}
90546 +
90547 +PVRSRV_ERROR
90548 +OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
90549 +              IMG_UINT32 ui32Bytes,
90550 +              IMG_UINT32 ui32MappingFlags,
90551 +              IMG_VOID **ppvCpuVAddr,
90552 +              IMG_HANDLE *phOSMemHandle)
90553 +{
90554 +    LinuxMemArea *psLinuxMemArea;
90555 +
90556 +#if 0
90557 +    
90558 +    if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS)
90559 +    {
90560 +        ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
90561 +        ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS;
90562 +    }
90563 +#endif
90564 +
90565 +    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
90566 +    {
90567 +        case PVRSRV_HAP_KERNEL_ONLY:
90568 +        {
90569 +            
90570 +            psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
90571 +            if(!psLinuxMemArea)
90572 +            {
90573 +                return PVRSRV_ERROR_GENERIC;
90574 +            }
90575 +            break;
90576 +        }
90577 +        case PVRSRV_HAP_SINGLE_PROCESS:
90578 +        {
90579 +            
90580 +            psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
90581 +            if(!psLinuxMemArea)
90582 +            {
90583 +                return PVRSRV_ERROR_GENERIC;
90584 +            }
90585 +            PVRMMapRegisterArea(psLinuxMemArea);
90586 +            break;
90587 +        }
90588 +        case PVRSRV_HAP_MULTI_PROCESS:
90589 +        {
90590 +            
90591 +#if defined(VIVT_CACHE) || defined(__sh__)
90592 +            
90593 +            ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
90594 +#endif
90595 +            psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
90596 +            if(!psLinuxMemArea)
90597 +            {
90598 +                return PVRSRV_ERROR_GENERIC;
90599 +            }
90600 +            PVRMMapRegisterArea(psLinuxMemArea);
90601 +            break;
90602 +        }
90603 +        default:
90604 +            PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags));
90605 +            *ppvCpuVAddr = NULL;
90606 +            *phOSMemHandle = (IMG_HANDLE)0;
90607 +            return PVRSRV_ERROR_GENERIC;
90608 +    }
90609 +
90610 +    *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
90611 +    *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
90612 +
90613 +    LinuxMemAreaRegister(psLinuxMemArea);
90614 +
90615 +    return PVRSRV_OK;
90616 +}
90617 +
90618 +PVRSRV_ERROR
90619 +OSUnReservePhys(IMG_VOID *pvCpuVAddr,
90620 +                IMG_UINT32 ui32Bytes,
90621 +                IMG_UINT32 ui32MappingFlags,
90622 +                IMG_HANDLE hOSMemHandle)
90623 +{
90624 +    LinuxMemArea *psLinuxMemArea;
90625 +
90626 +    PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
90627 +   PVR_UNREFERENCED_PARAMETER(ui32Bytes);
90628 +
90629 +    psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
90630 +    
90631 +    switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK)
90632 +    {
90633 +        case PVRSRV_HAP_KERNEL_ONLY:
90634 +            break;
90635 +        case PVRSRV_HAP_SINGLE_PROCESS:
90636 +        case PVRSRV_HAP_MULTI_PROCESS:
90637 +        {
90638 +            if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK)
90639 +            {
90640 +                 PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
90641 +                          __FUNCTION__, pvCpuVAddr, ui32Bytes,
90642 +                          ui32MappingFlags, hOSMemHandle));
90643 +                return PVRSRV_ERROR_GENERIC;
90644 +            }
90645 +            break;
90646 +        }
90647 +        default:
90648 +        {
90649 +            PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
90650 +            return PVRSRV_ERROR_INVALID_PARAMS;
90651 +        }
90652 +    }
90653 +    
90654 +    LinuxMemAreaDeepFree(psLinuxMemArea);
90655 +
90656 +    return PVRSRV_OK;
90657 +}
90658 +
90659 +
90660 +PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr)
90661 +{
90662 +#if !defined(NO_HARDWARE)
90663 +    PVR_UNREFERENCED_PARAMETER(ui32Size);
90664 +    PVR_UNREFERENCED_PARAMETER(pvLinAddr);
90665 +    PVR_UNREFERENCED_PARAMETER(psPhysAddr);
90666 +    PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__));
90667 +
90668 +    return PVRSRV_ERROR_OUT_OF_MEMORY;
90669 +#else
90670 +    IMG_VOID *pvKernLinAddr;
90671 +
90672 +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
90673 +    pvKernLinAddr = _KMallocWrapper(ui32Size, __FILE__, __LINE__);
90674 +#else
90675 +    pvKernLinAddr = KMallocWrapper(ui32Size);
90676 +#endif
90677 +    if (!pvKernLinAddr)
90678 +    {
90679 +    return PVRSRV_ERROR_OUT_OF_MEMORY;
90680 +    }
90681 +
90682 +    *pvLinAddr = pvKernLinAddr;
90683 +
90684 +    psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
90685 +
90686 +    return PVRSRV_OK;
90687 +#endif 
90688 +}
90689 +
90690 +
90691 +PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr)
90692 +{
90693 +#if !defined(NO_HARDWARE)
90694 +    PVR_UNREFERENCED_PARAMETER(ui32Size);
90695 +    PVR_UNREFERENCED_PARAMETER(pvLinAddr);
90696 +    PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
90697 +
90698 +    PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__));
90699 +#else
90700 +    PVR_UNREFERENCED_PARAMETER(ui32Size);
90701 +    PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr);
90702 +
90703 +    KFreeWrapper(pvLinAddr);
90704 +#endif
90705 +    return PVRSRV_OK;
90706 +}
90707 +
90708 +IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
90709 +{
90710 +#if !defined(NO_HARDWARE)
90711 +    return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
90712 +#else
90713 +    return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
90714 +#endif
90715 +}
90716 +
90717 +IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
90718 +{
90719 +#if !defined(NO_HARDWARE)
90720 +    writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
90721 +#else
90722 +    *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value;
90723 +#endif
90724 +}
90725 +
90726 +#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
90727 +
90728 +PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags)
90729 +{
90730 +    int err;
90731 +    IMG_UINT32 i;
90732 +    PVR_PCI_DEV *psPVRPCI;
90733 +
90734 +    PVR_TRACE(("OSPCISetDev"));
90735 +
90736 +    if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL,
90737 +        "PCI Device") != PVRSRV_OK)
90738 +    {
90739 +        PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure"));
90740 +        return IMG_NULL;
90741 +    }
90742 +
90743 +    psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie;
90744 +    psPVRPCI->ePCIFlags = eFlags;
90745 +
90746 +    err = pci_enable_device(psPVRPCI->psPCIDev);
90747 +    if (err != 0)
90748 +    {
90749 +        PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err));
90750 +        return IMG_NULL;
90751 +    }
90752 +
90753 +    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)    
90754 +    {
90755 +        pci_set_master(psPVRPCI->psPCIDev);
90756 +    }
90757 +
90758 +    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)           
90759 +    {
90760 +#if defined(CONFIG_PCI_MSI)
90761 +       if (psPVRPCI->psPCIDev->device == PSB_SYS_SGX_DEV_DEVICE_ID_1 ||
90762 +           psPVRPCI->psPCIDev->device == PSB_SYS_SGX_DEV_DEVICE_ID_2) // Disable MSI for Menlow
90763 +               psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;  
90764 +       else if(!psPVRPCI->psPCIDev->msi_enabled) 
90765 +       {
90766 +               err = pci_enable_msi(psPVRPCI->psPCIDev);
90767 +               if (err != 0)
90768 +               {
90769 +                       PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err));
90770 +                       psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI;  
90771 +               }
90772 +       }
90773 +#else
90774 +        PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
90775 +#endif
90776 +    }
90777 +
90778 +    
90779 +    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
90780 +    {
90781 +        psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
90782 +    }
90783 +
90784 +    return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
90785 +}
90786 +
90787 +PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags)
90788 +{
90789 +    struct pci_dev *psPCIDev;
90790 +
90791 +    psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL);
90792 +    if (psPCIDev == NULL)
90793 +    {
90794 +        PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device"));
90795 +        return IMG_NULL;
90796 +    }
90797 +
90798 +    return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags);
90799 +}
90800 +
90801 +PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ)
90802 +{
90803 +    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
90804 +
90805 +    *pui32IRQ = psPVRPCI->psPCIDev->irq;
90806 +
90807 +    return PVRSRV_OK;
90808 +}
90809 +
90810 +enum HOST_PCI_ADDR_RANGE_FUNC
90811 +{
90812 +    HOST_PCI_ADDR_RANGE_FUNC_LEN,
90813 +    HOST_PCI_ADDR_RANGE_FUNC_START,
90814 +    HOST_PCI_ADDR_RANGE_FUNC_END,
90815 +    HOST_PCI_ADDR_RANGE_FUNC_REQUEST,
90816 +    HOST_PCI_ADDR_RANGE_FUNC_RELEASE
90817 +};
90818 +
90819 +static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc,
90820 +                                     PVRSRV_PCI_DEV_HANDLE hPVRPCI,
90821 +                                     IMG_UINT32 ui32Index)
90822 +{
90823 +    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
90824 +
90825 +    if (ui32Index >= DEVICE_COUNT_RESOURCE)
90826 +    {
90827 +        PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range"));
90828 +        return 0;
90829 +
90830 +    }
90831 +
90832 +    switch (eFunc)
90833 +    {
90834 +        case HOST_PCI_ADDR_RANGE_FUNC_LEN:
90835 +            return pci_resource_len(psPVRPCI->psPCIDev, ui32Index);
90836 +        case HOST_PCI_ADDR_RANGE_FUNC_START:
90837 +            return pci_resource_start(psPVRPCI->psPCIDev, ui32Index);
90838 +        case HOST_PCI_ADDR_RANGE_FUNC_END:
90839 +            return pci_resource_end(psPVRPCI->psPCIDev, ui32Index);
90840 +        case HOST_PCI_ADDR_RANGE_FUNC_REQUEST:
90841 +        {
90842 +            int err;
90843 +
90844 +            err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, "PowerVR");
90845 +            if (err != 0)
90846 +            {
90847 +                PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err));
90848 +                return 0;
90849 +            }
90850 +            psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE;
90851 +            return 1;
90852 +        }
90853 +        case HOST_PCI_ADDR_RANGE_FUNC_RELEASE:
90854 +            if (psPVRPCI->abPCIResourceInUse[ui32Index])
90855 +            {
90856 +                pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index);
90857 +                psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE;
90858 +            }
90859 +            return 1;
90860 +        default:
90861 +            PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function"));
90862 +            break;
90863 +    }
90864 +
90865 +    return 0;
90866 +}
90867 +
90868 +IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
90869 +{
90870 +    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index); 
90871 +}
90872 +
90873 +IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
90874 +{
90875 +    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); 
90876 +}
90877 +
90878 +IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
90879 +{
90880 +    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); 
90881 +}
90882 +
90883 +PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
90884 +                                   IMG_UINT32 ui32Index)
90885 +{
90886 +    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK;
90887 +}
90888 +
90889 +PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
90890 +{
90891 +    return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK;
90892 +}
90893 +
90894 +PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
90895 +{
90896 +    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
90897 +    int i;
90898 +
90899 +    PVR_TRACE(("OSPCIReleaseDev"));
90900 +
90901 +    
90902 +    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
90903 +    {
90904 +        if (psPVRPCI->abPCIResourceInUse[i])
90905 +        {
90906 +            PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i));
90907 +            pci_release_region(psPVRPCI->psPCIDev, i);
90908 +            psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
90909 +        }
90910 +    }
90911 +
90912 +#if defined(CONFIG_PCI_MSI)
90913 +    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI)           
90914 +    {
90915 +        pci_disable_msi(psPVRPCI->psPCIDev);
90916 +    }
90917 +#endif
90918 +
90919 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
90920 +    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)    
90921 +    {
90922 +        pci_clear_master(psPVRPCI->psPCIDev);
90923 +    }
90924 +#endif
90925 +    pci_disable_device(psPVRPCI->psPCIDev);
90926 +
90927 +    OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
90928 +       
90929 +
90930 +    return PVRSRV_OK;
90931 +}
90932 +
90933 +PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
90934 +{
90935 +    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
90936 +    int i;
90937 +    int err;
90938 +
90939 +    PVR_TRACE(("OSPCISuspendDev"));
90940 +
90941 +    
90942 +    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
90943 +    {
90944 +        if (psPVRPCI->abPCIResourceInUse[i])
90945 +        {
90946 +            pci_release_region(psPVRPCI->psPCIDev, i);
90947 +        }
90948 +    }
90949 +
90950 +    err = pci_save_state(psPVRPCI->psPCIDev);
90951 +    if (err != 0)
90952 +    {
90953 +        PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err));
90954 +        return PVRSRV_ERROR_GENERIC;
90955 +    }
90956 +
90957 +    pci_disable_device(psPVRPCI->psPCIDev);
90958 +
90959 +    err = pci_set_power_state(psPVRPCI->psPCIDev, PCI_D3hot);//pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND));
90960 +    switch(err)
90961 +    {
90962 +        case 0:
90963 +            break;
90964 +        case -EIO:
90965 +            PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM"));
90966 +            break;
90967 +        case -EINVAL:
90968 +            PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state"));
90969 +            break;
90970 +        default:
90971 +            PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err));
90972 +            break;
90973 +    }
90974 +
90975 +    return PVRSRV_OK;
90976 +}
90977 +
90978 +PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
90979 +{
90980 +    PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
90981 +    int err;
90982 +    int i;
90983 +
90984 +    PVR_TRACE(("OSPCIResumeDev"));
90985 +
90986 +    err = pci_set_power_state(psPVRPCI->psPCIDev, PCI_D0);//pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON));
90987 +    switch(err)
90988 +    {
90989 +        case 0:
90990 +            break;
90991 +        case -EIO:
90992 +            PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM"));
90993 +            break;
90994 +        case -EINVAL:
90995 +            PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state"));
90996 +            return PVRSRV_ERROR_GENERIC;
90997 +        default:
90998 +            PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
90999 +            return PVRSRV_ERROR_GENERIC;
91000 +    }
91001 +
91002 +    err = pci_restore_state(psPVRPCI->psPCIDev);
91003 +    if (err != 0)
91004 +    {
91005 +        PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
91006 +        return PVRSRV_ERROR_GENERIC;
91007 +    }
91008 +
91009 +    err = pci_enable_device(psPVRPCI->psPCIDev);
91010 +    if (err != 0)
91011 +    {
91012 +        PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
91013 +        return PVRSRV_ERROR_GENERIC;
91014 +    }
91015 +
91016 +    if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER)    
91017 +        pci_set_master(psPVRPCI->psPCIDev);
91018 +
91019 +    
91020 +    for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
91021 +    {
91022 +        if (psPVRPCI->abPCIResourceInUse[i])
91023 +        {
91024 +            err = pci_request_region(psPVRPCI->psPCIDev, i, "PowerVR");
91025 +            if (err != 0)
91026 +            {
91027 +                PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
91028 +            }
91029 +        }
91030 +
91031 +    }
91032 +
91033 +    return PVRSRV_OK;
91034 +}
91035 +
91036 +#endif 
91037 +
91038 +#define        OS_MAX_TIMERS   8
91039 +
91040 +typedef struct TIMER_CALLBACK_DATA_TAG
91041 +{
91042 +    IMG_BOOL           bInUse;
91043 +    PFN_TIMER_FUNC             pfnTimerFunc;
91044 +    IMG_VOID           *pvData;        
91045 +    struct timer_list  sTimer;
91046 +    IMG_UINT32                 ui32Delay;
91047 +    IMG_BOOL                   bActive;
91048 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91049 +       struct work_struct      sWork;
91050 +#endif
91051 +}TIMER_CALLBACK_DATA;
91052 +
91053 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91054 +static struct workqueue_struct *psTimerWorkQueue;
91055 +#endif
91056 +
91057 +static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
91058 +
91059 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91060 +DEFINE_MUTEX(sTimerStructLock);
91061 +#else
91062 +static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
91063 +#endif
91064 +
91065 +static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
91066 +{    
91067 +    if (!psTimerCBData->bActive)
91068 +        return;
91069 +
91070 +    
91071 +    psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
91072 +    
91073 +    
91074 +    mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
91075 +}
91076 +
91077 +
91078 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91079 +static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
91080 +{
91081 +    TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
91082 +
91083 +    OSTimerCallbackBody(psTimerCBData);
91084 +}
91085 +#endif
91086 +
91087 +static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
91088 +{
91089 +    TIMER_CALLBACK_DATA        *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
91090 +    
91091 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91092 +    int res;
91093 +
91094 +    res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
91095 +    if (res == 0)
91096 +    {
91097 +        PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));             
91098 +    }
91099 +#else
91100 +    OSTimerCallbackBody(psTimerCBData);
91101 +#endif
91102 +}
91103 +
91104 +
91105 +IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
91106 +{
91107 +    TIMER_CALLBACK_DATA        *psTimerCBData;
91108 +    IMG_UINT32         ui32i;
91109 +#if !defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91110 +    unsigned long              ulLockFlags;
91111 +#endif
91112 +
91113 +    
91114 +    if(!pfnTimerFunc)
91115 +    {
91116 +        PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));               
91117 +        return IMG_NULL;               
91118 +    }
91119 +    
91120 +    
91121 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91122 +    mutex_lock(&sTimerStructLock);
91123 +#else
91124 +    spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
91125 +#endif
91126 +    for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
91127 +    {
91128 +        psTimerCBData = &sTimers[ui32i];
91129 +        if (!psTimerCBData->bInUse)
91130 +        {
91131 +            psTimerCBData->bInUse = IMG_TRUE;
91132 +            break;
91133 +        }
91134 +    }
91135 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91136 +    mutex_unlock(&sTimerStructLock);
91137 +#else
91138 +    spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
91139 +#endif
91140 +    if (ui32i >= OS_MAX_TIMERS)
91141 +    {
91142 +        PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use"));         
91143 +        return IMG_NULL;       
91144 +    }
91145 +
91146 +    psTimerCBData->pfnTimerFunc = pfnTimerFunc;
91147 +    psTimerCBData->pvData = pvData;
91148 +    psTimerCBData->bActive = IMG_FALSE;
91149 +    
91150 +    
91151 +
91152 +
91153 +    psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
91154 +                                ?      1
91155 +                                :      ((HZ * ui32MsTimeout) / 1000);
91156 +    
91157 +    init_timer(&psTimerCBData->sTimer);
91158 +    
91159 +    
91160 +    psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
91161 +    psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
91162 +    psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
91163 +    
91164 +    return (IMG_HANDLE)(ui32i + 1);
91165 +}
91166 +
91167 +
91168 +static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer)
91169 +{
91170 +    IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1;
91171 +
91172 +    PVR_ASSERT(ui32i < OS_MAX_TIMERS);
91173 +
91174 +    return &sTimers[ui32i];
91175 +}
91176 +
91177 +PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
91178 +{
91179 +    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
91180 +
91181 +    PVR_ASSERT(psTimerCBData->bInUse);
91182 +    PVR_ASSERT(!psTimerCBData->bActive);
91183 +
91184 +    
91185 +    psTimerCBData->bInUse = IMG_FALSE;
91186 +    
91187 +    return PVRSRV_OK;
91188 +}
91189 +
91190 +
91191 +PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
91192 +{
91193 +    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
91194 +
91195 +    PVR_ASSERT(psTimerCBData->bInUse);
91196 +    PVR_ASSERT(!psTimerCBData->bActive);
91197 +
91198 +    
91199 +    psTimerCBData->bActive = IMG_TRUE;
91200 +
91201 +    
91202 +    psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
91203 +
91204 +    
91205 +    add_timer(&psTimerCBData->sTimer);
91206 +    
91207 +    return PVRSRV_OK;
91208 +}
91209 +
91210 +
91211 +PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
91212 +{
91213 +    TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
91214 +
91215 +    PVR_ASSERT(psTimerCBData->bInUse);
91216 +    PVR_ASSERT(psTimerCBData->bActive);
91217 +
91218 +    
91219 +    psTimerCBData->bActive = IMG_FALSE;
91220 +       smp_mb();
91221 +
91222 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91223 +       flush_workqueue(psTimerWorkQueue);
91224 +#endif
91225 +
91226 +    
91227 +    del_timer_sync(&psTimerCBData->sTimer);    
91228 +    
91229 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91230 +    
91231 +       flush_workqueue(psTimerWorkQueue);
91232 +#endif
91233 +
91234 +    return PVRSRV_OK;
91235 +}
91236 +
91237 +
91238 +PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
91239 +{
91240 +
91241 +    PVRSRV_ERROR eError = PVRSRV_OK;
91242 +    
91243 +    if(psEventObject)
91244 +    {
91245 +        if(pszName)
91246 +        {
91247 +            
91248 +            strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
91249 +        }
91250 +        else
91251 +        {
91252 +               
91253 +            static IMG_UINT16 ui16NameIndex = 0;                       
91254 +            snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
91255 +        }
91256 +        
91257 +        if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
91258 +        {
91259 +             eError = PVRSRV_ERROR_OUT_OF_MEMORY;      
91260 +        }
91261 +
91262 +    }
91263 +    else
91264 +    {
91265 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
91266 +        eError = PVRSRV_ERROR_GENERIC; 
91267 +    }
91268 +    
91269 +    return eError;
91270 +
91271 +}
91272 +
91273 +
91274 +PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject)
91275 +{
91276 +    PVRSRV_ERROR eError = PVRSRV_OK;
91277 +
91278 +    if(psEventObject)
91279 +    {
91280 +        if(psEventObject->hOSEventKM)
91281 +        {
91282 +            LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
91283 +        }
91284 +        else
91285 +        {
91286 +            PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hOSEventKM is not a valid pointer"));
91287 +            eError = PVRSRV_ERROR_INVALID_PARAMS;
91288 +        }
91289 +    }
91290 +    else
91291 +    {
91292 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
91293 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
91294 +    }
91295 +    
91296 +    return eError;
91297 +}
91298 +
91299 +PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM)
91300 +{
91301 +    PVRSRV_ERROR eError;
91302 +    
91303 +    if(hOSEventKM)
91304 +    {
91305 +        eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
91306 +    }
91307 +    else
91308 +    {
91309 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: hOSEventKM is not a valid handle"));
91310 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
91311 +    }
91312 +    
91313 +    return eError;
91314 +}
91315 +
91316 +PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject,
91317 +                                            IMG_HANDLE *phOSEvent)
91318 +{
91319 +    PVRSRV_ERROR eError = PVRSRV_OK;
91320 +    
91321 +    if(psEventObject)
91322 +    {
91323 +        if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK)
91324 +        {
91325 +            PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed"));
91326 +            eError = PVRSRV_ERROR_INVALID_PARAMS;
91327 +        }
91328 +
91329 +    }
91330 +    else
91331 +    {
91332 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer"));
91333 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
91334 +    }
91335 +    
91336 +    return eError;
91337 +}
91338 +
91339 +PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject,
91340 +                                            IMG_HANDLE hOSEventKM)
91341 +{
91342 +    PVRSRV_ERROR eError = PVRSRV_OK;
91343 +
91344 +    if(psEventObject)
91345 +    {
91346 +        if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK)
91347 +        {
91348 +            PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed"));
91349 +            eError = PVRSRV_ERROR_INVALID_PARAMS;
91350 +        }
91351 +
91352 +    }
91353 +    else
91354 +    {
91355 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer"));
91356 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
91357 +    }
91358 +    
91359 +    return eError;
91360 +    
91361 +}
91362 +
91363 +PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM)
91364 +{
91365 +    PVRSRV_ERROR eError;
91366 +    
91367 +    if(hOSEventKM)
91368 +    {
91369 +        eError = LinuxEventObjectSignal(hOSEventKM);
91370 +    }
91371 +    else
91372 +    {
91373 +        PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignal: hOSEventKM is not a valid handle"));
91374 +        eError = PVRSRV_ERROR_INVALID_PARAMS;
91375 +    }
91376 +    
91377 +    return eError;
91378 +}
91379 +
91380 +IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
91381 +{
91382 +    return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE;
91383 +}
91384 +
91385 +PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, 
91386 +                          IMG_VOID *pvDest, 
91387 +                          IMG_VOID *pvSrc, 
91388 +                          IMG_UINT32 ui32Bytes)
91389 +{
91390 +    PVR_UNREFERENCED_PARAMETER(pvProcess);
91391 +
91392 +    if(copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
91393 +        return PVRSRV_OK;
91394 +    else
91395 +        return PVRSRV_ERROR_GENERIC;
91396 +}
91397 +
91398 +PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess, 
91399 +                             IMG_VOID *pvDest, 
91400 +                             IMG_VOID *pvSrc, 
91401 +                             IMG_UINT32 ui32Bytes)
91402 +{
91403 +    PVR_UNREFERENCED_PARAMETER(pvProcess);
91404 +
91405 +    if(copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
91406 +        return PVRSRV_OK;
91407 +    else
91408 +        return PVRSRV_ERROR_GENERIC;
91409 +}
91410 +
91411 +IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes)
91412 +{
91413 +    IMG_INT linuxType;
91414 +
91415 +    if (eVerification == PVR_VERIFY_READ)
91416 +    {
91417 +        linuxType = VERIFY_READ;
91418 +    }
91419 +    else
91420 +    {
91421 +        PVR_ASSERT(eVerification == PVR_VERIFY_WRITE);
91422 +        linuxType = VERIFY_WRITE;
91423 +    }
91424 +
91425 +    return access_ok(linuxType, pvUserPtr, ui32Bytes);
91426 +}
91427 +
91428 +typedef enum _eWrapMemType_
91429 +{
91430 +    WRAP_TYPE_CLEANUP,
91431 +    WRAP_TYPE_GET_USER_PAGES,
91432 +    WRAP_TYPE_FIND_VMA_PAGES,
91433 +    WRAP_TYPE_FIND_VMA_PFN
91434 +} eWrapMemType;
91435 +
91436 +typedef struct _sWrapMemInfo_
91437 +{
91438 +    eWrapMemType eType;
91439 +    IMG_INT iNumPages;
91440 +    struct page **ppsPages;
91441 +    IMG_SYS_PHYADDR *psPhysAddr;
91442 +    IMG_INT iPageOffset;
91443 +    IMG_INT iContiguous;
91444 +#if defined(DEBUG)
91445 +    IMG_UINT32 ulStartAddr;
91446 +    IMG_UINT32 ulBeyondEndAddr;
91447 +    struct vm_area_struct *psVMArea;
91448 +#endif
91449 +       IMG_BOOL bWrapWorkaround;
91450 +} sWrapMemInfo;
91451 +
91452 +static IMG_VOID CheckPagesContiguous(sWrapMemInfo *psInfo)
91453 +{
91454 +    IMG_INT i;
91455 +    IMG_UINT32 ui32AddrChk;
91456 +
91457 +    BUG_ON(psInfo == IMG_NULL);
91458 +
91459 +    psInfo->iContiguous = 1;
91460 +
91461 +    for (i = 0, ui32AddrChk = psInfo->psPhysAddr[0].uiAddr;
91462 +        i < psInfo->iNumPages;
91463 +        i++, ui32AddrChk += PAGE_SIZE)
91464 +    {
91465 +        if (psInfo->psPhysAddr[i].uiAddr != ui32AddrChk)
91466 +        {
91467 +            psInfo->iContiguous = 0;
91468 +            break;
91469 +        }
91470 +    }
91471 +}
91472 +
91473 +static struct page *CPUVAddrToPage(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr)
91474 +{
91475 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
91476 +    pgd_t *psPGD;
91477 +    pud_t *psPUD;
91478 +    pmd_t *psPMD;
91479 +    pte_t *psPTE;
91480 +    struct mm_struct *psMM = psVMArea->vm_mm;
91481 +    IMG_UINT32 ulPFN;
91482 +    spinlock_t *psPTLock;
91483 +    struct page *psPage;
91484 +
91485 +    psPGD = pgd_offset(psMM, ulCPUVAddr);
91486 +    if (pgd_none(*psPGD) || pgd_bad(*psPGD))
91487 +        return NULL;
91488 +
91489 +    psPUD = pud_offset(psPGD, ulCPUVAddr);
91490 +    if (pud_none(*psPUD) || pud_bad(*psPUD))
91491 +        return NULL;
91492 +
91493 +    psPMD = pmd_offset(psPUD, ulCPUVAddr);
91494 +    if (pmd_none(*psPMD) || pmd_bad(*psPMD))
91495 +        return NULL;
91496 +
91497 +    psPage = NULL;
91498 +
91499 +    psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
91500 +    if ((pte_none(*psPTE) != 0) || (pte_present(*psPTE) == 0) || (pte_write(*psPTE) == 0))
91501 +        goto exit_unlock;
91502 +
91503 +    ulPFN = pte_pfn(*psPTE);
91504 +    if (!pfn_valid(ulPFN))
91505 +        goto exit_unlock;
91506 +
91507 +    psPage = pfn_to_page(ulPFN);
91508 +
91509 +    get_page(psPage);
91510 +
91511 +exit_unlock:
91512 +    pte_unmap_unlock(psPTE, psPTLock);  
91513 +
91514 +    return psPage;
91515 +#else
91516 +    return NULL;
91517 +#endif
91518 +}
91519 +PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
91520 +{
91521 +    sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
91522 +    IMG_INT i;
91523 +
91524 +    BUG_ON(psInfo == IMG_NULL);
91525 +
91526 +    switch (psInfo->eType)
91527 +    {
91528 +        case WRAP_TYPE_CLEANUP:
91529 +            break;
91530 +        case WRAP_TYPE_FIND_VMA_PFN:
91531 +            break;
91532 +        case WRAP_TYPE_GET_USER_PAGES:
91533 +        {
91534 +            for (i = 0; i < psInfo->iNumPages; i++)
91535 +            {
91536 +                struct page *psPage = psInfo->ppsPages[i];
91537 +
91538 +                
91539 +                if (!PageReserved(psPage));
91540 +                {
91541 +                    SetPageDirty(psPage);
91542 +                }
91543 +                page_cache_release(psPage);
91544 +            }
91545 +            break;
91546 +        }
91547 +        case WRAP_TYPE_FIND_VMA_PAGES:
91548 +        {
91549 +            for (i = 0; i < psInfo->iNumPages; i++)
91550 +            {
91551 +                if(psInfo->bWrapWorkaround)
91552 +                    put_page(psInfo->ppsPages[i]);
91553 +                else
91554 +                    put_page_testzero(psInfo->ppsPages[i]);
91555 +            }
91556 +            break;
91557 +        }
91558 +        default:
91559 +        {
91560 +            PVR_DPF((PVR_DBG_ERROR,
91561 +                "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
91562 +            return PVRSRV_ERROR_GENERIC;
91563 +        }
91564 +    }
91565 +
91566 +    if (psInfo->ppsPages != IMG_NULL)
91567 +    {
91568 +        kfree(psInfo->ppsPages);
91569 +    }
91570 +
91571 +    if (psInfo->psPhysAddr != IMG_NULL)
91572 +    {
91573 +        kfree(psInfo->psPhysAddr);
91574 +    }
91575 +
91576 +    kfree(psInfo);
91577 +
91578 +    return PVRSRV_OK;
91579 +}
91580 +
91581 +PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, 
91582 +                                    IMG_UINT32 ui32Bytes, 
91583 +                                    IMG_SYS_PHYADDR *psSysPAddr,
91584 +                                    IMG_HANDLE *phOSWrapMem,
91585 +                                    IMG_BOOL bWrapWorkaround)
91586 +{
91587 +    IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr;
91588 +    IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes;
91589 +    IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig;
91590 +    IMG_UINT32 ulStartAddr;
91591 +    IMG_UINT32 ulAddrRange;
91592 +    IMG_UINT32 ulBeyondEndAddr;
91593 +    IMG_UINT32 ulAddr;
91594 +    IMG_INT iNumPagesMapped;
91595 +    IMG_INT i;
91596 +    struct vm_area_struct *psVMArea;
91597 +    sWrapMemInfo *psInfo;
91598 +
91599 +    
91600 +    ulStartAddr = ulStartAddrOrig & PAGE_MASK;
91601 +    ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
91602 +    ulAddrRange = ulBeyondEndAddr - ulStartAddr;
91603 +
91604 +    
91605 +    psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
91606 +    if (psInfo == NULL)
91607 +    {
91608 +        PVR_DPF((PVR_DBG_ERROR,
91609 +            "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
91610 +        return PVRSRV_ERROR_OUT_OF_MEMORY;
91611 +    }
91612 +    memset(psInfo, 0, sizeof(*psInfo));
91613 +    psInfo->bWrapWorkaround = bWrapWorkaround;
91614 +
91615 +#if defined(DEBUG)
91616 +    psInfo->ulStartAddr = ulStartAddrOrig;
91617 +    psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig;
91618 +#endif
91619 +
91620 +    psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT);
91621 +    psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK);
91622 +
91623 +    
91624 +    psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL);
91625 +    if (psInfo->psPhysAddr == NULL)
91626 +    {
91627 +        PVR_DPF((PVR_DBG_ERROR,
91628 +            "OSAcquirePhysPageAddr: Couldn't allocate page array"));           
91629 +        goto error_free;
91630 +    }
91631 +
91632 +    
91633 +    psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages),  GFP_KERNEL);
91634 +    if (psInfo->ppsPages == NULL)
91635 +    {
91636 +        PVR_DPF((PVR_DBG_ERROR,
91637 +            "OSAcquirePhysPageAddr: Couldn't allocate page array"));           
91638 +        goto error_free;
91639 +    }
91640 +
91641 +    
91642 +    down_read(&current->mm->mmap_sem);
91643 +    iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
91644 +    up_read(&current->mm->mmap_sem);
91645 +
91646 +    if (iNumPagesMapped >= 0)
91647 +    {
91648 +        
91649 +        if (iNumPagesMapped != psInfo->iNumPages)
91650 +        {
91651 +            PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, iNumPagesMapped));
91652 +
91653 +            
91654 +            for (i = 0; i < iNumPagesMapped; i++)
91655 +            {
91656 +                page_cache_release(psInfo->ppsPages[i]);
91657 +                    
91658 +            }
91659 +            goto error_free;
91660 +        }
91661 +
91662 +        
91663 +        for (i = 0; i < psInfo->iNumPages; i++)
91664 +        {
91665 +            IMG_CPU_PHYADDR CPUPhysAddr;
91666 +
91667 +            CPUPhysAddr.uiAddr = page_to_pfn(psInfo->ppsPages[i]) << PAGE_SHIFT;
91668 +            psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
91669 +            psSysPAddr[i] = psInfo->psPhysAddr[i];
91670 +            
91671 +        }
91672 +
91673 +        psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
91674 +
91675 +        goto exit_check;
91676 +    }
91677 +
91678 +    PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), trying something else", iNumPagesMapped));
91679 +    
91680 +    
91681 +    down_read(&current->mm->mmap_sem);
91682 +
91683 +    psVMArea = find_vma(current->mm, ulStartAddrOrig);
91684 +    if (psVMArea == NULL)
91685 +    {
91686 +        PVR_DPF((PVR_DBG_ERROR,
91687 +            "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %lx", ulStartAddrOrig));
91688 +        
91689 +        goto error_release_mmap_sem;
91690 +    }
91691 +#if defined(DEBUG)
91692 +    psInfo->psVMArea = psVMArea;
91693 +#endif
91694 +
91695 +    
91696 +    if (ulStartAddrOrig < psVMArea->vm_start)
91697 +    {
91698 +        PVR_DPF((PVR_DBG_ERROR,
91699 +            "OSAcquirePhysPageAddr: Start address %lx is outside of the region returned by find_vma", ulStartAddrOrig));
91700 +        goto error_release_mmap_sem;
91701 +    }
91702 +
91703 +    
91704 +    if (ulBeyondEndAddrOrig > psVMArea->vm_end)
91705 +    {
91706 +        PVR_DPF((PVR_DBG_ERROR,
91707 +            "OSAcquirePhysPageAddr: End address %lx is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
91708 +        goto error_release_mmap_sem;
91709 +    }
91710 +
91711 +    
91712 +    if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED))
91713 +    {
91714 +        PVR_DPF((PVR_DBG_ERROR,
91715 +            "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags));
91716 +        goto error_release_mmap_sem;
91717 +    }
91718 +
91719 +    
91720 +    if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE))
91721 +    {
91722 +        PVR_DPF((PVR_DBG_ERROR,
91723 +            "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags));
91724 +        goto error_release_mmap_sem;
91725 +    }
91726 +
91727 +    
91728 +    for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
91729 +    {
91730 +        struct page *psPage;
91731 +
91732 +        BUG_ON(i >= psInfo->iNumPages);
91733 +
91734 +        psPage = CPUVAddrToPage(psVMArea, ulAddr);
91735 +        if (psPage == NULL)
91736 +        {
91737 +            IMG_INT j;
91738 +
91739 +        PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't lookup page structure for address 0x%lx, trying something else", ulAddr));
91740 +
91741 +            
91742 +            for (j = 0; j < i; j++)
91743 +            {
91744 +                if(psInfo->bWrapWorkaround)
91745 +                    put_page(psInfo->ppsPages[j]);
91746 +                else
91747 +                    put_page_testzero(psInfo->ppsPages[j]);
91748 +            }
91749 +            break;
91750 +        }
91751 +
91752 +        psInfo->ppsPages[i] = psPage;
91753 +    }
91754 +
91755 +    BUG_ON(i > psInfo->iNumPages);
91756 +    if (i == psInfo->iNumPages)
91757 +    {
91758 +        
91759 +        for (i = 0; i < psInfo->iNumPages; i++)
91760 +        {
91761 +            struct page *psPage = psInfo->ppsPages[i];
91762 +            IMG_CPU_PHYADDR CPUPhysAddr;
91763 +
91764 +            
91765 +            CPUPhysAddr.uiAddr = page_to_pfn(psPage) << PAGE_SHIFT;
91766 +
91767 +            psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
91768 +            psSysPAddr[i] = psInfo->psPhysAddr[i];
91769 +        }
91770 +
91771 +        psInfo->eType = WRAP_TYPE_FIND_VMA_PAGES;
91772 +    }
91773 +    else
91774 +    {
91775 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) && defined(PVR_SECURE_HANDLES)
91776 +        
91777 +
91778 +        
91779 +        if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
91780 +        {
91781 +        PVR_DPF((PVR_DBG_WARNING,
91782 +            "OSAcquirePhysPageAddr: Region isn't a raw PFN mapping.  Giving up."));
91783 +            goto error_release_mmap_sem;
91784 +        }
91785 +        
91786 +        for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
91787 +        {
91788 +            IMG_CPU_PHYADDR CPUPhysAddr;
91789 +
91790 +            CPUPhysAddr.uiAddr = ((ulAddr - psVMArea->vm_start) + (psVMArea->vm_pgoff << PAGE_SHIFT)) & PAGE_MASK;
91791 +
91792 +            psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
91793 +            psSysPAddr[i] = psInfo->psPhysAddr[i];
91794 +        }
91795 +        BUG_ON(i != psInfo->iNumPages);
91796 +
91797 +        psInfo->eType = WRAP_TYPE_FIND_VMA_PFN;
91798 +
91799 +        
91800 +        PVR_DPF((PVR_DBG_WARNING,
91801 +            "OSAcquirePhysPageAddr: Region can't be locked down"));
91802 +#else
91803 +        PVR_DPF((PVR_DBG_WARNING,
91804 +            "OSAcquirePhysPageAddr: Raw PFN mappings not supported.  Giving up."));
91805 +        goto error_release_mmap_sem;
91806 +#endif 
91807 +    }
91808 +
91809 +    up_read(&current->mm->mmap_sem);
91810 +
91811 +exit_check:
91812 +    CheckPagesContiguous(psInfo);
91813 +
91814 +
91815 +    
91816 +    *phOSWrapMem = (IMG_HANDLE)psInfo;
91817 +
91818 +    return PVRSRV_OK;
91819 +
91820 +error_release_mmap_sem:
91821 +    up_read(&current->mm->mmap_sem);
91822 +error_free:
91823 +    psInfo->eType = WRAP_TYPE_CLEANUP;
91824 +    OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
91825 +    return PVRSRV_ERROR_GENERIC;
91826 +}
91827 +
91828 +PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
91829 +{
91830 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91831 +    {
91832 +        IMG_UINT32 ui32i;
91833 +
91834 +        psTimerWorkQueue = create_workqueue("pvr_timer");
91835 +        if (psTimerWorkQueue == NULL)
91836 +        {
91837 +           PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));              
91838 +           return PVRSRV_ERROR_GENERIC;
91839 +
91840 +        }
91841 +
91842 +        for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
91843 +        {
91844 +            TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
91845 +
91846 +           INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
91847 +        }
91848 +    }
91849 +#endif
91850 +    return PVRSRV_OK;
91851 +}
91852 +
91853 +IMG_VOID PVROSFuncDeInit(IMG_VOID)
91854 +{
91855 +#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
91856 +    if (psTimerWorkQueue != NULL)
91857 +    {
91858 +       destroy_workqueue(psTimerWorkQueue);
91859 +    }
91860 +#endif
91861 +}
91862 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osperproc.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osperproc.c
91863 new file mode 100644
91864 index 0000000..011c8f3
91865 --- /dev/null
91866 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/osperproc.c
91867 @@ -0,0 +1,113 @@
91868 +/**********************************************************************
91869 + *
91870 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
91871 + * 
91872 + * This program is free software; you can redistribute it and/or modify it
91873 + * under the terms and conditions of the GNU General Public License,
91874 + * version 2, as published by the Free Software Foundation.
91875 + * 
91876 + * This program is distributed in the hope it will be useful but, except 
91877 + * as otherwise stated in writing, without any warranty; without even the 
91878 + * implied warranty of merchantability or fitness for a particular purpose. 
91879 + * See the GNU General Public License for more details.
91880 + * 
91881 + * You should have received a copy of the GNU General Public License along with
91882 + * this program; if not, write to the Free Software Foundation, Inc.,
91883 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
91884 + * 
91885 + * The full GNU General Public License is included in this distribution in
91886 + * the file called "COPYING".
91887 + *
91888 + * Contact Information:
91889 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
91890 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
91891 + *
91892 + ******************************************************************************/
91893 +
91894 +#include "services_headers.h"
91895 +#include "osperproc.h"
91896 +
91897 +#include "env_perproc.h"
91898 +#include "proc.h"
91899 +
91900 +extern IMG_UINT32 gui32ReleasePID;
91901 +
91902 +PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
91903 +{
91904 +       PVRSRV_ERROR eError;
91905 +       IMG_HANDLE hBlockAlloc;
91906 +       PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
91907 +
91908 +       eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
91909 +                               sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
91910 +                               phOsPrivateData,
91911 +                               &hBlockAlloc,
91912 +                               "Environment per Process Data");
91913 +
91914 +       if (eError != PVRSRV_OK)
91915 +       {
91916 +               *phOsPrivateData = IMG_NULL;
91917 +
91918 +               PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError));
91919 +               return eError;
91920 +       }
91921 +
91922 +       psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData;
91923 +       OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc));
91924 +
91925 +       psEnvPerProc->hBlockAlloc = hBlockAlloc;
91926 +
91927 +       
91928 +       LinuxMMapPerProcessConnect(psEnvPerProc);
91929 +
91930 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
91931 +       
91932 +       INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
91933 +#endif
91934 +
91935 +       return PVRSRV_OK;
91936 +}
91937 +
91938 +PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
91939 +{
91940 +       PVRSRV_ERROR eError;
91941 +       PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
91942 +
91943 +       if (hOsPrivateData == IMG_NULL)
91944 +       {
91945 +               return PVRSRV_OK;
91946 +       }
91947 +
91948 +       psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData;
91949 +
91950 +       
91951 +       LinuxMMapPerProcessDisconnect(psEnvPerProc);
91952 +
91953 +       
91954 +       RemovePerProcessProcDir(psEnvPerProc);
91955 +
91956 +       eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
91957 +                               sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
91958 +                               hOsPrivateData,
91959 +                               psEnvPerProc->hBlockAlloc);
91960 +       
91961 +
91962 +       if (eError != PVRSRV_OK)
91963 +       {
91964 +               PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError));
91965 +       }
91966 +
91967 +       return PVRSRV_OK;
91968 +}
91969 +
91970 +PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
91971 +{
91972 +       return LinuxMMapPerProcessHandleOptions(psHandleBase);
91973 +}
91974 +
91975 +IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID)
91976 +{
91977 +       if(!gui32ReleasePID)
91978 +               return NULL;
91979 +       return PVRSRVPerProcessPrivateData(gui32ReleasePID);
91980 +}
91981 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pdump.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pdump.c
91982 new file mode 100644
91983 index 0000000..11d69d1
91984 --- /dev/null
91985 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pdump.c
91986 @@ -0,0 +1,662 @@
91987 +/**********************************************************************
91988 + *
91989 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
91990 + * 
91991 + * This program is free software; you can redistribute it and/or modify it
91992 + * under the terms and conditions of the GNU General Public License,
91993 + * version 2, as published by the Free Software Foundation.
91994 + * 
91995 + * This program is distributed in the hope it will be useful but, except 
91996 + * as otherwise stated in writing, without any warranty; without even the 
91997 + * implied warranty of merchantability or fitness for a particular purpose. 
91998 + * See the GNU General Public License for more details.
91999 + * 
92000 + * You should have received a copy of the GNU General Public License along with
92001 + * this program; if not, write to the Free Software Foundation, Inc.,
92002 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
92003 + * 
92004 + * The full GNU General Public License is included in this distribution in
92005 + * the file called "COPYING".
92006 + *
92007 + * Contact Information:
92008 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
92009 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
92010 + *
92011 + ******************************************************************************/
92012 +
92013 +#if defined (SUPPORT_SGX)
92014 +#if defined (PDUMP)
92015 +
92016 +#include <asm/atomic.h>
92017 +#include <stdarg.h>
92018 +#include "sgxdefs.h"
92019 +#include "services_headers.h"
92020 +
92021 +#include "pvrversion.h"
92022 +#include "pvr_debug.h"
92023 +
92024 +#include "dbgdrvif.h"
92025 +#include "sgxmmu.h"
92026 +#include "mm.h"
92027 +#include "pdump_km.h"
92028 +
92029 +#include <linux/tty.h>                 
92030 +
92031 +static IMG_BOOL PDumpWriteString2              (IMG_CHAR * pszString, IMG_UINT32 ui32Flags);
92032 +static IMG_BOOL PDumpWriteILock                        (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags);
92033 +static IMG_VOID DbgSetFrame                            (PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
92034 +static IMG_UINT32 DbgGetFrame                  (PDBG_STREAM psStream);
92035 +static IMG_VOID DbgSetMarker                   (PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
92036 +static IMG_UINT32 DbgWrite                             (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags);
92037 +
92038 +#define PDUMP_DATAMASTER_PIXEL         (1)
92039 +#define PDUMP_DATAMASTER_EDM           (3)
92040 +
92041 +#define MIN(a,b)       (a > b ? b : a)
92042 +
92043 +#define MAX_FILE_SIZE  0x40000000
92044 +
92045 +static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
92046 +
92047 +static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
92048 +
92049 +
92050 +
92051 +IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
92052 +                                                                                               "ScriptStream2",
92053 +                                                                                               "DriverInfoStream"};
92054 +typedef struct PDBG_PDUMP_STATE_TAG
92055 +{
92056 +       PDBG_STREAM psStream[PDUMP_NUM_STREAMS];
92057 +       IMG_UINT32 ui32ParamFileNum;
92058 +
92059 +       IMG_CHAR *pszMsg;
92060 +       IMG_CHAR *pszScript;
92061 +       IMG_CHAR *pszFile;
92062 +
92063 +} PDBG_PDUMP_STATE;
92064 +
92065 +static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL};
92066 +
92067 +#define SZ_MSG_SIZE_MAX                        PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
92068 +#define SZ_SCRIPT_SIZE_MAX             PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
92069 +#define SZ_FILENAME_SIZE_MAX   PVRSRV_PDUMP_MAX_COMMENT_SIZE-1
92070 +
92071 +
92072 +
92073 +
92074 +IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table);
92075 +
92076 +static inline IMG_BOOL PDumpSuspended(IMG_VOID)
92077 +{
92078 +       return atomic_read(&gsPDumpSuspended) != 0;
92079 +}
92080 +
92081 +PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
92082 +                                                                       IMG_UINT32 *pui32MaxLen)
92083 +{
92084 +       *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
92085 +       *pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
92086 +       if ((!*phScript) || PDumpSuspended())
92087 +       {
92088 +               return PVRSRV_ERROR_GENERIC;
92089 +       }
92090 +       return PVRSRV_OK;
92091 +}
92092 +
92093 +PVRSRV_ERROR PDumpOSGetMessageString(IMG_HANDLE *phMsg,
92094 +                                                                        IMG_UINT32 *pui32MaxLen)
92095 +{
92096 +       *phMsg = (IMG_HANDLE)gsDBGPdumpState.pszMsg;
92097 +       *pui32MaxLen = SZ_MSG_SIZE_MAX;
92098 +       if ((!*phMsg) || PDumpSuspended())
92099 +       {
92100 +               return PVRSRV_ERROR_GENERIC;
92101 +       }
92102 +       return PVRSRV_OK;
92103 +}
92104 +
92105 +PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
92106 +                                                                        IMG_UINT32 *pui32MaxLen)
92107 +{
92108 +       *ppszFile = gsDBGPdumpState.pszFile;
92109 +       *pui32MaxLen = SZ_FILENAME_SIZE_MAX;
92110 +       if ((!*ppszFile) || PDumpSuspended())
92111 +       {
92112 +               return PVRSRV_ERROR_GENERIC;
92113 +       }
92114 +       return PVRSRV_OK;
92115 +}
92116 +
92117 +IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags)
92118 +{
92119 +       return PDumpWriteString2(hScript, ui32Flags);
92120 +}
92121 +
92122 +PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...)
92123 +{
92124 +       IMG_CHAR* pszBuf = hBuf;
92125 +       IMG_UINT32 n;
92126 +       va_list vaArgs;
92127 +
92128 +       va_start(vaArgs, pszFormat);
92129 +
92130 +       n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs);
92131 +
92132 +       va_end(vaArgs);
92133 +
92134 +       if (n>=ui32ScriptSizeMax || n==-1)      
92135 +       {
92136 +               PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
92137 +
92138 +               return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
92139 +       }
92140 +
92141 +       return PVRSRV_OK;
92142 +}
92143 +
92144 +PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
92145 +{
92146 +       IMG_UINT32 n;
92147 +
92148 +       n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
92149 +
92150 +       if (n>=ui32ScriptSizeMax || n==-1)      
92151 +       {
92152 +               PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
92153 +
92154 +               return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
92155 +       }
92156 +
92157 +       return PVRSRV_OK;
92158 +}
92159 +
92160 +IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
92161 +{
92162 +       
92163 +}
92164 +
92165 +PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...)
92166 +{
92167 +       IMG_UINT32 n;
92168 +       va_list vaArgs;
92169 +
92170 +       va_start(vaArgs, pszFormat);
92171 +
92172 +       n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
92173 +
92174 +       va_end(vaArgs);
92175 +
92176 +       if (n>=ui32ScriptSizeMax || n==-1)      
92177 +       {
92178 +               PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
92179 +
92180 +               return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
92181 +       }
92182 +
92183 +       return PVRSRV_OK;
92184 +}
92185 +
92186 +IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
92187 +{
92188 +       IMG_CHAR* pszBuf = hBuffer;
92189 +       IMG_UINT32 ui32Count = 0;
92190 +
92191 +       while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) )
92192 +       {
92193 +               ui32Count++;
92194 +       }
92195 +       return(ui32Count);
92196 +}
92197 +
92198 +IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
92199 +{
92200 +       IMG_UINT32 ui32Count = 0;
92201 +       IMG_CHAR* pszBuf = hBuffer;
92202 +
92203 +       
92204 +       ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
92205 +
92206 +       
92207 +       if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
92208 +       {
92209 +               pszBuf[ui32Count] = '\n';
92210 +               ui32Count++;
92211 +               pszBuf[ui32Count] = '\0';
92212 +       }
92213 +       if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax))
92214 +       {
92215 +               pszBuf[ui32Count-1] = '\r';
92216 +               pszBuf[ui32Count] = '\n';
92217 +               ui32Count++;
92218 +               pszBuf[ui32Count] = '\0';
92219 +       }
92220 +}
92221 +
92222 +IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream)
92223 +{
92224 +       return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream];
92225 +}
92226 +
92227 +IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream)
92228 +{
92229 +       PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream];
92230 +       return gpfnDbgDrv->pfnGetStreamOffset(psStream);
92231 +}
92232 +
92233 +IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID)
92234 +{
92235 +       return gsDBGPdumpState.ui32ParamFileNum;
92236 +}
92237 +
92238 +IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream,
92239 +               IMG_UINT8 *psui8Data,
92240 +               IMG_UINT32 ui32Size,
92241 +               IMG_UINT32 ui32Flags)
92242 +{
92243 +       PDBG_STREAM psStream = (PDBG_STREAM)hStream;
92244 +       return PDumpWriteILock(psStream,
92245 +                                       psui8Data,
92246 +                                       ui32Size,
92247 +                                       ui32Flags);
92248 +}
92249 +
92250 +IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
92251 +{
92252 +       
92253 +       PVR_UNREFERENCED_PARAMETER(hStream);
92254 +       PVR_UNREFERENCED_PARAMETER(ui32Size);
92255 +       PVR_UNREFERENCED_PARAMETER(ui32Size);
92256 +}
92257 +
92258 +IMG_BOOL PDumpOSJTInitialised(IMG_VOID)
92259 +{
92260 +       if(gpfnDbgDrv)
92261 +       {
92262 +               return IMG_TRUE;
92263 +       }
92264 +       return IMG_FALSE;
92265 +}
92266 +
92267 +inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID)
92268 +{
92269 +       return atomic_read(&gsPDumpSuspended) != 0;
92270 +}
92271 +
92272 +IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
92273 +        IMG_HANDLE hOSMemHandle,
92274 +               IMG_UINT32 ui32Offset,
92275 +               IMG_UINT8 *pui8LinAddr,
92276 +               IMG_UINT32 ui32PageSize,
92277 +               IMG_DEV_PHYADDR *psDevPAddr)
92278 +{
92279 +       if(hOSMemHandle)
92280 +       {
92281 +               
92282 +               IMG_CPU_PHYADDR sCpuPAddr;
92283 +
92284 +               PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
92285 +
92286 +               sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
92287 +               PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
92288 +
92289 +               
92290 +               *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
92291 +       }
92292 +       else
92293 +       {
92294 +               IMG_CPU_PHYADDR sCpuPAddr;
92295 +
92296 +               PVR_UNREFERENCED_PARAMETER(ui32Offset);
92297 +
92298 +               sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
92299 +               *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
92300 +       }
92301 +}
92302 +
92303 +IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
92304 +               IMG_UINT32 ui32Offset,
92305 +               IMG_PUINT8 pui8LinAddr,
92306 +               IMG_UINT32 *pui32PageOffset)
92307 +{
92308 +       if(hOSMemHandle)
92309 +       {
92310 +               
92311 +               IMG_CPU_PHYADDR     sCpuPAddr;
92312 +
92313 +               PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
92314 +
92315 +               sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
92316 +           *pui32PageOffset = sCpuPAddr.uiAddr & (HOST_PAGESIZE() -1);
92317 +       }
92318 +       else
92319 +       {
92320 +               PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
92321 +               PVR_UNREFERENCED_PARAMETER(ui32Offset);
92322 +
92323 +               *pui32PageOffset = (IMG_UINT32)pui8LinAddr & (HOST_PAGESIZE() - 1);
92324 +       }
92325 +}
92326 +
92327 +
92328 +
92329 +IMG_VOID PDumpInit(IMG_VOID)
92330 +{
92331 +       IMG_UINT32 i;
92332 +
92333 +       
92334 +       if (!gpfnDbgDrv)
92335 +       {
92336 +               DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv);
92337 +
92338 +
92339 +
92340 +               
92341 +               if (gpfnDbgDrv == IMG_NULL)
92342 +               {
92343 +                       return;
92344 +               }
92345 +
92346 +               if(!gsDBGPdumpState.pszFile)
92347 +               {
92348 +                       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0,
92349 +                               "Filename string") != PVRSRV_OK)
92350 +                       {
92351 +                               goto init_failed;
92352 +                       }
92353 +               }
92354 +
92355 +               if(!gsDBGPdumpState.pszMsg)
92356 +               {
92357 +                       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0,
92358 +                               "Message string") != PVRSRV_OK)
92359 +                       {
92360 +                               goto init_failed;
92361 +                       }
92362 +               }
92363 +
92364 +               if(!gsDBGPdumpState.pszScript)
92365 +               {
92366 +                       if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0,
92367 +                               "Script string") != PVRSRV_OK)
92368 +                       {
92369 +                               goto init_failed;
92370 +                       }
92371 +               }
92372 +
92373 +               for(i=0; i < PDUMP_NUM_STREAMS; i++)
92374 +               {
92375 +                       gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i],
92376 +                                                                                                               DEBUG_CAPMODE_FRAMED,
92377 +                                                                                                               DEBUG_OUTMODE_STREAMENABLE,
92378 +                                                                                                               0,
92379 +                                                                                                               10);
92380 +
92381 +                       gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1);
92382 +                       gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0);
92383 +               }
92384 +
92385 +               PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME);
92386 +               PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FILE);
92387 +               PDUMPCOMMENT("Start of Init Phase");
92388 +       }
92389 +
92390 +       return;
92391 +
92392 +init_failed:
92393 +
92394 +       if(gsDBGPdumpState.pszFile)
92395 +       {
92396 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
92397 +               gsDBGPdumpState.pszFile = IMG_NULL;
92398 +       }
92399 +
92400 +       if(gsDBGPdumpState.pszScript)
92401 +       {
92402 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
92403 +               gsDBGPdumpState.pszScript = IMG_NULL;
92404 +       }
92405 +
92406 +       if(gsDBGPdumpState.pszMsg)
92407 +       {
92408 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
92409 +               gsDBGPdumpState.pszMsg = IMG_NULL;
92410 +       }
92411 +
92412 +       gpfnDbgDrv = IMG_NULL;
92413 +}
92414 +
92415 +
92416 +IMG_VOID PDumpDeInit(IMG_VOID)
92417 +{
92418 +       IMG_UINT32 i;
92419 +
92420 +       for(i=0; i < PDUMP_NUM_STREAMS; i++)
92421 +       {
92422 +               gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]);
92423 +       }
92424 +
92425 +       if(gsDBGPdumpState.pszFile)
92426 +       {
92427 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0);
92428 +               gsDBGPdumpState.pszFile = IMG_NULL;
92429 +       }
92430 +
92431 +       if(gsDBGPdumpState.pszScript)
92432 +       {
92433 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0);
92434 +               gsDBGPdumpState.pszScript = IMG_NULL;
92435 +       }
92436 +
92437 +       if(gsDBGPdumpState.pszMsg)
92438 +       {
92439 +               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0);
92440 +               gsDBGPdumpState.pszMsg = IMG_NULL;
92441 +       }
92442 +
92443 +       gpfnDbgDrv = IMG_NULL;
92444 +}
92445 +
92446 +PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID)
92447 +{
92448 +       IMG_UINT32 i;
92449 +
92450 +       if (gpfnDbgDrv)
92451 +       {
92452 +               PDUMPCOMMENT("Start Init Phase");
92453 +               for(i=0; i < PDUMP_NUM_STREAMS; i++)
92454 +               {
92455 +                       gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]);
92456 +               }
92457 +       }
92458 +       return PVRSRV_OK;
92459 +}
92460 +
92461 +PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID)
92462 +{
92463 +       IMG_UINT32 i;
92464 +
92465 +       if (gpfnDbgDrv)
92466 +       {
92467 +               PDUMPCOMMENT("Stop Init Phase");
92468 +
92469 +               for(i=0; i < PDUMP_NUM_STREAMS; i++)
92470 +               {
92471 +                       gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]);
92472 +               }
92473 +       }
92474 +       return PVRSRV_OK;
92475 +}
92476 +
92477 +IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
92478 +{
92479 +       return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
92480 +}
92481 +
92482 +
92483 +IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
92484 +{
92485 +       if (PDumpSuspended())
92486 +       {
92487 +               return IMG_FALSE;
92488 +       }
92489 +       return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE);
92490 +}
92491 +
92492 +PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
92493 +{
92494 +       IMG_UINT32      ui32Stream;
92495 +
92496 +       for     (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
92497 +       {
92498 +               if      (gsDBGPdumpState.psStream[ui32Stream])
92499 +               {
92500 +                       DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame);
92501 +               }
92502 +       }
92503 +
92504 +       return PVRSRV_OK;
92505 +}
92506 +
92507 +PVRSRV_ERROR PDumpGetFrameKM(IMG_PUINT32 pui32Frame)
92508 +{
92509 +       *pui32Frame = DbgGetFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
92510 +
92511 +       return PVRSRV_OK;
92512 +}
92513 +
92514 +
92515 +
92516 +static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
92517 +{
92518 +       return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
92519 +}
92520 +
92521 +
92522 +static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
92523 +{
92524 +       IMG_UINT32 ui32Written = 0;
92525 +       IMG_UINT32 ui32Off = 0;
92526 +
92527 +       if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0))
92528 +       {
92529 +               return IMG_TRUE;
92530 +       }
92531 +
92532 +
92533 +       
92534 +
92535 +       if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2])
92536 +       {
92537 +               IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]);
92538 +
92539 +               if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE)
92540 +               {
92541 +                       if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags)))
92542 +                       {
92543 +                               DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos);
92544 +                               gsDBGPdumpState.ui32ParamFileNum++;
92545 +                       }
92546 +               }
92547 +       }
92548 +
92549 +
92550 +       while (((IMG_UINT32) ui32Count > 0) && (ui32Written != 0xFFFFFFFF))
92551 +       {
92552 +               ui32Written = DbgWrite(psStream, &pui8Data[ui32Off], ui32Count, ui32Flags);
92553 +
92554 +               
92555 +
92556 +
92557 +               if (ui32Written == 0)
92558 +               {
92559 +                       OSReleaseThreadQuanta();
92560 +               }
92561 +
92562 +               if (ui32Written != 0xFFFFFFFF)
92563 +               {
92564 +                       ui32Off += ui32Written;
92565 +                       ui32Count -= ui32Written;
92566 +               }
92567 +       }
92568 +
92569 +       if (ui32Written == 0xFFFFFFFF)
92570 +       {
92571 +               return IMG_FALSE;
92572 +       }
92573 +
92574 +       return IMG_TRUE;
92575 +}
92576 +
92577 +static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame)
92578 +{
92579 +       gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
92580 +}
92581 +
92582 +
92583 +static IMG_UINT32 DbgGetFrame(PDBG_STREAM psStream)
92584 +{
92585 +       return gpfnDbgDrv->pfnGetFrame(psStream);
92586 +}
92587 +
92588 +static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
92589 +{
92590 +       gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
92591 +}
92592 +
92593 +static IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
92594 +{
92595 +       IMG_UINT32      ui32BytesWritten;
92596 +
92597 +       if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
92598 +       {
92599 +               
92600 +
92601 +               if (((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
92602 +                   (psStream->ui32Start == 0xFFFFFFFFUL) &&
92603 +                   (psStream->ui32End == 0xFFFFFFFFUL) &&
92604 +                    psStream->bInitPhaseComplete)
92605 +               {
92606 +                       ui32BytesWritten = ui32BCount;
92607 +               }
92608 +               else
92609 +               {
92610 +                       ui32BytesWritten = gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, 1);
92611 +               }
92612 +       }
92613 +       else
92614 +       {
92615 +               if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
92616 +               {
92617 +                       IMG_UINT32      ui32DbgFlags;
92618 +
92619 +                       ui32DbgFlags = 0;
92620 +                       if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
92621 +                       {
92622 +                               ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
92623 +                       }
92624 +
92625 +                       ui32BytesWritten = gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, 1, ui32DbgFlags);
92626 +               }
92627 +               else
92628 +               {
92629 +                       ui32BytesWritten = gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, 1);
92630 +               }
92631 +       }
92632 +
92633 +       return ui32BytesWritten;
92634 +}
92635 +
92636 +
92637 +IMG_VOID PDumpSuspendKM(IMG_VOID)
92638 +{
92639 +       atomic_inc(&gsPDumpSuspended);
92640 +}
92641 +
92642 +IMG_VOID PDumpResumeKM(IMG_VOID)
92643 +{
92644 +       atomic_dec(&gsPDumpSuspended);
92645 +}
92646 +
92647 +#endif 
92648 +#endif 
92649 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/private_data.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/private_data.h
92650 new file mode 100644
92651 index 0000000..0751765
92652 --- /dev/null
92653 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/private_data.h
92654 @@ -0,0 +1,67 @@
92655 +/**********************************************************************
92656 + *
92657 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
92658 + * 
92659 + * This program is free software; you can redistribute it and/or modify it
92660 + * under the terms and conditions of the GNU General Public License,
92661 + * version 2, as published by the Free Software Foundation.
92662 + * 
92663 + * This program is distributed in the hope it will be useful but, except 
92664 + * as otherwise stated in writing, without any warranty; without even the 
92665 + * implied warranty of merchantability or fitness for a particular purpose. 
92666 + * See the GNU General Public License for more details.
92667 + * 
92668 + * You should have received a copy of the GNU General Public License along with
92669 + * this program; if not, write to the Free Software Foundation, Inc.,
92670 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
92671 + * 
92672 + * The full GNU General Public License is included in this distribution in
92673 + * the file called "COPYING".
92674 + *
92675 + * Contact Information:
92676 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
92677 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
92678 + *
92679 + ******************************************************************************/
92680 +
92681 +#ifndef __INCLUDED_PRIVATE_DATA_H_
92682 +#define __INCLUDED_PRIVATE_DATA_H_
92683 +
92684 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
92685 +#include <linux/list.h>
92686 +#include <drm/drmP.h>
92687 +#endif
92688 +
92689 +typedef struct
92690 +{
92691 +       
92692 +       IMG_UINT32 ui32OpenPID;
92693 +
92694 +#if defined(PVR_SECURE_FD_EXPORT)
92695 +       
92696 +       IMG_HANDLE hKernelMemInfo;
92697 +#endif 
92698 +
92699 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
92700 +       
92701 +       struct list_head sDRMAuthListItem;
92702 +
92703 +       struct drm_file *psDRMFile;
92704 +#endif
92705 +
92706 +#if defined(SUPPORT_MEMINFO_IDS)
92707 +       
92708 +       IMG_UINT64 ui64Stamp;
92709 +#endif 
92710 +
92711 +       
92712 +       IMG_HANDLE hBlockAlloc;
92713 +
92714 +#if defined(SUPPORT_DRI_DRM_EXT)
92715 +       IMG_PVOID pPriv;        
92716 +#endif
92717 +}
92718 +PVRSRV_FILE_PRIVATE_DATA;
92719 +
92720 +#endif 
92721 +
92722 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.c
92723 new file mode 100644
92724 index 0000000..1ba2466
92725 --- /dev/null
92726 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.c
92727 @@ -0,0 +1,970 @@
92728 +/**********************************************************************
92729 + *
92730 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
92731 + * 
92732 + * This program is free software; you can redistribute it and/or modify it
92733 + * under the terms and conditions of the GNU General Public License,
92734 + * version 2, as published by the Free Software Foundation.
92735 + * 
92736 + * This program is distributed in the hope it will be useful but, except 
92737 + * as otherwise stated in writing, without any warranty; without even the 
92738 + * implied warranty of merchantability or fitness for a particular purpose. 
92739 + * See the GNU General Public License for more details.
92740 + * 
92741 + * You should have received a copy of the GNU General Public License along with
92742 + * this program; if not, write to the Free Software Foundation, Inc.,
92743 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
92744 + * 
92745 + * The full GNU General Public License is included in this distribution in
92746 + * the file called "COPYING".
92747 + *
92748 + * Contact Information:
92749 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
92750 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
92751 + *
92752 + ******************************************************************************/
92753 +
92754 +#ifndef AUTOCONF_INCLUDED
92755 + #include <linux/config.h>
92756 +#endif
92757 +
92758 +#include <linux/init.h>
92759 +#include <linux/module.h>
92760 +#include <linux/version.h>
92761 +#include <linux/fs.h>
92762 +#include <linux/proc_fs.h>
92763 +#include <linux/seq_file.h>
92764 +
92765 +#include "services_headers.h"
92766 +
92767 +#include "queue.h"
92768 +#include "resman.h"
92769 +#include "pvrmmap.h"
92770 +#include "pvr_debug.h"
92771 +#include "pvrversion.h"
92772 +#include "proc.h"
92773 +#include "perproc.h"
92774 +#include "env_perproc.h"
92775 +#include "linkage.h"
92776 +
92777 +#include "lists.h"
92778 +DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
92779 +
92780 +
92781 +static struct proc_dir_entry * dir;
92782 +
92783 +#ifndef PVR_PROC_USE_SEQ_FILE
92784 +static off_t procDumpSysNodes(IMG_CHAR *buf, size_t size, off_t off);
92785 +static off_t procDumpVersion(IMG_CHAR *buf, size_t size, off_t off);
92786 +#endif 
92787 +
92788 +
92789 +static const IMG_CHAR PVRProcDirRoot[] = "pvr";
92790 +
92791 +
92792 +#ifdef PVR_PROC_USE_SEQ_FILE
92793 +
92794 +#define PVR_PROC_SEQ_START_TOKEN (void*)1
92795 +static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
92796 +static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
92797 +static void pvr_proc_seq_stop (struct seq_file *m, void *v);
92798 +static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
92799 +static int pvr_proc_seq_show (struct seq_file *m, void *v);
92800 +static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
92801 +
92802 +static struct file_operations pvr_proc_operations =
92803 +{
92804 +       .open           = pvr_proc_open,
92805 +       .read           = seq_read,
92806 +       .write          = pvr_proc_write,
92807 +       .llseek         = seq_lseek,
92808 +       .release        = seq_release,
92809 +};
92810 +
92811 +static struct seq_operations pvr_proc_seq_operations =
92812 +{
92813 +       .start =        pvr_proc_seq_start,
92814 +       .next =         pvr_proc_seq_next,
92815 +       .stop =         pvr_proc_seq_stop,
92816 +       .show =         pvr_proc_seq_show,
92817 +};
92818 +
92819 +static struct proc_dir_entry* g_pProcQueue;
92820 +static struct proc_dir_entry* g_pProcVersion;
92821 +static struct proc_dir_entry* g_pProcSysNodes;
92822 +
92823 +#ifdef DEBUG
92824 +static struct proc_dir_entry* g_pProcDebugLevel;
92825 +#endif
92826 +
92827 +#ifdef PVR_MANUAL_POWER_CONTROL
92828 +static struct proc_dir_entry* g_pProcPowerLevel;
92829 +#endif
92830 +
92831 +
92832 +static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
92833 +
92834 +static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
92835 +static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
92836 +
92837 +#endif
92838 +
92839 +off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
92840 +{
92841 +    IMG_INT n;
92842 +    size_t space = size - (size_t)off;
92843 +    va_list ap;
92844 +
92845 +    PVR_ASSERT(space >= 0);
92846 +
92847 +    va_start (ap, format);
92848 +
92849 +    n = vsnprintf (buffer+off, space, format, ap);
92850 +
92851 +    va_end (ap);
92852 +    
92853 +    if (n >= (IMG_INT)space || n < 0)
92854 +    {
92855 +       
92856 +        buffer[size - 1] = 0;
92857 +        return (off_t)(size - 1);
92858 +    }
92859 +    else
92860 +    {
92861 +        return (off + (off_t)n);
92862 +    }
92863 +}
92864 +
92865 +
92866 +#ifdef PVR_PROC_USE_SEQ_FILE
92867 +
92868 +void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
92869 +{
92870 +       
92871 +       if(!off)
92872 +               return (void*)2;
92873 +       return NULL;
92874 +}
92875 +
92876 +
92877 +void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
92878 +{
92879 +       if(!off)
92880 +       {
92881 +               return PVR_PROC_SEQ_START_TOKEN;
92882 +       }
92883 +
92884 +       
92885 +       if(off == 1)
92886 +               return (void*)2;
92887 +
92888 +       return NULL;
92889 +}
92890 +
92891 +
92892 +static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
92893 +{
92894 +       IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
92895 +
92896 +       struct seq_file *seq = (struct seq_file*)file->private_data;
92897 +       struct proc_dir_entry* pvr_proc_entry = PDE(inode);
92898 +
92899 +       
92900 +       seq->private = pvr_proc_entry->data;
92901 +       return ret;
92902 +}
92903 +
92904 +static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
92905 +               size_t count, loff_t *ppos)
92906 +{
92907 +       struct inode *inode = file->f_path.dentry->d_inode;
92908 +       struct proc_dir_entry * dp;
92909 +
92910 +       dp = PDE(inode);
92911 +
92912 +       if (!dp->write_proc)
92913 +               return -EIO;
92914 +
92915 +       return dp->write_proc(file, buffer, count, dp->data);
92916 +}
92917 +
92918 +
92919 +static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
92920 +{
92921 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
92922 +       if(handlers->startstop != NULL)
92923 +               handlers->startstop(proc_seq_file, IMG_TRUE);
92924 +       return handlers->off2element(proc_seq_file, *pos);
92925 +}
92926 +
92927 +static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
92928 +{
92929 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
92930 +       if(handlers->startstop != NULL)
92931 +               handlers->startstop(proc_seq_file, IMG_FALSE);
92932 +}
92933 +
92934 +static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
92935 +{
92936 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
92937 +       (*pos)++;
92938 +       if( handlers->next != NULL)
92939 +               return handlers->next( proc_seq_file, v, *pos );
92940 +       return handlers->off2element(proc_seq_file, *pos);
92941 +}
92942 +
92943 +static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
92944 +{
92945 +       PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
92946 +       handlers->show( proc_seq_file,v );
92947 +    return 0;
92948 +}
92949 +
92950 +
92951 +
92952 +static struct proc_dir_entry* CreateProcEntryInDirSeq(
92953 +                                                                          struct proc_dir_entry *pdir,
92954 +                                                                          const IMG_CHAR * name,
92955 +                                                                  IMG_VOID* data,
92956 +                                                                          pvr_next_proc_seq_t next_handler,
92957 +                                                                          pvr_show_proc_seq_t show_handler,
92958 +                                                                          pvr_off2element_proc_seq_t off2element_handler,
92959 +                                                                          pvr_startstop_proc_seq_t startstop_handler,
92960 +                                                                          write_proc_t whandler
92961 +                                                                          )
92962 +{
92963 +
92964 +    struct proc_dir_entry * file;
92965 +       mode_t mode;
92966 +
92967 +    if (!dir)
92968 +    {
92969 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
92970 +        return NULL;
92971 +    }
92972 +
92973 +       mode = S_IFREG;
92974 +
92975 +    if (show_handler)
92976 +    {
92977 +               mode |= S_IRUGO;
92978 +    }
92979 +
92980 +    if (whandler)
92981 +    {
92982 +               mode |= S_IWUSR;
92983 +    }
92984 +
92985 +       file=create_proc_entry(name, mode, pdir);
92986 +
92987 +    if (file)
92988 +    {
92989 +               PVR_PROC_SEQ_HANDLERS *seq_handlers;
92990 +
92991 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
92992 +        file->owner = THIS_MODULE;
92993 +#endif
92994 +
92995 +               file->proc_fops = &pvr_proc_operations;
92996 +               file->write_proc = whandler;
92997 +
92998 +               
92999 +               file->data =  kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
93000 +               if(file->data)
93001 +               {
93002 +                       seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
93003 +                       seq_handlers->next = next_handler;
93004 +                       seq_handlers->show = show_handler;
93005 +                       seq_handlers->off2element = off2element_handler;
93006 +                       seq_handlers->startstop = startstop_handler;
93007 +                       seq_handlers->data = data;
93008 +
93009 +               return file;
93010 +               }
93011 +    }
93012 +
93013 +    PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
93014 +    return 0;
93015 +}
93016 +
93017 +
93018 +struct proc_dir_entry* CreateProcReadEntrySeq (
93019 +                                                               const IMG_CHAR * name,
93020 +                                                               IMG_VOID* data,
93021 +                                                               pvr_next_proc_seq_t next_handler,
93022 +                                                               pvr_show_proc_seq_t show_handler,
93023 +                                                               pvr_off2element_proc_seq_t off2element_handler,
93024 +                                                               pvr_startstop_proc_seq_t startstop_handler
93025 +                                                          )
93026 +{
93027 +       return CreateProcEntrySeq(name,
93028 +                                                         data,
93029 +                                                         next_handler,
93030 +                                                         show_handler,
93031 +                                                         off2element_handler,
93032 +                                                         startstop_handler,
93033 +                                                         NULL);
93034 +}
93035 +
93036 +struct proc_dir_entry* CreateProcEntrySeq (
93037 +                                                                                       const IMG_CHAR * name,
93038 +                                                                                       IMG_VOID* data,
93039 +                                                                                       pvr_next_proc_seq_t next_handler,
93040 +                                                                                       pvr_show_proc_seq_t show_handler,
93041 +                                                                                       pvr_off2element_proc_seq_t off2element_handler,
93042 +                                                                                       pvr_startstop_proc_seq_t startstop_handler,
93043 +                                                                                       write_proc_t whandler
93044 +                                                                                 )
93045 +{
93046 +       return CreateProcEntryInDirSeq(
93047 +                                                                  dir,
93048 +                                                                  name,
93049 +                                                                  data,
93050 +                                                                  next_handler,
93051 +                                                                  show_handler,
93052 +                                                                  off2element_handler,
93053 +                                                                  startstop_handler,
93054 +                                                                  NULL
93055 +                                                                 );
93056 +}
93057 +
93058 +
93059 +
93060 +struct proc_dir_entry* CreatePerProcessProcEntrySeq (
93061 +                                                                         const IMG_CHAR * name,
93062 +                                                                 IMG_VOID* data,
93063 +                                                                         pvr_next_proc_seq_t next_handler,
93064 +                                                                         pvr_show_proc_seq_t show_handler,
93065 +                                                                         pvr_off2element_proc_seq_t off2element_handler,
93066 +                                                                         pvr_startstop_proc_seq_t startstop_handler,
93067 +                                                                         write_proc_t whandler
93068 +                                                                        )
93069 +{
93070 +    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
93071 +    IMG_UINT32 ui32PID;
93072 +
93073 +    if (!dir)
93074 +    {
93075 +        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
93076 +        return NULL;
93077 +    }
93078 +
93079 +    ui32PID = OSGetCurrentProcessIDKM();
93080 +
93081 +    psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
93082 +    if (!psPerProc)
93083 +    {
93084 +        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
93085 +
93086 +        return NULL;
93087 +    }
93088 +
93089 +    if (!psPerProc->psProcDir)
93090 +    {
93091 +        IMG_CHAR dirname[16];
93092 +        IMG_INT ret;
93093 +
93094 +        ret = snprintf(dirname, sizeof(dirname), "%lu", ui32PID);
93095 +
93096 +               if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
93097 +               {
93098 +                       PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
93099 +                       return NULL;
93100 +               }
93101 +               else
93102 +               {
93103 +                       psPerProc->psProcDir = proc_mkdir(dirname, dir);
93104 +                       if (!psPerProc->psProcDir)
93105 +                       {
93106 +                               PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
93107 +                                               PVRProcDirRoot, ui32PID));
93108 +                               return NULL;
93109 +                       }
93110 +               }
93111 +    }
93112 +
93113 +    return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
93114 +                                                                  show_handler,off2element_handler,startstop_handler,whandler);
93115 +}
93116 +
93117 +
93118 +IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
93119 +{
93120 +    if (dir)
93121 +    {
93122 +               void* data = proc_entry->data ;
93123 +        PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
93124 +
93125 +        remove_proc_entry(proc_entry->name, dir);
93126 +               if( data)
93127 +                       kfree( data );
93128 +
93129 +    }
93130 +}
93131 +
93132 +IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
93133 +{
93134 +    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
93135 +
93136 +    psPerProc = LinuxTerminatingProcessPrivateData();
93137 +    if (!psPerProc)
93138 +    {
93139 +        psPerProc = PVRSRVFindPerProcessPrivateData();
93140 +        if (!psPerProc)
93141 +        {
93142 +            PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
93143 +                                    "remove %s, no per process data", proc_entry->name));
93144 +            return;
93145 +        }
93146 +    }
93147 +
93148 +    if (psPerProc->psProcDir)
93149 +    {
93150 +               void* data = proc_entry->data ;
93151 +        PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
93152 +
93153 +        remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
93154 +               if(data)
93155 +                       kfree( data );
93156 +    }
93157 +}
93158 +
93159 +#endif 
93160 +
93161 +static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
93162 +                         IMG_INT count, IMG_INT *eof, IMG_VOID *data)
93163 +{
93164 +    pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
93165 +
93166 +    off_t len = pprn (page, (size_t)count, off);
93167 +
93168 +    if (len == END_OF_FILE)
93169 +    {
93170 +        len  = 0;
93171 +        *eof = 1;
93172 +    }
93173 +    else if (!len)             
93174 +    {
93175 +        *start = (IMG_CHAR *) 0;   
93176 +    }
93177 +    else
93178 +    {
93179 +        *start = (IMG_CHAR *) 1;
93180 +    }
93181 +
93182 +    return len;
93183 +}
93184 +
93185 +
93186 +static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
93187 +{
93188 +    struct proc_dir_entry * file;
93189 +    mode_t mode;
93190 +
93191 +    if (!pdir)
93192 +    {
93193 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
93194 +
93195 +        return -ENOMEM;
93196 +    }
93197 +
93198 +    mode = S_IFREG;
93199 +
93200 +    if (rhandler)
93201 +    {
93202 +       mode |= S_IRUGO;
93203 +    }
93204 +
93205 +    if (whandler)
93206 +    {
93207 +       mode |= S_IWUSR;
93208 +    }
93209 +
93210 +    file = create_proc_entry(name, mode, pdir);
93211 +
93212 +    if (file)
93213 +    {
93214 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
93215 +        file->owner = THIS_MODULE;
93216 +#endif
93217 +               file->read_proc = rhandler;
93218 +               file->write_proc = whandler;
93219 +               file->data = data;
93220 +
93221 +               PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
93222 +
93223 +        return 0;
93224 +    }
93225 +
93226 +    PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
93227 +
93228 +    return -ENOMEM;
93229 +}
93230 +
93231 +
93232 +IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
93233 +{
93234 +    return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
93235 +}
93236 +
93237 +
93238 +IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
93239 +{
93240 +    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
93241 +    IMG_UINT32 ui32PID;
93242 +
93243 +    if (!dir)
93244 +    {
93245 +        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
93246 +
93247 +        return -ENOMEM;
93248 +    }
93249 +
93250 +    ui32PID = OSGetCurrentProcessIDKM();
93251 +
93252 +    psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
93253 +    if (!psPerProc)
93254 +    {
93255 +        PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
93256 +
93257 +        return -ENOMEM;
93258 +    }
93259 +
93260 +    if (!psPerProc->psProcDir)
93261 +    {
93262 +        IMG_CHAR dirname[16];
93263 +        IMG_INT ret;
93264 +
93265 +        ret = snprintf(dirname, sizeof(dirname), "%lu", ui32PID);
93266 +
93267 +               if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
93268 +               {
93269 +                       PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
93270 +
93271 +                                       return -ENOMEM;
93272 +               }
93273 +               else
93274 +               {
93275 +                       psPerProc->psProcDir = proc_mkdir(dirname, dir);
93276 +                       if (!psPerProc->psProcDir)
93277 +                       {
93278 +                       PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
93279 +
93280 +                       return -ENOMEM;
93281 +                       }
93282 +               }
93283 +    }
93284 +
93285 +    return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
93286 +}
93287 +
93288 +
93289 +IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
93290 +{
93291 +    struct proc_dir_entry * file;
93292 +
93293 +    if (!dir)
93294 +    {
93295 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
93296 +
93297 +        return -ENOMEM;
93298 +    }
93299 +
93300 +    file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
93301 +
93302 +    if (file)
93303 +    {
93304 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
93305 +        file->owner = THIS_MODULE;
93306 +#endif
93307 +        return 0;
93308 +    }
93309 +
93310 +    PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
93311 +
93312 +    return -ENOMEM;
93313 +}
93314 +
93315 +
93316 +IMG_INT CreateProcEntries(IMG_VOID)
93317 +{
93318 +    dir = proc_mkdir (PVRProcDirRoot, NULL);
93319 +
93320 +    if (!dir)
93321 +    {
93322 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot));
93323 +
93324 +        return -ENOMEM;
93325 +    }
93326 +
93327 +#ifdef PVR_PROC_USE_SEQ_FILE
93328 +       g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
93329 +       g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
93330 +       g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
93331 +
93332 +       if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
93333 +#else 
93334 +    if (CreateProcReadEntry("queue", QueuePrintQueues) ||
93335 +               CreateProcReadEntry("version", procDumpVersion) ||
93336 +               CreateProcReadEntry("nodes", procDumpSysNodes))
93337 +#endif 
93338 +    {
93339 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
93340 +
93341 +        return -ENOMEM;
93342 +    }
93343 +
93344 +
93345 +#ifdef DEBUG
93346 +
93347 +#ifdef PVR_PROC_USE_SEQ_FILE
93348 +       g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
93349 +                                                                                       ProcSeqShowDebugLevel,
93350 +                                                                                       ProcSeq1ElementOff2Element, NULL,
93351 +                                                                                   PVRDebugProcSetLevel);
93352 +       if(!g_pProcDebugLevel)
93353 +#else 
93354 +       if (CreateProcEntry ("debug_level", PVRDebugProcGetLevel, PVRDebugProcSetLevel, 0))
93355 +#endif 
93356 +    {
93357 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
93358 +
93359 +        return -ENOMEM;
93360 +    }
93361 +
93362 +#ifdef PVR_MANUAL_POWER_CONTROL
93363 +#ifdef PVR_PROC_USE_SEQ_FILE
93364 +       g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
93365 +                                                                                       ProcSeqShowPowerLevel,
93366 +                                                                                       ProcSeq1ElementOff2Element, NULL,
93367 +                                                                                   PVRProcSetPowerLevel);
93368 +       if(!g_pProcPowerLevel)
93369 +#else 
93370 +       if (CreateProcEntry("power_control", PVRProcGetPowerLevel, PVRProcSetPowerLevel, 0))
93371 +#endif
93372 +    {
93373 +        PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
93374 +
93375 +        return -ENOMEM;
93376 +    }
93377 +#endif
93378 +#endif
93379 +
93380 +    return 0;
93381 +}
93382 +
93383 +
93384 +IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
93385 +{
93386 +    if (dir)
93387 +    {
93388 +        remove_proc_entry(name, dir);
93389 +        PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
93390 +    }
93391 +}
93392 +
93393 +
93394 +IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
93395 +{
93396 +    PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
93397 +
93398 +    psPerProc = LinuxTerminatingProcessPrivateData();
93399 +    if (!psPerProc)
93400 +    {
93401 +        psPerProc = PVRSRVFindPerProcessPrivateData();
93402 +        if (!psPerProc)
93403 +        {
93404 +            PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
93405 +                                    "remove %s, no per process data", name));
93406 +            return;
93407 +        }
93408 +    }
93409 +
93410 +    if (psPerProc->psProcDir)
93411 +    {
93412 +        remove_proc_entry(name, psPerProc->psProcDir);
93413 +
93414 +        PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
93415 +    }
93416 +}
93417 +
93418 +
93419 +IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
93420 +{
93421 +    if (psPerProc->psProcDir)
93422 +    {
93423 +        while (psPerProc->psProcDir->subdir)
93424 +        {
93425 +            PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
93426 +
93427 +            RemoveProcEntry(psPerProc->psProcDir->subdir->name);
93428 +        }
93429 +        RemoveProcEntry(psPerProc->psProcDir->name);
93430 +    }
93431 +}
93432 +
93433 +IMG_VOID RemoveProcEntries(IMG_VOID)
93434 +{
93435 +#ifdef DEBUG
93436 +
93437 +#ifdef PVR_PROC_USE_SEQ_FILE
93438 +    RemoveProcEntrySeq( g_pProcDebugLevel );
93439 +#else 
93440 +    RemoveProcEntry("debug_level");
93441 +#endif 
93442 +
93443 +#ifdef PVR_MANUAL_POWER_CONTROL
93444 +#ifdef PVR_PROC_USE_SEQ_FILE
93445 +    RemoveProcEntrySeq( g_pProcPowerLevel );
93446 +#else 
93447 +    RemoveProcEntry("power_control");
93448 +#endif 
93449 +#endif 
93450 +
93451 +#endif 
93452 +
93453 +#ifdef PVR_PROC_USE_SEQ_FILE
93454 +    RemoveProcEntrySeq(g_pProcQueue);
93455 +    RemoveProcEntrySeq(g_pProcVersion);
93456 +       RemoveProcEntrySeq(g_pProcSysNodes);
93457 +#else 
93458 +    RemoveProcEntry("queue");
93459 +    RemoveProcEntry("version");
93460 +    RemoveProcEntry("nodes");
93461 +#endif 
93462 +
93463 +    while (dir->subdir)
93464 +    {
93465 +       PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
93466 +
93467 +       RemoveProcEntry(dir->subdir->name);
93468 +    }
93469 +
93470 +    remove_proc_entry(PVRProcDirRoot, NULL);
93471 +}
93472 +
93473 +
93474 +#ifdef PVR_PROC_USE_SEQ_FILE
93475 +
93476 +static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
93477 +{
93478 +       SYS_DATA * psSysData;
93479 +       IMG_CHAR *pszSystemVersionString = "None";
93480 +
93481 +       if(el == PVR_PROC_SEQ_START_TOKEN)
93482 +       {
93483 +               seq_printf( sfile,
93484 +                                               "Version %s (%s) %s\n",
93485 +                                               PVRVERSION_STRING,
93486 +                                               PVR_BUILD_TYPE, PVR_BUILD_DIR);
93487 +               return;
93488 +       }
93489 +
93490 +    SysAcquireData(&psSysData);
93491 +
93492 +    if(psSysData->pszVersionString)
93493 +       {
93494 +       pszSystemVersionString = psSysData->pszVersionString;
93495 +    }
93496 +
93497 +       seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
93498 +}
93499 +
93500 +#else
93501 +
93502 +static off_t procDumpVersion(IMG_CHAR *buf, size_t size, off_t off)
93503 +{
93504 +    SYS_DATA *psSysData;
93505 +
93506 +    if (off == 0)
93507 +    {
93508 +       return printAppend(buf, size, 0,
93509 +                                               "Version %s (%s) %s\n",
93510 +                                               PVRVERSION_STRING,
93511 +                                               PVR_BUILD_TYPE, PVR_BUILD_DIR);
93512 +    }
93513 +
93514 +    SysAcquireData(&psSysData)
93515 +
93516 +    if (off == 1)
93517 +    {
93518 +        IMG_CHAR *pszSystemVersionString = "None";
93519 +
93520 +        if(psSysData->pszVersionString)
93521 +        {
93522 +            pszSystemVersionString = psSysData->pszVersionString;
93523 +        }
93524 +
93525 +        if(strlen(pszSystemVersionString)
93526 +            + strlen("System Version String: \n")
93527 +            + 1 > size)
93528 +        {
93529 +            return 0;
93530 +        }
93531 +        return printAppend(buf, size, 0,
93532 +                            "System Version String: %s\n",
93533 +                            pszSystemVersionString);
93534 +    }
93535 +
93536 +    return END_OF_FILE;
93537 +}
93538 +
93539 +#endif 
93540 +
93541 +
93542 +static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
93543 +{
93544 +    switch (deviceType)
93545 +    {
93546 +        default:
93547 +        {
93548 +            static IMG_CHAR text[10];
93549 +
93550 +            sprintf(text, "?%x", (IMG_UINT)deviceType);
93551 +
93552 +            return text;
93553 +        }
93554 +    }
93555 +}
93556 +
93557 +
93558 +static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
93559 +{
93560 +    switch (deviceClass)
93561 +    {
93562 +       case PVRSRV_DEVICE_CLASS_3D:
93563 +       {
93564 +           return "3D";
93565 +       }
93566 +       case PVRSRV_DEVICE_CLASS_DISPLAY:
93567 +       {
93568 +           return "display";
93569 +       }
93570 +       case PVRSRV_DEVICE_CLASS_BUFFER:
93571 +       {
93572 +           return "buffer";
93573 +       }
93574 +       default:
93575 +       {
93576 +           static IMG_CHAR text[10];
93577 +
93578 +           sprintf(text, "?%x", (IMG_UINT)deviceClass);
93579 +           return text;
93580 +       }
93581 +    }
93582 +}
93583 +
93584 +IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
93585 +{
93586 +       off_t *pOff = va_arg(va, off_t*);
93587 +       if (--(*pOff))
93588 +       {
93589 +               return IMG_NULL;
93590 +       }
93591 +       else
93592 +       {
93593 +               return psNode;
93594 +       }
93595 +}
93596 +
93597 +#ifdef PVR_PROC_USE_SEQ_FILE
93598 +
93599 +static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
93600 +{
93601 +       SYS_DATA * psSysData;
93602 +    PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE*)el;
93603 +
93604 +       if(el == PVR_PROC_SEQ_START_TOKEN)
93605 +       {
93606 +               seq_printf( sfile,
93607 +                                               "Registered nodes\n"
93608 +                                               "Addr     Type     Class    Index Ref pvDev     Size Res\n");
93609 +               return;
93610 +       }
93611 +
93612 +    SysAcquireData(&psSysData);
93613 +
93614 +       seq_printf( sfile,
93615 +                                 "%p %-8s %-8s %4d  %2lu  %p  %3lu  %p\n",
93616 +                                 psDevNode,
93617 +                                 deviceTypeToString(psDevNode->sDevId.eDeviceType),
93618 +                                 deviceClassToString(psDevNode->sDevId.eDeviceClass),
93619 +                                 psDevNode->sDevId.eDeviceClass,
93620 +                                 psDevNode->ui32RefCount,
93621 +                                 psDevNode->pvDevice,
93622 +                                 psDevNode->ui32pvDeviceSize,
93623 +                                 psDevNode->hResManContext);
93624 +
93625 +}
93626 +
93627 +static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
93628 +{
93629 +    SYS_DATA *psSysData;
93630 +    PVRSRV_DEVICE_NODE *psDevNode;
93631 +       if(!off)
93632 +       {
93633 +               return PVR_PROC_SEQ_START_TOKEN;
93634 +       }
93635 +
93636 +    SysAcquireData(&psSysData);
93637 +
93638 +    
93639 +       psDevNode = (PVRSRV_DEVICE_NODE*)
93640 +                               List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
93641 +                                                                                                       DecOffPsDev_AnyVaCb,
93642 +                                                                                                       &off);
93643 +
93644 +       
93645 +       return (void*)psDevNode;
93646 +}
93647 +
93648 +#else 
93649 +
93650 +static
93651 +off_t procDumpSysNodes(IMG_CHAR *buf, size_t size, off_t off)
93652 +{
93653 +    SYS_DATA                   *psSysData;
93654 +    PVRSRV_DEVICE_NODE *psDevNode;
93655 +    off_t                              len;
93656 +
93657 +    
93658 +    if (size < 80)
93659 +    {
93660 +               return 0;
93661 +    }
93662 +
93663 +    if (off == 0)
93664 +    {
93665 +               return printAppend(buf, size, 0,
93666 +                                               "Registered nodes\n"
93667 +                                               "Addr     Type     Class    Index Ref pvDev     Size Res\n");
93668 +    }
93669 +
93670 +    SysAcquireData(&psSysData);
93671 +
93672 +    
93673 +       psDevNode = (PVRSRV_DEVICE_NODE*)
93674 +                               List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
93675 +                                                                                                       DecOffPsDev_AnyVaCb,
93676 +                                                                                                       &off);
93677 +
93678 +    if (!psDevNode)
93679 +    {
93680 +               return END_OF_FILE;
93681 +    }
93682 +
93683 +    len = printAppend(buf, size, 0,
93684 +                                 "%p %-8s %-8s %4d  %2lu  %p  %3lu  %p\n",
93685 +                                 psDevNode,
93686 +                                 deviceTypeToString(psDevNode->sDevId.eDeviceType),
93687 +                                 deviceClassToString(psDevNode->sDevId.eDeviceClass),
93688 +                                 psDevNode->sDevId.eDeviceClass,
93689 +                                 psDevNode->ui32RefCount,
93690 +                                 psDevNode->pvDevice,
93691 +                                 psDevNode->ui32pvDeviceSize,
93692 +                                 psDevNode->hResManContext);
93693 +    return (len);
93694 +}
93695 +
93696 +#endif 
93697 +
93698 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.h
93699 new file mode 100644
93700 index 0000000..3200961
93701 --- /dev/null
93702 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/proc.h
93703 @@ -0,0 +1,115 @@
93704 +/**********************************************************************
93705 + *
93706 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
93707 + * 
93708 + * This program is free software; you can redistribute it and/or modify it
93709 + * under the terms and conditions of the GNU General Public License,
93710 + * version 2, as published by the Free Software Foundation.
93711 + * 
93712 + * This program is distributed in the hope it will be useful but, except 
93713 + * as otherwise stated in writing, without any warranty; without even the 
93714 + * implied warranty of merchantability or fitness for a particular purpose. 
93715 + * See the GNU General Public License for more details.
93716 + * 
93717 + * You should have received a copy of the GNU General Public License along with
93718 + * this program; if not, write to the Free Software Foundation, Inc.,
93719 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
93720 + * 
93721 + * The full GNU General Public License is included in this distribution in
93722 + * the file called "COPYING".
93723 + *
93724 + * Contact Information:
93725 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
93726 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
93727 + *
93728 + ******************************************************************************/
93729 +
93730 +#ifndef __SERVICES_PROC_H__
93731 +#define __SERVICES_PROC_H__
93732 +
93733 +#include <asm/system.h>                
93734 +#include <linux/proc_fs.h>     
93735 +#include <linux/seq_file.h> 
93736 +
93737 +#define END_OF_FILE (off_t) -1
93738 +
93739 +typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t);
93740 +
93741 +
93742 +#ifdef PVR_PROC_USE_SEQ_FILE
93743 +#define PVR_PROC_SEQ_START_TOKEN (void*)1
93744 +typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t);
93745 +typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t);
93746 +typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*);
93747 +typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start);
93748 +
93749 +typedef struct _PVR_PROC_SEQ_HANDLERS_ {
93750 +       pvr_next_proc_seq_t *next;      
93751 +       pvr_show_proc_seq_t *show;      
93752 +       pvr_off2element_proc_seq_t *off2element;
93753 +       pvr_startstop_proc_seq_t *startstop;
93754 +       IMG_VOID *data;
93755 +} PVR_PROC_SEQ_HANDLERS;
93756 +
93757 +
93758 +void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off);
93759 +
93760 +void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off);
93761 +
93762 +
93763 +#endif 
93764 +
93765 +off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
93766 +       __attribute__((format(printf, 4, 5)));
93767 +
93768 +IMG_INT CreateProcEntries(IMG_VOID);
93769 +
93770 +IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler);
93771 +
93772 +IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
93773 +
93774 +IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data);
93775 +
93776 +IMG_VOID RemoveProcEntry(const IMG_CHAR * name);
93777 +
93778 +IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name);
93779 +
93780 +IMG_VOID RemoveProcEntries(IMG_VOID);
93781 +
93782 +#ifdef PVR_PROC_USE_SEQ_FILE
93783 +struct proc_dir_entry* CreateProcReadEntrySeq (
93784 +                                                               const IMG_CHAR* name, 
93785 +                                                               IMG_VOID* data,
93786 +                                                               pvr_next_proc_seq_t next_handler, 
93787 +                                                               pvr_show_proc_seq_t show_handler,
93788 +                                                               pvr_off2element_proc_seq_t off2element_handler,
93789 +                                                               pvr_startstop_proc_seq_t startstop_handler
93790 +                                                          );
93791 +
93792 +struct proc_dir_entry* CreateProcEntrySeq (
93793 +                                                               const IMG_CHAR* name, 
93794 +                                                               IMG_VOID* data,
93795 +                                                               pvr_next_proc_seq_t next_handler, 
93796 +                                                               pvr_show_proc_seq_t show_handler,
93797 +                                                               pvr_off2element_proc_seq_t off2element_handler,
93798 +                                                               pvr_startstop_proc_seq_t startstop_handler,
93799 +                                                               write_proc_t whandler
93800 +                                                          );
93801 +
93802 +struct proc_dir_entry* CreatePerProcessProcEntrySeq (
93803 +                                                               const IMG_CHAR* name, 
93804 +                                                               IMG_VOID* data,
93805 +                                                               pvr_next_proc_seq_t next_handler, 
93806 +                                                               pvr_show_proc_seq_t show_handler,
93807 +                                                               pvr_off2element_proc_seq_t off2element_handler,
93808 +                                                               pvr_startstop_proc_seq_t startstop_handler,
93809 +                                                               write_proc_t whandler
93810 +                                                          );
93811 +
93812 +
93813 +IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry);
93814 +IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry);
93815 +
93816 +#endif 
93817 +
93818 +#endif
93819 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_bridge_k.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_bridge_k.c
93820 new file mode 100644
93821 index 0000000..e4e4946
93822 --- /dev/null
93823 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_bridge_k.c
93824 @@ -0,0 +1,651 @@
93825 +/**********************************************************************
93826 + *
93827 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
93828 + * 
93829 + * This program is free software; you can redistribute it and/or modify it
93830 + * under the terms and conditions of the GNU General Public License,
93831 + * version 2, as published by the Free Software Foundation.
93832 + * 
93833 + * This program is distributed in the hope it will be useful but, except 
93834 + * as otherwise stated in writing, without any warranty; without even the 
93835 + * implied warranty of merchantability or fitness for a particular purpose. 
93836 + * See the GNU General Public License for more details.
93837 + * 
93838 + * You should have received a copy of the GNU General Public License along with
93839 + * this program; if not, write to the Free Software Foundation, Inc.,
93840 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
93841 + * 
93842 + * The full GNU General Public License is included in this distribution in
93843 + * the file called "COPYING".
93844 + *
93845 + * Contact Information:
93846 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
93847 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
93848 + *
93849 + ******************************************************************************/
93850 +
93851 +#include "img_defs.h"
93852 +#include "services.h"
93853 +#include "pvr_bridge.h"
93854 +#include "perproc.h"
93855 +#include "mutex.h"
93856 +#include "syscommon.h"
93857 +#include "pvr_debug.h"
93858 +#include "proc.h"
93859 +#include "private_data.h"
93860 +#include "linkage.h"
93861 +#include "pvr_bridge_km.h"
93862 +
93863 +#if defined(SUPPORT_DRI_DRM)
93864 +#include <drm/drmP.h>
93865 +#include "pvr_drm.h"
93866 +#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
93867 +#include "env_perproc.h"
93868 +#endif
93869 +#endif
93870 +
93871 +#if defined(SUPPORT_VGX)
93872 +#include "vgx_bridge.h"
93873 +#endif
93874 +
93875 +#if defined(SUPPORT_SGX)
93876 +#include "sgx_bridge.h"
93877 +#endif
93878 +
93879 +#include "bridged_pvr_bridge.h"
93880 +
93881 +#ifdef MODULE_TEST
93882 +#include "pvr_test_bridge.h"
93883 +#include "kern_test.h"
93884 +#endif
93885 +
93886 +
93887 +#if defined(SUPPORT_DRI_DRM)
93888 +#define        PRIVATE_DATA(pFile) ((pFile)->driver_priv)
93889 +#else
93890 +#define        PRIVATE_DATA(pFile) ((pFile)->private_data)
93891 +#endif
93892 +
93893 +#if defined(DEBUG_BRIDGE_KM)
93894 +
93895 +#ifdef PVR_PROC_USE_SEQ_FILE
93896 +static struct proc_dir_entry *g_ProcBridgeStats =0;
93897 +static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off);
93898 +static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el);
93899 +static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off);
93900 +static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start);
93901 +
93902 +#else 
93903 +static off_t printLinuxBridgeStats(IMG_CHAR * buffer, size_t size, off_t off);
93904 +#endif 
93905 +
93906 +#endif
93907 +
93908 +extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
93909 +
93910 +#if defined(SUPPORT_MEMINFO_IDS)
93911 +static IMG_UINT64 ui64Stamp;
93912 +#endif 
93913 +
93914 +PVRSRV_ERROR
93915 +LinuxBridgeInit(IMG_VOID)
93916 +{
93917 +#if defined(DEBUG_BRIDGE_KM)
93918 +       {
93919 +               IMG_INT iStatus;
93920 +#ifdef PVR_PROC_USE_SEQ_FILE
93921 +               g_ProcBridgeStats = CreateProcReadEntrySeq(
93922 +                                                                                                 "bridge_stats", 
93923 +                                                                                                 NULL,
93924 +                                                                                                 ProcSeqNextBridgeStats,
93925 +                                                                                                 ProcSeqShowBridgeStats,
93926 +                                                                                                 ProcSeqOff2ElementBridgeStats,
93927 +                                                                                                 ProcSeqStartstopBridgeStats
93928 +                                                                                                );
93929 +               iStatus = !g_ProcBridgeStats ? -1 : 0;
93930 +#else  
93931 +               iStatus = CreateProcReadEntry("bridge_stats", printLinuxBridgeStats);
93932 +#endif 
93933 +               
93934 +               if(iStatus!=0)
93935 +               {
93936 +                       return PVRSRV_ERROR_OUT_OF_MEMORY;
93937 +               }
93938 +       }
93939 +#endif
93940 +       return CommonBridgeInit();
93941 +}
93942 +
93943 +IMG_VOID
93944 +LinuxBridgeDeInit(IMG_VOID)
93945 +{
93946 +#if defined(DEBUG_BRIDGE_KM)
93947 +#ifdef PVR_PROC_USE_SEQ_FILE
93948 +    RemoveProcEntrySeq(g_ProcBridgeStats);
93949 +#else
93950 +       RemoveProcEntry("bridge_stats");
93951 +#endif
93952 +#endif
93953 +}
93954 +
93955 +#if defined(DEBUG_BRIDGE_KM)
93956 +
93957 +#ifdef PVR_PROC_USE_SEQ_FILE
93958 +
93959 +static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start) 
93960 +{
93961 +       if(start) 
93962 +       {
93963 +               LinuxLockMutex(&gPVRSRVLock);
93964 +       }
93965 +       else
93966 +       {
93967 +               LinuxUnLockMutex(&gPVRSRVLock);
93968 +       }
93969 +}
93970 +
93971 +
93972 +static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off)
93973 +{
93974 +       if(!off) 
93975 +       {
93976 +               return PVR_PROC_SEQ_START_TOKEN;
93977 +       }
93978 +
93979 +       if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
93980 +       {
93981 +               return (void*)0;
93982 +       }
93983 +
93984 +
93985 +       return (void*)&g_BridgeDispatchTable[off-1];
93986 +}
93987 +
93988 +static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off)
93989 +{
93990 +       return ProcSeqOff2ElementBridgeStats(sfile,off);
93991 +}
93992 +
93993 +
93994 +static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el)
93995 +{
93996 +       PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el;
93997 +
93998 +       if(el == PVR_PROC_SEQ_START_TOKEN) 
93999 +       {
94000 +               seq_printf(sfile,
94001 +                                                 "Total ioctl call count = %lu\n"
94002 +                                                 "Total number of bytes copied via copy_from_user = %lu\n"
94003 +                                                 "Total number of bytes copied via copy_to_user = %lu\n"
94004 +                                                 "Total number of bytes copied via copy_*_user = %lu\n\n"
94005 +                                                 "%-45s | %-40s | %10s | %20s | %10s\n",
94006 +                                                 g_BridgeGlobalStats.ui32IOCTLCount,
94007 +                                                 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
94008 +                                                 g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
94009 +                                                 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
94010 +                                                 "Bridge Name",
94011 +                                                 "Wrapper Function",
94012 +                                                 "Call Count",
94013 +                                                 "copy_from_user Bytes",
94014 +                                                 "copy_to_user Bytes"
94015 +                                                );
94016 +               return;
94017 +       }
94018 +
94019 +       seq_printf(sfile,
94020 +                                  "%-45s   %-40s   %-10lu   %-20lu   %-10lu\n",
94021 +                                  psEntry->pszIOCName,
94022 +                                  psEntry->pszFunctionName,
94023 +                                  psEntry->ui32CallCount,
94024 +                                  psEntry->ui32CopyFromUserTotalBytes,
94025 +                                  psEntry->ui32CopyToUserTotalBytes);
94026 +}
94027 +
94028 +#else 
94029 +
94030 +static off_t
94031 +printLinuxBridgeStats(IMG_CHAR * buffer, size_t count, off_t off)
94032 +{
94033 +       PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry;
94034 +       off_t Ret;
94035 +
94036 +       LinuxLockMutex(&gPVRSRVLock);
94037 +
94038 +       if(!off)
94039 +       {
94040 +               if(count < 500)
94041 +               {
94042 +                       Ret = 0;
94043 +                       goto unlock_and_return;
94044 +               }
94045 +               Ret = printAppend(buffer, count, 0,
94046 +                                                 "Total ioctl call count = %lu\n"
94047 +                                                 "Total number of bytes copied via copy_from_user = %lu\n"
94048 +                                                 "Total number of bytes copied via copy_to_user = %lu\n"
94049 +                                                 "Total number of bytes copied via copy_*_user = %lu\n\n"
94050 +                                                 "%-45s | %-40s | %10s | %20s | %10s\n",
94051 +                                                 g_BridgeGlobalStats.ui32IOCTLCount,
94052 +                                                 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
94053 +                                                 g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
94054 +                                                 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
94055 +                                                 "Bridge Name",
94056 +                                                 "Wrapper Function",
94057 +                                                 "Call Count",
94058 +                                                 "copy_from_user Bytes",
94059 +                                                 "copy_to_user Bytes"
94060 +                                                );
94061 +               goto unlock_and_return;
94062 +       }
94063 +
94064 +       if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
94065 +       {
94066 +               Ret = END_OF_FILE;
94067 +               goto unlock_and_return;
94068 +       }
94069 +
94070 +       if(count < 300)
94071 +       {
94072 +               Ret = 0;
94073 +               goto unlock_and_return;
94074 +       }
94075 +
94076 +       psEntry = &g_BridgeDispatchTable[off-1];
94077 +       Ret =  printAppend(buffer, count, 0,
94078 +                                          "%-45s   %-40s   %-10lu   %-20lu   %-10lu\n",
94079 +                                          psEntry->pszIOCName,
94080 +                                          psEntry->pszFunctionName,
94081 +                                          psEntry->ui32CallCount,
94082 +                                          psEntry->ui32CopyFromUserTotalBytes,
94083 +                                          psEntry->ui32CopyToUserTotalBytes);
94084 +
94085 +unlock_and_return:
94086 +       LinuxUnLockMutex(&gPVRSRVLock);
94087 +       return Ret;
94088 +}
94089 +#endif 
94090 +#endif 
94091 +
94092 +
94093 +
94094 +#if defined(SUPPORT_DRI_DRM)
94095 +IMG_INT
94096 +PVRSRV_BridgeDispatchKM(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
94097 +#else
94098 +IMG_INT32
94099 +PVRSRV_BridgeDispatchKM(struct file *pFile, IMG_UINT unref__ ioctlCmd, IMG_UINT32 arg)
94100 +#endif
94101 +{
94102 +       IMG_UINT32 cmd;
94103 +#if !defined(SUPPORT_DRI_DRM)
94104 +       PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
94105 +       PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
94106 +#endif
94107 +       PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
94108 +       IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
94109 +       PVRSRV_PER_PROCESS_DATA *psPerProc;
94110 +       IMG_INT err = -EFAULT;
94111 +
94112 +       LinuxLockMutex(&gPVRSRVLock);
94113 +
94114 +#if defined(SUPPORT_DRI_DRM)
94115 +       PVR_UNREFERENCED_PARAMETER(dev);
94116 +
94117 +       psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
94118 +       PVR_ASSERT(psBridgePackageKM != IMG_NULL);
94119 +#else
94120 +       PVR_UNREFERENCED_PARAMETER(ioctlCmd);
94121 +
94122 +       psBridgePackageKM = &sBridgePackageKM;
94123 +
94124 +       if(!OSAccessOK(PVR_VERIFY_WRITE,
94125 +                                  psBridgePackageUM,
94126 +                                  sizeof(PVRSRV_BRIDGE_PACKAGE)))
94127 +       {
94128 +               PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
94129 +                                __FUNCTION__));
94130 +
94131 +               goto unlock_and_return;
94132 +       }
94133 +       
94134 +       
94135 +       if(OSCopyFromUser(IMG_NULL,
94136 +                                         psBridgePackageKM,
94137 +                                         psBridgePackageUM,
94138 +                                         sizeof(PVRSRV_BRIDGE_PACKAGE))
94139 +         != PVRSRV_OK)
94140 +       {
94141 +               goto unlock_and_return;
94142 +       }
94143 +#endif
94144 +
94145 +       cmd = psBridgePackageKM->ui32BridgeID;
94146 +
94147 +#if defined(MODULE_TEST)
94148 +       switch (cmd)
94149 +       {
94150 +               case PVRSRV_BRIDGE_SERVICES_TEST_MEM1:
94151 +                       {
94152 +                               PVRSRV_ERROR eError = MemTest1();
94153 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94154 +                               {
94155 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94156 +                                       pReturn->eError = eError;
94157 +                               }
94158 +                       }
94159 +                       err = 0;
94160 +                       goto unlock_and_return;
94161 +               case PVRSRV_BRIDGE_SERVICES_TEST_MEM2:
94162 +                       {
94163 +                               PVRSRV_ERROR eError = MemTest2();
94164 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94165 +                               {
94166 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94167 +                                       pReturn->eError = eError;
94168 +                               }
94169 +                       }
94170 +                       err = 0;
94171 +                       goto unlock_and_return;
94172 +
94173 +               case PVRSRV_BRIDGE_SERVICES_TEST_RESOURCE:
94174 +                       {
94175 +                               PVRSRV_ERROR eError = ResourceTest();
94176 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94177 +                               {
94178 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94179 +                                       pReturn->eError = eError;
94180 +                               }
94181 +                       }
94182 +                       err = 0;
94183 +                       goto unlock_and_return;
94184 +
94185 +               case PVRSRV_BRIDGE_SERVICES_TEST_EVENTOBJECT:
94186 +                       {
94187 +                               PVRSRV_ERROR eError = EventObjectTest();
94188 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94189 +                               {
94190 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94191 +                                       pReturn->eError = eError;
94192 +                               }
94193 +                       }
94194 +                       err = 0;
94195 +                       goto unlock_and_return;
94196 +
94197 +               case PVRSRV_BRIDGE_SERVICES_TEST_MEMMAPPING:
94198 +                       {
94199 +                               PVRSRV_ERROR eError = MemMappingTest();
94200 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94201 +                               {
94202 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94203 +                                       pReturn->eError = eError;
94204 +                               }
94205 +                       }
94206 +                       err = 0;
94207 +                       goto unlock_and_return;
94208 +
94209 +               case PVRSRV_BRIDGE_SERVICES_TEST_PROCESSID:
94210 +                       {
94211 +                               PVRSRV_ERROR eError = ProcessIDTest();
94212 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94213 +                               {
94214 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94215 +                                       pReturn->eError = eError;
94216 +                               }
94217 +                       }
94218 +                       err = 0;
94219 +                       goto unlock_and_return;
94220 +
94221 +               case PVRSRV_BRIDGE_SERVICES_TEST_CLOCKUSWAITUS:
94222 +                       {
94223 +                               PVRSRV_ERROR eError = ClockusWaitusTest();
94224 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94225 +                               {
94226 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94227 +                                       pReturn->eError = eError;
94228 +                               }
94229 +                       }
94230 +                       err = 0;
94231 +                       goto unlock_and_return;
94232 +
94233 +               case PVRSRV_BRIDGE_SERVICES_TEST_TIMER:
94234 +                       {
94235 +                               PVRSRV_ERROR eError = TimerTest();
94236 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94237 +                               {
94238 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94239 +                                       pReturn->eError = eError;
94240 +                               }
94241 +                       }
94242 +                       err = 0;
94243 +                       goto unlock_and_return;
94244 +
94245 +               case PVRSRV_BRIDGE_SERVICES_TEST_PRIVSRV:
94246 +                       {
94247 +                               PVRSRV_ERROR eError = PrivSrvTest();
94248 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94249 +                               {
94250 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94251 +                                       pReturn->eError = eError;
94252 +                               }
94253 +                       }
94254 +                       err = 0;
94255 +                       goto unlock_and_return;
94256 +               case PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA:
94257 +               {
94258 +                       IMG_UINT32               ui32PID;
94259 +                       PVRSRV_PER_PROCESS_DATA *psPerProc;
94260 +                       PVRSRV_ERROR eError;
94261 +                       
94262 +                       ui32PID = OSGetCurrentProcessIDKM();
94263 +               
94264 +                       PVRSRVTrace("PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA %d", ui32PID);
94265 +                       
94266 +                       psPerProc = PVRSRVPerProcessData(ui32PID);
94267 +                                               
94268 +                       eError = CopyDataTest(psBridgePackageKM->pvParamIn, psBridgePackageKM->pvParamOut, psPerProc);
94269 +                       
94270 +                       *(PVRSRV_ERROR*)psBridgePackageKM->pvParamOut = eError;
94271 +                       err = 0;
94272 +                       goto unlock_and_return;
94273 +               }
94274 +
94275 +
94276 +               case PVRSRV_BRIDGE_SERVICES_TEST_POWERMGMT:
94277 +                       {
94278 +                               PVRSRV_ERROR eError = PowerMgmtTest();
94279 +                               if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
94280 +                               {
94281 +                                       PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
94282 +                                       pReturn->eError = eError;
94283 +                               }
94284 +                       }
94285 +                       err = 0;
94286 +                       goto unlock_and_return;
94287 +
94288 +       }
94289 +#endif
94290 +       
94291 +       if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
94292 +       {
94293 +               PVRSRV_ERROR eError;
94294 +
94295 +               eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
94296 +                                                                       (IMG_PVOID *)&psPerProc,
94297 +                                                                       psBridgePackageKM->hKernelServices,
94298 +                                                                       PVRSRV_HANDLE_TYPE_PERPROC_DATA);
94299 +               if(eError != PVRSRV_OK)
94300 +               {
94301 +                       PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)",
94302 +                                        __FUNCTION__, eError));
94303 +                       goto unlock_and_return;
94304 +               }
94305 +
94306 +               if(psPerProc->ui32PID != ui32PID)
94307 +               {
94308 +                       PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data "
94309 +                                        "belonging to process %d", __FUNCTION__, ui32PID,
94310 +                                        psPerProc->ui32PID));
94311 +                       goto unlock_and_return;
94312 +               }
94313 +       }
94314 +       else
94315 +       {
94316 +               
94317 +               psPerProc = PVRSRVPerProcessData(ui32PID);
94318 +               if(psPerProc == IMG_NULL)
94319 +               {
94320 +                       PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: "
94321 +                                        "Couldn't create per-process data area"));
94322 +                       goto unlock_and_return;
94323 +               }
94324 +       }
94325 +
94326 +       psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
94327 +
94328 +#if defined(PVR_SECURE_FD_EXPORT)
94329 +       switch(cmd)
94330 +       {
94331 +               case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
94332 +               {
94333 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
94334 +
94335 +                       if(psPrivateData->hKernelMemInfo)
94336 +                       {
94337 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo "
94338 +                                                "per file descriptor", __FUNCTION__));
94339 +                               err = -EINVAL;
94340 +                               goto unlock_and_return;
94341 +                       }
94342 +                       break;
94343 +               }
94344 +
94345 +               case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
94346 +               {
94347 +                       PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
94348 +                               (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
94349 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
94350 +
94351 +                       if(!psPrivateData->hKernelMemInfo)
94352 +                       {
94353 +                               PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
94354 +                                                "associated MemInfo handle", __FUNCTION__));
94355 +                               err = -EINVAL;
94356 +                               goto unlock_and_return;
94357 +                       }
94358 +
94359 +                       psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo;
94360 +                       break;
94361 +               }
94362 +
94363 +               default:
94364 +               {
94365 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
94366 +
94367 +                       if(psPrivateData->hKernelMemInfo)
94368 +                       {
94369 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
94370 +                                                "to use privileged service", __FUNCTION__));
94371 +                               goto unlock_and_return;
94372 +                       }
94373 +                       break;
94374 +               }
94375 +       }
94376 +#endif 
94377 +#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
94378 +       switch(cmd)
94379 +       {
94380 +               case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
94381 +               case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
94382 +               {
94383 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
94384 +                       int authenticated = pFile->authenticated;
94385 +                       PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
94386 +
94387 +                       if (authenticated)
94388 +                       {
94389 +                               break;
94390 +                       }
94391 +
94392 +                       
94393 +                       psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
94394 +                       if (psEnvPerProc == IMG_NULL)
94395 +                       {
94396 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__));
94397 +                               err = -EFAULT;
94398 +                               goto unlock_and_return;
94399 +                       }
94400 +
94401 +                       list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem)
94402 +                       {
94403 +                               struct drm_file *psDRMFile = psPrivateData->psDRMFile;
94404 +
94405 +                               if (pFile->master == psDRMFile->master)
94406 +                               {
94407 +                                       authenticated |= psDRMFile->authenticated;
94408 +                                       if (authenticated)
94409 +                                       {
94410 +                                               break;
94411 +                                       }
94412 +                               }
94413 +                       }
94414 +
94415 +                       if (!authenticated)
94416 +                       {
94417 +                               PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__));
94418 +                               err = -EPERM;
94419 +                               goto unlock_and_return;
94420 +                       }
94421 +                       break;
94422 +               }
94423 +               default:
94424 +                       break;
94425 +       }
94426 +#endif 
94427 +
94428 +       err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
94429 +       if(err != PVRSRV_OK)
94430 +               goto unlock_and_return;
94431 +
94432 +       switch(cmd)
94433 +       {
94434 +#if defined(PVR_SECURE_FD_EXPORT)
94435 +               case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
94436 +               {
94437 +                       PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
94438 +                               (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
94439 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
94440 +
94441 +                       psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo;
94442 +#if defined(SUPPORT_MEMINFO_IDS)
94443 +                       psExportDeviceMemOUT->ui64Stamp = psPrivateData->ui64Stamp = ++ui64Stamp;
94444 +#endif
94445 +                       break;
94446 +               }
94447 +#endif 
94448 +
94449 +#if defined(SUPPORT_MEMINFO_IDS)
94450 +               case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
94451 +               {
94452 +                       PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
94453 +                               (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
94454 +                       PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
94455 +                       psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp =     psPrivateData->ui64Stamp;
94456 +                       break;
94457 +               }
94458 +
94459 +               case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
94460 +               {
94461 +                       PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
94462 +                               (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
94463 +                       psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp = ++ui64Stamp;
94464 +                       break;
94465 +               }
94466 +#endif 
94467 +
94468 +               default:
94469 +                       break;
94470 +       }
94471 +
94472 +unlock_and_return:
94473 +       LinuxUnLockMutex(&gPVRSRVLock);
94474 +       return err;
94475 +}
94476 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_debug.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_debug.c
94477 new file mode 100644
94478 index 0000000..dbd54b1
94479 --- /dev/null
94480 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_debug.c
94481 @@ -0,0 +1,426 @@
94482 +/**********************************************************************
94483 + *
94484 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
94485 + * 
94486 + * This program is free software; you can redistribute it and/or modify it
94487 + * under the terms and conditions of the GNU General Public License,
94488 + * version 2, as published by the Free Software Foundation.
94489 + * 
94490 + * This program is distributed in the hope it will be useful but, except 
94491 + * as otherwise stated in writing, without any warranty; without even the 
94492 + * implied warranty of merchantability or fitness for a particular purpose. 
94493 + * See the GNU General Public License for more details.
94494 + * 
94495 + * You should have received a copy of the GNU General Public License along with
94496 + * this program; if not, write to the Free Software Foundation, Inc.,
94497 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
94498 + * 
94499 + * The full GNU General Public License is included in this distribution in
94500 + * the file called "COPYING".
94501 + *
94502 + * Contact Information:
94503 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
94504 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
94505 + *
94506 + ******************************************************************************/
94507 +
94508 +  
94509 +#ifndef AUTOCONF_INCLUDED
94510 + #include <linux/config.h>
94511 +#endif
94512 +
94513 +#include <asm/io.h>
94514 +#include <asm/uaccess.h>
94515 +#include <linux/kernel.h>
94516 +#include <linux/hardirq.h>
94517 +#include <linux/module.h>
94518 +#include <linux/spinlock.h>
94519 +#include <linux/tty.h>                 
94520 +#include <stdarg.h>
94521 +#include "img_types.h"
94522 +#include "servicesext.h"
94523 +#include "pvr_debug.h"
94524 +#include "proc.h"
94525 +#include "mutex.h"
94526 +#include "linkage.h"
94527 +
94528 +#if defined(PVRSRV_NEED_PVR_DPF)
94529 +
94530 +#define PVR_MAX_FILEPATH_LEN 256
94531 +
94532 +static IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING;
94533 +
94534 +#endif 
94535 +
94536 +#define        PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
94537 +
94538 +static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
94539 +
94540 +static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
94541 +
94542 +static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
94543 +
94544 +static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
94545 +
94546 +#define        USE_SPIN_LOCK (in_interrupt() || !preemptible())
94547 +
94548 +static inline void GetBufferLock(unsigned long *pulLockFlags)
94549 +{
94550 +       if (USE_SPIN_LOCK)
94551 +       {
94552 +               spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
94553 +       }
94554 +       else
94555 +       {
94556 +               LinuxLockMutex(&gsDebugMutexNonIRQ);
94557 +       }
94558 +}
94559 +
94560 +static inline void ReleaseBufferLock(unsigned long ulLockFlags)
94561 +{
94562 +       if (USE_SPIN_LOCK)
94563 +       {
94564 +               spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
94565 +       }
94566 +       else
94567 +       {
94568 +               LinuxUnLockMutex(&gsDebugMutexNonIRQ);
94569 +       }
94570 +}
94571 +
94572 +static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
94573 +{
94574 +       if (USE_SPIN_LOCK)
94575 +       {
94576 +               *ppszBuf = gszBufferIRQ;
94577 +               *pui32BufSiz = sizeof(gszBufferIRQ);
94578 +       }
94579 +       else
94580 +       {
94581 +               *ppszBuf = gszBufferNonIRQ;
94582 +               *pui32BufSiz = sizeof(gszBufferNonIRQ);
94583 +       }
94584 +}
94585 +
94586 +static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
94587 +{
94588 +       IMG_UINT32 ui32Used;
94589 +       IMG_UINT32 ui32Space;
94590 +       IMG_INT32 i32Len;
94591 +
94592 +       ui32Used = strlen(pszBuf);
94593 +       BUG_ON(ui32Used >= ui32BufSiz);
94594 +       ui32Space = ui32BufSiz - ui32Used;
94595 +
94596 +       i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
94597 +       pszBuf[ui32BufSiz - 1] = 0;
94598 +
94599 +       
94600 +       return (i32Len < 0 || i32Len >= ui32Space);
94601 +}
94602 +
94603 +IMG_VOID PVRDPFInit(IMG_VOID)
94604 +{
94605 +    LinuxInitMutex(&gsDebugMutexNonIRQ);
94606 +}
94607 +
94608 +IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
94609 +{
94610 +       va_list vaArgs;
94611 +       unsigned long ulLockFlags = 0;
94612 +       IMG_CHAR *pszBuf;
94613 +       IMG_UINT32 ui32BufSiz;
94614 +
94615 +       SelectBuffer(&pszBuf, &ui32BufSiz);
94616 +
94617 +       va_start(vaArgs, pszFormat);
94618 +
94619 +       GetBufferLock(&ulLockFlags);
94620 +       strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
94621 +
94622 +       if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
94623 +       {
94624 +               printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
94625 +       }
94626 +       else
94627 +       {
94628 +               printk(KERN_INFO "%s\n", pszBuf);
94629 +       }
94630 +
94631 +       ReleaseBufferLock(ulLockFlags);
94632 +       va_end(vaArgs);
94633 +
94634 +}
94635 +
94636 +#if defined(PVRSRV_NEED_PVR_ASSERT)
94637 +
94638 +IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
94639 +{
94640 +       PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
94641 +       BUG();
94642 +}
94643 +
94644 +#endif 
94645 +
94646 +#if defined(PVRSRV_NEED_PVR_TRACE)
94647 +
94648 +IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
94649 +{
94650 +       va_list VArgs;
94651 +       unsigned long ulLockFlags = 0;
94652 +       IMG_CHAR *pszBuf;
94653 +       IMG_UINT32 ui32BufSiz;
94654 +
94655 +       SelectBuffer(&pszBuf, &ui32BufSiz);
94656 +
94657 +       va_start(VArgs, pszFormat);
94658 +
94659 +       GetBufferLock(&ulLockFlags);
94660 +
94661 +       strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
94662 +
94663 +       if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
94664 +       {
94665 +               printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
94666 +       }
94667 +       else
94668 +       {
94669 +               printk(KERN_INFO "%s\n", pszBuf);
94670 +       }
94671 +       
94672 +       ReleaseBufferLock(ulLockFlags);
94673 +
94674 +       va_end(VArgs);
94675 +}
94676 +
94677 +#endif 
94678 +
94679 +#if defined(PVRSRV_NEED_PVR_DPF)
94680 +
94681 +static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
94682 +{
94683 +               va_list VArgs;
94684 +               IMG_BOOL bTrunc;
94685 +
94686 +               va_start (VArgs, pszFormat);
94687 +               
94688 +               bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
94689 +
94690 +               va_end (VArgs);
94691 +
94692 +               return bTrunc;
94693 +}
94694 +
94695 +IMG_VOID PVRSRVDebugPrintf     (
94696 +                                               IMG_UINT32      ui32DebugLevel,
94697 +                                               const IMG_CHAR* pszFullFileName,
94698 +                                               IMG_UINT32      ui32Line,
94699 +                                               const IMG_CHAR* pszFormat,
94700 +                                               ...
94701 +                                       )
94702 +{
94703 +       IMG_BOOL bTrace, bDebug;
94704 +       const IMG_CHAR *pszFileName = pszFullFileName;  
94705 +       IMG_CHAR *pszLeafName;  
94706 +               
94707 +       bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE;
94708 +       bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel);
94709 +
94710 +       if (bTrace || bDebug)
94711 +       {
94712 +               va_list vaArgs;
94713 +               unsigned long ulLockFlags = 0;
94714 +               IMG_CHAR *pszBuf;
94715 +               IMG_UINT32 ui32BufSiz;
94716 +
94717 +               SelectBuffer(&pszBuf, &ui32BufSiz);
94718 +
94719 +               va_start(vaArgs, pszFormat);
94720 +
94721 +               GetBufferLock(&ulLockFlags);
94722 +
94723 +               
94724 +               if (bDebug)
94725 +               {
94726 +                       switch(ui32DebugLevel)
94727 +                       {
94728 +                               case DBGPRIV_FATAL:
94729 +                               {
94730 +                                       strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
94731 +                                       break;
94732 +                               }
94733 +                               case DBGPRIV_ERROR:
94734 +                               {
94735 +                                       strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
94736 +                                       break;
94737 +                               }
94738 +                               case DBGPRIV_WARNING:
94739 +                               {
94740 +                                       strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
94741 +                                       break;
94742 +                               }
94743 +                               case DBGPRIV_MESSAGE:
94744 +                               {
94745 +                                       strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
94746 +                                       break;
94747 +                               }
94748 +                               case DBGPRIV_VERBOSE:
94749 +                               {
94750 +                                       strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
94751 +                                       break;
94752 +                               }
94753 +                               default:
94754 +                               {
94755 +                                       strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
94756 +                                       break;
94757 +                               }
94758 +                       }
94759 +               }
94760 +               else
94761 +               {
94762 +                       strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
94763 +               }
94764 +
94765 +               if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
94766 +               {
94767 +                       printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
94768 +               }
94769 +               else
94770 +               {
94771 +                       
94772 +                       if (!bTrace)
94773 +                       {
94774 +#ifdef DEBUG_LOG_PATH_TRUNCATE
94775 +                               
94776 +                               static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
94777 +
94778 +                               IMG_CHAR* pszTruncIter;
94779 +                               IMG_CHAR* pszTruncBackInter;
94780 +       
94781 +                               
94782 +                               pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
94783 +  
94784 +                               
94785 +                               strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
94786 +
94787 +                               if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
94788 +                                       IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
94789 +                                       strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
94790 +                               }
94791 +
94792 +                               pszTruncIter = szFileNameRewrite;
94793 +                               while(*pszTruncIter++ != 0) 
94794 +                               {
94795 +                                       IMG_CHAR* pszNextStartPoint;
94796 +                                       
94797 +                                       if(
94798 +                                          !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) && 
94799 +                                                ( *(pszTruncIter-1) == '.') &&
94800 +                                                ( *(pszTruncIter-2) == '.') &&
94801 +                                                ( *(pszTruncIter-3) == '/') )  
94802 +                                          ) continue;
94803 +  
94804 +                                       
94805 +                                       pszTruncBackInter = pszTruncIter - 3;
94806 +                                       while(*(--pszTruncBackInter) != '/') 
94807 +                                       {
94808 +                                               if(pszTruncBackInter <= szFileNameRewrite) break;
94809 +                                       }
94810 +                                       pszNextStartPoint = pszTruncBackInter;
94811 +
94812 +                                       
94813 +                                       while(*pszTruncIter != 0) 
94814 +                                       {
94815 +                                               *pszTruncBackInter++ = *pszTruncIter++;
94816 +                                       }
94817 +                                       *pszTruncBackInter = 0;
94818 +
94819 +                                       
94820 +                                       pszTruncIter = pszNextStartPoint;
94821 +                               }
94822 +
94823 +                               pszFileName = szFileNameRewrite;
94824 +                               
94825 +                               if(*pszFileName == '/') pszFileName++;
94826 +#endif
94827 +
94828 +#if !defined(__sh__)
94829 +                               pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
94830 +       
94831 +                               if (pszLeafName)
94832 +                               {
94833 +                                       pszFileName = pszLeafName;
94834 +                       } 
94835 +#endif 
94836 +
94837 +                               if (BAppend(pszBuf, ui32BufSiz, " [%lu, %s]", ui32Line, pszFileName))
94838 +                               {
94839 +                                       printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
94840 +                               }
94841 +                               else
94842 +                               {
94843 +                                       printk(KERN_INFO "%s\n", pszBuf);
94844 +                               }
94845 +                       }
94846 +                       else
94847 +                       {
94848 +                               printk(KERN_INFO "%s\n", pszBuf);
94849 +                       }
94850 +               }
94851 +
94852 +               ReleaseBufferLock(ulLockFlags);
94853 +
94854 +               va_end (vaArgs);
94855 +       }
94856 +}
94857 +
94858 +#endif 
94859 +
94860 +#if defined(DEBUG)
94861 +
94862 +IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel)
94863 +{
94864 +       printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(IMG_UINT)uDebugLevel);
94865 +
94866 +       gPVRDebugLevel = uDebugLevel;
94867 +}
94868 +
94869 +IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
94870 +{
94871 +#define        _PROC_SET_BUFFER_SZ             2
94872 +       IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
94873 +
94874 +       if (count != _PROC_SET_BUFFER_SZ)
94875 +       {
94876 +               return -EINVAL;
94877 +       }
94878 +       else
94879 +       {
94880 +               if (copy_from_user(data_buffer, buffer, count))
94881 +                       return -EINVAL;
94882 +               if (data_buffer[count - 1] != '\n')
94883 +                       return -EINVAL;
94884 +               PVRDebugSetLevel(data_buffer[0] - '0');
94885 +       }
94886 +       return (count);
94887 +}
94888 +
94889 +#ifdef PVR_PROC_USE_SEQ_FILE
94890 +void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)    
94891 +{
94892 +       seq_printf(sfile, "%lu\n", gPVRDebugLevel);
94893 +}
94894 +
94895 +#else 
94896 +IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
94897 +{
94898 +       if (off == 0) {
94899 +               *start = (IMG_CHAR *)1;
94900 +               return printAppend(page, count, 0, "%lu\n", gPVRDebugLevel);
94901 +       }
94902 +       *eof = 1;
94903 +       return 0;
94904 +}
94905 +#endif 
94906 +
94907 +#endif 
94908 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.c b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.c
94909 new file mode 100644
94910 index 0000000..9fa678d
94911 --- /dev/null
94912 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.c
94913 @@ -0,0 +1,310 @@
94914 +/**********************************************************************
94915 + *
94916 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
94917 + * 
94918 + * This program is free software; you can redistribute it and/or modify it
94919 + * under the terms and conditions of the GNU General Public License,
94920 + * version 2, as published by the Free Software Foundation.
94921 + * 
94922 + * This program is distributed in the hope it will be useful but, except 
94923 + * as otherwise stated in writing, without any warranty; without even the 
94924 + * implied warranty of merchantability or fitness for a particular purpose. 
94925 + * See the GNU General Public License for more details.
94926 + * 
94927 + * You should have received a copy of the GNU General Public License along with
94928 + * this program; if not, write to the Free Software Foundation, Inc.,
94929 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
94930 + * 
94931 + * The full GNU General Public License is included in this distribution in
94932 + * the file called "COPYING".
94933 + *
94934 + * Contact Information:
94935 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
94936 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
94937 + *
94938 + ******************************************************************************/
94939 +
94940 +#if defined(SUPPORT_DRI_DRM)
94941 +
94942 +#ifndef AUTOCONF_INCLUDED
94943 + #include <linux/config.h>
94944 +#endif
94945 +
94946 +#include <linux/init.h>
94947 +#include <linux/kernel.h>
94948 +#include <linux/module.h>
94949 +#include <linux/version.h>
94950 +#include <linux/fs.h>
94951 +#include <linux/proc_fs.h>
94952 +#include <asm/ioctl.h>
94953 +#include <drm/drmP.h>
94954 +#include <drm/drm.h>
94955 +
94956 +#include "img_defs.h"
94957 +#include "services.h"
94958 +#include "kerneldisplay.h"
94959 +#include "kernelbuffer.h"
94960 +#include "syscommon.h"
94961 +#include "pvrmmap.h"
94962 +#include "mm.h"
94963 +#include "mmap.h"
94964 +#include "mutex.h"
94965 +#include "pvr_debug.h"
94966 +#include "srvkm.h"
94967 +#include "perproc.h"
94968 +#include "handle.h"
94969 +#include "pvr_bridge_km.h"
94970 +#include "pvr_bridge.h"
94971 +#include "proc.h"
94972 +#include "pvrmodule.h"
94973 +#include "pvrversion.h"
94974 +#include "lock.h"
94975 +#include "linkage.h"
94976 +#include "pvr_drm_shared.h"
94977 +#include "pvr_drm.h"
94978 +
94979 +#define        MAKENAME_HELPER(x, y) x ## y
94980 +#define        MAKENAME(x, y) MAKENAME_HELPER(x, y)
94981 +
94982 +#define PVR_DRM_NAME   "pvrsrvkm"
94983 +#define PVR_DRM_DESC   "Imagination Technologies PVR DRM"
94984 +
94985 +#define PVR_PCI_IDS \
94986 +       {SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
94987 +       {0, 0, 0}
94988 +
94989 +struct pci_dev *gpsPVRLDMDev;
94990 +struct drm_device *gpsPVRDRMDev;
94991 +
94992 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
94993 +#error "Linux kernel version 2.6.25 or later required for PVR DRM support"
94994 +#endif
94995 +
94996 +#define PVR_DRM_FILE struct drm_file *
94997 +
94998 +#if !defined(SUPPORT_DRI_DRM_EXT)
94999 +static struct pci_device_id asPciIdList[] = {
95000 +       PVR_PCI_IDS
95001 +};
95002 +#endif
95003 +
95004 +IMG_INT PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags)
95005 +{
95006 +       IMG_INT iRes;
95007 +
95008 +       PVR_TRACE(("PVRSRVDrmLoad"));
95009 +
95010 +       gpsPVRDRMDev = dev;
95011 +       gpsPVRLDMDev = dev->pdev;
95012 +
95013 +#if defined(PDUMP)
95014 +       iRes = dbgdrv_init();
95015 +       if (iRes != 0)
95016 +       {
95017 +               return iRes;
95018 +       }
95019 +#endif
95020 +       
95021 +       iRes = PVRCore_Init();
95022 +       if (iRes != 0)
95023 +       {
95024 +               goto exit_dbgdrv_cleanup;
95025 +       }
95026 +
95027 +#if defined(DISPLAY_CONTROLLER)
95028 +       iRes = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(dev);
95029 +       if (iRes != 0)
95030 +       {
95031 +               goto exit_pvrcore_cleanup;
95032 +       }
95033 +#endif
95034 +       return 0;
95035 +
95036 +#if defined(DISPLAY_CONTROLLER)
95037 +exit_pvrcore_cleanup:
95038 +       PVRCore_Cleanup();
95039 +#endif
95040 +exit_dbgdrv_cleanup:
95041 +#if defined(PDUMP)
95042 +       dbgdrv_cleanup();
95043 +#endif
95044 +       return iRes;
95045 +}
95046 +
95047 +IMG_INT PVRSRVDrmUnload(struct drm_device *dev)
95048 +{
95049 +       PVR_TRACE(("PVRSRVDrmUnload"));
95050 +
95051 +#if defined(DISPLAY_CONTROLLER)
95052 +       PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(dev);
95053 +#endif
95054 +
95055 +       PVRCore_Cleanup();
95056 +
95057 +#if defined(PDUMP)
95058 +       dbgdrv_cleanup();
95059 +#endif
95060 +
95061 +       return 0;
95062 +}
95063 +
95064 +IMG_INT PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file)
95065 +{
95066 +       return PVRSRVOpen(dev, file);
95067 +}
95068 +
95069 +IMG_VOID PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file)
95070 +{
95071 +       PVRSRVRelease(dev, file);
95072 +}
95073 +
95074 +DRI_DRM_STATIC IMG_INT
95075 +PVRDRMIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
95076 +{
95077 +       return 0;
95078 +}
95079 +
95080 +#if defined(SUPPORT_DRI_DRM_EXT)
95081 +IMG_INT
95082 +PVRDRM_Dummy_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
95083 +{
95084 +       return 0;
95085 +}
95086 +#endif
95087 +
95088 +static IMG_INT
95089 +PVRDRMPCIBusIDField(struct drm_device *dev, IMG_UINT32 *pui32Field, IMG_UINT32 ui32FieldType)
95090 +{
95091 +       struct pci_dev *psPCIDev = (struct pci_dev *)dev->pdev;
95092 +
95093 +       switch (ui32FieldType)
95094 +       {
95095 +               case PVR_DRM_PCI_DOMAIN:
95096 +                       *pui32Field = pci_domain_nr(psPCIDev->bus);
95097 +                       break;
95098 +
95099 +               case PVR_DRM_PCI_BUS:
95100 +                       *pui32Field = psPCIDev->bus->number;
95101 +                       break;
95102 +
95103 +               case PVR_DRM_PCI_DEV:
95104 +                       *pui32Field = PCI_SLOT(psPCIDev->devfn);
95105 +                       break;
95106 +
95107 +               case PVR_DRM_PCI_FUNC:
95108 +                       *pui32Field = PCI_FUNC(psPCIDev->devfn);
95109 +                       break;
95110 +
95111 +               default:
95112 +                       return -EFAULT;
95113 +       }
95114 +
95115 +       return 0;
95116 +}
95117
95118 +DRI_DRM_STATIC IMG_INT
95119 +PVRDRMUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
95120 +{
95121 +       IMG_UINT32 *pui32Args = (IMG_UINT32 *)arg;
95122 +       IMG_UINT32 ui32Cmd = pui32Args[0];
95123 +       IMG_UINT32 ui32Arg1 = pui32Args[1];
95124 +       IMG_UINT32 *pui32OutArg = (IMG_UINT32 *)arg;
95125 +       IMG_INT ret = 0;
95126 +
95127 +       LinuxLockMutex(&gPVRSRVLock);
95128 +
95129 +       switch (ui32Cmd)
95130 +       {
95131 +               case PVR_DRM_UNPRIV_INIT_SUCCESFUL:
95132 +                       *pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0;
95133 +                       break;
95134 +
95135 +               case PVR_DRM_UNPRIV_BUSID_TYPE:
95136 +                       *pui32OutArg = PVR_DRM_BUS_TYPE_PCI;
95137 +                       break;
95138 +
95139 +               case PVR_DRM_UNPRIV_BUSID_FIELD:
95140 +                       ret = PVRDRMPCIBusIDField(dev, pui32OutArg, ui32Arg1);
95141 +
95142 +               default:
95143 +                       ret = -EFAULT;
95144 +       }
95145 +
95146 +       LinuxUnLockMutex(&gPVRSRVLock);
95147 +
95148 +       return ret;
95149 +}
95150 +
95151 +#if 0
95152 +struct drm_ioctl_desc sPVRDrmIoctls[] = {
95153 +       DRM_IOCTL_DEF(PVR_DRM_SRVKM_IOCTL, PVRSRV_BridgeDispatchKM, 0),
95154 +       DRM_IOCTL_DEF(PVR_DRM_IS_MASTER_IOCTL, PVRDRMIsMaster, DRM_MASTER),
95155 +       DRM_IOCTL_DEF(PVR_DRM_UNPRIV_IOCTL, PVRDRMUnprivCmd, 0),
95156 +#if defined(PDUMP)
95157 +       DRM_IOCTL_DEF(PVR_DRM_DBGDRV_IOCTL, dbgdrv_ioctl, 0),
95158 +#endif
95159 +};
95160 +
95161 +static IMG_INT pvr_max_ioctl = DRM_ARRAY_SIZE(sPVRDrmIoctls);
95162 +
95163 +static struct drm_driver sPVRDrmDriver = 
95164 +{
95165 +       .driver_features = 0,
95166 +       .dev_priv_size = sizeof(sPVRDrmBuffer),
95167 +       .load = PVRSRVDrmLoad,
95168 +       .unload = PVRSRVDrmUnload,
95169 +       .open = PVRSRVDrmOpen,
95170 +       .postclose = PVRSRVDrmPostClose,
95171 +       .suspend = PVRSRVDriverSuspend,
95172 +       .resume = PVRSRVDriverResume,
95173 +       .get_map_ofs = drm_core_get_map_ofs,
95174 +       .get_reg_ofs = drm_core_get_reg_ofs,
95175 +       .ioctls = sPVRDrmIoctls,
95176 +       .fops = 
95177 +       {
95178 +               .owner = THIS_MODULE,
95179 +               .open = drm_open,
95180 +               .release = drm_release,
95181 +               .ioctl = drm_ioctl,
95182 +               .mmap = PVRMMap,
95183 +               .poll = drm_poll,
95184 +               .fasync = drm_fasync,
95185 +       },
95186 +       .pci_driver = 
95187 +       {
95188 +               .name = PVR_DRM_NAME,
95189 +               .id_table = asPciIdList,
95190 +       },
95191 +               
95192 +       .name = PVR_DRM_NAME,
95193 +       .desc = PVR_DRM_DESC,
95194 +       .date = PVR_BUILD_DATE,
95195 +       .major = PVRVERSION_MAJ,
95196 +       .minor = PVRVERSION_MIN,
95197 +       .patchlevel = PVRVERSION_BUILD,
95198 +};
95199 +
95200 +static IMG_INT __init PVRSRVDrmInit(IMG_VOID)
95201 +{
95202 +       IMG_INT iRes;
95203 +       sPVRDrmDriver.num_ioctls = pvr_max_ioctl;
95204 +
95205 +       
95206 +       PVRDPFInit();
95207 +
95208 +       iRes = drm_init(&sPVRDrmDriver);
95209 +
95210 +       return iRes;
95211 +}
95212 +       
95213 +static IMG_VOID __exit PVRSRVDrmExit(IMG_VOID)
95214 +{
95215 +       drm_exit(&sPVRDrmDriver);
95216 +}
95217 +
95218 +module_init(PVRSRVDrmInit);
95219 +module_exit(PVRSRVDrmExit);
95220 +#endif 
95221 +#endif 
95222 +
95223 +
95224 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.h
95225 new file mode 100644
95226 index 0000000..fd8c81d
95227 --- /dev/null
95228 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/env/linux/pvr_drm.h
95229 @@ -0,0 +1,80 @@
95230 +/**********************************************************************
95231 + *
95232 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
95233 + * 
95234 + * This program is free software; you can redistribute it and/or modify it
95235 + * under the terms and conditions of the GNU General Public License,
95236 + * version 2, as published by the Free Software Foundation.
95237 + * 
95238 + * This program is distributed in the hope it will be useful but, except 
95239 + * as otherwise stated in writing, without any warranty; without even the 
95240 + * implied warranty of merchantability or fitness for a particular purpose. 
95241 + * See the GNU General Public License for more details.
95242 + * 
95243 + * You should have received a copy of the GNU General Public License along with
95244 + * this program; if not, write to the Free Software Foundation, Inc.,
95245 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
95246 + * 
95247 + * The full GNU General Public License is included in this distribution in
95248 + * the file called "COPYING".
95249 + *
95250 + * Contact Information:
95251 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
95252 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
95253 + *
95254 + ******************************************************************************/
95255 +
95256 +#if !defined(__PVR_DRM_H__)
95257 +#define __PVR_DRM_H__
95258 +
95259 +#include "pvr_drm_shared.h"
95260 +
95261 +#if defined(SUPPORT_DRI_DRM)
95262 +#define        PVR_DRM_MAKENAME_HELPER(x, y) x ## y
95263 +#define        PVR_DRM_MAKENAME(x, y) PVR_DRM_MAKENAME_HELPER(x, y)
95264 +
95265 +IMG_INT PVRCore_Init(IMG_VOID);
95266 +IMG_VOID PVRCore_Cleanup(IMG_VOID);
95267 +IMG_INT PVRSRVOpen(struct drm_device *dev, struct drm_file *pFile);
95268 +IMG_INT PVRSRVRelease(struct drm_device *dev, struct drm_file *pFile);
95269 +IMG_INT PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state);
95270 +IMG_INT PVRSRVDriverResume(struct drm_device *pDevice);
95271 +
95272 +IMG_INT PVRSRV_BridgeDispatchKM(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
95273 +
95274 +#if defined(SUPPORT_DRI_DRM_EXT)
95275 +#define        DRI_DRM_STATIC
95276 +IMG_INT PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags);
95277 +IMG_INT PVRSRVDrmUnload(struct drm_device *dev);
95278 +IMG_INT PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file);
95279 +IMG_VOID PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file);
95280 +IMG_INT PVRDRMIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
95281 +IMG_INT PVRDRMUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
95282 +IMG_INT PVRDRM_Dummy_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
95283 +#else
95284 +#define        DRI_DRM_STATIC  static
95285 +#endif 
95286 +
95287 +#if defined(DISPLAY_CONTROLLER)
95288 +extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device *);
95289 +extern void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device *);
95290 +#endif
95291 +
95292 +#if defined(PDUMP)
95293 +int dbgdrv_init(void);
95294 +void dbgdrv_cleanup(void);
95295 +IMG_INT dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
95296 +#endif
95297 +
95298 +#if !defined(SUPPORT_DRI_DRM_EXT)
95299 +#define        PVR_DRM_SRVKM_IOCTL     _IO(0, PVR_DRM_SRVKM_CMD)
95300 +#define        PVR_DRM_IS_MASTER_IOCTL _IO(0, PVR_DRM_IS_MASTER_CMD)
95301 +#define        PVR_DRM_UNPRIV_IOCTL    _IO(0, PVR_DRM_UNPRIV_CMD)
95302 +#define        PVR_DRM_DBGDRV_IOCTL    _IO(0, PVR_DRM_DBGDRV_CMD)
95303 +#endif
95304 +
95305 +#endif
95306 +
95307 +#endif 
95308 +
95309 +
95310 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgx535defs.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgx535defs.h
95311 new file mode 100644
95312 index 0000000..a683e9b
95313 --- /dev/null
95314 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgx535defs.h
95315 @@ -0,0 +1,637 @@
95316 +/**********************************************************************
95317 + *
95318 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
95319 + * 
95320 + * This program is free software; you can redistribute it and/or modify it
95321 + * under the terms and conditions of the GNU General Public License,
95322 + * version 2, as published by the Free Software Foundation.
95323 + * 
95324 + * This program is distributed in the hope it will be useful but, except 
95325 + * as otherwise stated in writing, without any warranty; without even the 
95326 + * implied warranty of merchantability or fitness for a particular purpose. 
95327 + * See the GNU General Public License for more details.
95328 + * 
95329 + * You should have received a copy of the GNU General Public License along with
95330 + * this program; if not, write to the Free Software Foundation, Inc.,
95331 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
95332 + * 
95333 + * The full GNU General Public License is included in this distribution in
95334 + * the file called "COPYING".
95335 + *
95336 + * Contact Information:
95337 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
95338 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
95339 + *
95340 + ******************************************************************************/
95341 +
95342 +#ifndef _SGX535DEFS_KM_H_
95343 +#define _SGX535DEFS_KM_H_
95344 +
95345 +#define EUR_CR_CLKGATECTL                   0x0000
95346 +#define EUR_CR_CLKGATECTL_2D_CLKG_MASK      0x00000003UL
95347 +#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT     0
95348 +#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK     0x00000030UL
95349 +#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT    4
95350 +#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK     0x00000300UL
95351 +#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT    8
95352 +#define EUR_CR_CLKGATECTL_TA_CLKG_MASK      0x00003000UL
95353 +#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT     12
95354 +#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK     0x00030000UL
95355 +#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT    16
95356 +#define EUR_CR_CLKGATECTL_USE_CLKG_MASK     0x00300000UL
95357 +#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT    20
95358 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000UL
95359 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
95360 +#define EUR_CR_CLKGATESTATUS                0x0004
95361 +#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK   0x00000001UL
95362 +#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT  0
95363 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK  0x00000010UL
95364 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
95365 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK  0x00000100UL
95366 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
95367 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK   0x00001000UL
95368 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT  12
95369 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK  0x00010000UL
95370 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
95371 +#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK  0x00100000UL
95372 +#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
95373 +#define EUR_CR_CLKGATECTLOVR                0x0008
95374 +#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK   0x00000003UL
95375 +#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT  0
95376 +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK  0x00000030UL
95377 +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
95378 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK  0x00000300UL
95379 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
95380 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK   0x00003000UL
95381 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT  12
95382 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK  0x00030000UL
95383 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
95384 +#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK  0x00300000UL
95385 +#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
95386 +#define EUR_CR_CORE_ID                      0x0010
95387 +#define EUR_CR_CORE_ID_CONFIG_MASK          0x0000FFFFUL
95388 +#define EUR_CR_CORE_ID_CONFIG_SHIFT         0
95389 +#define EUR_CR_CORE_ID_ID_MASK              0xFFFF0000UL
95390 +#define EUR_CR_CORE_ID_ID_SHIFT             16
95391 +#define EUR_CR_CORE_REVISION                0x0014
95392 +#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFUL
95393 +#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
95394 +#define EUR_CR_CORE_REVISION_MINOR_MASK     0x0000FF00UL
95395 +#define EUR_CR_CORE_REVISION_MINOR_SHIFT    8
95396 +#define EUR_CR_CORE_REVISION_MAJOR_MASK     0x00FF0000UL
95397 +#define EUR_CR_CORE_REVISION_MAJOR_SHIFT    16
95398 +#define EUR_CR_CORE_REVISION_DESIGNER_MASK  0xFF000000UL
95399 +#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
95400 +#define EUR_CR_DESIGNER_REV_FIELD1          0x0018
95401 +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFUL
95402 +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
95403 +#define EUR_CR_DESIGNER_REV_FIELD2          0x001C
95404 +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFUL
95405 +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
95406 +#define EUR_CR_SOFT_RESET                   0x0080
95407 +#define EUR_CR_SOFT_RESET_BIF_RESET_MASK    0x00000001UL
95408 +#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT   0
95409 +#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK   0x00000002UL
95410 +#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT  1
95411 +#define EUR_CR_SOFT_RESET_DPM_RESET_MASK    0x00000004UL
95412 +#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT   2
95413 +#define EUR_CR_SOFT_RESET_TA_RESET_MASK     0x00000008UL
95414 +#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT    3
95415 +#define EUR_CR_SOFT_RESET_USE_RESET_MASK    0x00000010UL
95416 +#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT   4
95417 +#define EUR_CR_SOFT_RESET_ISP_RESET_MASK    0x00000020UL
95418 +#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT   5
95419 +#define EUR_CR_SOFT_RESET_TSP_RESET_MASK    0x00000040UL
95420 +#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT   6
95421 +#define EUR_CR_EVENT_HOST_ENABLE2           0x0110
95422 +#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_MASK 0x00000010UL
95423 +#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_SHIFT 4
95424 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008UL
95425 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
95426 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004UL
95427 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
95428 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002UL
95429 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
95430 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001UL
95431 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
95432 +#define EUR_CR_EVENT_HOST_CLEAR2            0x0114
95433 +#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_MASK 0x00000010UL
95434 +#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_SHIFT 4
95435 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008UL
95436 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
95437 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004UL
95438 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
95439 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002UL
95440 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
95441 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001UL
95442 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
95443 +#define EUR_CR_EVENT_STATUS2                0x0118
95444 +#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_MASK 0x00000010UL
95445 +#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_SHIFT 4
95446 +#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008UL
95447 +#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
95448 +#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004UL
95449 +#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
95450 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002UL
95451 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
95452 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001UL
95453 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
95454 +#define EUR_CR_EVENT_STATUS                 0x012CUL
95455 +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000UL
95456 +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
95457 +#define EUR_CR_EVENT_STATUS_TIMER_MASK      0x20000000UL
95458 +#define EUR_CR_EVENT_STATUS_TIMER_SHIFT     29
95459 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000UL
95460 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
95461 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000UL
95462 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
95463 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000UL
95464 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
95465 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000UL
95466 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
95467 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000UL
95468 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
95469 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000UL
95470 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
95471 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000UL
95472 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
95473 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000UL
95474 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
95475 +#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK   0x00100000UL
95476 +#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT  20
95477 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000UL
95478 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
95479 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000UL
95480 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
95481 +#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK   0x00020000UL
95482 +#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT  17
95483 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000UL
95484 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
95485 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000UL
95486 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
95487 +#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK   0x00004000UL
95488 +#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT  14
95489 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000UL
95490 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
95491 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000UL
95492 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
95493 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK  0x00000800UL
95494 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
95495 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK  0x00000400UL
95496 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
95497 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200UL
95498 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
95499 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100UL
95500 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
95501 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080UL
95502 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
95503 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040UL
95504 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
95505 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020UL
95506 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
95507 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010UL
95508 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
95509 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008UL
95510 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
95511 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004UL
95512 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
95513 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002UL
95514 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
95515 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001UL
95516 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
95517 +#define EUR_CR_EVENT_HOST_ENABLE            0x0130
95518 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000UL
95519 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
95520 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000UL
95521 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
95522 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000UL
95523 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
95524 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000UL
95525 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
95526 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000UL
95527 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
95528 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000UL
95529 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
95530 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000UL
95531 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
95532 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000UL
95533 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
95534 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000UL
95535 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
95536 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000UL
95537 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
95538 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000UL
95539 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
95540 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000UL
95541 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
95542 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000UL
95543 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
95544 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000UL
95545 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
95546 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000UL
95547 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
95548 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000UL
95549 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
95550 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000UL
95551 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
95552 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000UL
95553 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
95554 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000UL
95555 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
95556 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800UL
95557 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
95558 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400UL
95559 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
95560 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200UL
95561 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
95562 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100UL
95563 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
95564 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080UL
95565 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
95566 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040UL
95567 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
95568 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020UL
95569 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
95570 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010UL
95571 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
95572 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008UL
95573 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
95574 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004UL
95575 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
95576 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002UL
95577 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
95578 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001UL
95579 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
95580 +#define EUR_CR_EVENT_HOST_CLEAR             0x0134
95581 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000UL
95582 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
95583 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK  0x20000000UL
95584 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
95585 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000UL
95586 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
95587 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000UL
95588 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
95589 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000UL
95590 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
95591 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000UL
95592 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
95593 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000UL
95594 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
95595 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000UL
95596 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
95597 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000UL
95598 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
95599 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000UL
95600 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
95601 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000UL
95602 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
95603 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000UL
95604 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
95605 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000UL
95606 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
95607 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000UL
95608 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
95609 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000UL
95610 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
95611 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000UL
95612 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
95613 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000UL
95614 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
95615 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000UL
95616 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
95617 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000UL
95618 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
95619 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800UL
95620 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
95621 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400UL
95622 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
95623 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200UL
95624 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
95625 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100UL
95626 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
95627 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080UL
95628 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
95629 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040UL
95630 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
95631 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020UL
95632 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
95633 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010UL
95634 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
95635 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008UL
95636 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
95637 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004UL
95638 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
95639 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002UL
95640 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
95641 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001UL
95642 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
95643 +#define EUR_CR_PDS                          0x0ABC
95644 +#define EUR_CR_PDS_DOUT_TIMEOUT_DISABLE_MASK 0x00000040UL
95645 +#define EUR_CR_PDS_DOUT_TIMEOUT_DISABLE_SHIFT 6
95646 +#define EUR_CR_PDS_EXEC_BASE                0x0AB8
95647 +#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK      0xFFF00000UL
95648 +#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT     20
95649 +#define EUR_CR_EVENT_KICKER                 0x0AC4
95650 +#define EUR_CR_EVENT_KICKER_ADDRESS_MASK    0xFFFFFFF0UL
95651 +#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT   4
95652 +#define EUR_CR_EVENT_KICK                   0x0AC8
95653 +#define EUR_CR_EVENT_KICK_NOW_MASK          0x00000001UL
95654 +#define EUR_CR_EVENT_KICK_NOW_SHIFT         0
95655 +#define EUR_CR_EVENT_TIMER                  0x0ACC
95656 +#define EUR_CR_EVENT_TIMER_ENABLE_MASK      0x01000000UL
95657 +#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT     24
95658 +#define EUR_CR_EVENT_TIMER_VALUE_MASK       0x00FFFFFFUL
95659 +#define EUR_CR_EVENT_TIMER_VALUE_SHIFT      0
95660 +#define EUR_CR_PDS_INV0                     0x0AD0
95661 +#define EUR_CR_PDS_INV0_DSC_MASK            0x00000001UL
95662 +#define EUR_CR_PDS_INV0_DSC_SHIFT           0
95663 +#define EUR_CR_PDS_INV1                     0x0AD4
95664 +#define EUR_CR_PDS_INV1_DSC_MASK            0x00000001UL
95665 +#define EUR_CR_PDS_INV1_DSC_SHIFT           0
95666 +#define EUR_CR_PDS_INV2                     0x0AD8
95667 +#define EUR_CR_PDS_INV2_DSC_MASK            0x00000001UL
95668 +#define EUR_CR_PDS_INV2_DSC_SHIFT           0
95669 +#define EUR_CR_PDS_INV3                     0x0ADC
95670 +#define EUR_CR_PDS_INV3_DSC_MASK            0x00000001UL
95671 +#define EUR_CR_PDS_INV3_DSC_SHIFT           0
95672 +#define EUR_CR_PDS_INV_CSC                  0x0AE0
95673 +#define EUR_CR_PDS_INV_CSC_KICK_MASK        0x00000001UL
95674 +#define EUR_CR_PDS_INV_CSC_KICK_SHIFT       0
95675 +#define EUR_CR_PDS_PC_BASE                  0x0B2C
95676 +#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK     0x3FFFFFFFUL
95677 +#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT    0
95678 +#define EUR_CR_BIF_CTRL                     0x0C00
95679 +#define EUR_CR_BIF_CTRL_NOREORDER_MASK      0x00000001UL
95680 +#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT     0
95681 +#define EUR_CR_BIF_CTRL_PAUSE_MASK          0x00000002UL
95682 +#define EUR_CR_BIF_CTRL_PAUSE_SHIFT         1
95683 +#define EUR_CR_BIF_CTRL_FLUSH_MASK          0x00000004UL
95684 +#define EUR_CR_BIF_CTRL_FLUSH_SHIFT         2
95685 +#define EUR_CR_BIF_CTRL_INVALDC_MASK        0x00000008UL
95686 +#define EUR_CR_BIF_CTRL_INVALDC_SHIFT       3
95687 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK    0x00000010UL
95688 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT   4
95689 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100UL
95690 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
95691 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200UL
95692 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
95693 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK  0x00000400UL
95694 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
95695 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800UL
95696 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
95697 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000UL
95698 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
95699 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000UL
95700 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
95701 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000UL
95702 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
95703 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000UL
95704 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
95705 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00010000UL
95706 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 16
95707 +#define EUR_CR_BIF_INT_STAT                 0x0C04
95708 +#define EUR_CR_BIF_INT_STAT_FAULT_MASK      0x00003FFFUL
95709 +#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT     0
95710 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK    0x00004000UL
95711 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT   14
95712 +#define EUR_CR_BIF_FAULT                    0x0C08
95713 +#define EUR_CR_BIF_FAULT_ADDR_MASK          0xFFFFF000UL
95714 +#define EUR_CR_BIF_FAULT_ADDR_SHIFT         12
95715 +#define EUR_CR_BIF_TILE0                    0x0C0C
95716 +#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK   0x00000FFFUL
95717 +#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT  0
95718 +#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK   0x00FFF000UL
95719 +#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT  12
95720 +#define EUR_CR_BIF_TILE0_CFG_MASK           0x0F000000UL
95721 +#define EUR_CR_BIF_TILE0_CFG_SHIFT          24
95722 +#define EUR_CR_BIF_TILE1                    0x0C10
95723 +#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK   0x00000FFFUL
95724 +#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT  0
95725 +#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK   0x00FFF000UL
95726 +#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT  12
95727 +#define EUR_CR_BIF_TILE1_CFG_MASK           0x0F000000UL
95728 +#define EUR_CR_BIF_TILE1_CFG_SHIFT          24
95729 +#define EUR_CR_BIF_TILE2                    0x0C14
95730 +#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK   0x00000FFFUL
95731 +#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT  0
95732 +#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK   0x00FFF000UL
95733 +#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT  12
95734 +#define EUR_CR_BIF_TILE2_CFG_MASK           0x0F000000UL
95735 +#define EUR_CR_BIF_TILE2_CFG_SHIFT          24
95736 +#define EUR_CR_BIF_TILE3                    0x0C18
95737 +#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK   0x00000FFFUL
95738 +#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT  0
95739 +#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK   0x00FFF000UL
95740 +#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT  12
95741 +#define EUR_CR_BIF_TILE3_CFG_MASK           0x0F000000UL
95742 +#define EUR_CR_BIF_TILE3_CFG_SHIFT          24
95743 +#define EUR_CR_BIF_TILE4                    0x0C1C
95744 +#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK   0x00000FFFUL
95745 +#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT  0
95746 +#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK   0x00FFF000UL
95747 +#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT  12
95748 +#define EUR_CR_BIF_TILE4_CFG_MASK           0x0F000000UL
95749 +#define EUR_CR_BIF_TILE4_CFG_SHIFT          24
95750 +#define EUR_CR_BIF_TILE5                    0x0C20
95751 +#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK   0x00000FFFUL
95752 +#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT  0
95753 +#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK   0x00FFF000UL
95754 +#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT  12
95755 +#define EUR_CR_BIF_TILE5_CFG_MASK           0x0F000000UL
95756 +#define EUR_CR_BIF_TILE5_CFG_SHIFT          24
95757 +#define EUR_CR_BIF_TILE6                    0x0C24
95758 +#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK   0x00000FFFUL
95759 +#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT  0
95760 +#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK   0x00FFF000UL
95761 +#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT  12
95762 +#define EUR_CR_BIF_TILE6_CFG_MASK           0x0F000000UL
95763 +#define EUR_CR_BIF_TILE6_CFG_SHIFT          24
95764 +#define EUR_CR_BIF_TILE7                    0x0C28
95765 +#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK   0x00000FFFUL
95766 +#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT  0
95767 +#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK   0x00FFF000UL
95768 +#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT  12
95769 +#define EUR_CR_BIF_TILE7_CFG_MASK           0x0F000000UL
95770 +#define EUR_CR_BIF_TILE7_CFG_SHIFT          24
95771 +#define EUR_CR_BIF_TILE8                    0x0C2C
95772 +#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK   0x00000FFFUL
95773 +#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT  0
95774 +#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK   0x00FFF000UL
95775 +#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT  12
95776 +#define EUR_CR_BIF_TILE8_CFG_MASK           0x0F000000UL
95777 +#define EUR_CR_BIF_TILE8_CFG_SHIFT          24
95778 +#define EUR_CR_BIF_TILE9                    0x0C30
95779 +#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK   0x00000FFFUL
95780 +#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT  0
95781 +#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK   0x00FFF000UL
95782 +#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT  12
95783 +#define EUR_CR_BIF_TILE9_CFG_MASK           0x0F000000UL
95784 +#define EUR_CR_BIF_TILE9_CFG_SHIFT          24
95785 +#define EUR_CR_BIF_DIR_LIST_BASE1           0x0C38
95786 +#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000UL
95787 +#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
95788 +#define EUR_CR_BIF_DIR_LIST_BASE2           0x0C3C
95789 +#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000UL
95790 +#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
95791 +#define EUR_CR_BIF_DIR_LIST_BASE3           0x0C40
95792 +#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000UL
95793 +#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
95794 +#define EUR_CR_BIF_DIR_LIST_BASE4           0x0C44
95795 +#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000UL
95796 +#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
95797 +#define EUR_CR_BIF_DIR_LIST_BASE5           0x0C48
95798 +#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000UL
95799 +#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
95800 +#define EUR_CR_BIF_DIR_LIST_BASE6           0x0C4C
95801 +#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000UL
95802 +#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
95803 +#define EUR_CR_BIF_DIR_LIST_BASE7           0x0C50
95804 +#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000UL
95805 +#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
95806 +#define EUR_CR_BIF_DIR_LIST_BASE8           0x0C54
95807 +#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFF000UL
95808 +#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 12
95809 +#define EUR_CR_BIF_DIR_LIST_BASE9           0x0C58
95810 +#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFF000UL
95811 +#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 12
95812 +#define EUR_CR_BIF_DIR_LIST_BASE10          0x0C5C
95813 +#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFF000UL
95814 +#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 12
95815 +#define EUR_CR_BIF_DIR_LIST_BASE11          0x0C60
95816 +#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFF000UL
95817 +#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 12
95818 +#define EUR_CR_BIF_DIR_LIST_BASE12          0x0C64
95819 +#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFF000UL
95820 +#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 12
95821 +#define EUR_CR_BIF_DIR_LIST_BASE13          0x0C68
95822 +#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFF000UL
95823 +#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 12
95824 +#define EUR_CR_BIF_DIR_LIST_BASE14          0x0C6C
95825 +#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFF000UL
95826 +#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 12
95827 +#define EUR_CR_BIF_DIR_LIST_BASE15          0x0C70
95828 +#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFF000UL
95829 +#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 12
95830 +#define EUR_CR_BIF_BANK_SET                 0x0C74
95831 +#define EUR_CR_BIF_BANK_SET_SELECT_MASK     0x000003FFUL
95832 +#define EUR_CR_BIF_BANK_SET_SELECT_SHIFT    0
95833 +#define EUR_CR_BIF_BANK0                    0x0C78
95834 +#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK     0x0000000FUL
95835 +#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT    0
95836 +#define EUR_CR_BIF_BANK0_INDEX_TA_MASK      0x000000F0UL
95837 +#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT     4
95838 +#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK    0x00000F00UL
95839 +#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT   8
95840 +#define EUR_CR_BIF_BANK0_INDEX_3D_MASK      0x0000F000UL
95841 +#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT     12
95842 +#define EUR_CR_BIF_BANK0_INDEX_2D_MASK      0x000F0000UL
95843 +#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT     16
95844 +#define EUR_CR_BIF_BANK1                    0x0C7C
95845 +#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK     0x0000000FUL
95846 +#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT    0
95847 +#define EUR_CR_BIF_BANK1_INDEX_TA_MASK      0x000000F0UL
95848 +#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT     4
95849 +#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK    0x00000F00UL
95850 +#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT   8
95851 +#define EUR_CR_BIF_BANK1_INDEX_3D_MASK      0x0000F000UL
95852 +#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT     12
95853 +#define EUR_CR_BIF_BANK1_INDEX_2D_MASK      0x000F0000UL
95854 +#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT     16
95855 +#define EUR_CR_BIF_ADT_TTE                  0x0C80
95856 +#define EUR_CR_BIF_ADT_TTE_VALUE_MASK       0x000000FFUL
95857 +#define EUR_CR_BIF_ADT_TTE_VALUE_SHIFT      0
95858 +#define EUR_CR_BIF_DIR_LIST_BASE0           0x0C84
95859 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000UL
95860 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
95861 +#define EUR_CR_BIF_TWOD_REQ_BASE            0x0C88
95862 +#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK  0xFFF00000UL
95863 +#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
95864 +#define EUR_CR_BIF_TA_REQ_BASE              0x0C90
95865 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK    0xFFF00000UL
95866 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT   20
95867 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1      0x0C94
95868 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_MASK 0x00000007UL
95869 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_SHIFT 0
95870 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_MASK 0x00000038UL
95871 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_SHIFT 3
95872 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_MASK 0x000001C0UL
95873 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_SHIFT 6
95874 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_MASK 0x00000E00UL
95875 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_SHIFT 9
95876 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_MASK 0x00007000UL
95877 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_SHIFT 12
95878 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_MASK 0x00038000UL
95879 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_SHIFT 15
95880 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2      0x0C98
95881 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_MASK 0x00000007UL
95882 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_SHIFT 0
95883 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_MASK 0x00000038UL
95884 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_SHIFT 3
95885 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_MASK 0x000001C0UL
95886 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_SHIFT 6
95887 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_MASK 0x00000E00UL
95888 +#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_SHIFT 9
95889 +#define EUR_CR_BIF_MEM_ARB_CONFIG           0x0CA0
95890 +#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_MASK 0x0000000FUL
95891 +#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT 0
95892 +#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_MASK 0x00000FF0UL
95893 +#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT 4
95894 +#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_MASK 0x00FFF000UL
95895 +#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT 12
95896 +#define EUR_CR_BIF_MEM_REQ_STAT             0x0CA8
95897 +#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK  0x000000FFUL
95898 +#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
95899 +#define EUR_CR_BIF_3D_REQ_BASE              0x0CAC
95900 +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK    0xFFF00000UL
95901 +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT   20
95902 +#define EUR_CR_BIF_ZLS_REQ_BASE             0x0CB0
95903 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK   0xFFF00000UL
95904 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT  20
95905 +#define EUR_CR_BIF_BANK_STATUS              0x0CB4
95906 +#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001UL
95907 +#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
95908 +#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002UL
95909 +#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
95910 +#define EUR_CR_2D_BLIT_STATUS               0x0E04
95911 +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFUL
95912 +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
95913 +#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK     0x01000000UL
95914 +#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT    24
95915 +#define EUR_CR_2D_VIRTUAL_FIFO_0            0x0E10
95916 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001UL
95917 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
95918 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EUL
95919 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
95920 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0UL
95921 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
95922 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000UL
95923 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
95924 +#define EUR_CR_2D_VIRTUAL_FIFO_1            0x0E14
95925 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFUL
95926 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
95927 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000UL
95928 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
95929 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000UL
95930 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
95931 +#define EUR_CR_2D_SOCIF                     0x0E18
95932 +#define EUR_CR_2D_SOCIF_FREESPACE_MASK      0x000000FFUL
95933 +#define EUR_CR_2D_SOCIF_FREESPACE_SHIFT     0
95934 +#define EUR_CR_2D_ALPHA                                                0x0E1C
95935 +#define EUR_CR_2D_ALPHA_COMPONENT_ONE_MASK  0x0000FF00UL
95936 +#define EUR_CR_2D_ALPHA_COMPONENT_ONE_SHIFT 8
95937 +#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_MASK 0x000000FFUL
95938 +#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_SHIFT 0
95939 +#define EUR_CR_USE_CODE_BASE(X)     (0x0A0C + (4 * (X)))
95940 +#define EUR_CR_USE_CODE_BASE_ADDR_MASK      0x01FFFFFFUL
95941 +#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT     0
95942 +#define EUR_CR_USE_CODE_BASE_DM_MASK        0x06000000UL
95943 +#define EUR_CR_USE_CODE_BASE_DM_SHIFT       25
95944 +#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
95945 +#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
95946 +
95947 +#define EUR_CR_MNE_CR_CTRL                                             0x0D00
95948 +#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK                 0x00008000UL
95949 +#define EUR_CR_MNE_CR_CTRL_INVAL                               0x0D20
95950 +
95951 +#endif 
95952 +
95953 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxdefs.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxdefs.h
95954 new file mode 100644
95955 index 0000000..fbffbf0
95956 --- /dev/null
95957 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxdefs.h
95958 @@ -0,0 +1,82 @@
95959 +/**********************************************************************
95960 + *
95961 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
95962 + * 
95963 + * This program is free software; you can redistribute it and/or modify it
95964 + * under the terms and conditions of the GNU General Public License,
95965 + * version 2, as published by the Free Software Foundation.
95966 + * 
95967 + * This program is distributed in the hope it will be useful but, except 
95968 + * as otherwise stated in writing, without any warranty; without even the 
95969 + * implied warranty of merchantability or fitness for a particular purpose. 
95970 + * See the GNU General Public License for more details.
95971 + * 
95972 + * You should have received a copy of the GNU General Public License along with
95973 + * this program; if not, write to the Free Software Foundation, Inc.,
95974 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
95975 + * 
95976 + * The full GNU General Public License is included in this distribution in
95977 + * the file called "COPYING".
95978 + *
95979 + * Contact Information:
95980 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
95981 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
95982 + *
95983 + ******************************************************************************/
95984 +
95985 +#ifndef _SGXDEFS_H_
95986 +#define        _SGXDEFS_H_
95987 +
95988 +#include "sgxerrata.h"
95989 +#include "sgxfeaturedefs.h"
95990 +
95991 +#if defined(SGX520)
95992 +#include "sgx520defs.h"
95993 +#else
95994 +#if defined(SGX530)
95995 +#include "sgx530defs.h"
95996 +#else
95997 +#if defined(SGX535)
95998 +#include "sgx535defs.h"
95999 +#else
96000 +#if defined(SGX535_V1_1)
96001 +#include "sgx535defs.h"
96002 +#else
96003 +#if defined(SGX540)
96004 +#include "sgx540defs.h"
96005 +#else
96006 +#if defined(SGX541)
96007 +#include "sgx541defs.h"
96008 +#else
96009 +#if defined(SGX543)
96010 +#include "sgx543defs.h"
96011 +#else
96012 +#if defined(SGX545)
96013 +#include "sgx545defs.h"
96014 +#else
96015 +#if defined(SGX531)
96016 +#include "sgx531defs.h"
96017 +#endif
96018 +#endif
96019 +#endif
96020 +#endif
96021 +#endif
96022 +#endif
96023 +#endif
96024 +#endif
96025 +#endif
96026 +
96027 +#if defined(SGX_FEATURE_MP)
96028 +#if defined(SGX541)
96029 +#if SGX_CORE_REV == 100
96030 +#include "sgx541_100mpdefs.h"
96031 +#else
96032 +#include "sgx541mpdefs.h"
96033 +#endif 
96034 +#else
96035 +#include "sgxmpdefs.h"
96036 +#endif 
96037 +#endif 
96038 +
96039 +#endif 
96040 +
96041 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxerrata.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxerrata.h
96042 new file mode 100644
96043 index 0000000..fe3e619
96044 --- /dev/null
96045 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxerrata.h
96046 @@ -0,0 +1,308 @@
96047 +/**********************************************************************
96048 + *
96049 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
96050 + * 
96051 + * This program is free software; you can redistribute it and/or modify it
96052 + * under the terms and conditions of the GNU General Public License,
96053 + * version 2, as published by the Free Software Foundation.
96054 + * 
96055 + * This program is distributed in the hope it will be useful but, except 
96056 + * as otherwise stated in writing, without any warranty; without even the 
96057 + * implied warranty of merchantability or fitness for a particular purpose. 
96058 + * See the GNU General Public License for more details.
96059 + * 
96060 + * You should have received a copy of the GNU General Public License along with
96061 + * this program; if not, write to the Free Software Foundation, Inc.,
96062 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
96063 + * 
96064 + * The full GNU General Public License is included in this distribution in
96065 + * the file called "COPYING".
96066 + *
96067 + * Contact Information:
96068 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
96069 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
96070 + *
96071 + ******************************************************************************/
96072 +
96073 +#ifndef _SGXERRATA_KM_H_
96074 +#define _SGXERRATA_KM_H_
96075 +
96076 +
96077 +#if defined(SGX520) && !defined(SGX_CORE_DEFINED)
96078 +       
96079 +       #define SGX_CORE_REV_HEAD       0
96080 +       #if defined(USE_SGX_CORE_REV_HEAD)
96081 +               
96082 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96083 +       #endif
96084 +
96085 +       #if SGX_CORE_REV == 100
96086 +       #else
96087 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96088 +               
96089 +       #else
96090 +               #error "sgxerrata.h: SGX520 Core Revision unspecified"
96091 +       #endif
96092 +       #endif
96093 +       
96094 +       #define SGX_CORE_DEFINED
96095 +#endif
96096 +
96097 +#if defined(SGX530) && !defined(SGX_CORE_DEFINED)
96098 +       
96099 +       #define SGX_CORE_REV_HEAD       0
96100 +       #if defined(USE_SGX_CORE_REV_HEAD)
96101 +               
96102 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96103 +       #endif
96104 +
96105 +       #if SGX_CORE_REV == 103
96106 +               #define FIX_HW_BRN_22934        
96107 +       #else
96108 +       #if SGX_CORE_REV == 110
96109 +               #define FIX_HW_BRN_22934        
96110 +       #else
96111 +       #if SGX_CORE_REV == 111
96112 +               #define FIX_HW_BRN_22934        
96113 +       #else
96114 +       #if SGX_CORE_REV == 120
96115 +               #define FIX_HW_BRN_22934        
96116 +       #else
96117 +       #if SGX_CORE_REV == 121
96118 +               #define FIX_HW_BRN_22934        
96119 +       #else
96120 +       #if SGX_CORE_REV == 125
96121 +               #define FIX_HW_BRN_22934        
96122 +       #else
96123 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96124 +               
96125 +       #else
96126 +               #error "sgxerrata.h: SGX530 Core Revision unspecified"
96127 +       #endif
96128 +       #endif
96129 +       #endif
96130 +       #endif
96131 +       #endif
96132 +#endif
96133 +        #endif
96134 +       
96135 +       #define SGX_CORE_DEFINED
96136 +#endif
96137 +
96138 +#if defined(SGX531) && !defined(SGX_CORE_DEFINED)
96139 +       
96140 +       #define SGX_CORE_REV_HEAD       0
96141 +       #if defined(USE_SGX_CORE_REV_HEAD)
96142 +               
96143 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96144 +       #endif
96145 +
96146 +       #if SGX_CORE_REV == 101
96147 +               #define FIX_HW_BRN_26620
96148 +               #define FIX_HW_BRN_28011
96149 +       #else
96150 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96151 +               
96152 +       #else
96153 +               #error "sgxerrata.h: SGX531 Core Revision unspecified"
96154 +       #endif
96155 +       #endif
96156 +       
96157 +       #define SGX_CORE_DEFINED
96158 +#endif
96159 +
96160 +#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED)
96161 +       
96162 +       #define SGX_CORE_REV_HEAD       0
96163 +       #if defined(USE_SGX_CORE_REV_HEAD)
96164 +               
96165 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96166 +       #endif
96167 +
96168 +       #if SGX_CORE_REV == 111
96169 +               #define FIX_HW_BRN_23281
96170 +               #define FIX_HW_BRN_23410
96171 +               #define FIX_HW_BRN_22693
96172 +               #define FIX_HW_BRN_22934                        
96173 +               #define FIX_HW_BRN_22997
96174 +               #define FIX_HW_BRN_23030
96175 +       #else
96176 +       #if SGX_CORE_REV == 1111
96177 +               #define FIX_HW_BRN_23281
96178 +               #define FIX_HW_BRN_23410
96179 +               #define FIX_HW_BRN_22693
96180 +               #define FIX_HW_BRN_22934        
96181 +               #define FIX_HW_BRN_22997
96182 +               #define FIX_HW_BRN_23030
96183 +       #else
96184 +       #if SGX_CORE_REV == 112
96185 +               #define FIX_HW_BRN_23281
96186 +               #define FIX_HW_BRN_23410
96187 +               #define FIX_HW_BRN_22693
96188 +               #define FIX_HW_BRN_22934        
96189 +               #define FIX_HW_BRN_22997
96190 +               #define FIX_HW_BRN_23030
96191 +       #else
96192 +       #if SGX_CORE_REV == 113
96193 +               #define FIX_HW_BRN_22934        
96194 +               #define FIX_HW_BRN_23281
96195 +               #define FIX_HW_BRN_23944
96196 +               #define FIX_HW_BRN_23410
96197 +       #else
96198 +       #if SGX_CORE_REV == 121
96199 +               #define FIX_HW_BRN_22934        
96200 +               #define FIX_HW_BRN_23944
96201 +               #define FIX_HW_BRN_23410
96202 +       #else
96203 +       #if SGX_CORE_REV == 126
96204 +               #define FIX_HW_BRN_22934        
96205 +       #else   
96206 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96207 +               
96208 +       #else
96209 +               #error "sgxerrata.h: SGX535 Core Revision unspecified"
96210 +
96211 +       #endif
96212 +       #endif
96213 +       #endif
96214 +       #endif
96215 +       #endif
96216 +       #endif
96217 +       #endif
96218 +       
96219 +       #define SGX_CORE_DEFINED
96220 +#endif
96221 +
96222 +#if defined(SGX540) && !defined(SGX_CORE_DEFINED)
96223 +       
96224 +       #define SGX_CORE_REV_HEAD       0
96225 +       #if defined(USE_SGX_CORE_REV_HEAD)
96226 +               
96227 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96228 +       #endif
96229 +
96230 +       #if SGX_CORE_REV == 101
96231 +               #define FIX_HW_BRN_25499
96232 +               #define FIX_HW_BRN_25503
96233 +               #define FIX_HW_BRN_26620
96234 +               #define FIX_HW_BRN_28011
96235 +       #else
96236 +       #if SGX_CORE_REV == 110
96237 +               #define FIX_HW_BRN_25503
96238 +               #define FIX_HW_BRN_26620
96239 +               #define FIX_HW_BRN_28011
96240 +       #else
96241 +       #if SGX_CORE_REV == 120
96242 +               #define FIX_HW_BRN_28011
96243 +       #else
96244 +       #if SGX_CORE_REV == 121
96245 +               #define FIX_HW_BRN_28011
96246 +       #else
96247 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96248 +               
96249 +       #else
96250 +               #error "sgxerrata.h: SGX540 Core Revision unspecified"
96251 +       #endif
96252 +       #endif
96253 +       #endif
96254 +       #endif
96255 +       #endif
96256 +       
96257 +       #define SGX_CORE_DEFINED
96258 +#endif
96259 +
96260 +#if defined(SGX541) && !defined(SGX_CORE_DEFINED)
96261 +       #if defined(SGX_FEATURE_MP)
96262 +               
96263 +               #define SGX_CORE_REV_HEAD       0
96264 +               #if defined(USE_SGX_CORE_REV_HEAD)
96265 +                       
96266 +                       #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96267 +               #endif
96268 +
96269 +               #if SGX_CORE_REV == 100
96270 +                       #define FIX_HW_BRN_27270
96271 +                       #define FIX_HW_BRN_28011
96272 +                       #define FIX_HW_BRN_27510
96273 +                       
96274 +               #else
96275 +               #if SGX_CORE_REV == 101
96276 +                       
96277 +               #else
96278 +               #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96279 +                       
96280 +               #else
96281 +                       #error "sgxerrata.h: SGX541 Core Revision unspecified"
96282 +               #endif
96283 +               #endif
96284 +               #endif
96285 +               
96286 +               #define SGX_CORE_DEFINED
96287 +       #else 
96288 +               #error "sgxerrata.h: SGX541 only supports MP configs (SGX_FEATURE_MP)"
96289 +       #endif 
96290 +#endif
96291 +
96292 +#if defined(SGX543) && !defined(SGX_CORE_DEFINED)
96293 +       #if defined(SGX_FEATURE_MP)
96294 +               
96295 +               #define SGX_CORE_REV_HEAD       0
96296 +               #if defined(USE_SGX_CORE_REV_HEAD)
96297 +                       
96298 +                       #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96299 +               #endif
96300 +
96301 +               #if SGX_CORE_REV == 100
96302 +                       
96303 +               #else
96304 +               #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96305 +                       
96306 +               #else
96307 +                       #error "sgxerrata.h: SGX543 Core Revision unspecified"
96308 +               #endif
96309 +               #endif
96310 +               
96311 +               #define SGX_CORE_DEFINED
96312 +       #else 
96313 +               #error "sgxerrata.h: SGX543 only supports MP configs (SGX_FEATURE_MP)"
96314 +       #endif 
96315 +#endif
96316 +
96317 +#if defined(SGX545) && !defined(SGX_CORE_DEFINED)
96318 +       
96319 +       #define SGX_CORE_REV_HEAD       0
96320 +       #if defined(USE_SGX_CORE_REV_HEAD)
96321 +               
96322 +               #define SGX_CORE_REV    SGX_CORE_REV_HEAD
96323 +       #endif
96324 +
96325 +       #if SGX_CORE_REV == 100
96326 +               #define FIX_HW_BRN_26620
96327 +               #define FIX_HW_BRN_27266
96328 +               #define FIX_HW_BRN_27456
96329 +       #else
96330 +       #if SGX_CORE_REV == 109
96331 +               
96332 +       #else
96333 +       #if SGX_CORE_REV == SGX_CORE_REV_HEAD
96334 +               
96335 +       #else
96336 +               #error "sgxerrata.h: SGX545 Core Revision unspecified"
96337 +       #endif
96338 +       #endif
96339 +       #endif
96340 +       
96341 +       #define SGX_CORE_DEFINED
96342 +#endif
96343 +
96344 +#if !defined(SGX_CORE_DEFINED)
96345 +#if defined (__GNUC__)
96346 +       #warning "sgxerrata.h: SGX Core Version unspecified"
96347 +#else
96348 +       #pragma message("sgxerrata.h: SGX Core Version unspecified")
96349 +#endif
96350 +#endif
96351 +
96352 +
96353 +#endif 
96354 +
96355 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h
96356 new file mode 100644
96357 index 0000000..782f613
96358 --- /dev/null
96359 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxfeaturedefs.h
96360 @@ -0,0 +1,163 @@
96361 +/**********************************************************************
96362 + *
96363 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
96364 + * 
96365 + * This program is free software; you can redistribute it and/or modify it
96366 + * under the terms and conditions of the GNU General Public License,
96367 + * version 2, as published by the Free Software Foundation.
96368 + * 
96369 + * This program is distributed in the hope it will be useful but, except 
96370 + * as otherwise stated in writing, without any warranty; without even the 
96371 + * implied warranty of merchantability or fitness for a particular purpose. 
96372 + * See the GNU General Public License for more details.
96373 + * 
96374 + * You should have received a copy of the GNU General Public License along with
96375 + * this program; if not, write to the Free Software Foundation, Inc.,
96376 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
96377 + * 
96378 + * The full GNU General Public License is included in this distribution in
96379 + * the file called "COPYING".
96380 + *
96381 + * Contact Information:
96382 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
96383 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
96384 + *
96385 + ******************************************************************************/
96386 +
96387 +#if defined(SGX520)
96388 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX520"
96389 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_520
96390 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (28)
96391 +       #define SGX_FEATURE_AUTOCLOCKGATING
96392 +#else
96393 +#if defined(SGX530)
96394 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX530"
96395 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_530
96396 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (28)
96397 +       #define SGX_FEATURE_AUTOCLOCKGATING
96398 +#else
96399 +#if defined(SGX535)
96400 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX535"
96401 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_535
96402 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (32)
96403 +       #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
96404 +       #define SGX_FEATURE_BIF_NUM_DIRLISTS                                    (16)
96405 +       #define SGX_FEATURE_2D_HARDWARE
96406 +       #define SGX_FEATURE_AUTOCLOCKGATING
96407 +       #define SUPPORT_SGX_GENERAL_MAPPING_HEAP
96408 +#else
96409 +#if defined(SGX540)
96410 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX540"
96411 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_540
96412 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (28)
96413 +       #define SGX_FEATURE_AUTOCLOCKGATING
96414 +       #define SGX_FEATURE_MULTI_EVENT_KICK
96415 +#else
96416 +#if defined(SGX541)
96417 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX541"
96418 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_541
96419 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (32)
96420 +       #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
96421 +       #define SGX_FEATURE_BIF_NUM_DIRLISTS                                    (8)
96422 +       #define SGX_FEATURE_AUTOCLOCKGATING
96423 +    #define SGX_FEATURE_SPM_MODE_0
96424 +       #define SGX_FEATURE_MULTI_EVENT_KICK
96425 +#else
96426 +#if defined(SGX543)
96427 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX543"
96428 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_543
96429 +       #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
96430 +       #define SGX_FEATURE_USE_UNLIMITED_PHASES
96431 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (32)
96432 +       #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
96433 +       #define SGX_FEATURE_BIF_NUM_DIRLISTS                                    (8)
96434 +       #define SGX_FEATURE_AUTOCLOCKGATING
96435 +       #define SGX_FEATURE_MONOLITHIC_UKERNEL
96436 +       #define SGX_FEATURE_MULTI_EVENT_KICK
96437 +       #define SGX_FEATURE_DATA_BREAKPOINTS
96438 +#else
96439 +#if defined(SGX531)
96440 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX531"
96441 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_531
96442 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (28)
96443 +       #define SGX_FEATURE_AUTOCLOCKGATING
96444 +       #define SGX_FEATURE_MULTI_EVENT_KICK
96445 +#else
96446 +#if defined(SGX545)
96447 +       #define SGX_CORE_FRIENDLY_NAME                                                  "SGX545"
96448 +       #define SGX_CORE_ID                                                                             SGX_CORE_ID_545
96449 +       #define SGX_FEATURE_ADDRESS_SPACE_SIZE                                  (32)
96450 +       #define SGX_FEATURE_AUTOCLOCKGATING
96451 +       #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING
96452 +       #define SGX_FEATURE_USE_UNLIMITED_PHASES
96453 +       #define SGX_FEATURE_DXT_TEXTURES
96454 +       #define SGX_FEATURE_VOLUME_TEXTURES
96455 +       #define SGX_FEATURE_HOST_ALLOC_FROM_DPM
96456 +       #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
96457 +       #define SGX_FEATURE_BIF_NUM_DIRLISTS                            (16)
96458 +       #define SGX_FEATURE_NUM_USE_PIPES                                       (4)
96459 +       #define SGX_FEATURE_TEXTURESTRIDE_EXTENSION
96460 +       #define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS
96461 +       #define SGX_FEATURE_MONOLITHIC_UKERNEL
96462 +       #define SGX_FEATURE_ZLS_EXTERNALZ
96463 +       #define SGX_FEATURE_VDM_CONTEXT_SWITCH_REV_2
96464 +       #define SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_2
96465 +       #define SGX_FEATURE_NUM_PDS_PIPES                                       (2)
96466 +       #define SGX_FEATURE_NATIVE_BACKWARD_BLIT
96467 +       #define SGX_FEATURE_MAX_TA_RENDER_TARGETS                               (512)
96468 +       #define SGX_FEATURE_SPM_MODE_0
96469 +       #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK
96470 +       #define SGX_FEATURE_DCU
96471 +       
96472 +       
96473 +       #define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
96474 +       #define SGX_FEATURE_MULTI_EVENT_KICK
96475 +#endif
96476 +#endif
96477 +#endif
96478 +#endif
96479 +#endif
96480 +#endif
96481 +#endif
96482 +#endif
96483 +
96484 +#if defined(FIX_HW_BRN_22693)
96485 +#undef SGX_FEATURE_AUTOCLOCKGATING
96486 +#endif
96487 +
96488 +#if defined(FIX_HW_BRN_27266)
96489 +#undef SGX_FEATURE_36BIT_MMU
96490 +#endif
96491 +
96492 +#if defined(FIX_HW_BRN_27456)
96493 +#undef SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
96494 +#endif
96495 +
96496 +#if defined(FIX_HW_BRN_22934)  \
96497 +       || defined(FIX_HW_BRN_25499)
96498 +#undef SGX_FEATURE_MULTI_EVENT_KICK
96499 +#endif
96500 +
96501 +#if defined(SGX_FEATURE_SYSTEM_CACHE)
96502 +       #if defined(SGX_FEATURE_36BIT_MMU)
96503 +               #error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU
96504 +       #endif
96505 +       #if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK)
96506 +               #define SGX_BYPASS_SYSTEM_CACHE
96507 +       #endif
96508 +#endif
96509 +
96510 +#if defined(SGX_FEATURE_MP)
96511 +#if !defined(SGX_FEATURE_MP_CORE_COUNT)
96512 +#error SGX_FEATURE_MP_CORE_COUNT must be defined when SGX_FEATURE_MP is defined
96513 +#endif
96514 +#else
96515 +#define SGX_FEATURE_MP_CORE_COUNT      (1)
96516 +#endif
96517 +
96518 +#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING)
96519 +#define SUPPORT_SGX_PRIORITY_SCHEDULING
96520 +#endif
96521 +
96522 +#include "img_types.h"
96523 +
96524 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxmmu.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxmmu.h
96525 new file mode 100644
96526 index 0000000..309de47
96527 --- /dev/null
96528 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/hwdefs/sgxmmu.h
96529 @@ -0,0 +1,79 @@
96530 +/**********************************************************************
96531 + *
96532 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
96533 + * 
96534 + * This program is free software; you can redistribute it and/or modify it
96535 + * under the terms and conditions of the GNU General Public License,
96536 + * version 2, as published by the Free Software Foundation.
96537 + * 
96538 + * This program is distributed in the hope it will be useful but, except 
96539 + * as otherwise stated in writing, without any warranty; without even the 
96540 + * implied warranty of merchantability or fitness for a particular purpose. 
96541 + * See the GNU General Public License for more details.
96542 + * 
96543 + * You should have received a copy of the GNU General Public License along with
96544 + * this program; if not, write to the Free Software Foundation, Inc.,
96545 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
96546 + * 
96547 + * The full GNU General Public License is included in this distribution in
96548 + * the file called "COPYING".
96549 + *
96550 + * Contact Information:
96551 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
96552 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
96553 + *
96554 + ******************************************************************************/
96555 +
96556 +#if !defined(__SGXMMU_KM_H__)
96557 +#define __SGXMMU_KM_H__
96558 +
96559 +#define SGX_MMU_PAGE_SHIFT                             (12)
96560 +#define SGX_MMU_PAGE_SIZE                              (1UL<<SGX_MMU_PAGE_SHIFT)
96561 +#define SGX_MMU_PAGE_MASK                              (SGX_MMU_PAGE_SIZE - 1UL)
96562 +
96563 +#define SGX_MMU_PD_SHIFT                               (10)
96564 +#define SGX_MMU_PD_SIZE                                        (1UL<<SGX_MMU_PD_SHIFT)
96565 +#define SGX_MMU_PD_MASK                                        (0xFFC00000UL)
96566 +
96567 +#if defined(SGX_FEATURE_36BIT_MMU)
96568 +       #define SGX_MMU_PDE_ADDR_MASK                   (0xFFFFFF00UL)
96569 +       #define SGX_MMU_PDE_ADDR_ALIGNSHIFT             (4)
96570 +#else
96571 +       #define SGX_MMU_PDE_ADDR_MASK                   (0xFFFFF000UL)
96572 +       #define SGX_MMU_PDE_ADDR_ALIGNSHIFT             (0)
96573 +#endif
96574 +#define SGX_MMU_PDE_VALID                              (0x00000001UL)
96575 +#define SGX_MMU_PDE_PAGE_SIZE_4K               (0x00000000UL)
96576 +#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
96577 +       #define SGX_MMU_PDE_PAGE_SIZE_16K               (0x00000002UL)
96578 +       #define SGX_MMU_PDE_PAGE_SIZE_64K               (0x00000004UL)
96579 +       #define SGX_MMU_PDE_PAGE_SIZE_256K              (0x00000006UL)
96580 +       #define SGX_MMU_PDE_PAGE_SIZE_1M                (0x00000008UL)
96581 +       #define SGX_MMU_PDE_PAGE_SIZE_4M                (0x0000000AUL)
96582 +       #define SGX_MMU_PDE_PAGE_SIZE_MASK              (0x0000000EUL)
96583 +#else
96584 +       #define SGX_MMU_PDE_WRITEONLY                   (0x00000002UL)
96585 +       #define SGX_MMU_PDE_READONLY                    (0x00000004UL)
96586 +       #define SGX_MMU_PDE_CACHECONSISTENT             (0x00000008UL)
96587 +       #define SGX_MMU_PDE_EDMPROTECT                  (0x00000010UL)
96588 +#endif
96589 +
96590 +#define SGX_MMU_PT_SHIFT                               (10)
96591 +#define SGX_MMU_PT_SIZE                                        (1UL<<SGX_MMU_PT_SHIFT)
96592 +#define SGX_MMU_PT_MASK                                        (0x003FF000UL)
96593 +
96594 +#if defined(SGX_FEATURE_36BIT_MMU)
96595 +       #define SGX_MMU_PTE_ADDR_MASK                   (0xFFFFFF00UL)
96596 +       #define SGX_MMU_PTE_ADDR_ALIGNSHIFT             (4)
96597 +#else
96598 +       #define SGX_MMU_PTE_ADDR_MASK                   (0xFFFFF000UL)
96599 +       #define SGX_MMU_PTE_ADDR_ALIGNSHIFT             (0)
96600 +#endif
96601 +#define SGX_MMU_PTE_VALID                              (0x00000001UL)
96602 +#define SGX_MMU_PTE_WRITEONLY                  (0x00000002UL)
96603 +#define SGX_MMU_PTE_READONLY                   (0x00000004UL)
96604 +#define SGX_MMU_PTE_CACHECONSISTENT            (0x00000008UL)
96605 +#define SGX_MMU_PTE_EDMPROTECT                 (0x00000010UL)
96606 +
96607 +#endif 
96608 +
96609 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/buffer_manager.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/buffer_manager.h
96610 new file mode 100644
96611 index 0000000..a47086d
96612 --- /dev/null
96613 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/buffer_manager.h
96614 @@ -0,0 +1,213 @@
96615 +/**********************************************************************
96616 + *
96617 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
96618 + * 
96619 + * This program is free software; you can redistribute it and/or modify it
96620 + * under the terms and conditions of the GNU General Public License,
96621 + * version 2, as published by the Free Software Foundation.
96622 + * 
96623 + * This program is distributed in the hope it will be useful but, except 
96624 + * as otherwise stated in writing, without any warranty; without even the 
96625 + * implied warranty of merchantability or fitness for a particular purpose. 
96626 + * See the GNU General Public License for more details.
96627 + * 
96628 + * You should have received a copy of the GNU General Public License along with
96629 + * this program; if not, write to the Free Software Foundation, Inc.,
96630 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
96631 + * 
96632 + * The full GNU General Public License is included in this distribution in
96633 + * the file called "COPYING".
96634 + *
96635 + * Contact Information:
96636 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
96637 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
96638 + *
96639 + ******************************************************************************/
96640 +
96641 +#ifndef _BUFFER_MANAGER_H_
96642 +#define _BUFFER_MANAGER_H_
96643 +
96644 +#include "img_types.h"
96645 +#include "ra.h"
96646 +#include "perproc.h"
96647 +
96648 +#if defined(__cplusplus)
96649 +extern "C"{
96650 +#endif 
96651 +       
96652 +typedef struct _BM_HEAP_ BM_HEAP;
96653 +
96654 +struct _BM_MAPPING_
96655 +{
96656 +       enum
96657 +       {
96658 +               hm_wrapped = 1,         
96659 +               hm_wrapped_scatter,     
96660 +               hm_wrapped_virtaddr, 
96661 +               hm_wrapped_scatter_virtaddr, 
96662 +               hm_env,                         
96663 +               hm_contiguous           
96664 +       } eCpuMemoryOrigin;
96665 +
96666 +       BM_HEAP                         *pBMHeap;       
96667 +       RA_ARENA                        *pArena;        
96668 +
96669 +       IMG_CPU_VIRTADDR        CpuVAddr;
96670 +       IMG_CPU_PHYADDR         CpuPAddr;
96671 +       IMG_DEV_VIRTADDR        DevVAddr;
96672 +       IMG_SYS_PHYADDR         *psSysAddr;
96673 +       IMG_SIZE_T                      uSize;
96674 +    IMG_HANDLE          hOSMemHandle;
96675 +       IMG_UINT32                      ui32Flags;
96676 +};
96677 +
96678 +typedef struct _BM_BUF_
96679 +{
96680 +       IMG_CPU_VIRTADDR        *CpuVAddr;
96681 +    IMG_VOID            *hOSMemHandle;
96682 +       IMG_CPU_PHYADDR         CpuPAddr;
96683 +       IMG_DEV_VIRTADDR        DevVAddr;
96684 +
96685 +       BM_MAPPING                      *pMapping;
96686 +       IMG_UINT32                      ui32RefCount;
96687 +} BM_BUF;
96688 +
96689 +struct _BM_HEAP_
96690 +{
96691 +       IMG_UINT32                              ui32Attribs;
96692 +       BM_CONTEXT                              *pBMContext;
96693 +       RA_ARENA                                *pImportArena;
96694 +       RA_ARENA                                *pLocalDevMemArena;
96695 +       RA_ARENA                                *pVMArena;
96696 +       DEV_ARENA_DESCRIPTOR    sDevArena;
96697 +       MMU_HEAP                                *pMMUHeap;
96698 +       
96699 +       struct _BM_HEAP_                *psNext;
96700 +       struct _BM_HEAP_                **ppsThis;
96701 +};
96702 +
96703 +struct _BM_CONTEXT_
96704 +{
96705 +       MMU_CONTEXT     *psMMUContext;
96706 +
96707 +       
96708 +        BM_HEAP *psBMHeap;
96709 +        
96710 +       
96711 +        BM_HEAP *psBMSharedHeap;
96712 +
96713 +       PVRSRV_DEVICE_NODE *psDeviceNode;
96714 +
96715 +       
96716 +       HASH_TABLE *pBufferHash;
96717 +
96718 +       
96719 +       IMG_HANDLE hResItem;
96720 +
96721 +       IMG_UINT32 ui32RefCount;
96722 +
96723 +       
96724 +
96725 +       struct _BM_CONTEXT_ *psNext;
96726 +       struct _BM_CONTEXT_ **ppsThis;
96727 +};
96728 +
96729 +
96730 +
96731 +typedef IMG_VOID *BM_HANDLE;
96732 +
96733 +#define BP_POOL_MASK         0x7 
96734 +
96735 +#define BP_CONTIGUOUS                  (1 << 3)
96736 +#define BP_PARAMBUFFER                 (1 << 4)
96737 +
96738 +#define BM_MAX_DEVMEM_ARENAS  2
96739 +
96740 +IMG_HANDLE
96741 +BM_CreateContext(PVRSRV_DEVICE_NODE                    *psDeviceNode,
96742 +                                IMG_DEV_PHYADDR                        *psPDDevPAddr,
96743 +                                PVRSRV_PER_PROCESS_DATA        *psPerProc,
96744 +                                IMG_BOOL                                       *pbCreated);
96745 +
96746 +
96747 +PVRSRV_ERROR
96748 +BM_DestroyContext (IMG_HANDLE hBMContext,
96749 +                                       IMG_BOOL *pbCreated);
96750 +
96751 +
96752 +IMG_HANDLE 
96753 +BM_CreateHeap (IMG_HANDLE hBMContext,
96754 +                               DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo);
96755 +
96756 +IMG_VOID 
96757 +BM_DestroyHeap (IMG_HANDLE hDevMemHeap);
96758 +
96759 +
96760 +IMG_BOOL 
96761 +BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode);
96762 +
96763 +IMG_BOOL
96764 +BM_Alloc (IMG_HANDLE                   hDevMemHeap,
96765 +                       IMG_DEV_VIRTADDR        *psDevVAddr,
96766 +                       IMG_SIZE_T                      uSize,
96767 +                       IMG_UINT32                      *pui32Flags,
96768 +                       IMG_UINT32                      uDevVAddrAlignment,
96769 +                       BM_HANDLE                       *phBuf);
96770 +
96771 +IMG_BOOL
96772 +BM_Wrap (      IMG_HANDLE hDevMemHeap,
96773 +                   IMG_SIZE_T ui32Size,
96774 +                       IMG_SIZE_T ui32Offset,
96775 +                       IMG_BOOL bPhysContig,
96776 +                       IMG_SYS_PHYADDR *psSysAddr,
96777 +                       IMG_VOID *pvCPUVAddr,
96778 +                       IMG_UINT32 *pui32Flags,
96779 +                       BM_HANDLE *phBuf);
96780 +
96781 +IMG_VOID
96782 +BM_Free (BM_HANDLE hBuf, 
96783 +               IMG_UINT32 ui32Flags);
96784 +
96785 +
96786 +IMG_CPU_VIRTADDR
96787 +BM_HandleToCpuVaddr (BM_HANDLE hBuf);
96788 +
96789 +IMG_DEV_VIRTADDR
96790 +BM_HandleToDevVaddr (BM_HANDLE hBuf);
96791 +
96792 +IMG_SYS_PHYADDR
96793 +BM_HandleToSysPaddr (BM_HANDLE hBuf);
96794 +
96795 +IMG_HANDLE
96796 +BM_HandleToOSMemHandle (BM_HANDLE hBuf);
96797 +
96798 +IMG_BOOL
96799 +BM_ContiguousStatistics (IMG_UINT32 uFlags,
96800 +                         IMG_UINT32 *pTotalBytes,
96801 +                         IMG_UINT32 *pAvailableBytes);
96802 +
96803 +
96804 +IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
96805 +                                                               IMG_DEV_VIRTADDR sDevVPageAddr,
96806 +                                                               IMG_DEV_PHYADDR *psDevPAddr);
96807 +
96808 +PVRSRV_ERROR BM_GetHeapInfo(IMG_HANDLE hDevMemHeap, 
96809 +                                                       PVRSRV_HEAP_INFO *psHeapInfo);
96810 +
96811 +MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap);
96812 +
96813 +MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext);
96814 +
96815 +IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap);
96816 +
96817 +PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext);
96818 +
96819 +
96820 +IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
96821 +
96822 +#if defined(__cplusplus)
96823 +}
96824 +#endif
96825 +
96826 +#endif
96827 +
96828 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/device.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/device.h
96829 new file mode 100644
96830 index 0000000..90c8c7a
96831 --- /dev/null
96832 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/device.h
96833 @@ -0,0 +1,278 @@
96834 +/**********************************************************************
96835 + *
96836 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
96837 + * 
96838 + * This program is free software; you can redistribute it and/or modify it
96839 + * under the terms and conditions of the GNU General Public License,
96840 + * version 2, as published by the Free Software Foundation.
96841 + * 
96842 + * This program is distributed in the hope it will be useful but, except 
96843 + * as otherwise stated in writing, without any warranty; without even the 
96844 + * implied warranty of merchantability or fitness for a particular purpose. 
96845 + * See the GNU General Public License for more details.
96846 + * 
96847 + * You should have received a copy of the GNU General Public License along with
96848 + * this program; if not, write to the Free Software Foundation, Inc.,
96849 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
96850 + * 
96851 + * The full GNU General Public License is included in this distribution in
96852 + * the file called "COPYING".
96853 + *
96854 + * Contact Information:
96855 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
96856 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
96857 + *
96858 + ******************************************************************************/
96859 +
96860 +#ifndef __DEVICE_H__
96861 +#define __DEVICE_H__
96862 +
96863 +#if defined(__cplusplus)
96864 +extern "C" {
96865 +#endif
96866 +       
96867 +#include "ra.h"                
96868 +#include "resman.h"            
96869 +
96870 +typedef struct _BM_CONTEXT_ BM_CONTEXT;
96871 +
96872 +typedef struct _MMU_HEAP_ MMU_HEAP;
96873 +typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
96874 +
96875 +#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG              (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0))
96876 +#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG   (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1))
96877 +#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG            (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2))
96878 +#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3))
96879 +
96880 +typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE;
96881 +#define DEVICE_MEMORY_HEAP_PERCONTEXT          0
96882 +#define DEVICE_MEMORY_HEAP_KERNEL                      1
96883 +#define DEVICE_MEMORY_HEAP_SHARED                      2
96884 +#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED     3
96885 +
96886 +#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY 1
96887 +#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV   2       
96888 +
96889 +typedef struct _DEVICE_MEMORY_HEAP_INFO_
96890 +{
96891 +       
96892 +       IMG_UINT32                              ui32HeapID;
96893 +
96894 +       
96895 +       IMG_CHAR                                *pszName;
96896 +
96897 +       
96898 +       IMG_CHAR                                *pszBSName;
96899 +       
96900 +       
96901 +       IMG_DEV_VIRTADDR                sDevVAddrBase;
96902 +
96903 +       
96904 +       IMG_UINT32                              ui32HeapSize;
96905 +
96906 +       
96907 +       IMG_UINT32                              ui32Attribs;
96908 +
96909 +       
96910 +       DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
96911 +       
96912 +       
96913 +       IMG_HANDLE                              hDevMemHeap;
96914 +       
96915 +       
96916 +       RA_ARENA                                *psLocalDevMemArena;
96917 +
96918 +       
96919 +       IMG_UINT32                              ui32DataPageSize;
96920 +
96921 +} DEVICE_MEMORY_HEAP_INFO;
96922 +
96923 +typedef struct _DEVICE_MEMORY_INFO_
96924 +{
96925 +       
96926 +       IMG_UINT32                              ui32AddressSpaceSizeLog2;
96927 +
96928 +       
96929 +
96930 +
96931 +       IMG_UINT32                              ui32Flags;
96932 +
96933 +       
96934 +       IMG_UINT32                              ui32HeapCount;
96935 +       
96936 +       
96937 +       IMG_UINT32                              ui32SyncHeapID;
96938 +       
96939 +       
96940 +       IMG_UINT32                              ui32MappingHeapID;
96941 +
96942 +       
96943 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
96944 +
96945 +       
96946 +    BM_CONTEXT                         *pBMKernelContext;
96947 +
96948 +       
96949 +    BM_CONTEXT                         *pBMContext;
96950 +
96951 +} DEVICE_MEMORY_INFO;
96952 +
96953 +
96954 +typedef struct DEV_ARENA_DESCRIPTOR_TAG
96955 +{
96956 +       IMG_UINT32                              ui32HeapID;             
96957 +
96958 +       IMG_CHAR                                *pszName;               
96959 +
96960 +       IMG_DEV_VIRTADDR                BaseDevVAddr;   
96961 +
96962 +       IMG_UINT32                              ui32Size;               
96963 +
96964 +       DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
96965 +
96966 +       
96967 +       IMG_UINT32                              ui32DataPageSize;
96968 +
96969 +       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo;
96970 +
96971 +} DEV_ARENA_DESCRIPTOR;
96972 +
96973 +typedef struct _SYS_DATA_TAG_ *PSYS_DATA;
96974 +
96975 +typedef struct _PVRSRV_DEVICE_NODE_
96976 +{
96977 +       PVRSRV_DEVICE_IDENTIFIER        sDevId;
96978 +       IMG_UINT32                                      ui32RefCount;
96979 +
96980 +       
96981 +
96982 +       
96983 +       PVRSRV_ERROR                    (*pfnInitDevice) (IMG_VOID*);
96984 +       
96985 +       PVRSRV_ERROR                    (*pfnDeInitDevice) (IMG_VOID*);
96986 +
96987 +       
96988 +       PVRSRV_ERROR                    (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
96989 +
96990 +       
96991 +       PVRSRV_ERROR                    (*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*);
96992 +       IMG_VOID                                (*pfnMMUFinalise)(MMU_CONTEXT*);
96993 +       IMG_VOID                                (*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*);
96994 +       MMU_HEAP*                               (*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**);
96995 +       IMG_VOID                                (*pfnMMUDelete)(MMU_HEAP*);
96996 +       IMG_BOOL                                (*pfnMMUAlloc)(MMU_HEAP*pMMU,
96997 +                                                                                  IMG_SIZE_T uSize,
96998 +                                                                                  IMG_SIZE_T *pActualSize,
96999 +                                                                                  IMG_UINT32 uFlags,
97000 +                                                                                  IMG_UINT32 uDevVAddrAlignment,
97001 +                                                                                  IMG_DEV_VIRTADDR *pDevVAddr);
97002 +       IMG_VOID                                (*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32);
97003 +       IMG_VOID                                (*pfnMMUEnable)(MMU_HEAP*);
97004 +       IMG_VOID                                (*pfnMMUDisable)(MMU_HEAP*);
97005 +       IMG_VOID                                (*pfnMMUMapPages)(MMU_HEAP *pMMU,
97006 +                                                                                         IMG_DEV_VIRTADDR devVAddr,
97007 +                                                                                         IMG_SYS_PHYADDR SysPAddr,
97008 +                                                                                         IMG_SIZE_T uSize,
97009 +                                                                                         IMG_UINT32 ui32MemFlags,
97010 +                                                                                         IMG_HANDLE hUniqueTag);
97011 +       IMG_VOID                                (*pfnMMUMapShadow)(MMU_HEAP            *pMMU,
97012 +                                                                                          IMG_DEV_VIRTADDR    MapBaseDevVAddr,
97013 +                                                                                          IMG_SIZE_T          uSize, 
97014 +                                                                                          IMG_CPU_VIRTADDR    CpuVAddr,
97015 +                                                                                          IMG_HANDLE          hOSMemHandle,
97016 +                                                                                          IMG_DEV_VIRTADDR    *pDevVAddr,
97017 +                                                                                          IMG_UINT32 ui32MemFlags,
97018 +                                                                                          IMG_HANDLE hUniqueTag);
97019 +       IMG_VOID                                (*pfnMMUUnmapPages)(MMU_HEAP *pMMU,
97020 +                                                                                               IMG_DEV_VIRTADDR dev_vaddr,
97021 +                                                                                               IMG_UINT32 ui32PageCount,
97022 +                                                                                               IMG_HANDLE hUniqueTag);
97023 +
97024 +       IMG_VOID                                (*pfnMMUMapScatter)(MMU_HEAP *pMMU,
97025 +                                                                                               IMG_DEV_VIRTADDR DevVAddr,
97026 +                                                                                               IMG_SYS_PHYADDR *psSysAddr,
97027 +                                                                                               IMG_SIZE_T uSize,
97028 +                                                                                               IMG_UINT32 ui32MemFlags,
97029 +                                                                                               IMG_HANDLE hUniqueTag);
97030 +
97031 +       IMG_DEV_PHYADDR                 (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
97032 +       IMG_DEV_PHYADDR                 (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext);
97033 +
97034 +       
97035 +       IMG_BOOL                                (*pfnDeviceISR)(IMG_VOID*);
97036 +       
97037 +       IMG_VOID                                *pvISRData;
97038 +       
97039 +       IMG_UINT32                              ui32SOCInterruptBit;
97040 +       
97041 +       IMG_VOID                                (*pfnDeviceMISR)(IMG_VOID*);
97042 +
97043 +       
97044 +       IMG_VOID                                (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
97045 +       
97046 +       IMG_BOOL                                bReProcessDeviceCommandComplete;
97047 +       
97048 +       
97049 +       DEVICE_MEMORY_INFO              sDevMemoryInfo;
97050 +
97051 +       
97052 +       IMG_VOID                                *pvDevice;
97053 +       IMG_UINT32                              ui32pvDeviceSize; 
97054 +               
97055 +       
97056 +       PRESMAN_CONTEXT                 hResManContext;
97057 +       
97058 +       
97059 +       PSYS_DATA                               psSysData;
97060 +       
97061 +       
97062 +       RA_ARENA                                *psLocalDevMemArena;
97063 +       
97064 +       IMG_UINT32                              ui32Flags;
97065 +       
97066 +       struct _PVRSRV_DEVICE_NODE_     *psNext;
97067 +       struct _PVRSRV_DEVICE_NODE_     **ppsThis;
97068 +} PVRSRV_DEVICE_NODE;
97069 +
97070 +PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
97071 +                                                                                         PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
97072 +                                                                                         IMG_UINT32 ui32SOCInterruptBit,
97073 +                                                                                         IMG_UINT32 *pui32DeviceIndex );
97074 +
97075 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex);
97076 +PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful);
97077 +
97078 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
97079 +
97080 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex);
97081 +
97082 +#if !defined(USE_CODE)
97083 +
97084 +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr,
97085 +                                                                                                  IMG_UINT32 ui32Value,
97086 +                                                                                                  IMG_UINT32 ui32Mask,
97087 +                                                                                                  IMG_UINT32 ui32Waitus,
97088 +                                                                                                  IMG_UINT32 ui32Tries);
97089 +
97090 +#endif 
97091 +
97092 +
97093 +#if defined (USING_ISR_INTERRUPTS)
97094 +PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value,
97095 +                                                               IMG_UINT32 ui32Mask,
97096 +                                                               IMG_UINT32 ui32Waitus,
97097 +                                                               IMG_UINT32 ui32Tries);
97098 +#endif 
97099 +
97100 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData);
97101 +IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData);
97102 +IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode);
97103 +IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData);
97104 +IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData);
97105 +
97106 +#if defined(__cplusplus)
97107 +}
97108 +#endif
97109 +       
97110 +#endif 
97111 +
97112 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/handle.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/handle.h
97113 new file mode 100644
97114 index 0000000..fda74f1
97115 --- /dev/null
97116 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/handle.h
97117 @@ -0,0 +1,382 @@
97118 +/**********************************************************************
97119 + *
97120 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
97121 + * 
97122 + * This program is free software; you can redistribute it and/or modify it
97123 + * under the terms and conditions of the GNU General Public License,
97124 + * version 2, as published by the Free Software Foundation.
97125 + * 
97126 + * This program is distributed in the hope it will be useful but, except 
97127 + * as otherwise stated in writing, without any warranty; without even the 
97128 + * implied warranty of merchantability or fitness for a particular purpose. 
97129 + * See the GNU General Public License for more details.
97130 + * 
97131 + * You should have received a copy of the GNU General Public License along with
97132 + * this program; if not, write to the Free Software Foundation, Inc.,
97133 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
97134 + * 
97135 + * The full GNU General Public License is included in this distribution in
97136 + * the file called "COPYING".
97137 + *
97138 + * Contact Information:
97139 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
97140 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
97141 + *
97142 + ******************************************************************************/
97143 +
97144 +#ifndef __HANDLE_H__
97145 +#define __HANDLE_H__
97146 +
97147 +#if defined (__cplusplus)
97148 +extern "C" {
97149 +#endif
97150 +
97151 +#include "img_types.h"
97152 +#include "hash.h"
97153 +#include "resman.h"
97154 +
97155 +typedef enum
97156 +{
97157 +       PVRSRV_HANDLE_TYPE_NONE = 0,
97158 +       PVRSRV_HANDLE_TYPE_PERPROC_DATA,
97159 +       PVRSRV_HANDLE_TYPE_DEV_NODE,
97160 +       PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
97161 +       PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
97162 +       PVRSRV_HANDLE_TYPE_MEM_INFO,
97163 +       PVRSRV_HANDLE_TYPE_SYNC_INFO,
97164 +       PVRSRV_HANDLE_TYPE_DISP_INFO,
97165 +       PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
97166 +       PVRSRV_HANDLE_TYPE_BUF_INFO,
97167 +       PVRSRV_HANDLE_TYPE_DISP_BUFFER,
97168 +       PVRSRV_HANDLE_TYPE_BUF_BUFFER,
97169 +       PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
97170 +       PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
97171 +       PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT,
97172 +       PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
97173 +       PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
97174 +       PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
97175 +       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
97176 +       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
97177 +       PVRSRV_HANDLE_TYPE_MMAP_INFO,
97178 +       PVRSRV_HANDLE_TYPE_SOC_TIMER
97179 +} PVRSRV_HANDLE_TYPE;
97180 +
97181 +typedef enum
97182 +{
97183 +       
97184 +       PVRSRV_HANDLE_ALLOC_FLAG_NONE =                 0,
97185 +       
97186 +       PVRSRV_HANDLE_ALLOC_FLAG_SHARED =               0x01,
97187 +       
97188 +       PVRSRV_HANDLE_ALLOC_FLAG_MULTI =                0x02,
97189 +       
97190 +       PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE =              0x04
97191 +} PVRSRV_HANDLE_ALLOC_FLAG;
97192 +
97193 +struct _PVRSRV_HANDLE_BASE_;
97194 +typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE;
97195 +
97196 +#ifdef PVR_SECURE_HANDLES
97197 +extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
97198 +
97199 +#define        KERNEL_HANDLE_BASE (gpsKernelHandleBase)
97200 +
97201 +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
97202 +
97203 +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
97204 +
97205 +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
97206 +
97207 +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle);
97208 +
97209 +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
97210 +
97211 +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
97212 +
97213 +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
97214 +
97215 +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
97216 +
97217 +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
97218 +
97219 +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize);
97220 +
97221 +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase);
97222 +
97223 +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase);
97224 +
97225 +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle);
97226 +
97227 +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase);
97228 +
97229 +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase);
97230 +
97231 +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
97232 +
97233 +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
97234 +
97235 +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase);
97236 +
97237 +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID);
97238 +
97239 +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID);
97240 +
97241 +#else  
97242 +
97243 +#define KERNEL_HANDLE_BASE IMG_NULL
97244 +
97245 +#ifdef INLINE_IS_PRAGMA
97246 +#pragma inline(PVRSRVAllocHandle)
97247 +#endif
97248 +static INLINE
97249 +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
97250 +{
97251 +       PVR_UNREFERENCED_PARAMETER(eType);
97252 +       PVR_UNREFERENCED_PARAMETER(eFlag);
97253 +       PVR_UNREFERENCED_PARAMETER(psBase);
97254 +
97255 +       *phHandle = pvData;
97256 +       return PVRSRV_OK;
97257 +}
97258 +
97259 +#ifdef INLINE_IS_PRAGMA
97260 +#pragma inline(PVRSRVAllocSubHandle)
97261 +#endif
97262 +static INLINE
97263 +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
97264 +{
97265 +       PVR_UNREFERENCED_PARAMETER(eType);
97266 +       PVR_UNREFERENCED_PARAMETER(eFlag);
97267 +       PVR_UNREFERENCED_PARAMETER(hParent);
97268 +       PVR_UNREFERENCED_PARAMETER(psBase);
97269 +
97270 +       *phHandle = pvData;
97271 +       return PVRSRV_OK;
97272 +}
97273 +
97274 +#ifdef INLINE_IS_PRAGMA
97275 +#pragma inline(PVRSRVFindHandle)
97276 +#endif
97277 +static INLINE
97278 +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
97279 +{
97280 +       PVR_UNREFERENCED_PARAMETER(eType);
97281 +       PVR_UNREFERENCED_PARAMETER(psBase);
97282 +
97283 +       *phHandle = pvData;
97284 +       return PVRSRV_OK;
97285 +}
97286 +
97287 +#ifdef INLINE_IS_PRAGMA
97288 +#pragma inline(PVRSRVLookupHandleAnyType)
97289 +#endif
97290 +static INLINE
97291 +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
97292 +{
97293 +       PVR_UNREFERENCED_PARAMETER(psBase);
97294 +       
97295 +       *peType = PVRSRV_HANDLE_TYPE_NONE;
97296 +
97297 +       *ppvData = hHandle;
97298 +       return PVRSRV_OK;
97299 +}
97300 +
97301 +#ifdef INLINE_IS_PRAGMA
97302 +#pragma inline(PVRSRVLookupHandle)
97303 +#endif
97304 +static INLINE
97305 +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
97306 +{
97307 +       PVR_UNREFERENCED_PARAMETER(psBase);
97308 +       PVR_UNREFERENCED_PARAMETER(eType);
97309 +
97310 +       *ppvData = hHandle;
97311 +       return PVRSRV_OK;
97312 +}
97313 +
97314 +#ifdef INLINE_IS_PRAGMA
97315 +#pragma inline(PVRSRVLookupSubHandle)
97316 +#endif
97317 +static INLINE
97318 +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
97319 +{
97320 +       PVR_UNREFERENCED_PARAMETER(psBase);
97321 +       PVR_UNREFERENCED_PARAMETER(eType);
97322 +       PVR_UNREFERENCED_PARAMETER(hAncestor);
97323 +
97324 +       *ppvData = hHandle;
97325 +       return PVRSRV_OK;
97326 +}
97327 +
97328 +#ifdef INLINE_IS_PRAGMA
97329 +#pragma inline(PVRSRVGetParentHandle)
97330 +#endif
97331 +static INLINE
97332 +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
97333 +{
97334 +       PVR_UNREFERENCED_PARAMETER(psBase);
97335 +       PVR_UNREFERENCED_PARAMETER(eType);
97336 +       PVR_UNREFERENCED_PARAMETER(hHandle);
97337 +
97338 +       *phParent = IMG_NULL;
97339 +
97340 +       return PVRSRV_OK;
97341 +}
97342 +
97343 +#ifdef INLINE_IS_PRAGMA
97344 +#pragma inline(PVRSRVLookupAndReleaseHandle)
97345 +#endif
97346 +static INLINE
97347 +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
97348 +{
97349 +       PVR_UNREFERENCED_PARAMETER(eType);
97350 +       PVR_UNREFERENCED_PARAMETER(psBase);
97351 +
97352 +       *ppvData = hHandle;
97353 +       return PVRSRV_OK;
97354 +}
97355 +
97356 +#ifdef INLINE_IS_PRAGMA
97357 +#pragma inline(PVRSRVReleaseHandle)
97358 +#endif
97359 +static INLINE
97360 +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
97361 +{
97362 +       PVR_UNREFERENCED_PARAMETER(hHandle);
97363 +       PVR_UNREFERENCED_PARAMETER(eType);
97364 +       PVR_UNREFERENCED_PARAMETER(psBase);
97365 +
97366 +       return PVRSRV_OK;
97367 +}
97368 +
97369 +#ifdef INLINE_IS_PRAGMA
97370 +#pragma inline(PVRSRVNewHandleBatch)
97371 +#endif
97372 +static INLINE
97373 +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
97374 +{
97375 +       PVR_UNREFERENCED_PARAMETER(psBase);
97376 +       PVR_UNREFERENCED_PARAMETER(ui32BatchSize);
97377 +
97378 +       return PVRSRV_OK;
97379 +}
97380 +
97381 +#ifdef INLINE_IS_PRAGMA
97382 +#pragma inline(PVRSRVCommitHandleBatch)
97383 +#endif
97384 +static INLINE
97385 +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
97386 +{
97387 +       PVR_UNREFERENCED_PARAMETER(psBase);
97388 +
97389 +       return PVRSRV_OK;
97390 +}
97391 +
97392 +#ifdef INLINE_IS_PRAGMA
97393 +#pragma inline(PVRSRVReleaseHandleBatch)
97394 +#endif
97395 +static INLINE
97396 +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
97397 +{
97398 +       PVR_UNREFERENCED_PARAMETER(psBase);
97399 +}
97400 +
97401 +#ifdef INLINE_IS_PRAGMA
97402 +#pragma inline(PVRSRVSetMaxHandle)
97403 +#endif
97404 +static INLINE
97405 +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
97406 +{
97407 +       PVR_UNREFERENCED_PARAMETER(psBase);
97408 +       PVR_UNREFERENCED_PARAMETER(ui32MaxHandle);
97409 +
97410 +       return PVRSRV_ERROR_NOT_SUPPORTED;
97411 +}
97412 +
97413 +#ifdef INLINE_IS_PRAGMA
97414 +#pragma inline(PVRSRVGetMaxHandle)
97415 +#endif
97416 +static INLINE
97417 +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
97418 +{
97419 +       PVR_UNREFERENCED_PARAMETER(psBase);
97420 +
97421 +       return 0;
97422 +}
97423 +
97424 +#ifdef INLINE_IS_PRAGMA
97425 +#pragma inline(PVRSRVEnableHandlePurging)
97426 +#endif
97427 +static INLINE
97428 +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
97429 +{
97430 +       PVR_UNREFERENCED_PARAMETER(psBase);
97431 +
97432 +       return PVRSRV_OK;
97433 +}
97434 +
97435 +#ifdef INLINE_IS_PRAGMA
97436 +#pragma inline(PVRSRVPurgeHandles)
97437 +#endif
97438 +static INLINE
97439 +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
97440 +{
97441 +       PVR_UNREFERENCED_PARAMETER(psBase);
97442 +
97443 +       return PVRSRV_OK;
97444 +}
97445 +
97446 +#ifdef INLINE_IS_PRAGMA
97447 +#pragma inline(PVRSRVAllocHandleBase)
97448 +#endif
97449 +static INLINE
97450 +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
97451 +{
97452 +       *ppsBase = IMG_NULL;
97453 +
97454 +       return PVRSRV_OK;
97455 +}
97456 +
97457 +#ifdef INLINE_IS_PRAGMA
97458 +#pragma inline(PVRSRVFreeHandleBase)
97459 +#endif
97460 +static INLINE
97461 +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
97462 +{
97463 +       PVR_UNREFERENCED_PARAMETER(psBase);
97464 +
97465 +       return PVRSRV_OK;
97466 +}
97467 +
97468 +#ifdef INLINE_IS_PRAGMA
97469 +#pragma inline(PVRSRVHandleInit)
97470 +#endif
97471 +static INLINE
97472 +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
97473 +{
97474 +       return PVRSRV_OK;
97475 +}
97476 +
97477 +#ifdef INLINE_IS_PRAGMA
97478 +#pragma inline(PVRSRVHandleDeInit)
97479 +#endif
97480 +static INLINE
97481 +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
97482 +{
97483 +       return PVRSRV_OK;
97484 +}
97485 +
97486 +#endif 
97487 +
97488 +#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \
97489 +       (IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag)
97490 +
97491 +#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \
97492 +       (IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent)
97493 +
97494 +#if defined (__cplusplus)
97495 +}
97496 +#endif
97497 +
97498 +#endif 
97499 +
97500 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/hash.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/hash.h
97501 new file mode 100644
97502 index 0000000..d45f4a9
97503 --- /dev/null
97504 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/hash.h
97505 @@ -0,0 +1,73 @@
97506 +/**********************************************************************
97507 + *
97508 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
97509 + * 
97510 + * This program is free software; you can redistribute it and/or modify it
97511 + * under the terms and conditions of the GNU General Public License,
97512 + * version 2, as published by the Free Software Foundation.
97513 + * 
97514 + * This program is distributed in the hope it will be useful but, except 
97515 + * as otherwise stated in writing, without any warranty; without even the 
97516 + * implied warranty of merchantability or fitness for a particular purpose. 
97517 + * See the GNU General Public License for more details.
97518 + * 
97519 + * You should have received a copy of the GNU General Public License along with
97520 + * this program; if not, write to the Free Software Foundation, Inc.,
97521 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
97522 + * 
97523 + * The full GNU General Public License is included in this distribution in
97524 + * the file called "COPYING".
97525 + *
97526 + * Contact Information:
97527 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
97528 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
97529 + *
97530 + ******************************************************************************/
97531 +
97532 +#ifndef _HASH_H_
97533 +#define _HASH_H_
97534 +
97535 +#include "img_types.h"
97536 +#include "osfunc.h"
97537 +
97538 +#if defined (__cplusplus)
97539 +extern "C" {
97540 +#endif
97541 +
97542 +typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
97543 +typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
97544 +
97545 +typedef struct _HASH_TABLE_ HASH_TABLE;
97546 +
97547 +IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
97548 +
97549 +IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
97550 +
97551 +HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
97552 +
97553 +HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
97554 +
97555 +IMG_VOID HASH_Delete (HASH_TABLE *pHash);
97556 +
97557 +IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
97558 +
97559 +IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
97560 +
97561 +IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
97562 +
97563 +IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
97564 +
97565 +IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
97566 +
97567 +IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
97568 +
97569 +#ifdef HASH_TRACE
97570 +IMG_VOID HASH_Dump (HASH_TABLE *pHash);
97571 +#endif
97572 +
97573 +#if defined (__cplusplus)
97574 +}
97575 +#endif
97576 +
97577 +#endif 
97578 +
97579 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/lists.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/lists.h
97580 new file mode 100644
97581 index 0000000..76d5af2
97582 --- /dev/null
97583 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/lists.h
97584 @@ -0,0 +1,176 @@
97585 +/**********************************************************************
97586 + *
97587 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
97588 + * 
97589 + * This program is free software; you can redistribute it and/or modify it
97590 + * under the terms and conditions of the GNU General Public License,
97591 + * version 2, as published by the Free Software Foundation.
97592 + * 
97593 + * This program is distributed in the hope it will be useful but, except 
97594 + * as otherwise stated in writing, without any warranty; without even the 
97595 + * implied warranty of merchantability or fitness for a particular purpose. 
97596 + * See the GNU General Public License for more details.
97597 + * 
97598 + * You should have received a copy of the GNU General Public License along with
97599 + * this program; if not, write to the Free Software Foundation, Inc.,
97600 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
97601 + * 
97602 + * The full GNU General Public License is included in this distribution in
97603 + * the file called "COPYING".
97604 + *
97605 + * Contact Information:
97606 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
97607 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
97608 + *
97609 + ******************************************************************************/
97610 +
97611 +#ifndef __LISTS_UTILS__
97612 +#define __LISTS_UTILS__
97613 +
97614 +#include <stdarg.h>
97615 +#include "img_types.h"
97616 +
97617 +#define DECLARE_LIST_FOR_EACH(TYPE) \
97618 +IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
97619 +
97620 +#define IMPLEMENT_LIST_FOR_EACH(TYPE) \
97621 +IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
97622 +{\
97623 +       while(psHead)\
97624 +       {\
97625 +               pfnCallBack(psHead);\
97626 +               psHead = psHead->psNext;\
97627 +       }\
97628 +}
97629 +
97630 +
97631 +#define DECLARE_LIST_FOR_EACH_VA(TYPE) \
97632 +IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...)
97633 +
97634 +#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \
97635 +IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \
97636 +{\
97637 +       va_list ap;\
97638 +       while(psHead)\
97639 +       {\
97640 +               va_start(ap, pfnCallBack);\
97641 +               pfnCallBack(psHead, ap);\
97642 +               psHead = psHead->psNext;\
97643 +               va_end(ap);\
97644 +       }\
97645 +}
97646 +
97647 +
97648 +#define DECLARE_LIST_ANY(TYPE) \
97649 +IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))
97650 +
97651 +#define IMPLEMENT_LIST_ANY(TYPE) \
97652 +IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\
97653 +{ \
97654 +       IMG_VOID *pResult;\
97655 +       TYPE *psNextNode;\
97656 +       pResult = IMG_NULL;\
97657 +       psNextNode = psHead;\
97658 +       while(psHead && !pResult)\
97659 +       {\
97660 +               psNextNode = psNextNode->psNext;\
97661 +               pResult = pfnCallBack(psHead);\
97662 +               psHead = psNextNode;\
97663 +       }\
97664 +       return pResult;\
97665 +}
97666 +
97667 +
97668 +#define DECLARE_LIST_ANY_VA(TYPE) \
97669 +IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)
97670 +
97671 +#define IMPLEMENT_LIST_ANY_VA(TYPE) \
97672 +IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
97673 +{\
97674 +       va_list ap;\
97675 +       TYPE *psNextNode;\
97676 +       IMG_VOID* pResult = IMG_NULL;\
97677 +       while(psHead && !pResult)\
97678 +       {\
97679 +               psNextNode = psHead->psNext;\
97680 +               va_start(ap, pfnCallBack);\
97681 +               pResult = pfnCallBack(psHead, ap);\
97682 +               va_end(ap);\
97683 +               psHead = psNextNode;\
97684 +       }\
97685 +       return pResult;\
97686 +}
97687 +
97688 +#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
97689 +RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))
97690 +
97691 +#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
97692 +RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\
97693 +{ \
97694 +       RTYPE result;\
97695 +       TYPE *psNextNode;\
97696 +       result = CONTINUE;\
97697 +       psNextNode = psHead;\
97698 +       while(psHead && result == CONTINUE)\
97699 +       {\
97700 +               psNextNode = psNextNode->psNext;\
97701 +               result = pfnCallBack(psHead);\
97702 +               psHead = psNextNode;\
97703 +       }\
97704 +       return result;\
97705 +}
97706 +
97707 +
97708 +#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
97709 +RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)
97710 +
97711 +#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
97712 +RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
97713 +{\
97714 +       va_list ap;\
97715 +       TYPE *psNextNode;\
97716 +       RTYPE result = CONTINUE;\
97717 +       while(psHead && result == CONTINUE)\
97718 +       {\
97719 +               psNextNode = psHead->psNext;\
97720 +               va_start(ap, pfnCallBack);\
97721 +               result = pfnCallBack(psHead, ap);\
97722 +               va_end(ap);\
97723 +               psHead = psNextNode;\
97724 +       }\
97725 +       return result;\
97726 +}
97727 +
97728 +
97729 +#define DECLARE_LIST_REMOVE(TYPE) \
97730 +IMG_VOID List_##TYPE##_Remove(TYPE *psNode)
97731 +
97732 +#define IMPLEMENT_LIST_REMOVE(TYPE) \
97733 +IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\
97734 +{\
97735 +       (*psNode->ppsThis)=psNode->psNext;\
97736 +       if(psNode->psNext)\
97737 +       {\
97738 +               psNode->psNext->ppsThis = psNode->ppsThis;\
97739 +       }\
97740 +}
97741 +
97742 +#define DECLARE_LIST_INSERT(TYPE) \
97743 +IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)
97744 +
97745 +#define IMPLEMENT_LIST_INSERT(TYPE) \
97746 +IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\
97747 +{\
97748 +       psNewNode->ppsThis = ppsHead;\
97749 +       psNewNode->psNext = *ppsHead;\
97750 +       *ppsHead = psNewNode;\
97751 +       if(psNewNode->psNext)\
97752 +       {\
97753 +               psNewNode->psNext->ppsThis = &(psNewNode->psNext);\
97754 +       }\
97755 +}
97756 +
97757 +
97758 +#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL)
97759 +
97760 +#endif
97761 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/metrics.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/metrics.h
97762 new file mode 100644
97763 index 0000000..2632f8d
97764 --- /dev/null
97765 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/metrics.h
97766 @@ -0,0 +1,130 @@
97767 +/**********************************************************************
97768 + *
97769 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
97770 + * 
97771 + * This program is free software; you can redistribute it and/or modify it
97772 + * under the terms and conditions of the GNU General Public License,
97773 + * version 2, as published by the Free Software Foundation.
97774 + * 
97775 + * This program is distributed in the hope it will be useful but, except 
97776 + * as otherwise stated in writing, without any warranty; without even the 
97777 + * implied warranty of merchantability or fitness for a particular purpose. 
97778 + * See the GNU General Public License for more details.
97779 + * 
97780 + * You should have received a copy of the GNU General Public License along with
97781 + * this program; if not, write to the Free Software Foundation, Inc.,
97782 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
97783 + * 
97784 + * The full GNU General Public License is included in this distribution in
97785 + * the file called "COPYING".
97786 + *
97787 + * Contact Information:
97788 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
97789 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
97790 + *
97791 + ******************************************************************************/
97792 +
97793 +#ifndef _METRICS_
97794 +#define _METRICS_
97795 +
97796 +
97797 +#if defined (__cplusplus)
97798 +extern "C" {
97799 +#endif
97800 +
97801 +
97802 +#if defined(DEBUG) || defined(TIMING)
97803 +
97804 +
97805 +typedef struct 
97806 +{
97807 +       IMG_UINT32 ui32Start;
97808 +       IMG_UINT32 ui32Stop;
97809 +       IMG_UINT32 ui32Total;
97810 +       IMG_UINT32 ui32Count;
97811 +} Temporal_Data;
97812 +
97813 +extern Temporal_Data asTimers[]; 
97814 +
97815 +extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID);
97816 +extern IMG_VOID   PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo);
97817 +extern IMG_VOID   PVRSRVOutputMetricTotals(IMG_VOID);
97818 +
97819 +
97820 +#define PVRSRV_TIMER_DUMMY                             0
97821 +
97822 +#define PVRSRV_TIMER_EXAMPLE_1                 1
97823 +#define PVRSRV_TIMER_EXAMPLE_2                 2
97824 +
97825 +
97826 +#define PVRSRV_NUM_TIMERS              (PVRSRV_TIMER_EXAMPLE_2 + 1)
97827 +
97828 +#define PVRSRV_TIME_START(X)   { \
97829 +                                                                       asTimers[X].ui32Count += 1; \
97830 +                                                                       asTimers[X].ui32Count |= 0x80000000L; \
97831 +                                                                       asTimers[X].ui32Start = PVRSRVTimeNow(); \
97832 +                                                                       asTimers[X].ui32Stop  = 0; \
97833 +                                                               }
97834 +
97835 +#define PVRSRV_TIME_SUSPEND(X) { \
97836 +                                                                       asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \
97837 +                                                               }
97838 +
97839 +#define PVRSRV_TIME_RESUME(X)  { \
97840 +                                                                       asTimers[X].ui32Start = PVRSRVTimeNow(); \
97841 +                                                               }
97842 +
97843 +#define PVRSRV_TIME_STOP(X)            { \
97844 +                                                                       asTimers[X].ui32Stop  += PVRSRVTimeNow() - asTimers[X].ui32Start; \
97845 +                                                                       asTimers[X].ui32Total += asTimers[X].ui32Stop; \
97846 +                                                                       asTimers[X].ui32Count &= 0x7FFFFFFFL; \
97847 +                                                               }
97848 +
97849 +#define PVRSRV_TIME_RESET(X)   { \
97850 +                                                                       asTimers[X].ui32Start = 0; \
97851 +                                                                       asTimers[X].ui32Stop  = 0; \
97852 +                                                                       asTimers[X].ui32Total = 0; \
97853 +                                                                       asTimers[X].ui32Count = 0; \
97854 +                                                               }
97855 +
97856 +
97857 +#if defined(__sh__)
97858 +
97859 +#define TST_REG   ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM))        
97860 +
97861 +#define TCOR_2    ((volatile IMG_UINT *)  (psDevInfo->pvSOCRegsBaseKM+28))     
97862 +#define TCNT_2    ((volatile IMG_UINT *)  (psDevInfo->pvSOCRegsBaseKM+32))     
97863 +#define TCR_2     ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36))     
97864 +
97865 +#define TIMER_DIVISOR  4
97866 +
97867 +#endif 
97868 +
97869 +
97870 +
97871 +
97872 +
97873 +#else 
97874 +
97875 +
97876 +
97877 +#define PVRSRV_TIME_START(X)
97878 +#define PVRSRV_TIME_SUSPEND(X)
97879 +#define PVRSRV_TIME_RESUME(X)
97880 +#define PVRSRV_TIME_STOP(X)
97881 +#define PVRSRV_TIME_RESET(X)
97882 +
97883 +#define PVRSRVSetupMetricTimers(X)
97884 +#define PVRSRVOutputMetricTotals()
97885 +
97886 +
97887 +
97888 +#endif 
97889 +
97890 +#if defined(__cplusplus)
97891 +}
97892 +#endif
97893 +
97894 +
97895 +#endif 
97896 +
97897 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osfunc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osfunc.h
97898 new file mode 100644
97899 index 0000000..7686c69
97900 --- /dev/null
97901 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osfunc.h
97902 @@ -0,0 +1,487 @@
97903 +/**********************************************************************
97904 + *
97905 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
97906 + * 
97907 + * This program is free software; you can redistribute it and/or modify it
97908 + * under the terms and conditions of the GNU General Public License,
97909 + * version 2, as published by the Free Software Foundation.
97910 + * 
97911 + * This program is distributed in the hope it will be useful but, except 
97912 + * as otherwise stated in writing, without any warranty; without even the 
97913 + * implied warranty of merchantability or fitness for a particular purpose. 
97914 + * See the GNU General Public License for more details.
97915 + * 
97916 + * You should have received a copy of the GNU General Public License along with
97917 + * this program; if not, write to the Free Software Foundation, Inc.,
97918 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
97919 + * 
97920 + * The full GNU General Public License is included in this distribution in
97921 + * the file called "COPYING".
97922 + *
97923 + * Contact Information:
97924 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
97925 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
97926 + *
97927 + ******************************************************************************/
97928 +
97929 +#ifdef DEBUG_RELEASE_BUILD
97930 +#pragma optimize( "", off )
97931 +#define DEBUG          1
97932 +#endif
97933 +
97934 +#ifndef __OSFUNC_H__
97935 +#define __OSFUNC_H__
97936 +
97937 +#if defined (__cplusplus)
97938 +extern "C" {
97939 +#endif
97940 +
97941 +#if defined(__linux__) && defined(__KERNEL__)
97942 +#include <linux/hardirq.h>
97943 +#include <linux/string.h>
97944 +#endif
97945 +
97946 +
97947 +       
97948 +       #define PVRSRV_PAGEABLE_SELECT          PVRSRV_OS_PAGEABLE_HEAP
97949 +
97950 +#define KERNEL_ID                      0xffffffffL
97951 +#define POWER_MANAGER_ID       0xfffffffeL
97952 +#define ISR_ID                         0xfffffffdL
97953 +#define TIMER_ID                       0xfffffffcL
97954 +
97955 +
97956 +#define HOST_PAGESIZE                  OSGetPageSize
97957 +#define HOST_PAGEMASK                  (~(HOST_PAGESIZE()-1))
97958 +#define HOST_PAGEALIGN(addr)   (((addr)+HOST_PAGESIZE()-1)&HOST_PAGEMASK)
97959 +
97960 +#define PVRSRV_OS_HEAP_MASK                    0xf 
97961 +#define PVRSRV_OS_PAGEABLE_HEAP                0x1 
97962 +#define PVRSRV_OS_NON_PAGEABLE_HEAP    0x2 
97963 +
97964 +
97965 +IMG_UINT32 OSClockus(IMG_VOID);
97966 +IMG_SIZE_T OSGetPageSize(IMG_VOID);
97967 +PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData,
97968 +                                                                IMG_UINT32 ui32Irq,
97969 +                                                                IMG_CHAR *pszISRName,
97970 +                                                                IMG_VOID *pvDeviceNode);
97971 +PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData);
97972 +PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq);
97973 +PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData);
97974 +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData);
97975 +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData);
97976 +IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_VOID* pvLinAddr);
97977 +IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
97978 +IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle);
97979 +IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
97980 +
97981 +PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle);
97982 +PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
97983 +
97984 +#if defined(SUPPORT_CPU_CACHED_BUFFERS)
97985 +IMG_VOID OSFlushCPUCacheKM(IMG_VOID);
97986 +IMG_VOID OSFlushCPUCacheRangeKM(IMG_VOID *pvRangeAddrStart,
97987 +                                                       IMG_VOID *pvRangeAddrEnd);
97988 +#endif
97989 +
97990 +#if defined(__linux__)
97991 +PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
97992 +                                                                       IMG_VOID *pvCpuVAddr, 
97993 +                                                                       IMG_SIZE_T ui32Bytes,
97994 +                                                                       IMG_UINT32 ui32Flags, 
97995 +                                                                       IMG_HANDLE *phOSMemHandle);
97996 +PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
97997 +                                                                       IMG_SIZE_T ui32Bytes,
97998 +                                                                       IMG_UINT32 ui32Flags,
97999 +                                                                       IMG_HANDLE hOSMemHandle);
98000 +#else  
98001 +#ifdef INLINE_IS_PRAGMA
98002 +#pragma inline(OSRegisterDiscontigMem)
98003 +#endif
98004 +static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
98005 +                                                                                                       IMG_VOID *pvCpuVAddr,
98006 +                                                                                                       IMG_SIZE_T ui32Bytes,
98007 +                                                                                                       IMG_UINT32 ui32Flags,
98008 +                                                                                                       IMG_HANDLE *phOSMemHandle)
98009 +{
98010 +       PVR_UNREFERENCED_PARAMETER(pBasePAddr);
98011 +       PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
98012 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98013 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98014 +       PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
98015 +
98016 +       return PVRSRV_ERROR_NOT_SUPPORTED;
98017 +}
98018 +
98019 +#ifdef INLINE_IS_PRAGMA
98020 +#pragma inline(OSUnRegisterDiscontigMem)
98021 +#endif
98022 +static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
98023 +                                                                                                       IMG_SIZE_T ui32Bytes,
98024 +                                                                                                       IMG_UINT32 ui32Flags,
98025 +                                                                                                       IMG_HANDLE hOSMemHandle)
98026 +{
98027 +       PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
98028 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98029 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98030 +       PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
98031 +
98032 +       return PVRSRV_ERROR_NOT_SUPPORTED;
98033 +}
98034 +#endif 
98035 +
98036 +
98037 +#if defined(__linux__)
98038 +#ifdef INLINE_IS_PRAGMA
98039 +#pragma inline(OSReserveDiscontigPhys)
98040 +#endif
98041 +static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
98042 +{
98043 +#if defined(__linux__) 
98044 +       *ppvCpuVAddr = IMG_NULL;
98045 +       return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle);   
98046 +#else
98047 +       extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr);
98048 +
98049 +       
98050 +       return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, ppvCpuVAddr, phOSMemHandle);
98051 +#endif 
98052 +}
98053 +
98054 +static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
98055 +{
98056 +#if defined(__linux__)
98057 +       OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
98058 +#endif
98059 +       
98060 +       return PVRSRV_OK;
98061 +}
98062 +#else  
98063 +
98064 +
98065 +#ifdef INLINE_IS_PRAGMA
98066 +#pragma inline(OSReserveDiscontigPhys)
98067 +#endif
98068 +static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
98069 +{
98070 +       PVR_UNREFERENCED_PARAMETER(pBasePAddr);
98071 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98072 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98073 +       PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr);
98074 +       PVR_UNREFERENCED_PARAMETER(phOSMemHandle);
98075 +
98076 +       return PVRSRV_ERROR_NOT_SUPPORTED;
98077 +}
98078 +
98079 +#ifdef INLINE_IS_PRAGMA
98080 +#pragma inline(OSUnReserveDiscontigPhys)
98081 +#endif
98082 +static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
98083 +{
98084 +       PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
98085 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98086 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98087 +       PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
98088 +
98089 +       return PVRSRV_ERROR_NOT_SUPPORTED;
98090 +}
98091 +#endif 
98092 +
98093 +PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
98094 +                                                       IMG_VOID *pvCpuVAddr,
98095 +                                                       IMG_SIZE_T ui32Bytes,
98096 +                                                       IMG_UINT32 ui32Flags,
98097 +                                                       IMG_HANDLE *phOSMemHandle);
98098 +PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr,
98099 +                                                       IMG_SIZE_T ui32Bytes,
98100 +                                                       IMG_UINT32 ui32Flags,
98101 +                                                       IMG_HANDLE hOSMemHandle);
98102 +
98103 +
98104 +
98105 +#if defined(__linux__)
98106 +PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
98107 +                                                          IMG_UINTPTR_T ui32ByteOffset,
98108 +                                                          IMG_SIZE_T ui32Bytes,
98109 +                                                          IMG_UINT32 ui32Flags,
98110 +                                                          IMG_HANDLE *phOSMemHandleRet);
98111 +PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags);
98112 +#else
98113 +#ifdef INLINE_IS_PRAGMA
98114 +#pragma inline(OSGetSubMemHandle)
98115 +#endif
98116 +static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
98117 +                                                                                        IMG_UINTPTR_T ui32ByteOffset,
98118 +                                                                                        IMG_SIZE_T ui32Bytes,
98119 +                                                                                        IMG_UINT32 ui32Flags,
98120 +                                                                                        IMG_HANDLE *phOSMemHandleRet)
98121 +{
98122 +       PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
98123 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98124 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98125 +
98126 +       *phOSMemHandleRet = hOSMemHandle;
98127 +       return PVRSRV_OK;
98128 +}
98129 +
98130 +static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags)
98131 +{
98132 +       PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
98133 +       PVR_UNREFERENCED_PARAMETER(ui32Flags);
98134 +       return PVRSRV_OK;
98135 +}
98136 +#endif
98137 +
98138 +IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID);
98139 +IMG_UINT32 OSGetCurrentThreadID( IMG_VOID );
98140 +IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
98141 +
98142 +PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_UINT32 ui32PageSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc);
98143 +PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc);
98144 +
98145 +
98146 +#ifdef PVRSRV_LOG_MEMORY_ALLOCS
98147 +       #define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \
98148 +               (PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \
98149 +                       OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
98150 +
98151 +       #define OSAllocPages(flags, size, pageSize, linAddr, pageAlloc) \
98152 +               (PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \
98153 +                       OSAllocPages_Impl(flags, size, pageSize, linAddr, pageAlloc))
98154 +               
98155 +       #define OSFreeMem(flags, size, linAddr, blockAlloc) \
98156 +               (PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \
98157 +                       OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
98158 +#else
98159 +       #define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \
98160 +               OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
98161 +       
98162 +       #define OSAllocPages OSAllocPages_Impl
98163 +       
98164 +       #define OSFreeMem(flags, size, linAddr, blockAlloc) \
98165 +                       OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
98166 +#endif
98167
98168 +#ifdef PVRSRV_DEBUG_OS_MEMORY
98169 +
98170 +       PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
98171 +                                                                               IMG_UINT32 ui32Size,
98172 +                                                                               IMG_PVOID *ppvCpuVAddr,
98173 +                                                                               IMG_HANDLE *phBlockAlloc,
98174 +                                                                               IMG_CHAR *pszFilename,
98175 +                                                                               IMG_UINT32 ui32Line);
98176 +       
98177 +       PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
98178 +                                                                        IMG_UINT32 ui32Size,
98179 +                                                                        IMG_PVOID pvCpuVAddr,
98180 +                                                                        IMG_HANDLE hBlockAlloc,
98181 +                                                                        IMG_CHAR *pszFilename,
98182 +                                                                        IMG_UINT32 ui32Line);
98183 +
98184 +
98185 +       typedef struct
98186 +       {       
98187 +               IMG_UINT8 sGuardRegionBefore[8];
98188 +               IMG_CHAR sFileName[128];
98189 +               IMG_UINT32 uLineNo;
98190 +               IMG_SIZE_T uSize;
98191 +               IMG_SIZE_T uSizeParityCheck;
98192 +               enum valid_tag
98193 +               {       isFree = 0x277260FF,
98194 +                       isAllocated = 0x260511AA
98195 +               } eValid;
98196 +       } OSMEM_DEBUG_INFO;
98197 +       
98198 +       #define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO)) 
98199 +       #define TEST_BUFFER_PADDING_AFTER  (8) 
98200 +       #define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER)
98201 +#else
98202 +       #define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations
98203 +       #define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations
98204 +#endif
98205
98206 +#if defined(__linux__) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
98207 +       PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
98208 +       PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
98209 +       
98210 +       #define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl
98211 +       #define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl
98212 +#else
98213 +       PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc);
98214 +       PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc);
98215 +       
98216 +       #define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
98217 +               OSAllocMem_Impl(flags, size, addr, blockAlloc)
98218 +       #define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
98219 +               OSFreeMem_Impl(flags, size, addr, blockAlloc)
98220 +#endif
98221 +
98222 +
98223 +
98224 +#if defined(__linux__)
98225 +IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_SIZE_T ui32ByteOffset);
98226 +#else
98227 +#ifdef INLINE_IS_PRAGMA
98228 +#pragma inline(OSMemHandleToCpuPAddr)
98229 +#endif
98230 +static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_SIZE_T ui32ByteOffset)
98231 +{
98232 +       IMG_CPU_PHYADDR sCpuPAddr;
98233 +       PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
98234 +       PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
98235 +       sCpuPAddr.uiAddr = 0;
98236 +       return sCpuPAddr;
98237 +}
98238 +#endif
98239 +PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData);
98240 +PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData);
98241 +IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc);
98242 +IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...);
98243 +#define OSStringLength(pszString) strlen(pszString)
98244 +
98245 +PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName,
98246 +                                                                PVRSRV_EVENTOBJECT *psEventObject);
98247 +PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject);
98248 +PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM);
98249 +PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM);
98250 +PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject,
98251 +                                                                                       IMG_HANDLE *phOSEvent);
98252 +PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject,
98253 +                                                                                       IMG_HANDLE hOSEventKM);
98254 +
98255 +
98256 +PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr);
98257 +PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr);
98258 +
98259 +IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T ui32Size,IMG_HANDLE *phMemBlock);
98260 +IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess);
98261 +IMG_VOID  OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess);
98262 +
98263 +IMG_VOID  UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_SIZE_T ui32Size, IMG_HANDLE hMemBlock);
98264 +
98265 +PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie,
98266 +                                                                 IMG_SYS_PHYADDR sCPUPhysAddr,
98267 +                                                                 IMG_SIZE_T uiSizeInBytes,
98268 +                                                                 IMG_UINT32 ui32CacheFlags,
98269 +                                                                 IMG_PVOID *ppvUserAddr,
98270 +                                                                 IMG_SIZE_T *puiActualSize,
98271 +                                                                 IMG_HANDLE hMappingHandle);
98272 +
98273 +PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie,
98274 +                                                                       IMG_PVOID pvUserAddr,
98275 +                                                                       IMG_PVOID pvProcess);
98276 +
98277 +PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
98278 +PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
98279 +IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
98280 +PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource);
98281 +PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource);
98282 +IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID);
98283 +IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
98284 +IMG_VOID OSReleaseThreadQuanta(IMG_VOID);
98285 +IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg);
98286 +IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value);
98287 +
98288 +#ifndef OSReadHWReg
98289 +IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
98290 +#endif
98291 +#ifndef OSWriteHWReg
98292 +IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
98293 +#endif
98294 +
98295 +typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*);
98296 +IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout);
98297 +PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer);
98298 +PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer);
98299 +PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer);
98300 +
98301 +PVRSRV_ERROR OSGetSysMemSize(IMG_SIZE_T *pui32Bytes);
98302 +
98303 +typedef enum _HOST_PCI_INIT_FLAGS_
98304 +{
98305 +       HOST_PCI_INIT_FLAG_BUS_MASTER   = 0x00000001,
98306 +       HOST_PCI_INIT_FLAG_MSI          = 0x00000002,
98307 +       HOST_PCI_INIT_FLAG_FORCE_I32    = 0x7fffffff
98308 +} HOST_PCI_INIT_FLAGS;
98309 +
98310 +struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_;
98311 +typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE;
98312 +
98313 +PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags);
98314 +PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags);
98315 +PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
98316 +PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ);
98317 +IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
98318 +IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
98319 +IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
98320 +PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
98321 +PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index);
98322 +PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
98323 +PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI);
98324 +
98325 +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData);
98326 +
98327 +IMG_VOID OSPanic(IMG_VOID);
98328 +
98329 +IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID);
98330 +
98331 +typedef enum _img_verify_test
98332 +{
98333 +       PVR_VERIFY_WRITE = 0,
98334 +       PVR_VERIFY_READ
98335 +} IMG_VERIFY_TEST;
98336 +
98337 +IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T ui32Bytes);
98338 +
98339 +PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
98340 +PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
98341 +
98342 +#if defined(__linux__)
98343 +PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, 
98344 +                                                                       IMG_SIZE_T ui32Bytes, 
98345 +                                                                       IMG_SYS_PHYADDR *psSysPAddr,
98346 +                                                                       IMG_HANDLE *phOSWrapMem,
98347 +                                                                       IMG_BOOL bWrapWorkaround);
98348 +PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem);
98349 +#else
98350 +#ifdef INLINE_IS_PRAGMA
98351 +#pragma inline(OSAcquirePhysPageAddr)
98352 +#endif
98353 +static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, 
98354 +                                                                                               IMG_SIZE_T ui32Bytes, 
98355 +                                                                                               IMG_SYS_PHYADDR *psSysPAddr,
98356 +                                                                                               IMG_HANDLE *phOSWrapMem,
98357 +                                                                                               IMG_BOOL bWrapWorkaround)
98358 +{
98359 +       PVR_UNREFERENCED_PARAMETER(pvCPUVAddr);
98360 +       PVR_UNREFERENCED_PARAMETER(ui32Bytes);
98361 +       PVR_UNREFERENCED_PARAMETER(psSysPAddr);
98362 +       PVR_UNREFERENCED_PARAMETER(phOSWrapMem);
98363 +       PVR_UNREFERENCED_PARAMETER(bWrapWorkaround);
98364 +       return PVRSRV_OK;       
98365 +}
98366 +#ifdef INLINE_IS_PRAGMA
98367 +#pragma inline(OSReleasePhysPageAddr)
98368 +#endif
98369 +static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
98370 +{
98371 +       PVR_UNREFERENCED_PARAMETER(hOSWrapMem);
98372 +       return PVRSRV_OK;       
98373 +}
98374 +#endif
98375 +                                                                       
98376 +#if defined(__linux__) && defined(__KERNEL__)
98377 +#define        OS_SUPPORTS_IN_LISR
98378 +static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData)
98379 +{
98380 +       return in_irq();
98381 +}
98382 +#endif
98383 +
98384 +#if defined (__cplusplus)
98385 +}
98386 +#endif
98387 +
98388 +#endif 
98389 +
98390 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osperproc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osperproc.h
98391 new file mode 100644
98392 index 0000000..80a912f
98393 --- /dev/null
98394 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/osperproc.h
98395 @@ -0,0 +1,76 @@
98396 +/**********************************************************************
98397 + *
98398 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
98399 + * 
98400 + * This program is free software; you can redistribute it and/or modify it
98401 + * under the terms and conditions of the GNU General Public License,
98402 + * version 2, as published by the Free Software Foundation.
98403 + * 
98404 + * This program is distributed in the hope it will be useful but, except 
98405 + * as otherwise stated in writing, without any warranty; without even the 
98406 + * implied warranty of merchantability or fitness for a particular purpose. 
98407 + * See the GNU General Public License for more details.
98408 + * 
98409 + * You should have received a copy of the GNU General Public License along with
98410 + * this program; if not, write to the Free Software Foundation, Inc.,
98411 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
98412 + * 
98413 + * The full GNU General Public License is included in this distribution in
98414 + * the file called "COPYING".
98415 + *
98416 + * Contact Information:
98417 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
98418 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
98419 + *
98420 + ******************************************************************************/
98421 +
98422 +#ifndef __OSPERPROC_H__
98423 +#define __OSPERPROC_H__
98424 +
98425 +#if defined (__cplusplus)
98426 +extern "C" {
98427 +#endif
98428 +
98429 +#if defined(__linux__)
98430 +PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData);
98431 +PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
98432 +
98433 +PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
98434 +#else  
98435 +#ifdef INLINE_IS_PRAGMA
98436 +#pragma inline(OSPerProcessPrivateDataInit)
98437 +#endif
98438 +static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
98439 +{
98440 +       PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
98441 +
98442 +       return PVRSRV_OK;
98443 +}
98444 +
98445 +#ifdef INLINE_IS_PRAGMA
98446 +#pragma inline(OSPerProcessPrivateDataDeInit)
98447 +#endif
98448 +static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
98449 +{
98450 +       PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
98451 +
98452 +       return PVRSRV_OK;
98453 +}
98454 +
98455 +#ifdef INLINE_IS_PRAGMA
98456 +#pragma inline(OSPerProcessSetHandleOptions)
98457 +#endif
98458 +static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
98459 +{
98460 +       PVR_UNREFERENCED_PARAMETER(psHandleBase);
98461 +
98462 +       return PVRSRV_OK;
98463 +}
98464 +#endif 
98465 +
98466 +#if defined (__cplusplus)
98467 +}
98468 +#endif
98469 +
98470 +#endif 
98471 +
98472 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_km.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_km.h
98473 new file mode 100644
98474 index 0000000..c780e22
98475 --- /dev/null
98476 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_km.h
98477 @@ -0,0 +1,451 @@
98478 +/**********************************************************************
98479 + *
98480 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
98481 + * 
98482 + * This program is free software; you can redistribute it and/or modify it
98483 + * under the terms and conditions of the GNU General Public License,
98484 + * version 2, as published by the Free Software Foundation.
98485 + * 
98486 + * This program is distributed in the hope it will be useful but, except 
98487 + * as otherwise stated in writing, without any warranty; without even the 
98488 + * implied warranty of merchantability or fitness for a particular purpose. 
98489 + * See the GNU General Public License for more details.
98490 + * 
98491 + * You should have received a copy of the GNU General Public License along with
98492 + * this program; if not, write to the Free Software Foundation, Inc.,
98493 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
98494 + * 
98495 + * The full GNU General Public License is included in this distribution in
98496 + * the file called "COPYING".
98497 + *
98498 + * Contact Information:
98499 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
98500 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
98501 + *
98502 + ******************************************************************************/
98503 +
98504 +#ifndef _PDUMP_KM_H_
98505 +#define _PDUMP_KM_H_
98506 +
98507 +#if (defined(LINUX) && (defined(SUPPORT_SGX) || defined(SUPPORT_MSVDX)))
98508 +
98509 +#define SGX_SUPPORT_COMMON_PDUMP
98510 +
98511 +#if defined(SGX_SUPPORT_COMMON_PDUMP)
98512 +#include <pdump_osfunc.h>
98513 +#endif
98514 +#endif 
98515 +
98516 +#if defined(__cplusplus)
98517 +extern "C" {
98518 +#endif
98519 +
98520 +#define PDUMP_FLAGS_NEVER                      0x08000000UL
98521 +#define PDUMP_FLAGS_TOOUT2MEM          0x10000000UL
98522 +#define PDUMP_FLAGS_LASTFRAME          0x20000000UL
98523 +#define PDUMP_FLAGS_RESETLFBUFFER      0x40000000UL
98524 +#define PDUMP_FLAGS_CONTINUOUS         0x80000000UL
98525 +
98526 +#define PDUMP_PD_UNIQUETAG                     (IMG_HANDLE)0
98527 +#define PDUMP_PT_UNIQUETAG                     (IMG_HANDLE)0
98528 +
98529 +#define PDUMP_STREAM_PARAM2                    0
98530 +#define PDUMP_STREAM_SCRIPT2           1
98531 +#define PDUMP_STREAM_DRIVERINFO                2
98532 +#define PDUMP_NUM_STREAMS                      3
98533 +
98534 +
98535 +#ifndef PDUMP
98536 +#define MAKEUNIQUETAG(hMemInfo)        (0)
98537 +#endif
98538 +
98539 +#ifdef PDUMP
98540 +
98541 +#define MAKEUNIQUETAG(hMemInfo)        (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)hMemInfo)->sMemBlk.hBuffer))->pMapping)
98542 +
98543 +       IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
98544 +                                                                                 IMG_UINT32                    ui32Offset,
98545 +                                                                                 IMG_UINT32                    ui32Value,
98546 +                                                                                 IMG_UINT32                    ui32Mask,
98547 +                                                                                 PDUMP_POLL_OPERATOR   eOperator,
98548 +                                                                                 IMG_UINT32                    ui32Flags,
98549 +                                                                                 IMG_HANDLE                    hUniqueTag);
98550 +
98551 +       IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData,
98552 +                                                                          IMG_PVOID                    pvAltLinAddr,
98553 +                                                                          IMG_PVOID                    pvLinAddr,
98554 +                                                                          PVRSRV_KERNEL_MEM_INFO       *psMemInfo,
98555 +                                                                          IMG_UINT32                   ui32Offset,
98556 +                                                                          IMG_UINT32                   ui32Bytes,
98557 +                                                                          IMG_UINT32                   ui32Flags,
98558 +                                                                          IMG_HANDLE                   hUniqueTag);
98559 +
98560 +       IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID                    pvAltLinAddr,
98561 +                                                                          PVRSRV_KERNEL_MEM_INFO       *psMemInfo,
98562 +                                                                          IMG_UINT32                   ui32Offset,
98563 +                                                                          IMG_UINT32                   ui32Bytes,
98564 +                                                                          IMG_UINT32                   ui32Flags,
98565 +                                                                          IMG_HANDLE                   hUniqueTag);
98566 +       PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_TYPE eDeviceType,
98567 +                                                                IMG_DEV_PHYADDR                *pPages,
98568 +                                                                IMG_UINT32                     ui32NumPages,
98569 +                                                                IMG_DEV_VIRTADDR       sDevAddr,
98570 +                                                                IMG_UINT32                     ui32Start,
98571 +                                                                IMG_UINT32                     ui32Length,
98572 +                                                                IMG_UINT32                     ui32Flags,
98573 +                                                                IMG_HANDLE                     hUniqueTag);
98574 +
98575 +       PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE     eDeviceType,
98576 +                                                        IMG_CPU_VIRTADDR       pvLinAddr,
98577 +                                                        IMG_UINT32                     ui32Bytes,
98578 +                                                        IMG_UINT32                     ui32Flags,
98579 +                                                        IMG_BOOL                       bInitialisePages,
98580 +                                                        IMG_HANDLE                     hUniqueTag1,
98581 +                                                        IMG_HANDLE                     hUniqueTag2);
98582 +       IMG_VOID PDumpInitCommon(IMG_VOID);
98583 +       IMG_VOID PDumpDeInitCommon(IMG_VOID);
98584 +       IMG_VOID PDumpInit(IMG_VOID);
98585 +       IMG_VOID PDumpDeInit(IMG_VOID);
98586 +       PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID);
98587 +       PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID);
98588 +       IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame);
98589 +       IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags);
98590 +       IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags);
98591 +
98592 +       PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_UINT32 ui32RegAddr,
98593 +                                                                        IMG_UINT32 ui32RegValue,
98594 +                                                                        IMG_UINT32 ui32Flags);
98595 +       PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_UINT32 ui32RegAddr,
98596 +                                                                               IMG_UINT32 ui32RegValue,
98597 +                                                                               IMG_UINT32 ui32Mask,
98598 +                                                                               IMG_UINT32 ui32Flags);
98599 +       PVRSRV_ERROR PDumpRegPolKM(IMG_UINT32 ui32RegAddr,
98600 +                                                          IMG_UINT32 ui32RegValue,
98601 +                                                          IMG_UINT32 ui32Mask);
98602 +
98603 +       IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(IMG_CHAR *pszFileName,
98604 +                                                                                 IMG_UINT32 ui32FileOffset,
98605 +                                                                                 IMG_UINT32 ui32Width,
98606 +                                                                                 IMG_UINT32 ui32Height,
98607 +                                                                                 IMG_UINT32 ui32StrideInBytes,
98608 +                                                                                 IMG_DEV_VIRTADDR sDevBaseAddr,
98609 +                                                                                 IMG_UINT32 ui32Size,
98610 +                                                                                 PDUMP_PIXEL_FORMAT ePixelFormat,
98611 +                                                                                 PDUMP_MEM_FORMAT eMemFormat,
98612 +                                                                                 IMG_UINT32 ui32PDumpFlags);
98613 +       IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszFileName,
98614 +                                                                                  IMG_UINT32 ui32FileOffset,
98615 +                                                                                  IMG_UINT32 ui32Address,
98616 +                                                                                  IMG_UINT32 ui32Size,
98617 +                                                                                  IMG_UINT32 ui32PDumpFlags);
98618 +
98619 +       IMG_BOOL PDumpIsSuspended(IMG_VOID);
98620 +
98621 +#if defined(SGX_SUPPORT_COMMON_PDUMP) || !defined(SUPPORT_VGX)
98622 +       
98623 +       PVRSRV_ERROR PDumpRegKM(IMG_UINT32              dwReg,
98624 +                                                       IMG_UINT32              dwData);
98625 +       PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...);
98626 +       PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32   ui32Flags,
98627 +                                                                          IMG_CHAR*    pszFormat,
98628 +                                                                          ...);
98629 +
98630 +       PVRSRV_ERROR PDumpPDReg(IMG_UINT32      ui32Reg,
98631 +                                                       IMG_UINT32      ui32dwData,
98632 +                                                       IMG_HANDLE      hUniqueTag);
98633 +       PVRSRV_ERROR PDumpPDRegWithFlags(IMG_UINT32             ui32Reg,
98634 +                                                                        IMG_UINT32             ui32Data,
98635 +                                                                        IMG_UINT32             ui32Flags,
98636 +                                                                        IMG_HANDLE             hUniqueTag);
98637 +#else
98638 +       IMG_VOID PDumpRegKM(IMG_UINT32          dwReg,
98639 +                                                       IMG_UINT32              dwData);
98640 +       IMG_VOID PDumpComment(IMG_CHAR* pszFormat, ...);
98641 +       IMG_VOID PDumpCommentWithFlags(IMG_UINT32       ui32Flags,
98642 +                                                                          IMG_CHAR*    pszFormat,
98643 +                                                                          ...);
98644 +
98645 +       
98646 +       IMG_VOID PDumpPDReg(IMG_UINT32  ui32Reg,
98647 +                                                       IMG_UINT32      ui32dwData,
98648 +                                                       IMG_HANDLE      hUniqueTag);
98649 +       IMG_VOID PDumpPDRegWithFlags(IMG_UINT32         ui32Reg,
98650 +                                                                        IMG_UINT32             ui32Data,
98651 +                                                                        IMG_UINT32             ui32Flags,
98652 +                                                                        IMG_HANDLE             hUniqueTag);
98653 +#endif 
98654 +
98655 +       IMG_VOID PDumpMsvdxRegRead(const IMG_CHAR* const        pRegRegion,
98656 +                                                          const IMG_UINT32             dwRegOffset);
98657 +
98658 +       IMG_VOID PDumpMsvdxRegWrite(const IMG_CHAR* const       pRegRegion,
98659 +                                                               const IMG_UINT32                dwRegOffset,
98660 +                                                               const IMG_UINT32                dwData);
98661 +
98662 +       PVRSRV_ERROR PDumpMsvdxRegPol(const IMG_CHAR* const     pRegRegion,
98663 +                                                                 const IMG_UINT32              ui32Offset,
98664 +                                                                 const IMG_UINT32              ui32CheckFuncIdExt,
98665 +                                                                 const IMG_UINT32              ui32RequValue,
98666 +                                                                 const IMG_UINT32              ui32Enable,
98667 +                                                                 const IMG_UINT32              ui32PollCount,
98668 +                                                                 const IMG_UINT32              ui32TimeOut);
98669 +
98670 +       PVRSRV_ERROR  PDumpMsvdxWriteRef(const IMG_CHAR* const  pRegRegion,
98671 +                                                                        const IMG_UINT32               ui32VLROffset,
98672 +                                                                        const IMG_UINT32               ui32Physical );
98673 +
98674 +       IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID);
98675 +       IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID);
98676 +
98677 +       IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_TYPE        eDeviceType,
98678 +                                                                 IMG_UINT32                    ui32DevVAddr,
98679 +                                                                 IMG_PUINT32                   pui32PhysPages,
98680 +                                                                 IMG_UINT32                    ui32NumPages,
98681 +                                                                 IMG_HANDLE                    hUniqueTag);
98682 +       PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
98683 +                                                                       IMG_CHAR *pszMemSpace,
98684 +                                                                       IMG_UINT32 *pui32MMUContextID,
98685 +                                                                       IMG_UINT32 ui32MMUType,
98686 +                                                                       IMG_HANDLE hUniqueTag1,
98687 +                                                                       IMG_VOID *pvPDCPUAddr);
98688 +       PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
98689 +                                                                       IMG_CHAR *pszMemSpace,
98690 +                                                                       IMG_UINT32 ui32MMUContextID,
98691 +                                                                       IMG_UINT32 ui32MMUType);
98692 +
98693 +       PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
98694 +                                                                  IMG_UINT32 ui32Offset,
98695 +                                                                  IMG_DEV_PHYADDR sPDDevPAddr,
98696 +                                                                  IMG_HANDLE hUniqueTag1,
98697 +                                                                  IMG_HANDLE hUniqueTag2);
98698 +
98699 +       IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame);
98700 +
98701 +
98702 +#if defined(LINUX)
98703 +#define COMMON_PDUMP_OS_SUPPORT
98704 +#endif
98705 +
98706 +#if defined (COMMON_PDUMP_OS_SUPPORT) && !defined(SUPPORT_VGX)
98707 +       
98708 +       PVRSRV_ERROR PDumpTASignatureRegisters(IMG_UINT32       ui32DumpFrameNum,
98709 +                                                                  IMG_UINT32   ui32TAKickCount,
98710 +                                                                  IMG_BOOL             bLastFrame,
98711 +                                                                  IMG_UINT32 *pui32Registers,
98712 +                                                                  IMG_UINT32 ui32NumRegisters);
98713 +
98714 +       PVRSRV_ERROR PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum,
98715 +                                                                                                                       IMG_BOOL bLastFrame,
98716 +                                                                                                                       IMG_UINT32 *pui32Registers,
98717 +                                                                                                                       IMG_UINT32 ui32NumRegisters);
98718 +
98719 +       PVRSRV_ERROR PDumpCounterRegisters(IMG_UINT32 ui32DumpFrameNum,
98720 +                                       IMG_BOOL                bLastFrame,
98721 +                                       IMG_UINT32 *pui32Registers,
98722 +                                       IMG_UINT32 ui32NumRegisters);
98723 +
98724 +       PVRSRV_ERROR PDumpRegRead(const IMG_UINT32 dwRegOffset, IMG_UINT32      ui32Flags);
98725 +
98726 +       PVRSRV_ERROR PDumpCycleCountRegRead(const IMG_UINT32 dwRegOffset, IMG_BOOL bLastFrame);
98727 +
98728 +       PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
98729 +       PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
98730 +
98731 +       PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_TYPE        eDeviceType,
98732 +                                                         IMG_UINT32                    ui32DevVAddr,
98733 +                                                         IMG_CPU_VIRTADDR              pvLinAddr,
98734 +                                                         IMG_HANDLE                    hOSMemHandle,
98735 +                                                         IMG_UINT32                    ui32NumBytes,
98736 +                                                         IMG_UINT32                    ui32PageSize,
98737 +                                                         IMG_HANDLE                    hUniqueTag);
98738 +       PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_TYPE    eDeviceType,
98739 +                                                                 IMG_CPU_VIRTADDR              pvLinAddr,
98740 +                                                                 IMG_UINT32                    ui32NumBytes,
98741 +                                                                 IMG_HANDLE                    hUniqueTag);
98742 +       PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_    *psBMHeap,
98743 +                                                       IMG_DEV_VIRTADDR        sDevVAddr,
98744 +                                                       IMG_UINT32                      ui32NumBytes,
98745 +                                                       IMG_UINT32                      ui32PageSize,
98746 +                                                       IMG_HANDLE              hUniqueTag,
98747 +                                                       IMG_BOOL                        bInterleaved);
98748 +       PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_TYPE      eDeviceType,
98749 +                                                               IMG_CPU_VIRTADDR        pvLinAddr,
98750 +                                                               IMG_UINT32                      ui32NumBytes,
98751 +                                                               IMG_HANDLE                      hUniqueTag);
98752 +
98753 +       IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(IMG_CHAR                        *pszFileName,
98754 +                                                                               IMG_UINT32                      ui32FileOffset,
98755 +                                                                               IMG_DEV_VIRTADDR        sDevBaseAddr,
98756 +                                                                               IMG_UINT32                      ui32Size,
98757 +                                                                               IMG_UINT32                      ui32PDumpFlags);
98758 +
98759 +       PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO   psROffMemInfo,
98760 +                                 IMG_UINT32                            ui32ROffOffset,
98761 +                                 IMG_UINT32                            ui32WPosVal,
98762 +                                 IMG_UINT32                            ui32PacketSize,
98763 +                                 IMG_UINT32                            ui32BufferSize,
98764 +                                 IMG_UINT32                            ui32Flags,
98765 +                                 IMG_HANDLE                            hUniqueTag);
98766 +
98767 +#else 
98768 +       IMG_VOID PDumpTASignatureRegisters(IMG_UINT32   ui32DumpFrameNum,
98769 +                          IMG_UINT32   ui32TAKickCount,
98770 +                          IMG_BOOL             bLastFrame,
98771 +                          IMG_UINT32 *pui32Registers,
98772 +                          IMG_UINT32 ui32NumRegisters);
98773 +       IMG_VOID PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum,
98774 +                       IMG_BOOL bLastFrame,
98775 +                       IMG_UINT32 *pui32Registers,
98776 +                       IMG_UINT32 ui32NumRegisters);
98777 +       IMG_VOID PDumpCounterRegisters(IMG_UINT32 ui32DumpFrameNum,
98778 +                       IMG_BOOL                bLastFrame,
98779 +                       IMG_UINT32 *pui32Registers,
98780 +                       IMG_UINT32 ui32NumRegisters);
98781 +
98782 +       IMG_VOID PDumpRegRead(const IMG_UINT32 dwRegOffset, IMG_UINT32  ui32Flags);
98783 +       IMG_VOID PDumpCycleCountRegRead(const IMG_UINT32 dwRegOffset, IMG_BOOL bLastFrame);
98784 +
98785 +       IMG_VOID PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
98786 +       IMG_VOID PDumpIDL(IMG_UINT32 ui32Clocks);
98787 +
98788 +       
98789 +       IMG_VOID PDumpMallocPages(PVRSRV_DEVICE_TYPE    eDeviceType,
98790 +                                                         IMG_UINT32                    ui32DevVAddr,
98791 +                                                         IMG_CPU_VIRTADDR              pvLinAddr,
98792 +                                                         IMG_HANDLE                    hOSMemHandle,
98793 +                                                         IMG_UINT32                    ui32NumBytes,
98794 +                                                         IMG_UINT32                    ui32PageSize,
98795 +                                                         IMG_HANDLE                    hUniqueTag);
98796 +       IMG_VOID PDumpMallocPageTable(PVRSRV_DEVICE_TYPE        eDeviceType,
98797 +                                                                 IMG_CPU_VIRTADDR              pvLinAddr,
98798 +                                                                 IMG_UINT32                    ui32NumBytes,
98799 +                                                                 IMG_HANDLE                    hUniqueTag);
98800 +       IMG_VOID PDumpFreePages(struct _BM_HEAP_        *psBMHeap,
98801 +                                                       IMG_DEV_VIRTADDR        sDevVAddr,
98802 +                                                       IMG_UINT32                      ui32NumBytes,
98803 +                                                       IMG_UINT32                      ui32PageSize,
98804 +                                                       IMG_HANDLE              hUniqueTag,
98805 +                                                       IMG_BOOL                        bInterleaved);
98806 +       IMG_VOID PDumpFreePageTable(PVRSRV_DEVICE_TYPE  eDeviceType,
98807 +                                                               IMG_CPU_VIRTADDR        pvLinAddr,
98808 +                                                               IMG_UINT32                      ui32NumBytes,
98809 +                                                               IMG_HANDLE                      hUniqueTag);
98810 +
98811 +       IMG_IMPORT IMG_VOID PDumpHWPerfCBKM(IMG_CHAR                    *pszFileName,
98812 +                                                                               IMG_UINT32                      ui32FileOffset,
98813 +                                                                               IMG_DEV_VIRTADDR        sDevBaseAddr,
98814 +                                                                               IMG_UINT32                      ui32Size,
98815 +                                                                               IMG_UINT32                      ui32PDumpFlags);
98816 +
98817 +       IMG_VOID PDumpCBP(PPVRSRV_KERNEL_MEM_INFO       psROffMemInfo,
98818 +                                 IMG_UINT32                            ui32ROffOffset,
98819 +                                 IMG_UINT32                            ui32WPosVal,
98820 +                                 IMG_UINT32                            ui32PacketSize,
98821 +                                 IMG_UINT32                            ui32BufferSize,
98822 +                                 IMG_UINT32                            ui32Flags,
98823 +                                 IMG_HANDLE                            hUniqueTag);
98824 +
98825 +#endif 
98826 +
98827 +       IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName,
98828 +                                                          IMG_UINT32 ui32FileOffset, 
98829 +                                                          PVRSRV_KERNEL_MEM_INFO *psMemInfo,
98830 +                                                          IMG_UINT32 uiAddr, 
98831 +                                                          IMG_UINT32 ui32Size,
98832 +                                                          IMG_UINT32 ui32PDumpFlags,
98833 +                                                          IMG_HANDLE hUniqueTag);
98834 +
98835 +       IMG_VOID PDumpSuspendKM(IMG_VOID);
98836 +       IMG_VOID PDumpResumeKM(IMG_VOID);
98837 +
98838 +       #define PDUMPMEMPOL                             PDumpMemPolKM
98839 +       #define PDUMPMEM                                PDumpMemKM
98840 +       #define PDUMPMEM2                               PDumpMem2KM
98841 +       #define PDUMPMEMUM                              PDumpMemUM
98842 +       #define PDUMPINIT                               PDumpInitCommon
98843 +       #define PDUMPDEINIT                             PDumpDeInitCommon
98844 +       #define PDUMPISLASTFRAME                PDumpIsLastCaptureFrameKM
98845 +       #define PDUMPTESTFRAME                  PDumpIsCaptureFrameKM
98846 +       #define PDUMPTESTNEXTFRAME              PDumpTestNextFrame
98847 +       #define PDUMPREGWITHFLAGS               PDumpRegWithFlagsKM
98848 +       #define PDUMPREG                                PDumpRegKM
98849 +       #define PDUMPCOMMENT                    PDumpComment
98850 +       #define PDUMPCOMMENTWITHFLAGS   PDumpCommentWithFlags
98851 +       #define PDUMPREGPOL                             PDumpRegPolKM
98852 +       #define PDUMPREGPOLWITHFLAGS    PDumpRegPolWithFlagsKM
98853 +       #define PDUMPMALLOCPAGES                PDumpMallocPages
98854 +       #define PDUMPMALLOCPAGETABLE    PDumpMallocPageTable
98855 +       #define PDUMPSETMMUCONTEXT              PDumpSetMMUContext
98856 +       #define PDUMPCLEARMMUCONTEXT    PDumpClearMMUContext
98857 +       #define PDUMPFREEPAGES                  PDumpFreePages
98858 +       #define PDUMPFREEPAGETABLE              PDumpFreePageTable
98859 +       #define PDUMPPDREG                              PDumpPDReg
98860 +       #define PDUMPPDREGWITHFLAGS             PDumpPDRegWithFlags
98861 +       #define PDUMPCBP                                PDumpCBP
98862 +       #define PDUMPMALLOCPAGESPHYS    PDumpMallocPagesPhys
98863 +       #define PDUMPENDINITPHASE               PDumpStopInitPhaseKM
98864 +       #define PDUMPMSVDXREGWRITE              PDumpMsvdxRegWrite
98865 +       #define PDUMPMSVDXREGREAD               PDumpMsvdxRegRead
98866 +       #define PDUMPMSVDXPOL                   PDumpMsvdxRegPol
98867 +       #define PDUMPMSVDXWRITEREF              PDumpMsvdxWriteRef
98868 +       #define PDUMPBITMAPKM                   PDumpBitmapKM
98869 +       #define PDUMPDRIVERINFO                 PDumpDriverInfoKM
98870 +       #define PDUMPIDLWITHFLAGS               PDumpIDLWithFlags
98871 +       #define PDUMPIDL                                PDumpIDL
98872 +       #define PDUMPSUSPEND                    PDumpSuspendKM
98873 +       #define PDUMPRESUME                             PDumpResumeKM
98874 +
98875 +#else
98876 +               #if ((defined(LINUX) || defined(GCC_IA32)) || defined(GCC_ARM))
98877 +                       #define PDUMPMEMPOL(args...)
98878 +                       #define PDUMPMEM(args...)
98879 +                       #define PDUMPMEM2(args...)
98880 +                       #define PDUMPMEMUM(args...)
98881 +                       #define PDUMPINIT(args...)
98882 +                       #define PDUMPDEINIT(args...)
98883 +                       #define PDUMPISLASTFRAME(args...)
98884 +                       #define PDUMPTESTFRAME(args...)
98885 +                       #define PDUMPTESTNEXTFRAME(args...)
98886 +                       #define PDUMPREGWITHFLAGS(args...)
98887 +                       #define PDUMPREG(args...)
98888 +                       #define PDUMPCOMMENT(args...)
98889 +                       #define PDUMPREGPOL(args...)
98890 +                       #define PDUMPREGPOLWITHFLAGS(args...)
98891 +                       #define PDUMPMALLOCPAGES(args...)
98892 +                       #define PDUMPMALLOCPAGETABLE(args...)
98893 +                       #define PDUMPSETMMUCONTEXT(args...)
98894 +                       #define PDUMPCLEARMMUCONTEXT(args...)
98895 +                       #define PDUMPFREEPAGES(args...)
98896 +                       #define PDUMPFREEPAGETABLE(args...)
98897 +                       #define PDUMPPDREG(args...)
98898 +                       #define PDUMPPDREGWITHFLAGS(args...)
98899 +                       #define PDUMPSYNC(args...)
98900 +                       #define PDUMPCOPYTOMEM(args...)
98901 +                       #define PDUMPWRITE(args...)
98902 +                       #define PDUMPCBP(args...)
98903 +                       #define PDUMPCOMMENTWITHFLAGS(args...)
98904 +                       #define PDUMPMALLOCPAGESPHYS(args...)
98905 +                       #define PDUMPENDINITPHASE(args...)
98906 +                       #define PDUMPMSVDXREG(args...)
98907 +                       #define PDUMPMSVDXREGWRITE(args...)
98908 +                       #define PDUMPMSVDXREGREAD(args...)
98909 +                       #define PDUMPMSVDXPOLEQ(args...)
98910 +                       #define PDUMPMSVDXPOL(args...)
98911 +                       #define PDUMPBITMAPKM(args...)
98912 +                       #define PDUMPDRIVERINFO(args...)
98913 +                       #define PDUMPIDLWITHFLAGS(args...)
98914 +                       #define PDUMPIDL(args...)
98915 +                       #define PDUMPSUSPEND(args...)
98916 +                       #define PDUMPRESUME(args...)
98917 +                       #define PDUMPMSVDXWRITEREF(args...)
98918 +               #else
98919 +                       #error Compiler not specified
98920 +               #endif
98921 +#endif
98922 +
98923 +#if defined (__cplusplus)
98924 +}
98925 +#endif
98926 +
98927 +#endif 
98928 +
98929 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_osfunc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_osfunc.h
98930 new file mode 100644
98931 index 0000000..7c6db05
98932 --- /dev/null
98933 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/pdump_osfunc.h
98934 @@ -0,0 +1,137 @@
98935 +/**********************************************************************
98936 + *
98937 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
98938 + * 
98939 + * This program is free software; you can redistribute it and/or modify it
98940 + * under the terms and conditions of the GNU General Public License,
98941 + * version 2, as published by the Free Software Foundation.
98942 + * 
98943 + * This program is distributed in the hope it will be useful but, except 
98944 + * as otherwise stated in writing, without any warranty; without even the 
98945 + * implied warranty of merchantability or fitness for a particular purpose. 
98946 + * See the GNU General Public License for more details.
98947 + * 
98948 + * You should have received a copy of the GNU General Public License along with
98949 + * this program; if not, write to the Free Software Foundation, Inc.,
98950 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
98951 + * 
98952 + * The full GNU General Public License is included in this distribution in
98953 + * the file called "COPYING".
98954 + *
98955 + * Contact Information:
98956 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
98957 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
98958 + *
98959 + ******************************************************************************/
98960 +
98961 +#ifndef __PDUMP_OSFUNC_H__
98962 +#define __PDUMP_OSFUNC_H__
98963 +
98964 +#include <stdarg.h>
98965 +
98966 +#if defined(__cplusplus)
98967 +extern "C" {
98968 +#endif
98969 +
98970 +
98971 +#define MAX_PDUMP_STRING_LENGTH (256)
98972 +#define PDUMP_GET_SCRIPT_STRING()                              \
98973 +       IMG_HANDLE hScript;                                                     \
98974 +       IMG_UINT32      ui32MaxLen;                                             \
98975 +       PVRSRV_ERROR eError;                                            \
98976 +       eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
98977 +       if(eError != PVRSRV_OK) return eError;
98978 +
98979 +#define PDUMP_GET_MSG_STRING()                                 \
98980 +       IMG_HANDLE hMsg;                                                        \
98981 +       IMG_UINT32      ui32MaxLen;                                             \
98982 +       PVRSRV_ERROR eError;                                            \
98983 +       eError = PDumpOSGetMessageString(&hMsg, &ui32MaxLen);\
98984 +       if(eError != PVRSRV_OK) return eError;
98985 +
98986 +#define PDUMP_GET_FILE_STRING()                                \
98987 +       IMG_CHAR *pszFileName;                                  \
98988 +       IMG_UINT32      ui32MaxLen;                                     \
98989 +       PVRSRV_ERROR eError;                                    \
98990 +       eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
98991 +       if(eError != PVRSRV_OK) return eError;
98992 +
98993 +#define PDUMP_GET_SCRIPT_AND_FILE_STRING()             \
98994 +       IMG_HANDLE hScript;                                                     \
98995 +       IMG_CHAR *pszFileName;                                          \
98996 +       IMG_UINT32      ui32MaxLenScript;                               \
98997 +       IMG_UINT32      ui32MaxLenFileName;                             \
98998 +       PVRSRV_ERROR eError;                                            \
98999 +       eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
99000 +       if(eError != PVRSRV_OK) return eError;          \
99001 +       eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
99002 +       if(eError != PVRSRV_OK) return eError;
99003 +
99004 +
99005 +       
99006 +       PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
99007 +
99008 +       
99009 +       PVRSRV_ERROR PDumpOSGetMessageString(IMG_HANDLE *phMsg, IMG_UINT32 *pui32MaxLen);
99010 +
99011 +       
99012 +       PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
99013 +
99014 +
99015 +
99016 +
99017 +#define PDUMP_va_list  va_list
99018 +#define PDUMP_va_start va_start
99019 +#define PDUMP_va_end   va_end
99020 +
99021 +
99022 +
99023 +IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream);
99024 +
99025 +IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream);
99026 +
99027 +IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID);
99028 +
99029 +IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags);
99030 +
99031 +IMG_BOOL PDumpOSIsSuspended(IMG_VOID);
99032 +
99033 +IMG_BOOL PDumpOSJTInitialised(IMG_VOID);
99034 +
99035 +IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream,
99036 +               IMG_UINT8 *psui8Data,
99037 +               IMG_UINT32 ui32Size,
99038 +               IMG_UINT32 ui32Flags);
99039 +
99040 +IMG_BOOL PDumpOSWriteString2(IMG_HANDLE        hScript, IMG_UINT32 ui32Flags);
99041 +
99042 +PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...);
99043 +
99044 +IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...);
99045 +
99046 +PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...);
99047 +
99048 +PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs);
99049 +
99050 +IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
99051 +
99052 +IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
99053 +
99054 +IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
99055 +        IMG_HANDLE hOSMemHandle,
99056 +               IMG_UINT32 ui32Offset,
99057 +               IMG_UINT8 *pui8LinAddr,
99058 +               IMG_UINT32 ui32PageSize,
99059 +               IMG_DEV_PHYADDR *psDevPAddr);
99060 +
99061 +IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
99062 +               IMG_UINT32 ui32Offset,
99063 +               IMG_PUINT8 pui8LinAddr,
99064 +               IMG_UINT32 *pui32PageOffset);
99065 +
99066 +#if defined (__cplusplus)
99067 +}
99068 +#endif
99069 +
99070 +#endif 
99071 +
99072 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/perproc.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/perproc.h
99073 new file mode 100644
99074 index 0000000..233bb59
99075 --- /dev/null
99076 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/perproc.h
99077 @@ -0,0 +1,110 @@
99078 +/**********************************************************************
99079 + *
99080 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99081 + * 
99082 + * This program is free software; you can redistribute it and/or modify it
99083 + * under the terms and conditions of the GNU General Public License,
99084 + * version 2, as published by the Free Software Foundation.
99085 + * 
99086 + * This program is distributed in the hope it will be useful but, except 
99087 + * as otherwise stated in writing, without any warranty; without even the 
99088 + * implied warranty of merchantability or fitness for a particular purpose. 
99089 + * See the GNU General Public License for more details.
99090 + * 
99091 + * You should have received a copy of the GNU General Public License along with
99092 + * this program; if not, write to the Free Software Foundation, Inc.,
99093 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99094 + * 
99095 + * The full GNU General Public License is included in this distribution in
99096 + * the file called "COPYING".
99097 + *
99098 + * Contact Information:
99099 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99100 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99101 + *
99102 + ******************************************************************************/
99103 +
99104 +#ifndef __PERPROC_H__
99105 +#define __PERPROC_H__
99106 +
99107 +#if defined (__cplusplus)
99108 +extern "C" {
99109 +#endif
99110 +
99111 +#include "img_types.h"
99112 +#include "resman.h"
99113 +
99114 +#include "handle.h"
99115 +
99116 +typedef struct _PVRSRV_PER_PROCESS_DATA_
99117 +{
99118 +       IMG_UINT32              ui32PID;
99119 +       IMG_HANDLE              hBlockAlloc;
99120 +       PRESMAN_CONTEXT         hResManContext;
99121 +       IMG_HANDLE              hPerProcData;
99122 +       PVRSRV_HANDLE_BASE      *psHandleBase;
99123 +#if defined (PVR_SECURE_HANDLES)
99124 +       
99125 +       IMG_BOOL                bHandlesBatched;
99126 +#endif  
99127 +       IMG_UINT32              ui32RefCount;
99128 +
99129 +       
99130 +       IMG_BOOL                bInitProcess;
99131 +
99132 +       
99133 +       IMG_HANDLE              hOsPrivateData;
99134 +} PVRSRV_PER_PROCESS_DATA;
99135 +
99136 +PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID);
99137 +
99138 +PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32    ui32PID);
99139 +IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32     ui32PID);
99140 +
99141 +PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID);
99142 +PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID);
99143 +
99144 +#ifdef INLINE_IS_PRAGMA
99145 +#pragma inline(PVRSRVFindPerProcessData)
99146 +#endif
99147 +static INLINE
99148 +PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID)
99149 +{
99150 +       return PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
99151 +}
99152 +
99153 +
99154 +#ifdef INLINE_IS_PRAGMA
99155 +#pragma inline(PVRSRVProcessPrivateData)
99156 +#endif
99157 +static INLINE
99158 +IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc)
99159 +{
99160 +       return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL;
99161 +}
99162 +
99163 +
99164 +#ifdef INLINE_IS_PRAGMA
99165 +#pragma inline(PVRSRVPerProcessPrivateData)
99166 +#endif
99167 +static INLINE
99168 +IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID)
99169 +{
99170 +       return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID));
99171 +}
99172 +
99173 +#ifdef INLINE_IS_PRAGMA
99174 +#pragma inline(PVRSRVFindPerProcessPrivateData)
99175 +#endif
99176 +static INLINE
99177 +IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID)
99178 +{
99179 +       return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData());
99180 +}
99181 +
99182 +#if defined (__cplusplus)
99183 +}
99184 +#endif
99185 +
99186 +#endif 
99187 +
99188 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/power.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/power.h
99189 new file mode 100644
99190 index 0000000..cd8d737
99191 --- /dev/null
99192 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/power.h
99193 @@ -0,0 +1,133 @@
99194 +/**********************************************************************
99195 + *
99196 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99197 + * 
99198 + * This program is free software; you can redistribute it and/or modify it
99199 + * under the terms and conditions of the GNU General Public License,
99200 + * version 2, as published by the Free Software Foundation.
99201 + * 
99202 + * This program is distributed in the hope it will be useful but, except 
99203 + * as otherwise stated in writing, without any warranty; without even the 
99204 + * implied warranty of merchantability or fitness for a particular purpose. 
99205 + * See the GNU General Public License for more details.
99206 + * 
99207 + * You should have received a copy of the GNU General Public License along with
99208 + * this program; if not, write to the Free Software Foundation, Inc.,
99209 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99210 + * 
99211 + * The full GNU General Public License is included in this distribution in
99212 + * the file called "COPYING".
99213 + *
99214 + * Contact Information:
99215 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99216 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99217 + *
99218 + ******************************************************************************/
99219 +
99220 +#ifndef POWER_H
99221 +#define POWER_H
99222 +
99223 +#if defined(__cplusplus)
99224 +extern "C" {
99225 +#endif
99226 +
99227 +
99228
99229 +typedef struct _PVRSRV_POWER_DEV_TAG_
99230 +{
99231 +       PFN_PRE_POWER                                   pfnPrePower;
99232 +       PFN_POST_POWER                                  pfnPostPower;
99233 +       PFN_PRE_CLOCKSPEED_CHANGE               pfnPreClockSpeedChange;
99234 +       PFN_POST_CLOCKSPEED_CHANGE              pfnPostClockSpeedChange;
99235 +       IMG_HANDLE                                              hDevCookie;
99236 +       IMG_UINT32                                              ui32DeviceIndex;
99237 +       PVRSRV_DEV_POWER_STATE                  eDefaultPowerState;
99238 +       PVRSRV_DEV_POWER_STATE                  eCurrentPowerState;
99239 +       struct _PVRSRV_POWER_DEV_TAG_   *psNext;
99240 +       struct _PVRSRV_POWER_DEV_TAG_   **ppsThis;
99241 +
99242 +} PVRSRV_POWER_DEV;
99243 +
99244 +typedef enum _PVRSRV_INIT_SERVER_STATE_
99245 +{
99246 +       PVRSRV_INIT_SERVER_Unspecified          = -1,   
99247 +       PVRSRV_INIT_SERVER_RUNNING                      = 0,    
99248 +       PVRSRV_INIT_SERVER_RAN                          = 1,    
99249 +       PVRSRV_INIT_SERVER_SUCCESSFUL           = 2,    
99250 +       PVRSRV_INIT_SERVER_NUM                          = 3,    
99251 +       PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff
99252 +
99253 +} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE;
99254 +
99255 +IMG_IMPORT
99256 +IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE     eInitServerState);
99257 +
99258 +IMG_IMPORT
99259 +PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState);
99260 +
99261 +
99262 +
99263 +IMG_IMPORT
99264 +PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32        ui32CallerID,
99265 +                                                        IMG_BOOL       bSystemPowerEvent);
99266 +IMG_IMPORT
99267 +IMG_VOID PVRSRVPowerUnlock(IMG_UINT32  ui32CallerID);
99268 +
99269 +IMG_IMPORT
99270 +PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32                            ui32DeviceIndex,
99271 +                                                                                PVRSRV_DEV_POWER_STATE eNewPowerState,
99272 +                                                                                IMG_UINT32                             ui32CallerID,
99273 +                                                                                IMG_BOOL                               bRetainMutex);
99274 +
99275 +IMG_IMPORT
99276 +PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
99277 +IMG_IMPORT
99278 +PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
99279 +
99280 +IMG_IMPORT
99281 +PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState);
99282 +
99283 +IMG_IMPORT
99284 +PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32                                      ui32DeviceIndex,
99285 +                                                                          PFN_PRE_POWER                                pfnPrePower,
99286 +                                                                          PFN_POST_POWER                               pfnPostPower,
99287 +                                                                          PFN_PRE_CLOCKSPEED_CHANGE    pfnPreClockSpeedChange,
99288 +                                                                          PFN_POST_CLOCKSPEED_CHANGE   pfnPostClockSpeedChange,
99289 +                                                                          IMG_HANDLE                                   hDevCookie,
99290 +                                                                          PVRSRV_DEV_POWER_STATE               eCurrentPowerState,
99291 +                                                                          PVRSRV_DEV_POWER_STATE               eDefaultPowerState);
99292 +
99293 +IMG_IMPORT
99294 +PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex);
99295 +
99296 +IMG_IMPORT
99297 +IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex);
99298 +
99299 +IMG_IMPORT
99300 +PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32        ui32DeviceIndex,
99301 +                                                                                        IMG_BOOL       bIdleDevice,
99302 +                                                                                        IMG_VOID       *pvInfo);
99303 +
99304 +IMG_IMPORT
99305 +IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32   ui32DeviceIndex,
99306 +                                                                                 IMG_BOOL              bIdleDevice,
99307 +                                                                                 IMG_VOID              *pvInfo);
99308 +
99309 +
99310 +/*
99311 + * PVRSRVPowerOnSystemWithDevice
99312 + *
99313 + * Description: Power on the System if it is off, but instead of powering all
99314 + * of the devices to their "default" state, only turn on the specified
99315 + * device index.
99316 + */
99317 +IMG_EXPORT
99318 +PVRSRV_ERROR PVRSRVPowerOnSystemWithDevice(IMG_UINT32  ui32DeviceIndex,
99319 +                                          IMG_UINT32   ui32CallerID,
99320 +                                          IMG_BOOL     bRetainMutex);
99321 +
99322 +#if defined (__cplusplus)
99323 +}
99324 +#endif
99325 +#endif 
99326 +
99327 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/queue.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/queue.h
99328 new file mode 100644
99329 index 0000000..0646137
99330 --- /dev/null
99331 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/queue.h
99332 @@ -0,0 +1,119 @@
99333 +/**********************************************************************
99334 + *
99335 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99336 + * 
99337 + * This program is free software; you can redistribute it and/or modify it
99338 + * under the terms and conditions of the GNU General Public License,
99339 + * version 2, as published by the Free Software Foundation.
99340 + * 
99341 + * This program is distributed in the hope it will be useful but, except 
99342 + * as otherwise stated in writing, without any warranty; without even the 
99343 + * implied warranty of merchantability or fitness for a particular purpose. 
99344 + * See the GNU General Public License for more details.
99345 + * 
99346 + * You should have received a copy of the GNU General Public License along with
99347 + * this program; if not, write to the Free Software Foundation, Inc.,
99348 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99349 + * 
99350 + * The full GNU General Public License is included in this distribution in
99351 + * the file called "COPYING".
99352 + *
99353 + * Contact Information:
99354 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99355 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99356 + *
99357 + ******************************************************************************/
99358 +
99359 +#ifndef QUEUE_H
99360 +#define QUEUE_H
99361 +
99362 +
99363 +#if defined(__cplusplus)
99364 +extern "C" {
99365 +#endif
99366 +
99367 +#define UPDATE_QUEUE_ROFF(psQueue, ui32Size)                                           \
99368 +       psQueue->ui32ReadOffset = (psQueue->ui32ReadOffset + ui32Size)  \
99369 +       & (psQueue->ui32QueueSize - 1);
99370 +
99371 + typedef struct _COMMAND_COMPLETE_DATA_
99372 + {
99373 +       IMG_BOOL                        bInUse;
99374 +               
99375 +       IMG_UINT32                      ui32DstSyncCount;       
99376 +       IMG_UINT32                      ui32SrcSyncCount;       
99377 +       PVRSRV_SYNC_OBJECT      *psDstSync;                     
99378 +       PVRSRV_SYNC_OBJECT      *psSrcSync;                     
99379 +       IMG_UINT32                      ui32AllocSize;          
99380 + }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA;
99381 +
99382 +#if !defined(USE_CODE)
99383 +IMG_VOID QueueDumpDebugInfo(IMG_VOID);
99384 +
99385 +IMG_IMPORT
99386 +PVRSRV_ERROR PVRSRVProcessQueues (IMG_UINT32   ui32CallerID,
99387 +                                                                 IMG_BOOL              bFlush);
99388 +
99389 +#if defined(__linux__) && defined(__KERNEL__) 
99390 +#include <linux/types.h>
99391 +#include <linux/seq_file.h>
99392 +off_t
99393 +QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off);
99394 +
99395 +#ifdef PVR_PROC_USE_SEQ_FILE
99396 +void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off);
99397 +void ProcSeqShowQueue(struct seq_file *sfile,void* el);
99398 +#endif
99399 +
99400 +#endif
99401 +
99402 +
99403 +IMG_IMPORT
99404 +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
99405 +                                                                                                        PVRSRV_QUEUE_INFO **ppsQueueInfo);
99406 +IMG_IMPORT
99407 +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo);
99408 +
99409 +IMG_IMPORT
99410 +PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO      *psQueue,
99411 +                                                                                               PVRSRV_COMMAND          **ppsCommand,
99412 +                                                                                               IMG_UINT32                      ui32DevIndex,
99413 +                                                                                               IMG_UINT16                      CommandType,
99414 +                                                                                               IMG_UINT32                      ui32DstSyncCount,
99415 +                                                                                               PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
99416 +                                                                                               IMG_UINT32                      ui32SrcSyncCount,
99417 +                                                                                               PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
99418 +                                                                                               IMG_SIZE_T                      ui32DataByteSize );
99419 +
99420 +IMG_IMPORT
99421 +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
99422 +                                                                                               IMG_SIZE_T ui32ParamSize,
99423 +                                                                                               IMG_VOID **ppvSpace);
99424 +
99425 +IMG_IMPORT
99426 +PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
99427 +                                                                                               PVRSRV_COMMAND *psCommand);
99428 +
99429 +IMG_IMPORT
99430 +IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR);
99431 +
99432 +IMG_VOID PVRSRVCommandCompleteCallbacks(IMG_VOID);
99433 +
99434 +IMG_IMPORT
99435 +PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32            ui32DevIndex,
99436 +                                                                                PFN_CMD_PROC   *ppfnCmdProcList,
99437 +                                                                                IMG_UINT32             ui32MaxSyncsPerCmd[][2],
99438 +                                                                                IMG_UINT32             ui32CmdCount);
99439 +IMG_IMPORT
99440 +PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32      ui32DevIndex,
99441 +                                                                          IMG_UINT32   ui32CmdCount);
99442 +
99443 +#endif 
99444 +
99445 +
99446 +#if defined (__cplusplus)
99447 +}
99448 +#endif
99449 +
99450 +#endif 
99451 +
99452 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/ra.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/ra.h
99453 new file mode 100644
99454 index 0000000..3cb7e78
99455 --- /dev/null
99456 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/ra.h
99457 @@ -0,0 +1,155 @@
99458 +/**********************************************************************
99459 + *
99460 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99461 + * 
99462 + * This program is free software; you can redistribute it and/or modify it
99463 + * under the terms and conditions of the GNU General Public License,
99464 + * version 2, as published by the Free Software Foundation.
99465 + * 
99466 + * This program is distributed in the hope it will be useful but, except 
99467 + * as otherwise stated in writing, without any warranty; without even the 
99468 + * implied warranty of merchantability or fitness for a particular purpose. 
99469 + * See the GNU General Public License for more details.
99470 + * 
99471 + * You should have received a copy of the GNU General Public License along with
99472 + * this program; if not, write to the Free Software Foundation, Inc.,
99473 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99474 + * 
99475 + * The full GNU General Public License is included in this distribution in
99476 + * the file called "COPYING".
99477 + *
99478 + * Contact Information:
99479 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99480 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99481 + *
99482 + ******************************************************************************/
99483 +
99484 +#ifndef _RA_H_
99485 +#define _RA_H_
99486 +
99487 +#include "img_types.h"
99488 +#include "hash.h"
99489 +#include "osfunc.h"
99490 +
99491 +typedef struct _RA_ARENA_ RA_ARENA;                    
99492 +typedef struct _BM_MAPPING_ BM_MAPPING;
99493 +
99494 +
99495 +
99496 +#define RA_STATS 
99497 +
99498 +
99499 +struct _RA_STATISTICS_
99500 +{
99501 +    
99502 +    IMG_SIZE_T uSpanCount;
99503 +
99504 +    
99505 +    IMG_SIZE_T uLiveSegmentCount;
99506 +
99507 +    
99508 +    IMG_SIZE_T uFreeSegmentCount;
99509 +
99510 +    
99511 +    IMG_SIZE_T uTotalResourceCount;
99512 +    
99513 +    
99514 +    IMG_SIZE_T uFreeResourceCount;
99515 +
99516 +    
99517 +    IMG_SIZE_T uCumulativeAllocs;
99518 +
99519 +    
99520 +    IMG_SIZE_T uCumulativeFrees;
99521 +
99522 +    
99523 +    IMG_SIZE_T uImportCount;
99524 +
99525 +    
99526 +    IMG_SIZE_T uExportCount;
99527 +};
99528 +typedef struct _RA_STATISTICS_ RA_STATISTICS;
99529 +
99530 +struct _RA_SEGMENT_DETAILS_
99531 +{
99532 +       IMG_SIZE_T      uiSize;
99533 +       IMG_CPU_PHYADDR sCpuPhyAddr;
99534 +       IMG_HANDLE      hSegment;
99535 +};
99536 +typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
99537 +
99538 +RA_ARENA *
99539 +RA_Create (IMG_CHAR *name,
99540 +           IMG_UINTPTR_T base,
99541 +           IMG_SIZE_T uSize,
99542 +           BM_MAPPING *psMapping,
99543 +           IMG_SIZE_T uQuantum, 
99544 +           IMG_BOOL (*imp_alloc)(IMG_VOID *_h,
99545 +                                IMG_SIZE_T uSize,
99546 +                                IMG_SIZE_T *pActualSize,
99547 +                                BM_MAPPING **ppsMapping,
99548 +                                IMG_UINT32 uFlags,
99549 +                                IMG_UINTPTR_T *pBase),
99550 +           IMG_VOID (*imp_free) (IMG_VOID *,
99551 +                                IMG_UINTPTR_T,
99552 +                                BM_MAPPING *),
99553 +           IMG_VOID (*backingstore_free) (IMG_VOID *,
99554 +                                          IMG_SIZE_T,
99555 +                                          IMG_SIZE_T,
99556 +                                          IMG_HANDLE),
99557 +           IMG_VOID *import_handle);
99558 +
99559 +IMG_VOID
99560 +RA_Delete (RA_ARENA *pArena);
99561 +
99562 +IMG_BOOL
99563 +RA_TestDelete (RA_ARENA *pArena);
99564 +
99565 +IMG_BOOL
99566 +RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize);
99567 +
99568 +IMG_BOOL
99569 +RA_Alloc (RA_ARENA *pArena, 
99570 +          IMG_SIZE_T uSize,
99571 +          IMG_SIZE_T *pActualSize,
99572 +          BM_MAPPING **ppsMapping, 
99573 +          IMG_UINT32 uFlags,
99574 +          IMG_UINT32 uAlignment,
99575 +                 IMG_UINT32 uAlignmentOffset,
99576 +          IMG_UINTPTR_T *pBase);
99577 +
99578 +IMG_VOID 
99579 +RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore);
99580 +
99581 +
99582 +#ifdef RA_STATS
99583 +
99584 +#define CHECK_SPACE(total)                                     \
99585 +{                                                                                      \
99586 +       if(total<100)                                                   \
99587 +               return PVRSRV_ERROR_INVALID_PARAMS;     \
99588 +}
99589 +
99590 +#define UPDATE_SPACE(str, count, total)                \
99591 +{                                                                                      \
99592 +       if(count == -1)                                                 \
99593 +               return PVRSRV_ERROR_INVALID_PARAMS;     \
99594 +       else                                                                    \
99595 +       {                                                                               \
99596 +               str += count;                                           \
99597 +               total -= count;                                         \
99598 +       }                                                                               \
99599 +}
99600 +
99601 +
99602 +IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails);
99603 +
99604 +
99605 +PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
99606 +                                                       IMG_CHAR **ppszStr, 
99607 +                                                       IMG_UINT32 *pui32StrLen);
99608 +
99609 +#endif 
99610 +
99611 +#endif
99612 +
99613 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/resman.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/resman.h
99614 new file mode 100644
99615 index 0000000..c5571f7
99616 --- /dev/null
99617 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/resman.h
99618 @@ -0,0 +1,113 @@
99619 +/**********************************************************************
99620 + *
99621 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99622 + * 
99623 + * This program is free software; you can redistribute it and/or modify it
99624 + * under the terms and conditions of the GNU General Public License,
99625 + * version 2, as published by the Free Software Foundation.
99626 + * 
99627 + * This program is distributed in the hope it will be useful but, except 
99628 + * as otherwise stated in writing, without any warranty; without even the 
99629 + * implied warranty of merchantability or fitness for a particular purpose. 
99630 + * See the GNU General Public License for more details.
99631 + * 
99632 + * You should have received a copy of the GNU General Public License along with
99633 + * this program; if not, write to the Free Software Foundation, Inc.,
99634 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99635 + * 
99636 + * The full GNU General Public License is included in this distribution in
99637 + * the file called "COPYING".
99638 + *
99639 + * Contact Information:
99640 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99641 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99642 + *
99643 + ******************************************************************************/
99644 +
99645 +#ifndef __RESMAN_H__
99646 +#define __RESMAN_H__
99647 +
99648 +#if defined (__cplusplus)
99649 +extern "C" {
99650 +#endif
99651 +
99652 +enum {
99653 +       
99654 +       RESMAN_TYPE_SHARED_PB_DESC = 1,                                 
99655 +       RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,                         
99656 +       RESMAN_TYPE_HW_RENDER_CONTEXT,                                  
99657 +       RESMAN_TYPE_HW_TRANSFER_CONTEXT,                                
99658 +       RESMAN_TYPE_HW_2D_CONTEXT,                                              
99659 +       RESMAN_TYPE_TRANSFER_CONTEXT,                                   
99660 +
99661 +       
99662 +       
99663 +       
99664 +       
99665 +       RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,                 
99666 +       RESMAN_TYPE_DISPLAYCLASS_DEVICE,                                
99667 +
99668 +       
99669 +       RESMAN_TYPE_BUFFERCLASS_DEVICE,                                 
99670 +       
99671 +       
99672 +       RESMAN_TYPE_OS_USERMODE_MAPPING,                                
99673 +       
99674 +       
99675 +       RESMAN_TYPE_DEVICEMEM_CONTEXT,                                  
99676 +       RESMAN_TYPE_DEVICECLASSMEM_MAPPING,                             
99677 +       RESMAN_TYPE_DEVICEMEM_MAPPING,                                  
99678 +       RESMAN_TYPE_DEVICEMEM_WRAP,                                             
99679 +       RESMAN_TYPE_DEVICEMEM_ALLOCATION,                               
99680 +       RESMAN_TYPE_EVENT_OBJECT,                                               
99681 +    RESMAN_TYPE_SHARED_MEM_INFO,                    
99682 +    RESMAN_TYPE_MODIFY_SYNC_OPS,                                       
99683 +       
99684 +       
99685 +       RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION                 
99686 +};
99687 +
99688 +#define RESMAN_CRITERIA_ALL                            0x00000000      
99689 +#define RESMAN_CRITERIA_RESTYPE                        0x00000001      
99690 +#define RESMAN_CRITERIA_PVOID_PARAM            0x00000002      
99691 +#define RESMAN_CRITERIA_UI32_PARAM             0x00000004      
99692 +
99693 +typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param); 
99694 +
99695 +typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM;
99696 +typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT;
99697 +
99698 +PVRSRV_ERROR ResManInit(IMG_VOID);
99699 +IMG_VOID ResManDeInit(IMG_VOID);
99700 +
99701 +PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT hResManContext,
99702 +                                                          IMG_UINT32           ui32ResType, 
99703 +                                                          IMG_PVOID            pvParam, 
99704 +                                                          IMG_UINT32           ui32Param, 
99705 +                                                          RESMAN_FREE_FN       pfnFreeResource);
99706 +
99707 +PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM   psResItem);
99708 +
99709 +PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT   hResManContext,
99710 +                                                                        IMG_UINT32                     ui32SearchCriteria, 
99711 +                                                                        IMG_UINT32                     ui32ResType, 
99712 +                                                                        IMG_PVOID                      pvParam, 
99713 +                                                                        IMG_UINT32                     ui32Param);
99714 +
99715 +PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM          psResItem,
99716 +                                                        PRESMAN_CONTEXT        psNewResManContext);
99717 +
99718 +PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT   hResManContext,
99719 +                                                                        PRESMAN_ITEM           psItem);
99720 +
99721 +PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE                    hPerProc,
99722 +                                                                PRESMAN_CONTEXT        *phResManContext);
99723 +IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext,
99724 +                                                               IMG_BOOL                bKernelContext);
99725 +
99726 +#if defined (__cplusplus)
99727 +}
99728 +#endif
99729 +
99730 +#endif 
99731 +
99732 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/services_headers.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/services_headers.h
99733 new file mode 100644
99734 index 0000000..eb00dbb
99735 --- /dev/null
99736 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/services_headers.h
99737 @@ -0,0 +1,49 @@
99738 +/**********************************************************************
99739 + *
99740 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99741 + * 
99742 + * This program is free software; you can redistribute it and/or modify it
99743 + * under the terms and conditions of the GNU General Public License,
99744 + * version 2, as published by the Free Software Foundation.
99745 + * 
99746 + * This program is distributed in the hope it will be useful but, except 
99747 + * as otherwise stated in writing, without any warranty; without even the 
99748 + * implied warranty of merchantability or fitness for a particular purpose. 
99749 + * See the GNU General Public License for more details.
99750 + * 
99751 + * You should have received a copy of the GNU General Public License along with
99752 + * this program; if not, write to the Free Software Foundation, Inc.,
99753 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99754 + * 
99755 + * The full GNU General Public License is included in this distribution in
99756 + * the file called "COPYING".
99757 + *
99758 + * Contact Information:
99759 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99760 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99761 + *
99762 + ******************************************************************************/
99763 +
99764 +#ifndef SERVICES_HEADERS_H
99765 +#define SERVICES_HEADERS_H
99766 +
99767 +#ifdef DEBUG_RELEASE_BUILD
99768 +#pragma optimize( "", off )
99769 +#define DEBUG          1
99770 +#endif
99771 +
99772 +#include "img_defs.h"
99773 +#include "services.h"
99774 +#include "servicesint.h"
99775 +#include "power.h"
99776 +#include "resman.h"
99777 +#include "queue.h"
99778 +#include "srvkm.h"
99779 +#include "kerneldisplay.h"
99780 +#include "syscommon.h"
99781 +#include "pvr_debug.h"
99782 +#include "metrics.h"
99783 +#include "osfunc.h"
99784 +
99785 +#endif 
99786 +
99787 diff --git a/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/srvkm.h b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/srvkm.h
99788 new file mode 100644
99789 index 0000000..a344253
99790 --- /dev/null
99791 +++ b/drivers/gpu/drm/mrst/pvr/services4/srvkm/include/srvkm.h
99792 @@ -0,0 +1,69 @@
99793 +/**********************************************************************
99794 + *
99795 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99796 + * 
99797 + * This program is free software; you can redistribute it and/or modify it
99798 + * under the terms and conditions of the GNU General Public License,
99799 + * version 2, as published by the Free Software Foundation.
99800 + * 
99801 + * This program is distributed in the hope it will be useful but, except 
99802 + * as otherwise stated in writing, without any warranty; without even the 
99803 + * implied warranty of merchantability or fitness for a particular purpose. 
99804 + * See the GNU General Public License for more details.
99805 + * 
99806 + * You should have received a copy of the GNU General Public License along with
99807 + * this program; if not, write to the Free Software Foundation, Inc.,
99808 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99809 + * 
99810 + * The full GNU General Public License is included in this distribution in
99811 + * the file called "COPYING".
99812 + *
99813 + * Contact Information:
99814 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99815 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99816 + *
99817 + ******************************************************************************/
99818 +
99819 +#ifndef SRVKM_H
99820 +#define SRVKM_H
99821 +
99822 +
99823 +#if defined(__cplusplus)
99824 +extern "C" {
99825 +#endif
99826 +
99827 +       
99828 +       #ifdef PVR_DISABLE_LOGGING
99829 +       #define PVR_LOG(X)
99830 +       #else
99831 +       #define PVR_LOG(X)                      PVRSRVReleasePrintf X
99832 +       #endif
99833 +
99834 +       IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat,
99835 +                                                                               ...);
99836 +
99837 +       IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32    ui32PID);
99838 +       IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32     ui32PID);
99839 +
99840 +       IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State);
99841 +
99842 +       PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave);
99843 +
99844 +#if defined (__cplusplus)
99845 +}
99846 +#endif
99847 +
99848 +#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \
99849 +{\
99850 +       IMG_UINT32 uiOffset, uiStart, uiCurrent, uiNotLastLoop;                                                         \
99851 +       for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, uiNotLastLoop = 1;\
99852 +               ((uiCurrent - uiStart + uiOffset) < TIMEOUT) || uiNotLastLoop--;                                \
99853 +               uiCurrent = OSClockus(),                                                                                                                \
99854 +               uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset,                   \
99855 +               uiStart = uiCurrent < uiStart ? 0 : uiStart)
99856 +
99857 +#define END_LOOP_UNTIL_TIMEOUT() \
99858 +}
99859 +
99860 +
99861 +#endif 
99862 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/include/syscommon.h b/drivers/gpu/drm/mrst/pvr/services4/system/include/syscommon.h
99863 new file mode 100644
99864 index 0000000..20b83c1
99865 --- /dev/null
99866 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/include/syscommon.h
99867 @@ -0,0 +1,217 @@
99868 +/**********************************************************************
99869 + *
99870 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
99871 + * 
99872 + * This program is free software; you can redistribute it and/or modify it
99873 + * under the terms and conditions of the GNU General Public License,
99874 + * version 2, as published by the Free Software Foundation.
99875 + * 
99876 + * This program is distributed in the hope it will be useful but, except 
99877 + * as otherwise stated in writing, without any warranty; without even the 
99878 + * implied warranty of merchantability or fitness for a particular purpose. 
99879 + * See the GNU General Public License for more details.
99880 + * 
99881 + * You should have received a copy of the GNU General Public License along with
99882 + * this program; if not, write to the Free Software Foundation, Inc.,
99883 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
99884 + * 
99885 + * The full GNU General Public License is included in this distribution in
99886 + * the file called "COPYING".
99887 + *
99888 + * Contact Information:
99889 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
99890 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
99891 + *
99892 + ******************************************************************************/
99893 +
99894 +#ifndef _SYSCOMMON_H
99895 +#define _SYSCOMMON_H
99896 +
99897 +#include "sysconfig.h"      
99898 +#include "sysinfo.h"           
99899 +#include "servicesint.h"
99900 +#include "queue.h"
99901 +#include "power.h"
99902 +#include "resman.h"
99903 +#include "ra.h"
99904 +#include "device.h"
99905 +#include "buffer_manager.h"
99906
99907 +#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
99908 +#include <asm/io.h>
99909 +#endif
99910 +
99911 +#if defined (__cplusplus)
99912 +extern "C" {
99913 +#endif
99914 +
99915 +typedef struct _SYS_DEVICE_ID_TAG
99916 +{
99917 +       IMG_UINT32      uiID;
99918 +       IMG_BOOL        bInUse;
99919 +
99920 +} SYS_DEVICE_ID;
99921 +
99922 +
99923 +#define SYS_MAX_LOCAL_DEVMEM_ARENAS    4
99924 +
99925 +typedef struct _SYS_DATA_TAG_
99926 +{
99927 +    IMG_UINT32                  ui32NumDevices;                
99928 +       SYS_DEVICE_ID                           sDeviceID[SYS_DEVICE_COUNT];
99929 +    PVRSRV_DEVICE_NODE                 *psDeviceNodeList;                      
99930 +    PVRSRV_POWER_DEV                   *psPowerDeviceList;                     
99931 +       PVRSRV_RESOURCE                         sPowerStateChangeResource;      
99932 +       PVRSRV_SYS_POWER_STATE          eCurrentPowerState;                     
99933 +       PVRSRV_SYS_POWER_STATE          eFailedPowerState;                      
99934 +       IMG_UINT32                                      ui32CurrentOSPowerState;        
99935 +    PVRSRV_QUEUE_INFO           *psQueueList;                  
99936 +       PVRSRV_KERNEL_SYNC_INFO         *psSharedSyncInfoList;          
99937 +    IMG_PVOID                   pvEnvSpecificData;             
99938 +    IMG_PVOID                   pvSysSpecificData;             
99939 +       PVRSRV_RESOURCE                         sQProcessResource;                      
99940 +       IMG_VOID                                        *pvSOCRegsBase;                         
99941 +    IMG_HANDLE                  hSOCTimerRegisterOSMemHandle; 
99942 +       IMG_UINT32                                      *pvSOCTimerRegisterKM;          
99943 +       IMG_VOID                                        *pvSOCClockGateRegsBase;        
99944 +       IMG_UINT32                                      ui32SOCClockGateRegsSize;
99945 +       PFN_CMD_PROC                            *ppfnCmdProcList[SYS_DEVICE_COUNT];
99946 +                                                                                                                       
99947 +
99948 +
99949 +       PCOMMAND_COMPLETE_DATA          *ppsCmdCompleteData[SYS_DEVICE_COUNT];
99950 +                                                                                                                       
99951 +
99952 +       IMG_BOOL                    bReProcessQueues;                   
99953 +
99954 +       RA_ARENA                                        *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; 
99955 +
99956 +    IMG_CHAR                    *pszVersionString;          
99957 +       PVRSRV_EVENTOBJECT                      *psGlobalEventObject;                   
99958 +
99959 +       IMG_BOOL                                        bFlushAll;                                      
99960 +
99961 +} SYS_DATA;
99962 +
99963 +
99964 +
99965 +PVRSRV_ERROR SysInitialise(IMG_VOID);
99966 +PVRSRV_ERROR SysFinalise(IMG_VOID);
99967 +
99968 +PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData);
99969 +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
99970 +                                                                       IMG_VOID **ppvDeviceMap);
99971 +
99972 +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
99973 +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
99974 +
99975 +IMG_UINT32 SysGetInterruptSource(SYS_DATA                      *psSysData,
99976 +                                                                PVRSRV_DEVICE_NODE *psDeviceNode);
99977 +
99978 +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits);
99979 +
99980 +PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex);
99981 +
99982 +PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
99983 +PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
99984 +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
99985 +                                                                       PVRSRV_DEV_POWER_STATE eNewPowerState,
99986 +                                                                       PVRSRV_DEV_POWER_STATE eCurrentPowerState);
99987 +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
99988 +                                                                        PVRSRV_DEV_POWER_STATE eNewPowerState,
99989 +                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState);
99990 +
99991 +#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
99992 +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData);
99993 +IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData);
99994 +#endif
99995 +
99996 +PVRSRV_ERROR SysOEMFunction (  IMG_UINT32      ui32ID, 
99997 +                                                               IMG_VOID        *pvIn,
99998 +                                                               IMG_UINT32  ulInSize,
99999 +                                                               IMG_VOID        *pvOut,
100000 +                                                               IMG_UINT32      ulOutSize);
100001 +
100002 +
100003 +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr);
100004 +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
100005 +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr);
100006 +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr);
100007 +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr);
100008 +#if defined(PVR_LMA)
100009 +IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr);
100010 +IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr);
100011 +#endif
100012 +
100013 +extern SYS_DATA* gpsSysData;
100014 +
100015 +#if !defined(USE_CODE)
100016 +
100017 +#ifdef INLINE_IS_PRAGMA
100018 +#pragma inline(SysAcquireData)
100019 +#endif
100020 +static INLINE PVRSRV_ERROR SysAcquireData(SYS_DATA **ppsSysData)
100021 +{
100022 +       
100023 +       *ppsSysData = gpsSysData;
100024 +
100025 +       
100026 +
100027 +
100028 +
100029 +       if (!gpsSysData)
100030 +       {
100031 +               return PVRSRV_ERROR_GENERIC;    
100032 +       }
100033 +               
100034 +       return PVRSRV_OK;
100035 +}
100036 +
100037 +
100038 +#ifdef INLINE_IS_PRAGMA
100039 +#pragma inline(SysInitialiseCommon)
100040 +#endif
100041 +static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData)
100042 +{
100043 +       PVRSRV_ERROR    eError;
100044 +
100045 +       
100046 +       eError = PVRSRVInit(psSysData);
100047 +
100048 +       return eError;
100049 +}
100050 +
100051 +#ifdef INLINE_IS_PRAGMA
100052 +#pragma inline(SysDeinitialiseCommon)
100053 +#endif
100054 +static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData)
100055 +{
100056 +       
100057 +       PVRSRVDeInit(psSysData);
100058 +
100059 +       OSDestroyResource(&psSysData->sPowerStateChangeResource);
100060 +}
100061 +#endif 
100062 +
100063 +
100064 +#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__))
100065 +#define        SysReadHWReg(p, o) OSReadHWReg(p, o)
100066 +#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v)
100067 +#else  
100068 +static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
100069 +{
100070 +       return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
100071 +}
100072 +
100073 +static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
100074 +{
100075 +       writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
100076 +}
100077 +#endif 
100078 +
100079 +#if defined(__cplusplus)
100080 +}
100081 +#endif
100082 +
100083 +#endif
100084 +
100085 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/.gitignore b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/.gitignore
100086 new file mode 100644
100087 index 0000000..2f89523
100088 --- /dev/null
100089 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/.gitignore
100090 @@ -0,0 +1,5 @@
100091 +bin_pc_i686*
100092 +tmp_pc_i686*
100093 +host_pc_i686*
100094 +*.o
100095 +*.o.cmd
100096 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/oemfuncs.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/oemfuncs.h
100097 new file mode 100644
100098 index 0000000..0d3b6d7
100099 --- /dev/null
100100 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/oemfuncs.h
100101 @@ -0,0 +1,72 @@
100102 +/**********************************************************************
100103 + *
100104 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
100105 + * 
100106 + * This program is free software; you can redistribute it and/or modify it
100107 + * under the terms and conditions of the GNU General Public License,
100108 + * version 2, as published by the Free Software Foundation.
100109 + * 
100110 + * This program is distributed in the hope it will be useful but, except 
100111 + * as otherwise stated in writing, without any warranty; without even the 
100112 + * implied warranty of merchantability or fitness for a particular purpose. 
100113 + * See the GNU General Public License for more details.
100114 + * 
100115 + * You should have received a copy of the GNU General Public License along with
100116 + * this program; if not, write to the Free Software Foundation, Inc.,
100117 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
100118 + * 
100119 + * The full GNU General Public License is included in this distribution in
100120 + * the file called "COPYING".
100121 + *
100122 + * Contact Information:
100123 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
100124 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
100125 + *
100126 + ******************************************************************************/
100127 +
100128 +#if !defined(__OEMFUNCS_H__)
100129 +#define __OEMFUNCS_H__
100130 +
100131 +#if defined (__cplusplus)
100132 +extern "C" {
100133 +#endif
100134 +
100135 +#define OEM_EXCHANGE_POWER_STATE       (1<<0)
100136 +#define OEM_DEVICE_MEMORY_POWER                (1<<1)
100137 +#define OEM_DISPLAY_POWER                      (1<<2)
100138 +#define OEM_GET_EXT_FUNCS                      (1<<3)
100139 +
100140 +typedef struct OEM_ACCESS_INFO_TAG
100141 +{
100142 +       IMG_UINT32              ui32Size;
100143 +       IMG_UINT32      ui32FBPhysBaseAddress;
100144 +       IMG_UINT32              ui32FBMemAvailable;             
100145 +       IMG_UINT32      ui32SysPhysBaseAddress;
100146 +       IMG_UINT32              ui32SysSize;
100147 +       IMG_UINT32              ui32DevIRQ;
100148 +} OEM_ACCESS_INFO, *POEM_ACCESS_INFO; 
100149
100150 +typedef IMG_UINT32   (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32  Ioctl,
100151 +                                                                                               IMG_BYTE   *pInBuf,
100152 +                                                                                               IMG_UINT32  InBufLen, 
100153 +                                                                                           IMG_BYTE   *pOutBuf,
100154 +                                                                                               IMG_UINT32  OutBufLen,
100155 +                                                                                               IMG_UINT32 *pdwBytesTransferred);
100156 +
100157 +
100158 +typedef PVRSRV_ERROR (*PFN_SRV_READREGSTRING)(PPVRSRV_REGISTRY_INFO psRegInfo);
100159 +
100160 +
100161 +typedef struct PVRSRV_DC_OEM_JTABLE_TAG
100162 +{
100163 +       PFN_SRV_BRIDGEDISPATCH                  pfnOEMBridgeDispatch;
100164 +       PFN_SRV_READREGSTRING                   pfnOEMReadRegistryString;
100165 +       PFN_SRV_READREGSTRING                   pfnOEMWriteRegistryString;
100166 +
100167 +} PVRSRV_DC_OEM_JTABLE;
100168 +#if defined(__cplusplus)
100169 +}
100170 +#endif
100171 +
100172 +#endif 
100173 +
100174 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.c b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.c
100175 new file mode 100644
100176 index 0000000..b7fa0c4
100177 --- /dev/null
100178 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.c
100179 @@ -0,0 +1,479 @@
100180 +/**************************************************************************
100181 + * Copyright (c) 2009, Intel Corporation.
100182 + * All Rights Reserved.
100183 + *
100184 + * This program is free software; you can redistribute it and/or modify it
100185 + * under the terms and conditions of the GNU General Public License,
100186 + * version 2, as published by the Free Software Foundation.
100187 + *
100188 + * This program is distributed in the hope it will be useful, but WITHOUT
100189 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
100190 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
100191 + * more details.
100192 + *
100193 + * You should have received a copy of the GNU General Public License along with
100194 + * this program; if not, write to the Free Software Foundation, Inc.,
100195 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
100196 + *
100197 + * Authors:
100198 + *    Benjamin Defnet <benjamin.r.defnet@intel.com>
100199 + *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
100200 + *
100201 + **************************************************************************/
100202 +
100203 +#include "ospm_power.h"
100204 +#include "psb_drv.h"
100205 +#include "psb_msvdx.h"
100206 +#include "lnc_topaz.h"
100207 +#include "servicesext.h"
100208 +#include "power.h"
100209 +#include "services.h"
100210 +#include "osfunc.h"
100211 +#include <linux/mutex.h>
100212 +
100213 +extern IMG_UINT32 gui32SGXDeviceID;
100214 +extern IMG_UINT32 gui32MRSTDisplayDeviceID;
100215 +extern IMG_UINT32 gui32MRSTMSVDXDeviceID;
100216 +extern IMG_UINT32 gui32MRSTTOPAZDeviceID;
100217 +
100218 +struct drm_device *gpDrmDevice = NULL;
100219 +static struct mutex g_ospm_mutex;
100220 +static bool gbSuspendInProgress = false;
100221 +static bool gbResumeInProgress = false;
100222 +static int g_hw_power_status_mask;
100223 +static atomic_t g_display_access_count;
100224 +static atomic_t g_graphics_access_count;
100225 +static atomic_t g_videoenc_access_count;
100226 +static atomic_t g_videodec_access_count;
100227 +
100228 +/*
100229 + * ospm_power_init
100230 + *
100231 + * Description: Initialize this ospm power management module
100232 + */
100233 +void ospm_power_init(struct drm_device *dev)
100234 +{
100235 +       struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
100236 +       struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
100237 +
100238 +       pci_write_config_dword(pci_root, 0xD0, 0xd0047800);
100239 +       pci_read_config_dword(pci_root, 0xD4, &dev_priv->ospm_base);
100240 +       dev_priv->ospm_base &= 0xffff;
100241 +
100242 +       dev_priv->apm_reg = MSG_READ32(PSB_PUNIT_PORT, PSB_APMBA);
100243 +       dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
100244 +
100245 +       gpDrmDevice = dev;
100246 +       mutex_init(&g_ospm_mutex);
100247 +       g_hw_power_status_mask = OSPM_ALL_ISLANDS;
100248 +       atomic_set(&g_display_access_count, 0);
100249 +       atomic_set(&g_graphics_access_count, 0);
100250 +       atomic_set(&g_videoenc_access_count, 0);
100251 +       atomic_set(&g_videodec_access_count, 0);
100252 +
100253 +
100254 +#ifdef OSPM_STAT
100255 +       dev_priv->graphics_state = PSB_PWR_STATE_ON;
100256 +       dev_priv->gfx_last_mode_change = jiffies;
100257 +       dev_priv->gfx_on_time = 0;
100258 +       dev_priv->gfx_off_time = 0;
100259 +#endif
100260 +}
100261 +
100262 +/*
100263 + * ospm_power_uninit
100264 + *
100265 + * Description: Uninitialize this ospm power management module
100266 + */
100267 +void ospm_power_uninit(void)
100268 +{
100269 +       mutex_destroy(&g_ospm_mutex);
100270 +}
100271 +
100272 +/*
100273 + * ospm_power_suspend
100274 + *
100275 + * Description: OSPM is telling our driver to suspend so save state
100276 + * and power down all hardware.
100277 + */
100278 +int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
100279 +{
100280 +       struct drm_device *dev = pci_get_drvdata(pdev);
100281 +       struct drm_psb_private *dev_priv =
100282 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
100283 +       struct drm_mode_config *mode_config = &dev->mode_config;
100284 +       struct drm_connector *connector;
100285 +       int ret = 0;
100286 +       bool bDisplayOff = false;
100287 +       
100288 +       mutex_lock(&g_ospm_mutex);
100289 +
100290 +       if (atomic_read(&g_graphics_access_count) ||
100291 +           atomic_read(&g_videoenc_access_count) ||
100292 +           atomic_read(&g_videodec_access_count) ||
100293 +           atomic_read(&g_display_access_count))
100294 +               ret = -EBUSY;
100295 +       //SGX will be powered off when idle due to D0i3 support.  If we don't wait
100296 +       //for D0i3, then we hit cases where user mode driver gets stuck waiting
100297 +       //for command completion when SGX is powered off.
100298 +       else if (ospm_power_is_hw_on(OSPM_GRAPHICS_ISLAND))
100299 +               ret = -EBUSY;
100300 +       else if (psb_check_msvdx_idle(dev))
100301 +               ret = -EBUSY;
100302 +       else if (IS_MRST(dev) && !dev_priv->topaz_disabled && lnc_check_topaz_idle(dev))
100303 +               ret = -EBUSY;
100304 +
100305 +       gbSuspendInProgress = true;
100306 +
100307 +       if (!ret) {
100308 +               PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
100309 +               bDisplayOff = true;
100310 +       } else if (!atomic_read(&g_display_access_count)) {
100311 +               //At least power down the display
100312 +               PVRSRVSetDevicePowerStateKM(gui32MRSTDisplayDeviceID,
100313 +                                           PVRSRV_DEV_POWER_STATE_OFF,
100314 +                                           KERNEL_ID,
100315 +                                           IMG_FALSE);
100316 +               bDisplayOff = true;
100317 +       }
100318 +
100319 +       if (bDisplayOff) {
100320 +               //Set dpms status to off so that an "xset dpms force on" from the 
100321 +               //OSPM Framework (or elsewhere) actually executes
100322 +               list_for_each_entry(connector, &mode_config->connector_list, head) {
100323 +                       connector->dpms = DRM_MODE_DPMS_OFF;
100324 +               }
100325 +       }
100326 +
100327 +       gbSuspendInProgress = false;
100328 +
100329 +       mutex_unlock(&g_ospm_mutex);
100330 +       return ret;
100331 +}
100332 +
100333 +/*
100334 + * ospm_power_resume
100335 + *
100336 + * Description: OSPM is telling our driver to resume so restore state
100337 + * and power up necessary hardware.
100338 + */
100339 +int ospm_power_resume(struct pci_dev *pdev)
100340 +{
100341 +       struct drm_device *dev = pci_get_drvdata(pdev);
100342 +       struct drm_mode_config *mode_config = &dev->mode_config;
100343 +       struct drm_connector *connector;
100344 +
100345 +       mutex_lock(&g_ospm_mutex);
100346 +       gbResumeInProgress = true;
100347 +       PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0);
100348 +
100349 +       //Set dpms status to on.  We should probably only do this for
100350 +       //connectors that were on prior to the suspend, but for Moorestown
100351 +       //we only have one connector so just brute force it.
100352 +       list_for_each_entry(connector, &mode_config->connector_list, head) {
100353 +               connector->dpms = DRM_MODE_DPMS_ON;
100354 +       }
100355 +
100356 +       gbResumeInProgress = false;
100357 +       mutex_unlock(&g_ospm_mutex);
100358 +       return 0;
100359 +}
100360 +
100361 +
100362 +/*
100363 + * ospm_power_island_down
100364 + *
100365 + * Description: Cut power to the specified island(s) (powergating)
100366 + */
100367 +void ospm_power_island_down(int hw_islands)
100368 +{
100369 +       u32 pwr_cnt = 0;
100370 +       u32 pwr_mask = 0;
100371 +       u32 pwr_sts;
100372 +
100373 +       struct drm_psb_private *dev_priv =
100374 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
100375 +
100376 +       g_hw_power_status_mask &= ~hw_islands;
100377 +
100378 +       if (hw_islands & OSPM_GRAPHICS_ISLAND) {
100379 +               pwr_cnt |= PSB_PWRGT_GFX_MASK;
100380 +               pwr_mask |= PSB_PWRGT_GFX_MASK;
100381 +        #ifdef OSPM_STAT
100382 +        if (dev_priv->graphics_state == PSB_PWR_STATE_ON) {
100383 +            dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
100384 +            dev_priv->gfx_last_mode_change = jiffies;
100385 +            dev_priv->graphics_state = PSB_PWR_STATE_OFF;
100386 +            dev_priv->gfx_off_cnt++;
100387 +        }
100388 +        #endif
100389 +       }
100390 +       if (hw_islands & OSPM_VIDEO_ENC_ISLAND) {
100391 +               pwr_cnt |= PSB_PWRGT_VID_ENC_MASK;
100392 +               pwr_mask |= PSB_PWRGT_VID_ENC_MASK;
100393 +       }
100394 +       if (hw_islands & OSPM_VIDEO_DEC_ISLAND) {
100395 +               pwr_cnt |= PSB_PWRGT_VID_DEC_MASK;
100396 +               pwr_mask |= PSB_PWRGT_VID_DEC_MASK;
100397 +       }
100398 +       if (pwr_cnt) {
100399 +               pwr_cnt |= inl(dev_priv->apm_base);
100400 +               outl(pwr_cnt, dev_priv->apm_base);
100401 +               while (true) {
100402 +                       pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
100403 +                       if ((pwr_sts & pwr_mask) == pwr_mask)
100404 +                               break;
100405 +                       else
100406 +                               udelay(10);
100407 +               }
100408 +       }
100409 +
100410 +       if (hw_islands & OSPM_DISPLAY_ISLAND) {
100411 +               pwr_mask = PSB_PWRGT_DISPLAY_MASK;
100412 +               outl(PSB_PWRGT_DISPLAY_MASK, (dev_priv->ospm_base + PSB_PM_SSC));
100413 +               while (true) {
100414 +                       pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
100415 +                       if ((pwr_sts & pwr_mask) == pwr_mask)
100416 +                               break;
100417 +                       else
100418 +                               udelay(10);
100419 +               }
100420 +       }
100421 +}
100422 +
100423 +/*
100424 + * ospm_power_island_up
100425 + *
100426 + * Description: Restore power to the specified island(s) (powergating)
100427 + */
100428 +void ospm_power_island_up(int hw_islands)
100429 +{
100430 +       u32 pwr_cnt;
100431 +       u32 pwr_sts;
100432 +       u32 pwr_mask;
100433 +
100434 +       struct drm_psb_private *dev_priv =
100435 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
100436 +
100437 +       if (IS_MRST(gpDrmDevice) && 
100438 +               (hw_islands & (OSPM_GRAPHICS_ISLAND | OSPM_VIDEO_ENC_ISLAND |
100439 +                      OSPM_VIDEO_DEC_ISLAND))) {
100440 +               pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
100441 +               pwr_mask = 0;
100442 +               if (hw_islands & OSPM_GRAPHICS_ISLAND) {
100443 +                       pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
100444 +                       pwr_mask |= PSB_PWRGT_GFX_MASK;
100445 +            #ifdef OSPM_STAT
100446 +            if (dev_priv->graphics_state == PSB_PWR_STATE_OFF) {
100447 +                dev_priv->gfx_off_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
100448 +                dev_priv->gfx_last_mode_change = jiffies;
100449 +                dev_priv->graphics_state = PSB_PWR_STATE_ON;
100450 +                dev_priv->gfx_on_cnt++;
100451 +            }
100452 +            #endif
100453 +               }
100454 +               if (hw_islands & OSPM_VIDEO_ENC_ISLAND) {
100455 +                       pwr_cnt &= ~PSB_PWRGT_VID_ENC_MASK;
100456 +                       pwr_mask |= PSB_PWRGT_VID_ENC_MASK;
100457 +               }
100458 +               if (hw_islands & OSPM_VIDEO_DEC_ISLAND) {
100459 +                       pwr_cnt &= ~PSB_PWRGT_VID_DEC_MASK;
100460 +                       pwr_mask |= PSB_PWRGT_VID_DEC_MASK;
100461 +               }
100462 +
100463 +               outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
100464 +               while (true) {
100465 +                       pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
100466 +                       if ((pwr_sts & pwr_mask) == 0)
100467 +                               break;
100468 +                       else
100469 +                               udelay(10);
100470 +               }
100471 +       }
100472 +
100473 +       if (hw_islands & OSPM_DISPLAY_ISLAND) {
100474 +               pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
100475 +               pwr_cnt &= ~PSB_PWRGT_DISPLAY_MASK;
100476 +               pwr_mask = PSB_PWRGT_DISPLAY_MASK;
100477 +               outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
100478 +               while (true) {
100479 +                       pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
100480 +                       if ((pwr_sts & pwr_mask) == 0)
100481 +                               break;
100482 +                       else
100483 +                               udelay(10);
100484 +               }
100485 +       }
100486 +
100487 +       g_hw_power_status_mask |= hw_islands;
100488 +}
100489 +
100490 +/*
100491 + * ospm_power_using_hw_begin
100492 + *
100493 + * Description: Notify PowerMgmt module that you will be accessing the
100494 + * specified island's hw so don't power it off.  If the island is off,
100495 + * this function will behave differently depending on the type param.
100496 + *
100497 + * OSPM_UHB_FORCE_POWER_ON:
100498 + *     Power on the specified island.
100499 + * OSPM_UHB_IGNORE_POWER_OFF:
100500 + *     Increment the access counters.  The caller is expected to power on
100501 + *     the island if necessary.
100502 + * OSPM_UHB_ONLY_IF_ON:
100503 + *     Return false and the caller is expected to not access the hw.
100504 + *
100505 + * NOTE *** If this is called from and interrupt handler or other atomic
100506 + * context, then it will return false if we are in the middle of a
100507 + * power state transition and the caller will be expected to handle that
100508 + * even if type is OSPM_UHB_FORCE_POWER_ON.
100509 + */
100510 +bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage)
100511 +{
100512 +       bool ret = false;
100513 +       bool b_island_is_off = false;
100514 +       bool b_atomic = (in_interrupt() || in_atomic());
100515 +       bool b_force_on = (usage == OSPM_UHB_FORCE_POWER_ON);
100516 +       bool b_ignore_off = (usage == OSPM_UHB_IGNORE_POWER_OFF);
100517 +       IMG_UINT32 deviceID = 0;
100518 +
100519 +       if (!b_atomic)
100520 +               mutex_lock(&g_ospm_mutex);
100521 +       else if ((gbSuspendInProgress || gbResumeInProgress) && b_force_on)
100522 +               goto FailExit;
100523 +
100524 +       b_island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask);
100525 +
100526 +       if (b_island_is_off && !b_force_on && !b_ignore_off)
100527 +               goto FailExit;
100528 +
100529 +       if (b_island_is_off && b_force_on) {
100530 +               switch(hw_island)
100531 +               {
100532 +               case OSPM_GRAPHICS_ISLAND:
100533 +                   deviceID = gui32SGXDeviceID;
100534 +                   break;
100535 +               case OSPM_DISPLAY_ISLAND:
100536 +                   deviceID = gui32MRSTDisplayDeviceID;
100537 +                   break;
100538 +               case OSPM_VIDEO_DEC_ISLAND:
100539 +                   deviceID = gui32MRSTMSVDXDeviceID;
100540 +                   break;
100541 +               case OSPM_VIDEO_ENC_ISLAND:
100542 +                   deviceID = gui32MRSTTOPAZDeviceID;
100543 +                   break;
100544 +               }
100545 +
100546 +               if (PVRSRVPowerOnSystemWithDevice(deviceID, b_atomic ? ISR_ID : KERNEL_ID, IMG_FALSE) != PVRSRV_OK)
100547 +                       goto FailExit;
100548 +       } 
100549 +
100550 +       switch(hw_island)
100551 +       {
100552 +       case OSPM_GRAPHICS_ISLAND:
100553 +               atomic_inc(&g_graphics_access_count);
100554 +       case OSPM_VIDEO_ENC_ISLAND:
100555 +               atomic_inc(&g_videoenc_access_count);
100556 +       case OSPM_VIDEO_DEC_ISLAND:
100557 +               atomic_inc(&g_videodec_access_count);
100558 +       case OSPM_DISPLAY_ISLAND:
100559 +               atomic_inc(&g_display_access_count);
100560 +       }
100561 +
100562 +       ret = true;
100563 +FailExit:
100564 +
100565 +       if (!b_atomic)
100566 +               mutex_unlock(&g_ospm_mutex);
100567 +
100568 +       return ret;
100569 +}
100570 +
100571 +
100572 +/*
100573 + * ospm_power_using_hw_end
100574 + *
100575 + * Description: Notify PowerMgmt module that you are done accessing the
100576 + * specified island's hw so feel free to power it off.  Note that this
100577 + * function doesn't actually power off the islands.
100578 + */
100579 +void ospm_power_using_hw_end(int hw_island)
100580 +{
100581 +       switch(hw_island)
100582 +       {
100583 +       case OSPM_GRAPHICS_ISLAND:
100584 +               atomic_dec(&g_graphics_access_count);
100585 +       case OSPM_VIDEO_ENC_ISLAND:
100586 +               atomic_dec(&g_videoenc_access_count);
100587 +       case OSPM_VIDEO_DEC_ISLAND:
100588 +               atomic_dec(&g_videodec_access_count);
100589 +       case OSPM_DISPLAY_ISLAND:
100590 +               atomic_dec(&g_display_access_count);
100591 +       }
100592 +
100593 +       WARN_ON(atomic_read(&g_graphics_access_count) < 0);
100594 +       WARN_ON(atomic_read(&g_videoenc_access_count) < 0);
100595 +       WARN_ON(atomic_read(&g_videodec_access_count) < 0);
100596 +       WARN_ON(atomic_read(&g_display_access_count) < 0);
100597 +}
100598 +
100599 +/*
100600 + * ospm_power_is_hw_on
100601 + *
100602 + * Description: do an instantaneous check for if the specified islands
100603 + * are on.  Only use this in cases where you know the g_state_change_mutex
100604 + * is already held such as in irq install/uninstall.  Otherwise, use
100605 + * ospm_power_using_hw_begin().
100606 + */
100607 +bool ospm_power_is_hw_on(int hw_islands)
100608 +{
100609 +       return ((g_hw_power_status_mask & hw_islands) == hw_islands);
100610 +}
100611 +
100612 +void ospm_apm_power_down_msvdx(struct drm_device *dev)
100613 +{
100614 +       uint32_t ui32_reg_value = 0;
100615 +       mutex_lock(&g_ospm_mutex);
100616 +
100617 +       if (atomic_read(&g_videodec_access_count))
100618 +               goto out;
100619 +       if (psb_check_msvdx_idle(dev))
100620 +               goto out;
100621 +
100622 +       /* FIXME: workaround for HSD3469585  
100623 +        *        re-enable DRAM Self Refresh Mode 
100624 +        *        by setting DUNIT.DPMC0 
100625 +        */
100626 +       ui32_reg_value = MSG_READ32(0x1, 0x4);
100627 +       MSG_WRITE32(0x1, 0x4, (ui32_reg_value | (0x1 << 7)));
100628 +       
100629 +       gbSuspendInProgress = true;
100630 +       PVRSRVSetDevicePowerStateKM(gui32MRSTMSVDXDeviceID,
100631 +                                   PVRSRV_DEV_POWER_STATE_OFF,
100632 +                                   ISR_ID,
100633 +                                   IMG_FALSE);
100634 +       gbSuspendInProgress = false;
100635 +out:
100636 +       mutex_unlock(&g_ospm_mutex);
100637 +       return;
100638 +}
100639 +
100640 +void ospm_apm_power_down_topaz(struct drm_device *dev)
100641 +{
100642 +       mutex_lock(&g_ospm_mutex);
100643 +
100644 +       if (atomic_read(&g_videoenc_access_count))
100645 +               goto out;
100646 +       if (lnc_check_topaz_idle(dev))
100647 +               goto out;
100648 +
100649 +       gbSuspendInProgress = true;
100650 +       PVRSRVSetDevicePowerStateKM(gui32MRSTTOPAZDeviceID,
100651 +                                   PVRSRV_DEV_POWER_STATE_OFF,
100652 +                                   ISR_ID,
100653 +                                   IMG_FALSE);
100654 +       gbSuspendInProgress = false;
100655 +out:
100656 +       mutex_unlock(&g_ospm_mutex);
100657 +       return;
100658 +}
100659 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.h
100660 new file mode 100644
100661 index 0000000..835bfae
100662 --- /dev/null
100663 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/ospm_power.h
100664 @@ -0,0 +1,79 @@
100665 +/**************************************************************************
100666 + * Copyright (c) 2009, Intel Corporation.
100667 + * All Rights Reserved.
100668 + *
100669 + * This program is free software; you can redistribute it and/or modify it
100670 + * under the terms and conditions of the GNU General Public License,
100671 + * version 2, as published by the Free Software Foundation.
100672 + *
100673 + * This program is distributed in the hope it will be useful, but WITHOUT
100674 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
100675 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
100676 + * more details.
100677 + *
100678 + * You should have received a copy of the GNU General Public License along with
100679 + * this program; if not, write to the Free Software Foundation, Inc.,
100680 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
100681 + *
100682 + * Authors:
100683 + *    Benjamin Defnet <benjamin.r.defnet@intel.com>
100684 + *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
100685 + *
100686 + **************************************************************************/
100687 +
100688 +#ifndef _OSPM_POWER_H_
100689 +#define _OSPM_POWER_H_
100690 +
100691 +#include <linux/pci.h>
100692 +#include <drm/drmP.h>
100693 +
100694 +#define OSPM_GRAPHICS_ISLAND   0x1
100695 +#define OSPM_VIDEO_ENC_ISLAND  0x2
100696 +#define OSPM_VIDEO_DEC_ISLAND  0x4
100697 +#define OSPM_DISPLAY_ISLAND    0x8
100698 +#define OSPM_ALL_ISLANDS       0xf
100699 +
100700 +
100701 +typedef enum _UHBUsage
100702 +{
100703 +    OSPM_UHB_ONLY_IF_ON = 0,
100704 +    OSPM_UHB_FORCE_POWER_ON,
100705 +    OSPM_UHB_IGNORE_POWER_OFF,
100706 +} UHBUsage;
100707 +
100708 +
100709 +void ospm_power_init(struct drm_device *dev);
100710 +void ospm_power_uninit(void);
100711 +
100712 +/*
100713 + * OSPM will call these functions
100714 + */
100715 +int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state);
100716 +int ospm_power_resume(struct pci_dev *pdev);
100717 +
100718 +/*
100719 + * These are the functions the driver should use to wrap all hw access
100720 + * (i.e. register reads and writes)
100721 + */
100722 +bool ospm_power_using_hw_begin(int hw_island, UHBUsage type);
100723 +void ospm_power_using_hw_end(int hw_island);
100724 +
100725 +/*
100726 + * Power up/down different hw component rails/islands
100727 + */
100728 +void ospm_power_island_down(int hw_islands);
100729 +void ospm_power_island_up(int hw_islands);
100730 +
100731 +/*
100732 + * Use this function to do an instantaneous check for if the hw is on.
100733 + * Only use this in cases where you know the g_state_change_mutex
100734 + * is already held such as in irq install/uninstall and you need to
100735 + * prevent a deadlock situation.  Otherwise use ospm_power_using_hw_begin().
100736 + */
100737 +bool ospm_power_is_hw_on(int hw_islands);
100738 +
100739 +/* Use these functions to power down video HW for D0i3 purpose  */
100740 +void ospm_apm_power_down_msvdx(struct drm_device *dev);
100741 +void ospm_apm_power_down_topaz(struct drm_device *dev);
100742 +
100743 +#endif /*_OSPM_POWER_H_*/
100744 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.c b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.c
100745 new file mode 100644
100746 index 0000000..6c56df5
100747 --- /dev/null
100748 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.c
100749 @@ -0,0 +1,135 @@
100750 +/**********************************************************************
100751 + *
100752 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
100753 + * 
100754 + * This program is free software; you can redistribute it and/or modify it
100755 + * under the terms and conditions of the GNU General Public License,
100756 + * version 2, as published by the Free Software Foundation.
100757 + * 
100758 + * This program is distributed in the hope it will be useful but, except 
100759 + * as otherwise stated in writing, without any warranty; without even the 
100760 + * implied warranty of merchantability or fitness for a particular purpose. 
100761 + * See the GNU General Public License for more details.
100762 + * 
100763 + * You should have received a copy of the GNU General Public License along with
100764 + * this program; if not, write to the Free Software Foundation, Inc.,
100765 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
100766 + * 
100767 + * The full GNU General Public License is included in this distribution in
100768 + * the file called "COPYING".
100769 + *
100770 + * Contact Information:
100771 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
100772 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
100773 + *
100774 + ******************************************************************************/
100775 +
100776 +#include <drm/drmP.h>
100777 +#include <drm/drm.h>
100778 +
100779 +#include "pvr_drm_shared.h"
100780 +
100781 +#include "services_headers.h"
100782 +#include "private_data.h"
100783 +#include "pvr_drm.h"
100784 +
100785 +#include "pvr_bridge.h"
100786 +#include "linkage.h"
100787 +#include "mmap.h"
100788 +
100789 +#if defined(PDUMP)
100790 +#include "client/linuxsrv.h"
100791 +#endif
100792 +
100793 +#include "sys_pvr_drm_import.h"
100794 +
100795 +#include "sys_pvr_drm_export.h"
100796 +
100797 +int
100798 +SYSPVRInit(void)
100799 +{
100800 +       PVRDPFInit();
100801 +
100802 +       return 0;
100803 +}
100804 +
100805 +
100806 +int
100807 +SYSPVRLoad(struct drm_device *dev, unsigned long flags)
100808 +{
100809 +       return PVRSRVDrmLoad(dev, flags);
100810 +}
100811 +
100812 +int
100813 +SYSPVROpen(struct drm_device *dev, struct drm_file *pFile)
100814 +{
100815 +       return PVRSRVDrmOpen(dev, pFile);
100816 +}
100817 +
100818 +int
100819 +SYSPVRUnload(struct drm_device *dev)
100820 +{
100821 +       return PVRSRVDrmUnload(dev);
100822 +}
100823 +
100824 +void
100825 +SYSPVRPostClose(struct drm_device *dev, struct drm_file *file)
100826 +{
100827 +       return PVRSRVDrmPostClose(dev, file);
100828 +}
100829 +
100830 +int
100831 +SYSPVRBridgeDispatch(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100832 +{
100833 +       return PVRSRV_BridgeDispatchKM(dev, arg, pFile);
100834 +}
100835 +
100836 +int
100837 +SYSPVRDCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100838 +{
100839 +       return PVRDRM_Dummy_ioctl(dev, arg, pFile);
100840 +
100841 +}
100842 +
100843 +int
100844 +SYSPVRBCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100845 +{
100846 +       return PVRDRM_Dummy_ioctl(dev, arg, pFile);
100847 +
100848 +}
100849 +
100850 +int
100851 +SYSPVRIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100852 +{
100853 +       return PVRDRMIsMaster(dev, arg, pFile);
100854 +}
100855 +
100856 +int
100857 +SYSPVRUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100858 +{
100859 +       return PVRDRMUnprivCmd(dev, arg, pFile);
100860 +}
100861 +
100862 +int
100863 +SYSPVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
100864 +{
100865 +       int ret;
100866 +
100867 +       ret = PVRMMap(pFile, ps_vma);
100868 +       if (ret == -ENOENT)
100869 +       {
100870 +               ret = drm_mmap(pFile, ps_vma);
100871 +       }
100872 +
100873 +       return ret;
100874 +}
100875 +
100876 +int
100877 +SYSPVRDBGDrivIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
100878 +{
100879 +#if defined(PDUMP)
100880 +       return dbgdrv_ioctl(dev, arg, pFile);
100881 +#else
100882 +       return -EINVAL;
100883 +#endif
100884 +}
100885 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
100886 new file mode 100644
100887 index 0000000..c73cea1
100888 --- /dev/null
100889 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_export.h
100890 @@ -0,0 +1,87 @@
100891 +/**********************************************************************
100892 + *
100893 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
100894 + * 
100895 + * This program is free software; you can redistribute it and/or modify it
100896 + * under the terms and conditions of the GNU General Public License,
100897 + * version 2, as published by the Free Software Foundation.
100898 + * 
100899 + * This program is distributed in the hope it will be useful but, except 
100900 + * as otherwise stated in writing, without any warranty; without even the 
100901 + * implied warranty of merchantability or fitness for a particular purpose. 
100902 + * See the GNU General Public License for more details.
100903 + * 
100904 + * You should have received a copy of the GNU General Public License along with
100905 + * this program; if not, write to the Free Software Foundation, Inc.,
100906 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
100907 + * 
100908 + * The full GNU General Public License is included in this distribution in
100909 + * the file called "COPYING".
100910 + *
100911 + * Contact Information:
100912 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
100913 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
100914 + *
100915 + ******************************************************************************/
100916 +
100917 +#if !defined(__SYS_PVR_DRM_EXPORT_H__)
100918 +#define __SYS_PVR_DRM_EXPORT_H__
100919 +
100920 +#include "pvr_drm_shared.h"
100921 +
100922 +#if defined(__KERNEL__)
100923 +
100924 +#include "services_headers.h"
100925 +#include "private_data.h"
100926 +#include "pvr_drm.h"
100927 +
100928 +#include "pvr_bridge.h"
100929 +
100930 +#if defined(PDUMP)
100931 +#include "client/linuxsrv.h"
100932 +#endif
100933 +
100934 +#define PVR_DRM_SRVKM_IOCTL \
100935 +       DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_SRVKM_CMD, PVRSRV_BRIDGE_PACKAGE)
100936 +
100937 +#define PVR_DRM_DISP_IOCTL \
100938 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DISP_CMD)
100939 +
100940 +#define PVR_DRM_BC_IOCTL \
100941 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_BC_CMD)
100942 +
100943 +#define        PVR_DRM_IS_MASTER_IOCTL \
100944 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_IS_MASTER_CMD)
100945 +
100946 +#define        PVR_DRM_UNPRIV_IOCTL \
100947 +       DRM_IOWR(DRM_COMMAND_BASE + PVR_DRM_UNPRIV_CMD, IMG_UINT32)
100948 +
100949 +#if defined(PDUMP)
100950 +#define        PVR_DRM_DBGDRV_IOCTL \
100951 +       DRM_IOW(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD, IOCTL_PACKAGE)
100952 +#else
100953 +#define        PVR_DRM_DBGDRV_IOCTL \
100954 +       DRM_IO(DRM_COMMAND_BASE + PVR_DRM_DBGDRV_CMD)
100955 +#endif
100956 +
100957 +int SYSPVRInit(void);
100958 +int SYSPVRLoad(struct drm_device *dev, unsigned long flags);
100959 +int SYSPVROpen(struct drm_device *dev, struct drm_file *pFile);
100960 +int SYSPVRUnload(struct drm_device *dev);
100961 +void SYSPVRPostClose(struct drm_device *dev, struct drm_file *file);
100962 +int SYSPVRBridgeDispatch(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100963 +int SYSPVRDCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100964 +int SYSPVRBCDriverIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100965 +int SYSPVRIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100966 +int SYSPVRUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100967 +
100968 +int SYSPVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
100969 +
100970 +int SYSPVRDBGDrivIoctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile);
100971 +
100972 +int SYSPVRServiceSGXInterrupt(struct drm_device *dev);
100973 +
100974 +#endif 
100975 +
100976 +#endif 
100977 +
100978 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_import.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_import.h
100979 new file mode 100644
100980 index 0000000..1efeb75
100981 --- /dev/null
100982 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sys_pvr_drm_import.h
100983 @@ -0,0 +1,45 @@
100984 +/**********************************************************************
100985 + *
100986 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
100987 + * 
100988 + * This program is free software; you can redistribute it and/or modify it
100989 + * under the terms and conditions of the GNU General Public License,
100990 + * version 2, as published by the Free Software Foundation.
100991 + * 
100992 + * This program is distributed in the hope it will be useful but, except 
100993 + * as otherwise stated in writing, without any warranty; without even the 
100994 + * implied warranty of merchantability or fitness for a particular purpose. 
100995 + * See the GNU General Public License for more details.
100996 + * 
100997 + * You should have received a copy of the GNU General Public License along with
100998 + * this program; if not, write to the Free Software Foundation, Inc.,
100999 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
101000 + * 
101001 + * The full GNU General Public License is included in this distribution in
101002 + * the file called "COPYING".
101003 + *
101004 + * Contact Information:
101005 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
101006 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
101007 + *
101008 + ******************************************************************************/
101009 +
101010 +#if !defined(__SYS_PVR_DRM_IMPORT_H__)
101011 +#define __SYS_PVR_DRM_IMPORT_H__
101012 +
101013 +#if defined(__KERNEL__)
101014 +#include "psb_drm.h"
101015 +#endif
101016 +
101017 +#define DRM_PSB_PLACEMENT_OFFSET   0x13
101018 +
101019 +#if 0
101020 +#define DRM_PVR_RESERVED1      0x0D
101021 +#define DRM_PVR_RESERVED2      0x0E
101022 +#define DRM_PVR_RESERVED3      0x0F
101023 +#define DRM_PVR_RESERVED4      0x10
101024 +#define DRM_PVR_RESERVED5      0x11
101025 +#define DRM_PVR_RESERVED6      0x12
101026 +#endif
101027 +
101028 +#endif 
101029 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.c b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.c
101030 new file mode 100644
101031 index 0000000..955f793
101032 --- /dev/null
101033 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.c
101034 @@ -0,0 +1,1022 @@
101035 +/**********************************************************************
101036 + *
101037 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
101038 + * 
101039 + * This program is free software; you can redistribute it and/or modify it
101040 + * under the terms and conditions of the GNU General Public License,
101041 + * version 2, as published by the Free Software Foundation.
101042 + * 
101043 + * This program is distributed in the hope it will be useful but, except 
101044 + * as otherwise stated in writing, without any warranty; without even the 
101045 + * implied warranty of merchantability or fitness for a particular purpose. 
101046 + * See the GNU General Public License for more details.
101047 + * 
101048 + * You should have received a copy of the GNU General Public License along with
101049 + * this program; if not, write to the Free Software Foundation, Inc.,
101050 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
101051 + * 
101052 + * The full GNU General Public License is included in this distribution in
101053 + * the file called "COPYING".
101054 + *
101055 + * Contact Information:
101056 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
101057 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
101058 + *
101059 + ******************************************************************************/
101060 +
101061 +#if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM)
101062 +#include "linux/pci.h"
101063 +#endif
101064 +#if defined(SUPPORT_DRI_DRM)
101065 +#include "drm/drmP.h"
101066 +#endif
101067 +
101068 +#include "sgxdefs.h"
101069 +#include "services_headers.h"
101070 +#include "kerneldisplay.h"
101071 +#include "oemfuncs.h"
101072 +#include "sgxinfo.h"
101073 +#include "sgxinfokm.h"
101074 +#include "pdump_km.h"
101075 +#include "syslocal.h"
101076 +#include "env_data.h"
101077 +#include "ospm_power.h"
101078 +#include "psb_drv.h"
101079 +#include "sysirq.h"
101080 +#include "msvdx_power.h"
101081 +#include "topaz_power.h"
101082 +#include "sys_pvr_drm_export.h"
101083 +
101084 +/* Graphics MSI address and data region in PCIx */
101085 +#define MRST_PCIx_MSI_ADDR_LOC         0x94
101086 +#define MRST_PCIx_MSI_DATA_LOC         0x98
101087 +
101088 +#define SYS_SGX_CLOCK_SPEED                    (400000000)
101089 +#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ                (100) 
101090 +#define SYS_SGX_PDS_TIMER_FREQ                 (1000) 
101091 +#define SYS_SGX_ACTIVE_POWER_LATENCY_MS                (50)
101092 +
101093 +#if defined(SUPPORT_DRI_DRM_EXT)
101094 +#define        DRI_DRM_STATIC
101095 +#else
101096 +#define        DRI_DRM_STATIC  static
101097 +#endif
101098 +
101099 +SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
101100 +SYS_DATA  gsSysData;
101101 +
101102 +static SYS_SPECIFIC_DATA gsSysSpecificData;
101103 +
101104 +IMG_UINT32             gui32SGXDeviceID;
101105 +static SGX_DEVICE_MAP  gsSGXDeviceMap;
101106 +extern IMG_UINT32      gui32MRSTDisplayDeviceID;
101107 +IMG_UINT32             gui32MRSTMSVDXDeviceID;
101108 +IMG_UINT32             gui32MRSTTOPAZDeviceID;
101109 +
101110 +extern struct drm_device *gpDrmDevice;
101111 +
101112 +#if !defined(NO_HARDWARE)
101113 +IMG_CPU_VIRTADDR gsPoulsboRegsCPUVaddr;
101114 +
101115 +IMG_CPU_VIRTADDR gsPoulsboDisplayRegsCPUVaddr;
101116 +#endif
101117 +
101118 +#ifdef LDM_PCI
101119 +extern struct pci_dev *gpsPVRLDMDev;
101120 +#endif
101121 +
101122 +#define        POULSBO_ADDR_RANGE_INDEX        (MMADR_INDEX - 4)
101123 +#define        POULSBO_HP_ADDR_RANGE_INDEX     (GMADR_INDEX - 4)
101124 +static PVRSRV_ERROR PCIInitDev(SYS_DATA *psSysData)
101125 +{
101126 +       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
101127 +
101128 +#ifdef LDM_PCI
101129 +       psSysSpecData->hSGXPCI = OSPCISetDev((IMG_VOID *)psSysSpecData->psPCIDev, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI);
101130 +#else
101131 +       psSysSpecData->hSGXPCI = OSPCIAcquireDev(SYS_SGX_DEV_VENDOR_ID, gpDrmDevice->pci_device, HOST_PCI_INIT_FLAG_BUS_MASTER | HOST_PCI_INIT_FLAG_MSI);
101132 +#endif
101133 +       if (!psSysSpecData->hSGXPCI)
101134 +       {
101135 +               PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device"));
101136 +               return PVRSRV_ERROR_GENERIC;
101137 +       }
101138 +
101139 +        SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV);
101140 +
101141 +       PVR_TRACE(("PCI memory region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX)));
101142 +       PVR_TRACE(("Host Port region: %x to %x", OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX), OSPCIAddrRangeEnd(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX)));
101143 +
101144 +       
101145 +       if (OSPCIAddrRangeLen(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) < (IS_MRST(gpDrmDevice)? POULSBO_MAX_OFFSET:PSB_POULSBO_MAX_OFFSET))
101146 +       {
101147 +               PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region isn't big enough"));
101148 +               return PVRSRV_ERROR_GENERIC;
101149 +       }
101150 +
101151 +       
101152 +       if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX) != PVRSRV_OK)
101153 +       {
101154 +               PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available"));
101155 +               return PVRSRV_ERROR_GENERIC;
101156 +       }
101157 +        SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE);
101158 +       
101159 +       
101160 +       if (OSPCIRequestAddrRange(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX) != PVRSRV_OK)
101161 +       {
101162 +               PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Host Port region not available"));
101163 +               return PVRSRV_ERROR_GENERIC;
101164 +       }
101165 +        SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE);
101166 +       
101167 +       return PVRSRV_OK;
101168 +}
101169 +
101170 +static IMG_VOID PCIDeInitDev(SYS_DATA *psSysData)
101171 +{
101172 +       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
101173 +
101174 +       if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE))
101175 +       {
101176 +               OSPCIReleaseAddrRange(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX);
101177 +       }
101178 +
101179 +       if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE))
101180 +       {
101181 +               OSPCIReleaseAddrRange(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX);
101182 +       }
101183 +
101184 +       if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV))
101185 +       {
101186 +               OSPCIReleaseDev(psSysSpecData->hSGXPCI);
101187 +       }
101188 +}
101189 +static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
101190 +{
101191 +       IMG_UINT32 ui32BaseAddr = 0;
101192 +       IMG_UINT32 ui32IRQ = 0;
101193 +       IMG_UINT32 ui32HostPortAddr = 0;
101194 +       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
101195 +
101196 +       ui32BaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX);
101197 +       ui32HostPortAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX);
101198 +       if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK)
101199 +       {
101200 +               PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ"));
101201 +               return PVRSRV_ERROR_INVALID_DEVICE;
101202 +       }
101203 +
101204 +       PVR_TRACE(("ui32BaseAddr: %p", ui32BaseAddr));
101205 +       PVR_TRACE(("ui32HostPortAddr: %p", ui32HostPortAddr));
101206 +       PVR_TRACE(("IRQ: %d", ui32IRQ));
101207 +
101208 +       
101209 +       gsSGXDeviceMap.ui32Flags = 0x0;
101210 +       gsSGXDeviceMap.ui32IRQ = ui32IRQ;
101211 +
101212 +       if (IS_MRST(gpDrmDevice))
101213 +               gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + SGX_REGS_OFFSET;
101214 +       else
101215 +               gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + PSB_SGX_REGS_OFFSET;
101216 +
101217 +       gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
101218 +       gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE;
101219 +       
101220 +#if defined(SGX_FEATURE_HOST_PORT)
101221 +       
101222 +       gsSGXDeviceMap.ui32Flags = SGX_HOSTPORT_PRESENT;
101223 +       gsSGXDeviceMap.sHPSysPBase.uiAddr = ui32HostPortAddr;
101224 +       gsSGXDeviceMap.sHPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sHPSysPBase);
101225 +
101226 +       if (IS_MRST(gpDrmDevice))
101227 +               gsSGXDeviceMap.ui32HPSize = SYS_SGX_HP_SIZE;
101228 +       else
101229 +               gsSGXDeviceMap.ui32HPSize = PSB_SYS_SGX_HP_SIZE;
101230 +#endif         
101231 +
101232 +#if defined(MRST_SLAVEPORT)
101233 +       
101234 +       gsSGXDeviceMap.sSPSysPBase.uiAddr = ui32BaseAddr + MRST_SGX_SP_OFFSET;
101235 +       gsSGXDeviceMap.sSPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sSPSysPBase);
101236 +       gsSGXDeviceMap.ui32SPSize = SGX_SP_SIZE;
101237 +#endif
101238 +       
101239 +
101240 +
101241 +
101242 +       gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0;
101243 +       gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0;
101244 +       gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0;
101245 +       gsSGXDeviceMap.ui32LocalMemSize = 0;
101246 +
101247 +       
101248 +       {
101249 +               IMG_SYS_PHYADDR sPoulsboRegsCpuPBase;
101250 +               sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_REGS_OFFSET;
101251 +               gsPoulsboRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase),
101252 +                                                                                                POULSBO_REG_SIZE,
101253 +                                                                                                PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101254 +                                                                                                IMG_NULL);
101255 +
101256 +               sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_DISPLAY_REGS_OFFSET;
101257 +               gsPoulsboDisplayRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase),
101258 +                                                                                                POULSBO_DISPLAY_REG_SIZE,
101259 +                                                                                                PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101260 +                                                                                                IMG_NULL);
101261 +       }
101262 +
101263 +       return PVRSRV_OK;
101264 +}
101265 +
101266 +
101267 +#define VERSION_STR_MAX_LEN_TEMPLATE "SGX revision = 000.000.000"
101268 +static PVRSRV_ERROR SysCreateVersionString(SYS_DATA *psSysData)
101269 +{
101270 +    IMG_UINT32 ui32MaxStrLen;
101271 +    PVRSRV_ERROR eError;
101272 +    IMG_INT32 i32Count;
101273 +    IMG_CHAR *pszVersionString;
101274 +    IMG_UINT32 ui32SGXRevision = 0;
101275 +       IMG_VOID *pvSGXRegs;
101276 +
101277 +       pvSGXRegs = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
101278 +                                                                                        gsSGXDeviceMap.ui32RegsSize,
101279 +                                                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101280 +                                                                                        IMG_NULL);
101281 +
101282 +       if (pvSGXRegs != IMG_NULL)
101283 +       {
101284 +            ui32SGXRevision = OSReadHWReg(pvSGXRegs, EUR_CR_CORE_REVISION);
101285 +            OSUnMapPhysToLin(pvSGXRegs,
101286 +                                                                                               gsSGXDeviceMap.ui32RegsSize,
101287 +                                                                                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101288 +                                                                                               IMG_NULL);
101289 +       }
101290 +       else
101291 +       {
101292 +            PVR_DPF((PVR_DBG_ERROR,"SysCreateVersionString: Couldn't map SGX registers"));
101293 +       }
101294 +
101295 +    ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
101296 +    eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
101297 +                          ui32MaxStrLen + 1,
101298 +                          (IMG_PVOID *)&pszVersionString,
101299 +                          IMG_NULL,
101300 +                         "Version String");
101301 +    if(eError != PVRSRV_OK)
101302 +    {
101303 +               return PVRSRV_ERROR_GENERIC;
101304 +    }
101305 +
101306 +    i32Count = OSSNPrintf(pszVersionString, ui32MaxStrLen + 1,
101307 +                           "SGX revision = %u.%u.%u",
101308 +                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)
101309 +                            >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
101310 +                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)
101311 +                            >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
101312 +                           (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
101313 +                            >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
101314 +                           );
101315 +    if(i32Count == -1)
101316 +    {
101317 +        ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
101318 +        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
101319 +                    ui32MaxStrLen + 1,
101320 +                    pszVersionString,
101321 +                    IMG_NULL);
101322 +               
101323 +               return PVRSRV_ERROR_GENERIC;
101324 +    }
101325 +
101326 +    psSysData->pszVersionString = pszVersionString;
101327 +
101328 +    return PVRSRV_OK;
101329 +}
101330 +
101331 +static IMG_VOID SysFreeVersionString(SYS_DATA *psSysData)
101332 +{ 
101333 +    if(psSysData->pszVersionString)
101334 +    {
101335 +        IMG_UINT32 ui32MaxStrLen;
101336 +        ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE);
101337 +        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
101338 +                    ui32MaxStrLen+1,
101339 +                    psSysData->pszVersionString,
101340 +                    IMG_NULL);
101341 +               psSysData->pszVersionString = IMG_NULL;
101342 +    }
101343 +}
101344 +
101345 +extern int drm_psb_ospm;
101346 +
101347 +PVRSRV_ERROR SysInitialise(IMG_VOID)
101348 +{
101349 +       IMG_UINT32                      i                         = 0;
101350 +       PVRSRV_ERROR            eError;
101351 +       PVRSRV_DEVICE_NODE      *psDeviceNode;
101352 +       SGX_TIMING_INFORMATION* psTimingInfo;
101353 +       struct drm_psb_private *dev_priv =
101354 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
101355 +
101356 +       gpsSysData = &gsSysData;
101357 +       OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
101358 +
101359 +       gpsSysData->pvSysSpecificData = &gsSysSpecificData;
101360 +       gsSysSpecificData.ui32SysSpecificData = 0;
101361 +#ifdef LDM_PCI
101362 +       
101363 +       PVR_ASSERT(gpsPVRLDMDev != IMG_NULL);
101364 +       gsSysSpecificData.psPCIDev = gpsPVRLDMDev;
101365 +#endif
101366 +
101367 +       eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
101368 +       if (eError != PVRSRV_OK)
101369 +       {
101370 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
101371 +               SysDeinitialise(gpsSysData);
101372 +               gpsSysData = IMG_NULL;
101373 +               return eError;
101374 +       }
101375 +
101376 +       
101377 +       psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
101378 +       psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
101379 +       psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; 
101380 +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
101381 +       psTimingInfo->bEnableActivePM = (drm_psb_ospm != 0);
101382 +       printk(KERN_ERR "SGX APM is %s\n", (drm_psb_ospm != 0)? "enabled":"disabled");
101383 +#else  
101384 +       psTimingInfo->bEnableActivePM = IMG_FALSE;
101385 +#endif 
101386 +       psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; 
101387 +       psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; 
101388 +
101389 +       eError = PCIInitDev(gpsSysData);
101390 +       if (eError != PVRSRV_OK)
101391 +       {
101392 +               SysDeinitialise(gpsSysData);
101393 +               gpsSysData = IMG_NULL;
101394 +               return eError;
101395 +       }
101396 +
101397 +       gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
101398 +
101399 +       
101400 +       for(i=0; i<SYS_DEVICE_COUNT; i++)
101401 +       {
101402 +               gpsSysData->sDeviceID[i].uiID = i;
101403 +               gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
101404 +       }
101405 +
101406 +       gpsSysData->psDeviceNodeList = IMG_NULL;
101407 +       gpsSysData->psQueueList = IMG_NULL;
101408 +
101409 +       eError = SysInitialiseCommon(gpsSysData);
101410 +       if (eError != PVRSRV_OK)
101411 +       {
101412 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));
101413 +               SysDeinitialise(gpsSysData);
101414 +               gpsSysData = IMG_NULL;
101415 +               return eError;
101416 +       }
101417 +       
101418 +       
101419 +
101420 +
101421 +
101422 +       eError = SysLocateDevices(gpsSysData);
101423 +       if (eError != PVRSRV_OK)
101424 +       {
101425 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
101426 +               SysDeinitialise(gpsSysData);
101427 +               gpsSysData = IMG_NULL;
101428 +               return eError;
101429 +       }
101430 +
101431 +       
101432 +
101433 +
101434 +       eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
101435 +                                                                 DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
101436 +       if (eError != PVRSRV_OK)
101437 +       {
101438 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
101439 +               SysDeinitialise(gpsSysData);
101440 +               gpsSysData = IMG_NULL;
101441 +               return eError;
101442 +       }
101443 +
101444 +
101445 +       /* register MSVDX, with 0 interrupt bit, no interrupt will be served */
101446 +       eError = PVRSRVRegisterDevice(gpsSysData, MSVDXRegisterDevice,
101447 +                                     DEVICE_MSVDX_INTERRUPT, &gui32MRSTMSVDXDeviceID);
101448 +       if (eError != PVRSRV_OK)
101449 +       {
101450 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register MSVDXdevice!"));
101451 +               SysDeinitialise(gpsSysData);
101452 +               gpsSysData = IMG_NULL;
101453 +               return eError;
101454 +       }
101455 +
101456 +       if (IS_MRST(gpDrmDevice) && !dev_priv->topaz_disabled)
101457 +       {
101458 +               /* register TOPAZ, with 0 interrupt bit, no interrupt will be served */
101459 +               eError = PVRSRVRegisterDevice(gpsSysData, TOPAZRegisterDevice,
101460 +                                             DEVICE_TOPAZ_INTERRUPT, &gui32MRSTTOPAZDeviceID);
101461 +               if (eError != PVRSRV_OK)
101462 +               {
101463 +                       PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register TOPAZdevice!"));
101464 +                       SysDeinitialise(gpsSysData);
101465 +                       gpsSysData = IMG_NULL;
101466 +                       return eError;
101467 +               }
101468 +       }
101469 +
101470 +       psDeviceNode = gpsSysData->psDeviceNodeList;
101471 +
101472 +       while(psDeviceNode)
101473 +       {
101474 +               
101475 +               switch(psDeviceNode->sDevId.eDeviceType)
101476 +               {
101477 +                       case PVRSRV_DEVICE_TYPE_SGX:
101478 +                       {
101479 +                               DEVICE_MEMORY_INFO *psDevMemoryInfo;
101480 +                               DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
101481 +                               
101482 +                               
101483 +                               psDeviceNode->psLocalDevMemArena = IMG_NULL;
101484 +                               
101485 +                               
101486 +                               psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
101487 +                               psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
101488 +                               
101489 +                               
101490 +                               for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)
101491 +                               {
101492 +                                       psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
101493 +#ifdef OEM_CUSTOMISE
101494 +                                       
101495 +#endif
101496 +                               }
101497 +
101498 +                               break;
101499 +                       }
101500 +                       case PVRSRV_DEVICE_TYPE_MSVDX:
101501 +                       /* nothing need to do here */
101502 +                       break;
101503 +                       case PVRSRV_DEVICE_TYPE_TOPAZ:
101504 +                       break;
101505 +                       default:
101506 +                       {
101507 +                               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));
101508 +                               return PVRSRV_ERROR_INIT_FAILURE;
101509 +                       }
101510 +               }
101511 +
101512 +               
101513 +               psDeviceNode = psDeviceNode->psNext;
101514 +       }
101515 +
101516 +       PDUMPINIT();
101517 +       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PDUMP_INIT);
101518 +
101519 +       
101520 +       eError = PVRSRVInitialiseDevice (gui32SGXDeviceID);
101521 +       if (eError != PVRSRV_OK)
101522 +       {
101523 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
101524 +               SysDeinitialise(gpsSysData);
101525 +               gpsSysData = IMG_NULL;
101526 +               return eError;
101527 +       }
101528 +       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_SGX_INITIALISED);
101529 +
101530 +       eError = PVRSRVInitialiseDevice (gui32MRSTMSVDXDeviceID);
101531 +       if (eError != PVRSRV_OK)
101532 +       {
101533 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
101534 +               SysDeinitialise(gpsSysData);
101535 +               gpsSysData = IMG_NULL;
101536 +               return eError;
101537 +       }
101538 +
101539 +       if (IS_MRST(gpDrmDevice) && !dev_priv->topaz_disabled)
101540 +       {
101541 +               eError = PVRSRVInitialiseDevice (gui32MRSTTOPAZDeviceID);
101542 +               if (eError != PVRSRV_OK)
101543 +               {
101544 +                       PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
101545 +                       SysDeinitialise(gpsSysData);
101546 +                       gpsSysData = IMG_NULL;
101547 +                       return eError;
101548 +               }
101549 +       }
101550 +
101551 +       if (!sysirq_init(gpDrmDevice))
101552 +       {
101553 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
101554 +               SysDeinitialise(gpsSysData);
101555 +               gpsSysData = IMG_NULL;
101556 +               return PVRSRV_ERROR_INIT_FAILURE;           
101557 +       }
101558 +
101559 +       return PVRSRV_OK;
101560 +}
101561 +
101562 +PVRSRV_ERROR SysFinalise(IMG_VOID)
101563 +{
101564 +       PVRSRV_ERROR eError = PVRSRV_OK;
101565 +
101566 +       eError = SysCreateVersionString(gpsSysData);
101567 +       if (eError != PVRSRV_OK)
101568 +       {
101569 +               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to create a system version string"));
101570 +       }
101571 +       else
101572 +       {
101573 +           PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
101574 +       }
101575 +
101576 +       return eError;
101577 +}
101578 +
101579 +PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
101580 +{
101581 +       PVRSRV_ERROR eError;
101582 +
101583 +       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
101584 +
101585 +       sysirq_uninit(gpDrmDevice);
101586 +
101587 +       if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_SGX_INITIALISED))
101588 +       {
101589 +               
101590 +               eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID);
101591 +               if (eError != PVRSRV_OK)
101592 +               {
101593 +                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));
101594 +                       return eError;
101595 +               }
101596 +       }
101597 +
101598 +       SysFreeVersionString(psSysData);
101599 +
101600 +       PCIDeInitDev(psSysData);
101601 +
101602 +       eError = OSDeInitEnvData(psSysData->pvEnvSpecificData);
101603 +       if (eError != PVRSRV_OK)
101604 +       {
101605 +               PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));
101606 +               return eError;
101607 +       }
101608 +
101609 +       SysDeinitialiseCommon(gpsSysData);
101610 +
101611 +
101612 +#if !defined(NO_HARDWARE)
101613 +       
101614 +       OSUnMapPhysToLin(gsPoulsboRegsCPUVaddr,
101615 +                                                                                        POULSBO_REG_SIZE,
101616 +                                                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101617 +                                                                                        IMG_NULL);
101618 +
101619 +       OSUnMapPhysToLin(gsPoulsboDisplayRegsCPUVaddr,
101620 +                                                                                        POULSBO_DISPLAY_REG_SIZE,
101621 +                                                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101622 +                                                                                        IMG_NULL);
101623 +#endif
101624 +       if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_PDUMP_INIT))
101625 +       {
101626 +               PDUMPDEINIT();
101627 +       }
101628 +
101629 +       gpsSysData = IMG_NULL;
101630 +
101631 +       return PVRSRV_OK;
101632 +}
101633 +
101634 +
101635 +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, 
101636 +                                                                       IMG_VOID **ppvDeviceMap)
101637 +{
101638 +       switch(eDeviceType)
101639 +       {
101640 +               case PVRSRV_DEVICE_TYPE_SGX:
101641 +               {
101642 +                       
101643 +                       *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
101644 +                       break;
101645 +               }
101646 +               default:
101647 +               {
101648 +                       PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
101649 +               }
101650 +       }
101651 +       return PVRSRV_OK;       
101652 +}
101653 +
101654 +
101655 +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, 
101656 +                                                                               IMG_CPU_PHYADDR CpuPAddr)
101657 +{
101658 +       IMG_DEV_PHYADDR DevPAddr;
101659 +
101660 +       PVR_UNREFERENCED_PARAMETER(eDeviceType);
101661 +
101662 +       
101663 +       DevPAddr.uiAddr = CpuPAddr.uiAddr;
101664 +
101665 +       return DevPAddr;
101666 +}
101667 +
101668 +
101669 +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
101670 +{
101671 +       IMG_CPU_PHYADDR cpu_paddr;
101672 +
101673 +       
101674 +       cpu_paddr.uiAddr = sys_paddr.uiAddr;
101675 +       return cpu_paddr;
101676 +}
101677 +
101678 +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
101679 +{
101680 +       IMG_SYS_PHYADDR sys_paddr;
101681 +       
101682 +       
101683 +       sys_paddr.uiAddr = cpu_paddr.uiAddr;
101684 +       return sys_paddr;
101685 +}
101686 +
101687 +
101688 +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
101689 +{
101690 +    IMG_DEV_PHYADDR DevPAddr;
101691 +
101692 +       PVR_UNREFERENCED_PARAMETER(eDeviceType);
101693 +
101694 +       
101695 +    DevPAddr.uiAddr = SysPAddr.uiAddr;
101696 +    
101697 +    return DevPAddr;
101698 +}
101699 +
101700 +
101701 +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
101702 +{
101703 +    IMG_SYS_PHYADDR SysPAddr;
101704 +
101705 +       PVR_UNREFERENCED_PARAMETER(eDeviceType);
101706 +
101707 +    
101708 +    SysPAddr.uiAddr = DevPAddr.uiAddr;
101709 +
101710 +    return SysPAddr;
101711 +}
101712 +
101713 +
101714 +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
101715 +{
101716 +  
101717 +  psDeviceNode->ui32SOCInterruptBit = DEVICE_DISP_INTERRUPT;   
101718 +}
101719 +
101720 +
101721 +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
101722 +{
101723 +       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
101724 +}
101725 +
101726 +PVRSRV_ERROR SysOEMFunction (  IMG_UINT32      ui32ID, 
101727 +                                                               IMG_VOID        *pvIn,
101728 +                                                               IMG_UINT32  ulInSize,
101729 +                                                               IMG_VOID        *pvOut,
101730 +                                                               IMG_UINT32      ulOutSize)
101731 +{
101732 +       if (ulInSize || pvIn);
101733 +
101734 +       if ((ui32ID == OEM_GET_EXT_FUNCS) &&
101735 +               (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))
101736 +       {
101737 +               PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*)pvOut;
101738 +
101739 +               psOEMJTable->pfnOEMReadRegistryString  = IMG_NULL;
101740 +               psOEMJTable->pfnOEMWriteRegistryString = IMG_NULL;
101741 +
101742 +               return PVRSRV_OK;
101743 +       }
101744 +
101745 +       return PVRSRV_ERROR_INVALID_PARAMS;
101746 +}
101747 +
101748 +
101749 +PVRSRV_ERROR SysMapInRegisters(IMG_VOID)
101750 +{
101751 +       PVRSRV_DEVICE_NODE *psDeviceNodeList;
101752 +
101753 +       psDeviceNodeList = gpsSysData->psDeviceNodeList;
101754 +
101755 +       while (psDeviceNodeList)
101756 +       {
101757 +               switch(psDeviceNodeList->sDevId.eDeviceType)
101758 +               {
101759 +               case PVRSRV_DEVICE_TYPE_SGX:
101760 +               {
101761 +                       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice;
101762 +                       
101763 +                       if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS))
101764 +                       {
101765 +                               psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
101766 +                                                                        gsSGXDeviceMap.ui32RegsSize,
101767 +                                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101768 +                                                                        IMG_NULL);
101769 +
101770 +                               if (!psDevInfo->pvRegsBaseKM)
101771 +                               {
101772 +                                       PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in SGX registers\n"));
101773 +                                       return PVRSRV_ERROR_BAD_MAPPING;
101774 +                               }
101775 +                               SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
101776 +                       }
101777 +                       psDevInfo->ui32RegSize   = gsSGXDeviceMap.ui32RegsSize;
101778 +                       psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase;
101779 +
101780 +#if defined(SGX_FEATURE_HOST_PORT)
101781 +                       if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
101782 +                       {
101783 +                               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP))
101784 +                               {
101785 +                                       
101786 +                                       psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase,
101787 +                                                                                                                    gsSGXDeviceMap.ui32HPSize,
101788 +                                                                                                                    PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101789 +                                                                                                                    IMG_NULL);
101790 +                                       if (!psDevInfo->pvHostPortBaseKM)
101791 +                                       {
101792 +                                               PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n"));
101793 +                                               return PVRSRV_ERROR_BAD_MAPPING;
101794 +                                       }
101795 +                                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
101796 +                               }
101797 +                               psDevInfo->ui32HPSize  = gsSGXDeviceMap.ui32HPSize;
101798 +                               psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase;
101799 +                       }
101800 +#endif 
101801 +                       break;
101802 +               }
101803 +               default:
101804 +                       break;
101805 +               }
101806 +               psDeviceNodeList = psDeviceNodeList->psNext;
101807 +       }
101808 +
101809 +       return PVRSRV_OK;
101810 +}
101811 +
101812 +
101813 +PVRSRV_ERROR SysUnmapRegisters(IMG_VOID)
101814 +{
101815 +       PVRSRV_DEVICE_NODE *psDeviceNodeList;
101816 +
101817 +       psDeviceNodeList = gpsSysData->psDeviceNodeList;
101818 +
101819 +       while (psDeviceNodeList)
101820 +       {
101821 +               switch (psDeviceNodeList->sDevId.eDeviceType)
101822 +               {
101823 +               case PVRSRV_DEVICE_TYPE_SGX:
101824 +               {
101825 +                       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice;
101826 +#if !(defined(NO_HARDWARE) && defined(__linux__))
101827 +                       
101828 +                       if (psDevInfo->pvRegsBaseKM)
101829 +                       {
101830 +                               OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
101831 +                                                gsSGXDeviceMap.ui32RegsSize,
101832 +                                                PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101833 +                                                IMG_NULL);
101834 +
101835 +                               SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS);
101836 +                       }
101837 +#endif 
101838 +
101839 +                       psDevInfo->pvRegsBaseKM = IMG_NULL;
101840 +                       psDevInfo->ui32RegSize          = 0;
101841 +                       psDevInfo->sRegsPhysBase.uiAddr = 0;
101842 +
101843 +#if defined(SGX_FEATURE_HOST_PORT)
101844 +                       if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT)
101845 +                       {
101846 +                               
101847 +                               if (psDevInfo->pvHostPortBaseKM)
101848 +                               {
101849 +                                       OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
101850 +                                                        gsSGXDeviceMap.ui32HPSize,
101851 +                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101852 +                                                        IMG_NULL);
101853 +
101854 +                                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP);
101855 +
101856 +                                       psDevInfo->pvHostPortBaseKM = IMG_NULL;
101857 +                               }
101858 +
101859 +                               psDevInfo->ui32HPSize  = 0;
101860 +                               psDevInfo->sHPSysPAddr.uiAddr = 0;
101861 +                       }
101862 +#endif 
101863 +                       break;
101864 +               }
101865 +               default:
101866 +                       break;
101867 +               }
101868 +               psDeviceNodeList = psDeviceNodeList->psNext;
101869 +       }
101870 +
101871 +#if !(defined(NO_HARDWARE) && defined(__linux__))
101872 +       
101873 +       OSUnMapPhysToLin(gsPoulsboRegsCPUVaddr,
101874 +                               POULSBO_REG_SIZE,
101875 +                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101876 +                               IMG_NULL);
101877 +
101878 +       
101879 +       OSUnMapPhysToLin(gsPoulsboDisplayRegsCPUVaddr,
101880 +                               POULSBO_DISPLAY_REG_SIZE,
101881 +                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
101882 +                               IMG_NULL);
101883 +
101884 +#endif 
101885 +
101886 +       return PVRSRV_OK;
101887 +}
101888 +
101889 +
101890 +PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
101891 +{
101892 +       PVRSRV_ERROR eError= PVRSRV_OK;
101893 +       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)(gsSysSpecificData.hSGXPCI);
101894 +
101895 +       if (eNewPowerState != gpsSysData->eCurrentPowerState)
101896 +       {
101897 +               if ((eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) &&
101898 +                       (gpsSysData->eCurrentPowerState < PVRSRV_SYS_POWER_STATE_D3))
101899 +               {
101900 +                       drm_irq_uninstall(gpDrmDevice);
101901 +
101902 +                       SysUnmapRegisters();
101903 +
101904 +                       //Save some pci state that won't get saved properly by pci_save_state()
101905 +                       pci_read_config_dword(psPVRPCI->psPCIDev, 0x5C, &gsSysSpecificData.saveBSM);
101906 +                       pci_read_config_dword(psPVRPCI->psPCIDev, 0xFC, &gsSysSpecificData.saveVBT);
101907 +                       pci_read_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_ADDR_LOC, &gsSysSpecificData.msi_addr);
101908 +                       pci_read_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_DATA_LOC, &gsSysSpecificData.msi_data);
101909 +
101910 +                       eError = OSPCISuspendDev(gsSysSpecificData.hSGXPCI);
101911 +                       if (eError != PVRSRV_OK)
101912 +                       {
101913 +                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSPCISuspendDev failed (%d)", eError));
101914 +                       }
101915 +               }
101916 +       }
101917 +
101918 +       return eError;
101919 +}
101920 +
101921 +PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
101922 +{
101923 +       PVRSRV_ERROR eError = PVRSRV_OK;
101924 +       PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)(gsSysSpecificData.hSGXPCI);
101925 +
101926 +       if (eNewPowerState != gpsSysData->eCurrentPowerState)
101927 +       {
101928 +               if ((gpsSysData->eCurrentPowerState == PVRSRV_SYS_POWER_STATE_D3) &&
101929 +                       (eNewPowerState < PVRSRV_SYS_POWER_STATE_D3))
101930 +               {
101931 +                       eError = OSPCIResumeDev(gsSysSpecificData.hSGXPCI);
101932 +                       if (eError != PVRSRV_OK)
101933 +                       {
101934 +                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSPCIResumeDev failed (%d)", eError));
101935 +                               return eError;
101936 +                       }
101937 +
101938 +                       //Restore some pci state that will not have gotten restored properly by pci_restore_state()
101939 +                       pci_write_config_dword(psPVRPCI->psPCIDev, 0x5c, gsSysSpecificData.saveBSM);
101940 +                       pci_write_config_dword(psPVRPCI->psPCIDev, 0xFC, gsSysSpecificData.saveVBT);
101941 +                       pci_write_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_ADDR_LOC, gsSysSpecificData.msi_addr);
101942 +                       pci_write_config_dword(psPVRPCI->psPCIDev, MRST_PCIx_MSI_DATA_LOC, gsSysSpecificData.msi_data);
101943 +
101944 +                       eError = SysLocateDevices(gpsSysData);
101945 +                       if (eError != PVRSRV_OK)
101946 +                       {
101947 +                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to locate devices"));
101948 +                               return eError;
101949 +                       }
101950 +
101951 +                       eError = SysMapInRegisters();
101952 +                       if (eError != PVRSRV_OK)
101953 +                       {
101954 +                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: Failed to map in registers"));
101955 +                               return eError;
101956 +                       }
101957 +
101958 +                       drm_irq_install(gpDrmDevice);
101959 +               }
101960 +       }
101961 +       return eError;
101962 +}
101963 +
101964 +
101965 +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32                 ui32DeviceIndex,
101966 +                                                                       PVRSRV_DEV_POWER_STATE  eNewPowerState,
101967 +                                                                       PVRSRV_DEV_POWER_STATE  eCurrentPowerState)
101968 +{
101969 +       if ((eNewPowerState != eCurrentPowerState) &&
101970 +           (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF))
101971 +       {
101972 +               if (ui32DeviceIndex == gui32SGXDeviceID)
101973 +               {
101974 +                       PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Remove SGX power"));
101975 +                       sysirq_uninstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
101976 +                       ospm_power_island_down(OSPM_GRAPHICS_ISLAND);
101977 +               }
101978 +               else if (ui32DeviceIndex == gui32MRSTDisplayDeviceID)
101979 +               {
101980 +                       sysirq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
101981 +                       ospm_power_island_down(OSPM_DISPLAY_ISLAND);
101982 +               }
101983 +               else if (ui32DeviceIndex == gui32MRSTMSVDXDeviceID)
101984 +               {
101985 +                       sysirq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
101986 +                       if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
101987 +                               ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
101988 +                       } else {
101989 +                               ospm_power_island_up(OSPM_DISPLAY_ISLAND);
101990 +                               ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
101991 +                               ospm_power_island_down(OSPM_DISPLAY_ISLAND);
101992 +                       }
101993 +               }
101994 +               else if (ui32DeviceIndex == gui32MRSTTOPAZDeviceID)
101995 +               {
101996 +                       if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
101997 +                               ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
101998 +                       } else {
101999 +                               ospm_power_island_up(OSPM_DISPLAY_ISLAND);
102000 +                               ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
102001 +                               ospm_power_island_down(OSPM_DISPLAY_ISLAND);
102002 +                       }
102003 +               }
102004 +       }
102005 +
102006 +       return PVRSRV_OK;
102007 +}
102008 +
102009 +
102010 +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32                        ui32DeviceIndex,
102011 +                                                                        PVRSRV_DEV_POWER_STATE eNewPowerState,
102012 +                                                                        PVRSRV_DEV_POWER_STATE eCurrentPowerState)
102013 +{
102014 +       if ((eNewPowerState != eCurrentPowerState) &&
102015 +           (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF))
102016 +       {
102017 +               if (ui32DeviceIndex == gui32SGXDeviceID)
102018 +               {
102019 +                       PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePostPowerState: Restore SGX power"));
102020 +                       ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
102021 +                       sysirq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
102022 +                       sysirq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
102023 +               }
102024 +               else if (ui32DeviceIndex == gui32MRSTDisplayDeviceID)
102025 +               {
102026 +                       ospm_power_island_up(OSPM_DISPLAY_ISLAND);
102027 +                       sysirq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
102028 +                       sysirq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
102029 +               }
102030 +               else if (ui32DeviceIndex == gui32MRSTMSVDXDeviceID)
102031 +               {
102032 +                       if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
102033 +                               ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
102034 +                       } else {
102035 +                               ospm_power_island_up(OSPM_DISPLAY_ISLAND);
102036 +                               ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
102037 +                               ospm_power_island_down(OSPM_DISPLAY_ISLAND);
102038 +                       }
102039 +                       sysirq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
102040 +                       sysirq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
102041 +               }
102042 +               else if (ui32DeviceIndex == gui32MRSTTOPAZDeviceID)
102043 +               {
102044 +                       if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
102045 +                               ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
102046 +                       } else {
102047 +                               ospm_power_island_up(OSPM_DISPLAY_ISLAND);
102048 +                               ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
102049 +                               ospm_power_island_down(OSPM_DISPLAY_ISLAND);
102050 +                       }
102051 +               }
102052 +       }
102053 +
102054 +       return PVRSRV_OK;
102055 +}
102056 +
102057 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.h
102058 new file mode 100644
102059 index 0000000..0476e2c
102060 --- /dev/null
102061 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysconfig.h
102062 @@ -0,0 +1,139 @@
102063 +/**********************************************************************
102064 + *
102065 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
102066 + * 
102067 + * This program is free software; you can redistribute it and/or modify it
102068 + * under the terms and conditions of the GNU General Public License,
102069 + * version 2, as published by the Free Software Foundation.
102070 + * 
102071 + * This program is distributed in the hope it will be useful but, except 
102072 + * as otherwise stated in writing, without any warranty; without even the 
102073 + * implied warranty of merchantability or fitness for a particular purpose. 
102074 + * See the GNU General Public License for more details.
102075 + * 
102076 + * You should have received a copy of the GNU General Public License along with
102077 + * this program; if not, write to the Free Software Foundation, Inc.,
102078 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102079 + * 
102080 + * The full GNU General Public License is included in this distribution in
102081 + * the file called "COPYING".
102082 + *
102083 + * Contact Information:
102084 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
102085 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
102086 + *
102087 + ******************************************************************************/
102088 +
102089 +#if !defined(__SOCCONFIG_H__)
102090 +#define __SOCCONFIG_H__
102091 +#include "syscommon.h"
102092 +
102093 +#define VS_PRODUCT_NAME        "SGX Moorestown"
102094 +
102095 +#define SYS_NO_POWER_LOCK_TIMEOUT
102096 +
102097 +#define SGX_FEATURE_HOST_PORT
102098 +
102099 +#define SYS_SGX_USSE_COUNT                                     (2)
102100 +
102101 +#define POULSBO_REGS_OFFSET    0x00000
102102 +#define POULSBO_REG_SIZE       0x2100  
102103 +
102104 +#define SGX_REGS_OFFSET                0x80000
102105 +#define PSB_SGX_REGS_OFFSET    0x40000
102106 +#define SGX_REG_SIZE           0x4000
102107 +#define MSVDX_REGS_OFFSET      0x50000
102108 +
102109 +#ifdef SUPPORT_MSVDX
102110 +#define        POULSBO_MAX_OFFSET      (MSVDX_REGS_OFFSET + MSVDX_REG_SIZE)
102111 +#else
102112 +#define        POULSBO_MAX_OFFSET      (SGX_REGS_OFFSET + SGX_REG_SIZE)
102113 +#define        PSB_POULSBO_MAX_OFFSET  (PSB_SGX_REGS_OFFSET + SGX_REG_SIZE)
102114 +#endif
102115 +
102116 +#define SYS_SGX_DEV_VENDOR_ID          0x8086
102117 +#define PSB_SYS_SGX_DEV_DEVICE_ID_1    0x8108
102118 +#define PSB_SYS_SGX_DEV_DEVICE_ID_2    0x8109
102119 +
102120 +#define SYS_SGX_DEVICE_IDS \
102121 +    {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108}, \
102122 +    {0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109}, \
102123 +    {0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102124 +    {0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102125 +    {0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102126 +    {0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102127 +    {0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102128 +    {0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102129 +    {0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102130 +    {0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, \
102131 +    {0, 0, 0}
102132 +
102133 +
102134 +#define MMADR_INDEX                    4
102135 +#define IOPORT_INDEX           5
102136 +#define GMADR_INDEX                    6
102137 +#define MMUADR_INDEX           7
102138 +#define FBADR_INDEX                    23
102139 +#define FBSIZE_INDEX           24
102140 +
102141 +#define DISPLAY_SURFACE_SIZE        (4 * 1024 * 1024)
102142 +
102143 +#define DEVICE_SGX_INTERRUPT           (1<<0)
102144 +#define DEVICE_MSVDX_INTERRUPT         (1<<1)
102145 +#define DEVICE_DISP_INTERRUPT          (1<<2)
102146 +#define DEVICE_TOPAZ_INTERRUPT         (1<<3)
102147 +
102148 +#define POULSBO_DISP_MASK                                      (1<<17)
102149 +#define POULSBO_THALIA_MASK                                    (1<<18)
102150 +#define POULSBO_MSVDX_MASK                                     (1<<19)
102151 +#define POULSBO_VSYNC_PIPEA_VBLANK_MASK                (1<<7)
102152 +#define POULSBO_VSYNC_PIPEA_EVENT_MASK         (1<<6)
102153 +#define POULSBO_VSYNC_PIPEB_VBLANK_MASK                (1<<5)
102154 +#define POULSBO_VSYNC_PIPEB_EVENT_MASK         (1<<4)
102155 +
102156 +#define POULSBO_DISPLAY_REGS_OFFSET                    0x70000
102157 +#define POULSBO_DISPLAY_REG_SIZE                       0x2000          
102158 +
102159 +#define POULSBO_DISPLAY_A_CONFIG                       0x00008
102160 +#define POULSBO_DISPLAY_A_STATUS_SELECT                0x00024
102161 +#define POULSBO_DISPLAY_B_CONFIG                       0x01008
102162 +#define POULSBO_DISPLAY_B_STATUS_SELECT                0x01024
102163 +
102164 +#define POULSBO_DISPLAY_PIPE_ENABLE                    (1<<31)
102165 +#define POULSBO_DISPLAY_VSYNC_STS_EN           (1<<25)
102166 +#define POULSBO_DISPLAY_VSYNC_STS                      (1<<9)
102167 +
102168 +#if defined(SGX_FEATURE_HOST_PORT)
102169 +       #define SYS_SGX_HP_SIZE         0x8000000
102170 +       #define PSB_SYS_SGX_HP_SIZE     0x4000000
102171 +       
102172 +       #define SYS_SGX_HOSTPORT_BASE_DEVVADDR 0xD0000000
102173 +       #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030)
102174 +               
102175 +
102176 +
102177 +               #define SYS_SGX_HOSTPORT_BRN23030_OFFSET 0x7C00000
102178 +       #endif
102179 +#endif
102180 +
102181
102182 +typedef struct
102183 +{
102184 +       union
102185 +       {
102186 +#if !defined(VISTA)
102187 +               IMG_UINT8       aui8PCISpace[256];
102188 +               IMG_UINT16      aui16PCISpace[128];
102189 +               IMG_UINT32      aui32PCISpace[64];
102190 +#endif
102191 +               struct  
102192 +               {
102193 +                       IMG_UINT16      ui16VenID;
102194 +                       IMG_UINT16      ui16DevID;
102195 +                       IMG_UINT16      ui16PCICmd;
102196 +                       IMG_UINT16      ui16PCIStatus;
102197 +               }s;
102198 +       }u;
102199 +} PCICONFIG_SPACE, *PPCICONFIG_SPACE;
102200 +
102201 +#endif 
102202 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysinfo.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysinfo.h
102203 new file mode 100644
102204 index 0000000..97d02dd
102205 --- /dev/null
102206 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysinfo.h
102207 @@ -0,0 +1,43 @@
102208 +/**********************************************************************
102209 + *
102210 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
102211 + * 
102212 + * This program is free software; you can redistribute it and/or modify it
102213 + * under the terms and conditions of the GNU General Public License,
102214 + * version 2, as published by the Free Software Foundation.
102215 + * 
102216 + * This program is distributed in the hope it will be useful but, except 
102217 + * as otherwise stated in writing, without any warranty; without even the 
102218 + * implied warranty of merchantability or fitness for a particular purpose. 
102219 + * See the GNU General Public License for more details.
102220 + * 
102221 + * You should have received a copy of the GNU General Public License along with
102222 + * this program; if not, write to the Free Software Foundation, Inc.,
102223 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102224 + * 
102225 + * The full GNU General Public License is included in this distribution in
102226 + * the file called "COPYING".
102227 + *
102228 + * Contact Information:
102229 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
102230 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
102231 + *
102232 + ******************************************************************************/
102233 +
102234 +#if !defined(__SYSINFO_H__)
102235 +#define __SYSINFO_H__
102236 +
102237 +#define MAX_HW_TIME_US                         (500000)
102238 +#define WAIT_TRY_COUNT                         (10000)
102239 +
102240 +typedef enum _SYS_DEVICE_TYPE_
102241 +{
102242 +       SYS_DEVICE_SGX                                          = 0,
102243 +
102244 +       SYS_DEVICE_FORCE_I16                            = 0x7fff
102245 +
102246 +} SYS_DEVICE_TYPE;
102247 +
102248 +#define SYS_DEVICE_COUNT 4 
102249 +
102250 +#endif 
102251 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.c b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.c
102252 new file mode 100644
102253 index 0000000..d71196e
102254 --- /dev/null
102255 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.c
102256 @@ -0,0 +1,565 @@
102257 +/**************************************************************************
102258 + * Copyright (c) 2009, Intel Corporation.
102259 + * All Rights Reserved.
102260 + *
102261 + * This program is free software; you can redistribute it and/or modify it
102262 + * under the terms and conditions of the GNU General Public License,
102263 + * version 2, as published by the Free Software Foundation.
102264 + *
102265 + * This program is distributed in the hope it will be useful, but WITHOUT
102266 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
102267 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
102268 + * more details.
102269 + *
102270 + * You should have received a copy of the GNU General Public License along with
102271 + * this program; if not, write to the Free Software Foundation, Inc.,
102272 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102273 + *
102274 + * Authors:
102275 + *    Benjamin Defnet <benjamin.r.defnet@intel.com>
102276 + *
102277 + **************************************************************************/
102278 +
102279 +#include "sysirq.h"
102280 +#include "sysconfig.h"
102281 +#include "psb_drv.h"
102282 +#include "ospm_power.h"
102283 +#include "lnc_topaz.h"
102284 +#include "psb_msvdx.h"
102285 +#include "psb_intel_reg.h"
102286 +
102287 +extern SYS_DATA* gpsSysData;
102288 +extern struct drm_device *gpDrmDevice;
102289 +
102290 +void sysirq_preinstall_islands(struct drm_device *dev, int hw_islands);
102291 +int  sysirq_postinstall_islands(struct drm_device *dev, int hw_islands);
102292 +static void sysirq_enable_pipestat(struct drm_psb_private *dev_priv, u32 mask);
102293 +static void sysirq_disable_pipestat(struct drm_psb_private *dev_priv, u32 mask);
102294 +
102295 +bool sysirq_init(struct drm_device *dev)
102296 +{
102297 +       struct drm_psb_private *dev_priv =
102298 +           (struct drm_psb_private *) dev->dev_private;
102299 +
102300 +       OSInstallMISR(gpsSysData);
102301 +
102302 +       PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
102303 +       PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
102304 +
102305 +       dev_priv->vdc_irq_mask = 0;
102306 +       dev_priv->pipestat[0] = 0;
102307 +       dev_priv->pipestat[1] = 0;
102308 +
102309 +       dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
102310 +
102311 +       if (drm_vblank_init(dev, PSB_NUM_PIPE) != 0)
102312 +               return false;
102313 +
102314 +       if (drm_irq_install(dev) != 0)
102315 +               return false;
102316 +
102317 +       dev->vblank_disable_allowed = 1;
102318 +       dev_priv->vblanksEnabledForFlips = false;
102319 +
102320 +       return true;
102321 +}
102322 +
102323 +void sysirq_uninit(struct drm_device *dev)
102324 +{
102325 +       drm_irq_uninstall(dev);
102326 +       drm_vblank_cleanup(dev);
102327 +       OSUninstallMISR(gpsSysData);        
102328 +}
102329 +
102330 +void sysirq_preinstall(struct drm_device *dev)
102331 +{
102332 +       sysirq_preinstall_islands(dev, OSPM_ALL_ISLANDS);
102333 +}
102334 +
102335 +void sysirq_preinstall_islands(struct drm_device *dev, int hw_islands)
102336 +{
102337 +#if defined (SYS_USING_INTERRUPTS)    
102338 +       struct drm_psb_private *dev_priv =
102339 +           (struct drm_psb_private *) dev->dev_private;
102340 +       unsigned long irqflags;
102341 +
102342 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102343 +
102344 +       if ((hw_islands & OSPM_DISPLAY_ISLAND) && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
102345 +               if (dev->vblank_enabled[0] || dev_priv->vblanksEnabledForFlips)
102346 +                       dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
102347 +               if (dev_priv->psb_dpst_state)
102348 +                       dev_priv->vdc_irq_mask |= _PSB_DPST_PIPEA_FLAG;
102349 +       }
102350 +       if ((hw_islands & OSPM_GRAPHICS_ISLAND) && ospm_power_is_hw_on(OSPM_GRAPHICS_ISLAND))
102351 +               dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG;
102352 +       if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
102353 +               dev_priv->vdc_irq_mask |= _PSB_IRQ_MSVDX_FLAG;
102354 +       if (IS_MRST(dev) && (hw_islands & OSPM_VIDEO_ENC_ISLAND) && !dev_priv->topaz_disabled &&
102355 +           ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
102356 +               dev_priv->vdc_irq_mask |= _LNC_IRQ_TOPAZ_FLAG;
102357 +
102358 +       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102359 +
102360 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102361 +#endif
102362 +}
102363 +
102364 +
102365 +int sysirq_postinstall(struct drm_device *dev)
102366 +{
102367 +       return sysirq_postinstall_islands(dev, OSPM_ALL_ISLANDS);
102368 +}
102369 +
102370 +int sysirq_postinstall_islands(struct drm_device *dev, int hw_islands)
102371 +{
102372 +#if defined (SYS_USING_INTERRUPTS)
102373 +       struct drm_psb_private *dev_priv =
102374 +           (struct drm_psb_private *) dev->dev_private;
102375 +       unsigned long irqflags;
102376 +
102377 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102378 +
102379 +       if ((hw_islands & OSPM_DISPLAY_ISLAND) && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
102380 +               if (IS_POULSBO(dev))
102381 +                       PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
102382 +
102383 +               if (dev_priv->vdc_irq_mask & _PSB_VSYNC_PIPEA_FLAG) {
102384 +                       if (IS_MRST(dev))
102385 +                               sysirq_enable_pipestat(dev_priv,
102386 +                                   PIPE_START_VBLANK_INTERRUPT_ENABLE |
102387 +                                   PIPE_VBLANK_INTERRUPT_ENABLE);
102388 +                       else
102389 +                               sysirq_enable_pipestat(dev_priv,
102390 +                                   PIPE_VBLANK_INTERRUPT_ENABLE);
102391 +
102392 +               } else {
102393 +                       sysirq_disable_pipestat(dev_priv,
102394 +                           PIPE_VBLANK_INTERRUPT_ENABLE |
102395 +                           PIPE_START_VBLANK_INTERRUPT_ENABLE);
102396 +               }
102397 +
102398 +               if (dev_priv->vdc_irq_mask & _PSB_DPST_PIPEA_FLAG) {
102399 +                       printk(KERN_ALERT "TURNING ON DPST\n");
102400 +                       sysirq_turn_on_dpst(dev);
102401 +               } else {
102402 +                       printk(KERN_ALERT "TURNING OFF DPST\n");
102403 +                       sysirq_turn_off_dpst(dev);
102404 +               }
102405 +       }
102406 +
102407 +       if (IS_MRST(dev) && (hw_islands & OSPM_VIDEO_ENC_ISLAND) && !dev_priv->topaz_disabled &&
102408 +           ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
102409 +               lnc_topaz_enableirq(dev);
102410 +
102411 +       if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
102412 +               psb_msvdx_enableirq(dev);
102413 +
102414 +       /*This register is safe even if display island is off*/
102415 +       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102416 +
102417 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102418 +#endif
102419 +       return 0;
102420 +}
102421 +
102422 +void sysirq_uninstall(struct drm_device *dev)
102423 +{
102424 +       sysirq_uninstall_islands(dev, OSPM_ALL_ISLANDS);
102425 +}
102426 +
102427 +void sysirq_uninstall_islands(struct drm_device *dev, int hw_islands)
102428 +{
102429 +#if defined (SYS_USING_INTERRUPTS)
102430 +       struct drm_psb_private *dev_priv =
102431 +           (struct drm_psb_private *) dev->dev_private;
102432 +       unsigned long irqflags;
102433 +
102434 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102435 +
102436 +       if ((hw_islands & OSPM_DISPLAY_ISLAND) && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
102437 +               if (dev_priv->vdc_irq_mask & _PSB_VSYNC_PIPEA_FLAG)
102438 +                       sysirq_disable_pipestat(dev_priv,
102439 +                           PIPE_VBLANK_INTERRUPT_ENABLE |
102440 +                           PIPE_START_VBLANK_INTERRUPT_ENABLE);
102441 +               if (dev_priv->vdc_irq_mask & _PSB_DPST_PIPEA_FLAG)
102442 +                       sysirq_turn_off_dpst(dev);
102443 +
102444 +               dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
102445 +                                         _PSB_IRQ_MSVDX_FLAG |
102446 +                                         _LNC_IRQ_TOPAZ_FLAG;
102447 +       }
102448 +
102449 +       if (hw_islands & OSPM_GRAPHICS_ISLAND)
102450 +               dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
102451 +
102452 +       if (hw_islands & OSPM_VIDEO_DEC_ISLAND)
102453 +               dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG;
102454 +
102455 +       if (hw_islands & OSPM_VIDEO_ENC_ISLAND)
102456 +               dev_priv->vdc_irq_mask &= ~_LNC_IRQ_TOPAZ_FLAG;
102457 +
102458 +       /*These two registers are safe even if display island is off*/
102459 +       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102460 +       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102461 +
102462 +       wmb();
102463 +
102464 +       /*This register is safe even if display island is off*/
102465 +       PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
102466 +
102467 +       if (IS_MRST(dev) && (hw_islands & OSPM_VIDEO_ENC_ISLAND) && !dev_priv->topaz_disabled &&
102468 +           ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
102469 +               lnc_topaz_disableirq(dev);
102470 +
102471 +       if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
102472 +               psb_msvdx_disableirq(dev);
102473 +
102474 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102475 +#endif
102476 +}
102477 +
102478 +irqreturn_t sysirq_handler(DRM_IRQ_ARGS)
102479 +{
102480 +       bool bStatus = false;
102481 +#if defined(SYS_USING_INTERRUPTS)    
102482 +       struct drm_device *dev = (struct drm_device *) arg;
102483 +       struct drm_psb_private *dev_priv =
102484 +           (struct drm_psb_private *) dev->dev_private;
102485 +
102486 +       spin_lock(&dev_priv->irqmask_lock);
102487 +
102488 +       /* Now process all of the other interrupts */
102489 +       bStatus = PVRSRVSystemLISR(gpsSysData);
102490 +
102491 +       if (bStatus)
102492 +       {
102493 +               OSScheduleMISR((IMG_VOID *)gpsSysData);
102494 +       }
102495 +
102496 +       spin_unlock(&dev_priv->irqmask_lock);
102497 +
102498 +#endif
102499 +       return bStatus ? IRQ_HANDLED : IRQ_NONE;
102500 +}
102501 +
102502 +
102503 +IMG_UINT32 SysGetInterruptSource(SYS_DATA* psSysData, PVRSRV_DEVICE_NODE *psDeviceNode)
102504 +{
102505 +       struct drm_psb_private *dev_priv =
102506 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
102507 +
102508 +       IMG_UINT32 ui32Devices = 0;
102509 +       IMG_UINT32 ui32Data, ui32DIMMask;
102510 +
102511 +       PVR_UNREFERENCED_PARAMETER(psSysData);
102512 +       PVR_UNREFERENCED_PARAMETER(psDeviceNode);
102513 +
102514 +       ui32Data = PSB_RVDC32(PSB_INT_IDENTITY_R);
102515 +
102516 +       if ((ui32Data & _PSB_IRQ_SGX_FLAG) && ospm_power_is_hw_on(OSPM_GRAPHICS_ISLAND))
102517 +       {
102518 +               ui32Devices |= DEVICE_SGX_INTERRUPT;
102519 +       }
102520 +
102521 +       if ((ui32Data & _PSB_IRQ_MSVDX_FLAG) && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
102522 +               ui32Devices |= DEVICE_MSVDX_INTERRUPT;
102523 +       }
102524 +
102525 +       if ((ui32Data & _LNC_IRQ_TOPAZ_FLAG) && ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
102526 +               ui32Devices |= DEVICE_TOPAZ_INTERRUPT;
102527 +       }
102528 +
102529 +       ui32DIMMask = PSB_RVDC32(PSB_INT_ENABLE_R);
102530 +       ui32DIMMask &= ~(_PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG | _LNC_IRQ_TOPAZ_FLAG);
102531 +
102532 +       if ((ui32Data & ui32DIMMask) && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND))
102533 +       {
102534 +               ui32Devices |= DEVICE_DISP_INTERRUPT;
102535 +       }
102536 +
102537 +       return (ui32Devices);
102538 +}
102539 +
102540 +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
102541 +{
102542 +       struct drm_psb_private *dev_priv =
102543 +           (struct drm_psb_private *) gpDrmDevice->dev_private;
102544 +       IMG_UINT32 ui32Data;
102545 +
102546 +       PVR_UNREFERENCED_PARAMETER(psSysData);
102547 +       PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
102548 +
102549 +       ui32Data = PSB_RVDC32(PSB_INT_IDENTITY_R);
102550 +       ui32Data &= dev_priv->vdc_irq_mask;
102551 +       PSB_WVDC32(ui32Data, PSB_INT_IDENTITY_R);
102552 +       ui32Data = PSB_RVDC32(PSB_INT_IDENTITY_R);
102553 +}
102554 +
102555 +void sysirq_turn_on_dpst(struct drm_device *dev)
102556 +{
102557 +       struct drm_psb_private *dev_priv =
102558 +               (struct drm_psb_private *) dev->dev_private;
102559 +       u32 hist_reg;
102560 +       u32 pwm_reg;
102561 +       u32 pipea_stat;
102562 +
102563 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102564 +               PSB_WVDC32(BIT31, HISTOGRAM_LOGIC_CONTROL);
102565 +               hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
102566 +               PSB_WVDC32(BIT31, HISTOGRAM_INT_CONTROL);
102567 +               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
102568 +
102569 +               PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
102570 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102571 +               PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE | PWM_PHASEIN_INT_ENABLE,
102572 +                          PWM_CONTROL_LOGIC);
102573 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102574 +
102575 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102576 +               PSB_WVDC32(pipea_stat | PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
102577 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102578 +
102579 +               PSB_WVDC32(pipea_stat | PIPE_DPST_EVENT_STATUS, PIPEASTAT);
102580 +               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
102581 +               PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,HISTOGRAM_INT_CONTROL);
102582 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102583 +               PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, PWM_CONTROL_LOGIC);
102584 +               
102585 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102586 +       }
102587 +}
102588 +
102589 +int sysirq_enable_dpst(struct drm_device *dev)
102590 +{
102591 +       struct drm_psb_private *dev_priv =
102592 +               (struct drm_psb_private *) dev->dev_private;
102593 +       unsigned long irqflags;
102594 +
102595 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102596 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102597 +               /* enable DPST */
102598 +               dev_priv->vdc_irq_mask |= _PSB_DPST_PIPEA_FLAG;
102599 +               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102600 +               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102601 +
102602 +               sysirq_turn_on_dpst(dev);
102603 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102604 +       }
102605 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102606 +       return 0;
102607 +}
102608 +
102609 +void sysirq_turn_off_dpst(struct drm_device *dev)
102610 +{
102611 +       struct drm_psb_private *dev_priv =
102612 +           (struct drm_psb_private *) dev->dev_private;
102613 +       u32 hist_reg;
102614 +       u32 pwm_reg;
102615 +       u32 pipea_stat;
102616 +
102617 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102618 +               PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
102619 +               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
102620 +
102621 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102622 +               PSB_WVDC32(pipea_stat & ~PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
102623 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102624 +
102625 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102626 +               PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), PWM_CONTROL_LOGIC);
102627 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102628 +
102629 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102630 +       }
102631 +}
102632 +
102633 +int sysirq_disable_dpst(struct drm_device *dev)
102634 +{
102635 +       struct drm_psb_private *dev_priv =
102636 +           (struct drm_psb_private *) dev->dev_private;
102637 +       unsigned long irqflags;
102638 +       u32 hist_reg;
102639 +       u32 pwm_reg;
102640 +       u32 pipea_stat;
102641 +
102642 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102643 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102644 +               dev_priv->vdc_irq_mask &= ~_PSB_DPST_PIPEA_FLAG;
102645 +               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102646 +               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102647 +
102648 +               PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
102649 +               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
102650 +
102651 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102652 +               PSB_WVDC32(pipea_stat & ~PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
102653 +               pipea_stat = PSB_RVDC32(PIPEASTAT);
102654 +
102655 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102656 +               PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), PWM_CONTROL_LOGIC);
102657 +               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
102658 +
102659 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102660 +       }
102661 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102662 +
102663 +       return 0;
102664 +}
102665 +
102666 +/* Called from drm generic code, passed 'crtc' which
102667 + * we use as a pipe index
102668 + */
102669 +int sysirq_enable_vblank(struct drm_device *dev, int pipe)
102670 +{
102671 +#if defined(SYS_USING_INTERRUPTS)    
102672 +       struct drm_psb_private *dev_priv =
102673 +           (struct drm_psb_private *) dev->dev_private;
102674 +       unsigned long irqflags;
102675 +       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
102676 +       u32 pipeconf = 0;
102677 +
102678 +       if (pipe != 0)
102679 +               return -EINVAL;
102680 +
102681 +       //Check if already enabled
102682 +       if (dev_priv->vdc_irq_mask & _PSB_VSYNC_PIPEA_FLAG)
102683 +               return 0;
102684 +
102685 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102686 +               pipeconf = REG_READ(pipeconf_reg);
102687 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102688 +       }
102689 +       if (!(pipeconf & PIPEACONF_ENABLE))
102690 +               return -EINVAL;
102691 +
102692 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102693 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102694 +               if (pipe == 0)
102695 +                       dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
102696 +               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102697 +               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102698 +               if (IS_MRST(dev)) {
102699 +                       sysirq_enable_pipestat(dev_priv,
102700 +                           PIPE_START_VBLANK_INTERRUPT_ENABLE |
102701 +                           PIPE_VBLANK_INTERRUPT_ENABLE);
102702 +               } else
102703 +                       sysirq_enable_pipestat(dev_priv,
102704 +                           PIPE_VBLANK_INTERRUPT_ENABLE);
102705 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102706 +       }
102707 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102708 +#endif
102709 +       return 0;
102710 +}
102711 +
102712 +
102713 +/* Called from drm generic code, passed 'crtc' which
102714 + * we use as a pipe index
102715 + */
102716 +void sysirq_disable_vblank(struct drm_device *dev, int pipe)
102717 +{
102718 +#if defined(SYS_USING_INTERRUPTS)    
102719 +       struct drm_psb_private *dev_priv =
102720 +           (struct drm_psb_private *) dev->dev_private;
102721 +       unsigned long irqflags;
102722 +       
102723 +       //Don't disable if flips currently require vblanks to be enabled
102724 +       if (dev_priv->vblanksEnabledForFlips)
102725 +               return;
102726 +       
102727 +       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
102728 +       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102729 +               if (pipe == 0)
102730 +                       dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
102731 +               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
102732 +               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
102733 +               sysirq_disable_pipestat(dev_priv,
102734 +                   PIPE_VBLANK_INTERRUPT_ENABLE |
102735 +                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
102736 +               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102737 +       }
102738 +       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
102739 +#endif
102740 +}
102741 +
102742 +
102743 +static void
102744 +sysirq_enable_pipestat(struct drm_psb_private *dev_priv, u32 mask)
102745 +{
102746 +       if ((dev_priv->pipestat[0] & mask) != mask) {
102747 +               dev_priv->pipestat[0] |= mask;
102748 +               /* Enable the interrupt, clear any pending status */
102749 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102750 +                       u32 writeVal = PSB_RVDC32(PIPEASTAT);
102751 +                       writeVal |= (mask | (mask >> 16));
102752 +                       PSB_WVDC32(writeVal, PIPEASTAT);
102753 +                       (void) PSB_RVDC32(PIPEASTAT);
102754 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102755 +               }
102756 +       }
102757 +}
102758 +
102759 +static void
102760 +sysirq_disable_pipestat(struct drm_psb_private *dev_priv, u32 mask)
102761 +{
102762 +       if ((dev_priv->pipestat[0] & mask) != 0) {
102763 +               dev_priv->pipestat[0] &= ~mask;
102764 +               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
102765 +                       u32 writeVal = PSB_RVDC32(PIPEASTAT);
102766 +                       writeVal &= ~mask;
102767 +                       PSB_WVDC32(writeVal, PIPEASTAT);
102768 +                       (void) PSB_RVDC32(PIPEASTAT);
102769 +                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102770 +               }
102771 +       }
102772 +}
102773 +
102774 +
102775 +/* Called from drm generic code, passed a 'crtc', which
102776 + * we use as a pipe index
102777 + */
102778 +u32 sysirq_get_vblank_counter(struct drm_device *dev, int pipe)
102779 +{
102780 +       u32 count = 0;
102781 +#if defined(SYS_USING_INTERRUPTS)    
102782 +       unsigned long high_frame;
102783 +       unsigned long low_frame;
102784 +       u32 high1, high2, low;
102785 +
102786 +       if (pipe != 0)
102787 +               return 0;
102788 +       
102789 +       if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) 
102790 +               return 0;
102791 +
102792 +       high_frame = PIPEAFRAMEHIGH;
102793 +       low_frame = PIPEAFRAMEPIXEL;
102794 +       
102795 +       if (!(REG_READ(PIPEACONF) & PIPEACONF_ENABLE)) {
102796 +               DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
102797 +               goto sysirq_get_vblank_counter_exit;
102798 +       }
102799 +
102800 +       /*
102801 +        * High & low register fields aren't synchronized, so make sure
102802 +        * we get a low value that's stable across two reads of the high
102803 +        * register.
102804 +        */
102805 +       do {
102806 +               high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
102807 +                        PIPE_FRAME_HIGH_SHIFT);
102808 +               low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
102809 +                       PIPE_FRAME_LOW_SHIFT);
102810 +               high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
102811 +                        PIPE_FRAME_HIGH_SHIFT);
102812 +       } while (high1 != high2);
102813 +
102814 +       count = (high1 << 8) | low;
102815 +
102816 +sysirq_get_vblank_counter_exit:
102817 +
102818 +       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
102819 +#endif
102820 +       return count;
102821 +}
102822 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.h
102823 new file mode 100644
102824 index 0000000..fef16be
102825 --- /dev/null
102826 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysirq.h
102827 @@ -0,0 +1,49 @@
102828 +/**************************************************************************
102829 + * Copyright (c) 2009, Intel Corporation.
102830 + * All Rights Reserved.
102831 + *
102832 + * This program is free software; you can redistribute it and/or modify it
102833 + * under the terms and conditions of the GNU General Public License,
102834 + * version 2, as published by the Free Software Foundation.
102835 + *
102836 + * This program is distributed in the hope it will be useful, but WITHOUT
102837 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
102838 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
102839 + * more details.
102840 + *
102841 + * You should have received a copy of the GNU General Public License along with
102842 + * this program; if not, write to the Free Software Foundation, Inc.,
102843 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102844 + *
102845 + * Authors:
102846 + *    Benjamin Defnet <benjamin.r.defnet@intel.com>
102847 + *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
102848 + *
102849 + **************************************************************************/
102850 +
102851 +#ifndef _SYSIRQ_H_
102852 +#define _SYSIRQ_H_
102853 +
102854 +#include <drm/drmP.h>
102855 +
102856 +bool sysirq_init(struct drm_device *dev);
102857 +void sysirq_uninit(struct drm_device *dev);
102858 +
102859 +void sysirq_preinstall(struct drm_device *dev);
102860 +int  sysirq_postinstall(struct drm_device *dev);
102861 +void sysirq_uninstall(struct drm_device *dev);
102862 +irqreturn_t sysirq_handler(DRM_IRQ_ARGS);
102863 +
102864 +void sysirq_preinstall_islands(struct drm_device *dev, int hw_islands);
102865 +int  sysirq_postinstall_islands(struct drm_device *dev, int hw_islands);
102866 +void sysirq_uninstall_islands(struct drm_device *dev, int hw_islands);
102867 +
102868 +int sysirq_enable_dpst(struct drm_device *dev);
102869 +int sysirq_disable_dpst(struct drm_device *dev);
102870 +void sysirq_turn_on_dpst(struct drm_device *dev);
102871 +void sysirq_turn_off_dpst(struct drm_device *dev);
102872 +int  sysirq_enable_vblank(struct drm_device *dev, int pipe);
102873 +void sysirq_disable_vblank(struct drm_device *dev, int pipe);
102874 +u32  sysirq_get_vblank_counter(struct drm_device *dev, int pipe);
102875 +
102876 +#endif //_SYSIRQ_H_
102877 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/syslocal.h b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/syslocal.h
102878 new file mode 100644
102879 index 0000000..8e97cab
102880 --- /dev/null
102881 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/syslocal.h
102882 @@ -0,0 +1,82 @@
102883 +/**********************************************************************
102884 + *
102885 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
102886 + * 
102887 + * This program is free software; you can redistribute it and/or modify it
102888 + * under the terms and conditions of the GNU General Public License,
102889 + * version 2, as published by the Free Software Foundation.
102890 + * 
102891 + * This program is distributed in the hope it will be useful but, except 
102892 + * as otherwise stated in writing, without any warranty; without even the 
102893 + * implied warranty of merchantability or fitness for a particular purpose. 
102894 + * See the GNU General Public License for more details.
102895 + * 
102896 + * You should have received a copy of the GNU General Public License along with
102897 + * this program; if not, write to the Free Software Foundation, Inc.,
102898 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102899 + * 
102900 + * The full GNU General Public License is included in this distribution in
102901 + * the file called "COPYING".
102902 + *
102903 + * Contact Information:
102904 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
102905 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
102906 + *
102907 + ******************************************************************************/
102908 +
102909 +#if !defined(__SYSLOCAL_H__)
102910 +#define __SYSLOCAL_H__
102911 +
102912 +#define SYS_SPECIFIC_DATA_PCI_ACQUIRE_DEV              0x00000001
102913 +#define SYS_SPECIFIC_DATA_PCI_REQUEST_SGX_ADDR_RANGE   0x00000002
102914 +#define SYS_SPECIFIC_DATA_PCI_REQUEST_HOST_PORT_RANGE  0x00000004
102915 +#if defined(NO_HARDWARE)
102916 +#define SYS_SPECIFIC_DATA_ALLOC_DUMMY_SGX_REGS         0x00000008
102917 +#if defined(SUPPORT_MSVDX)
102918 +#define        SYS_SPECIFIC_DATA_ALLOC_DUMMY_MSVDX_REGS        0x00000020
102919 +#endif 
102920 +#endif 
102921 +#define        SYS_SPECIFIC_DATA_SGX_INITIALISED               0x00000040
102922 +#if defined(SUPPORT_MSVDX)
102923 +#define        SYS_SPECIFIC_DATA_MSVDX_INITIALISED             0x00000080
102924 +#endif 
102925 +#define        SYS_SPECIFIC_DATA_MISR_INSTALLED                0x00000100
102926 +#define        SYS_SPECIFIC_DATA_LISR_INSTALLED                0x00000200
102927 +#define        SYS_SPECIFIC_DATA_PDUMP_INIT                    0x00000400
102928 +#define        SYS_SPECIFIC_DATA_IRQ_ENABLED                   0x00000800
102929 +
102930 +#define        SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS             0x00001000
102931 +#define        SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP               0x00004000
102932 +#define        SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS           0x00008000
102933 +#define        SYS_SPECIFIC_DATA_PM_IRQ_DISABLE                0x00010000
102934 +#define        SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR             0x00020000
102935 +
102936 +#define        SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))
102937 +
102938 +#define        SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))
102939 +
102940 +#define        SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)
102941
102942
102943 +typedef struct _SYS_SPECIFIC_DATA_TAG_
102944 +{
102945 +       
102946 +       IMG_UINT32 ui32SysSpecificData;
102947 +#ifdef __linux__
102948 +       PVRSRV_PCI_DEV_HANDLE hSGXPCI;
102949 +#endif
102950 +#ifdef LDM_PCI
102951 +       struct pci_dev *psPCIDev;
102952 +#endif
102953 +       /* MSI reg save */
102954 +       uint32_t msi_addr;
102955 +       uint32_t msi_data;
102956 +
102957 +       uint32_t saveBSM;
102958 +       uint32_t saveVBT;
102959 +} SYS_SPECIFIC_DATA;
102960 +
102961
102962 +#endif 
102963 +
102964 +
102965 diff --git a/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysutils.c b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysutils.c
102966 new file mode 100644
102967 index 0000000..b89a1da
102968 --- /dev/null
102969 +++ b/drivers/gpu/drm/mrst/pvr/services4/system/moorestown/sysutils.c
102970 @@ -0,0 +1,30 @@
102971 +/**********************************************************************
102972 + *
102973 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
102974 + * 
102975 + * This program is free software; you can redistribute it and/or modify it
102976 + * under the terms and conditions of the GNU General Public License,
102977 + * version 2, as published by the Free Software Foundation.
102978 + * 
102979 + * This program is distributed in the hope it will be useful but, except 
102980 + * as otherwise stated in writing, without any warranty; without even the 
102981 + * implied warranty of merchantability or fitness for a particular purpose. 
102982 + * See the GNU General Public License for more details.
102983 + * 
102984 + * You should have received a copy of the GNU General Public License along with
102985 + * this program; if not, write to the Free Software Foundation, Inc.,
102986 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
102987 + * 
102988 + * The full GNU General Public License is included in this distribution in
102989 + * the file called "COPYING".
102990 + *
102991 + * Contact Information:
102992 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
102993 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
102994 + *
102995 + ******************************************************************************/
102996 +
102997 +#include "services_headers.h"
102998 +#include "sysinfo.h"
102999 +#include "syslocal.h"
103000 +
103001 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/client/linuxsrv.h b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/client/linuxsrv.h
103002 new file mode 100644
103003 index 0000000..adfcd75
103004 --- /dev/null
103005 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/client/linuxsrv.h
103006 @@ -0,0 +1,48 @@
103007 +/**********************************************************************
103008 + *
103009 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
103010 + * 
103011 + * This program is free software; you can redistribute it and/or modify it
103012 + * under the terms and conditions of the GNU General Public License,
103013 + * version 2, as published by the Free Software Foundation.
103014 + * 
103015 + * This program is distributed in the hope it will be useful but, except 
103016 + * as otherwise stated in writing, without any warranty; without even the 
103017 + * implied warranty of merchantability or fitness for a particular purpose. 
103018 + * See the GNU General Public License for more details.
103019 + * 
103020 + * You should have received a copy of the GNU General Public License along with
103021 + * this program; if not, write to the Free Software Foundation, Inc.,
103022 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
103023 + * 
103024 + * The full GNU General Public License is included in this distribution in
103025 + * the file called "COPYING".
103026 + *
103027 + * Contact Information:
103028 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
103029 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
103030 + *
103031 + ******************************************************************************/
103032 +
103033 +#ifndef _LINUXSRV_H__
103034 +#define _LINUXSRV_H__
103035 +
103036 +typedef struct tagIOCTL_PACKAGE
103037 +{
103038 +       IMG_UINT32 ui32Cmd;              
103039 +       IMG_UINT32 ui32Size;                       
103040 +       IMG_VOID        *pInBuffer;          
103041 +       IMG_UINT32  ui32InBufferSize;     
103042 +       IMG_VOID    *pOutBuffer;         
103043 +       IMG_UINT32  ui32OutBufferSize;    
103044 +} IOCTL_PACKAGE;
103045 +
103046 +IMG_UINT32 DeviceIoControl(IMG_UINT32 hDevice,         
103047 +                                               IMG_UINT32 ui32ControlCode, 
103048 +                                               IMG_VOID *pInBuffer,            
103049 +                                               IMG_UINT32 ui32InBufferSize,
103050 +                                               IMG_VOID *pOutBuffer,           
103051 +                                               IMG_UINT32 ui32OutBufferSize,  
103052 +                                               IMG_UINT32 *pui32BytesReturned); 
103053 +
103054 +#endif 
103055 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c
103056 new file mode 100644
103057 index 0000000..b769273
103058 --- /dev/null
103059 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.c
103060 @@ -0,0 +1,2075 @@
103061 +/**********************************************************************
103062 + *
103063 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
103064 + *
103065 + * This program is free software; you can redistribute it and/or modify it
103066 + * under the terms and conditions of the GNU General Public License,
103067 + * version 2, as published by the Free Software Foundation.
103068 + *
103069 + * This program is distributed in the hope it will be useful but, except
103070 + * as otherwise stated in writing, without any warranty; without even the
103071 + * implied warranty of merchantability or fitness for a particular purpose.
103072 + * See the GNU General Public License for more details.
103073 + *
103074 + * You should have received a copy of the GNU General Public License along with
103075 + * this program; if not, write to the Free Software Foundation, Inc.,
103076 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
103077 + *
103078 + * The full GNU General Public License is included in this distribution in
103079 + * the file called "COPYING".
103080 + *
103081 + * Contact Information:
103082 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
103083 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
103084 + *
103085 + ******************************************************************************/
103086 +
103087 +
103088 +#ifdef LINUX
103089 +#include <linux/string.h>
103090 +#endif
103091 +
103092 +#include "img_types.h"
103093 +#include "pvr_debug.h"
103094 +#include "dbgdrvif.h"
103095 +#include "dbgdriv.h"
103096 +#include "hotkey.h"
103097 +#include "hostfunc.h"
103098 +
103099 +
103100 +
103101 +
103102 +#define LAST_FRAME_BUF_SIZE    1024
103103 +
103104 +typedef struct _DBG_LASTFRAME_BUFFER_ {
103105 +       PDBG_STREAM     psStream;
103106 +       IMG_UINT8 ui8Buffer[LAST_FRAME_BUF_SIZE];
103107 +       IMG_UINT32              ui32BufLen;
103108 +       struct _DBG_LASTFRAME_BUFFER_   *psNext;
103109 +} *PDBG_LASTFRAME_BUFFER;
103110 +
103111 +
103112 +static PDBG_STREAM     g_psStreamList = 0;
103113 +static PDBG_LASTFRAME_BUFFER   g_psLFBufferList;
103114 +
103115 +static IMG_UINT32              g_ui32LOff = 0;
103116 +static IMG_UINT32              g_ui32Line = 0;
103117 +static IMG_UINT32              g_ui32MonoLines = 25;
103118 +
103119 +static IMG_BOOL                        g_bHotkeyMiddump = IMG_FALSE;
103120 +static IMG_UINT32              g_ui32HotkeyMiddumpStart = 0xffffffff;
103121 +static IMG_UINT32              g_ui32HotkeyMiddumpEnd = 0xffffffff;
103122 +
103123 +IMG_VOID *                             g_pvAPIMutex=IMG_NULL;
103124 +
103125 +extern IMG_UINT32              g_ui32HotKeyFrame;
103126 +extern IMG_BOOL                        g_bHotKeyPressed;
103127 +extern IMG_BOOL                        g_bHotKeyRegistered;
103128 +
103129 +IMG_BOOL                               gbDumpThisFrame = IMG_FALSE;
103130 +
103131 +
103132 +IMG_UINT32 SpaceInStream(PDBG_STREAM psStream);
103133 +IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize);
103134 +PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream);
103135 +
103136 +DBGKM_SERVICE_TABLE g_sDBGKMServices =
103137 +{
103138 +       sizeof (DBGKM_SERVICE_TABLE),
103139 +       ExtDBGDrivCreateStream,
103140 +       ExtDBGDrivDestroyStream,
103141 +       ExtDBGDrivFindStream,
103142 +       ExtDBGDrivWriteString,
103143 +       ExtDBGDrivReadString,
103144 +       ExtDBGDrivWrite,
103145 +       ExtDBGDrivRead,
103146 +       ExtDBGDrivSetCaptureMode,
103147 +       ExtDBGDrivSetOutputMode,
103148 +       ExtDBGDrivSetDebugLevel,
103149 +       ExtDBGDrivSetFrame,
103150 +       ExtDBGDrivGetFrame,
103151 +       ExtDBGDrivOverrideMode,
103152 +       ExtDBGDrivDefaultMode,
103153 +       ExtDBGDrivWrite2,
103154 +       ExtDBGDrivWriteStringCM,
103155 +       ExtDBGDrivWriteCM,
103156 +       ExtDBGDrivSetMarker,
103157 +       ExtDBGDrivGetMarker,
103158 +       ExtDBGDrivStartInitPhase,
103159 +       ExtDBGDrivStopInitPhase,
103160 +       ExtDBGDrivIsCaptureFrame,
103161 +       ExtDBGDrivWriteLF,
103162 +       ExtDBGDrivReadLF,
103163 +       ExtDBGDrivGetStreamOffset,
103164 +       ExtDBGDrivSetStreamOffset,
103165 +       ExtDBGDrivIsLastCaptureFrame,
103166 +       ExtDBGDrivWaitForEvent
103167 +};
103168 +
103169 +
103170 +
103171 +
103172 +
103173 +IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *      pszName, IMG_UINT32 ui32CapMode, IMG_UINT32     ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size)
103174 +{
103175 +       IMG_VOID *      pvRet;
103176 +
103177 +
103178 +       HostAquireMutex(g_pvAPIMutex);
103179 +
103180 +       pvRet=DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags, ui32Size);
103181 +
103182 +
103183 +       HostReleaseMutex(g_pvAPIMutex);
103184 +
103185 +       return pvRet;
103186 +}
103187 +
103188 +void IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream)
103189 +{
103190 +
103191 +       HostAquireMutex(g_pvAPIMutex);
103192 +
103193 +       DBGDrivDestroyStream(psStream);
103194 +
103195 +
103196 +       HostReleaseMutex(g_pvAPIMutex);
103197 +
103198 +       return;
103199 +}
103200 +
103201 +IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
103202 +{
103203 +       IMG_VOID *      pvRet;
103204 +
103205 +
103206 +       HostAquireMutex(g_pvAPIMutex);
103207 +
103208 +       pvRet=DBGDrivFindStream(pszName, bResetStream);
103209 +
103210 +
103211 +       HostReleaseMutex(g_pvAPIMutex);
103212 +
103213 +       return pvRet;
103214 +}
103215 +
103216 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
103217 +{
103218 +       IMG_UINT32      ui32Ret;
103219 +
103220 +
103221 +       HostAquireMutex(g_pvAPIMutex);
103222 +
103223 +       ui32Ret=DBGDrivWriteString(psStream, pszString, ui32Level);
103224 +
103225 +
103226 +       HostReleaseMutex(g_pvAPIMutex);
103227 +
103228 +       return ui32Ret;
103229 +}
103230 +
103231 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
103232 +{
103233 +       IMG_UINT32 ui32Ret;
103234 +
103235 +
103236 +       HostAquireMutex(g_pvAPIMutex);
103237 +
103238 +       ui32Ret=DBGDrivReadString(psStream, pszString, ui32Limit);
103239 +
103240 +
103241 +       HostReleaseMutex(g_pvAPIMutex);
103242 +
103243 +       return ui32Ret;
103244 +}
103245 +
103246 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
103247 +{
103248 +       IMG_UINT32      ui32Ret;
103249 +
103250 +
103251 +       HostAquireMutex(g_pvAPIMutex);
103252 +
103253 +       ui32Ret=DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
103254 +
103255 +
103256 +       HostReleaseMutex(g_pvAPIMutex);
103257 +
103258 +       return ui32Ret;
103259 +}
103260 +
103261 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
103262 +{
103263 +       IMG_UINT32 ui32Ret;
103264 +
103265 +
103266 +       HostAquireMutex(g_pvAPIMutex);
103267 +
103268 +       ui32Ret=DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf);
103269 +
103270 +
103271 +       HostReleaseMutex(g_pvAPIMutex);
103272 +
103273 +       return ui32Ret;
103274 +}
103275 +
103276 +void IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
103277 +{
103278 +
103279 +       HostAquireMutex(g_pvAPIMutex);
103280 +
103281 +       DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End, ui32SampleRate);
103282 +
103283 +
103284 +       HostReleaseMutex(g_pvAPIMutex);
103285 +
103286 +       return;
103287 +}
103288 +
103289 +void IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
103290 +{
103291 +
103292 +       HostAquireMutex(g_pvAPIMutex);
103293 +
103294 +       DBGDrivSetOutputMode(psStream, ui32OutMode);
103295 +
103296 +
103297 +       HostReleaseMutex(g_pvAPIMutex);
103298 +
103299 +       return;
103300 +}
103301 +
103302 +void IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
103303 +{
103304 +
103305 +       HostAquireMutex(g_pvAPIMutex);
103306 +
103307 +       DBGDrivSetDebugLevel(psStream, ui32DebugLevel);
103308 +
103309 +
103310 +       HostReleaseMutex(g_pvAPIMutex);
103311 +
103312 +       return;
103313 +}
103314 +
103315 +void IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
103316 +{
103317 +
103318 +       HostAquireMutex(g_pvAPIMutex);
103319 +
103320 +       DBGDrivSetFrame(psStream, ui32Frame);
103321 +
103322 +
103323 +       HostReleaseMutex(g_pvAPIMutex);
103324 +
103325 +       return;
103326 +}
103327 +
103328 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream)
103329 +{
103330 +       IMG_UINT32      ui32Ret;
103331 +
103332 +
103333 +       HostAquireMutex(g_pvAPIMutex);
103334 +
103335 +       ui32Ret=DBGDrivGetFrame(psStream);
103336 +
103337 +
103338 +       HostReleaseMutex(g_pvAPIMutex);
103339 +
103340 +       return ui32Ret;
103341 +}
103342 +
103343 +IMG_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
103344 +{
103345 +       IMG_BOOL        bRet;
103346 +
103347 +
103348 +       HostAquireMutex(g_pvAPIMutex);
103349 +
103350 +       bRet = DBGDrivIsLastCaptureFrame(psStream);
103351 +
103352 +
103353 +       HostReleaseMutex(g_pvAPIMutex);
103354 +
103355 +       return bRet;
103356 +}
103357 +
103358 +IMG_BOOL IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
103359 +{
103360 +       IMG_BOOL        bRet;
103361 +
103362 +
103363 +       HostAquireMutex(g_pvAPIMutex);
103364 +
103365 +       bRet = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame);
103366 +
103367 +
103368 +       HostReleaseMutex(g_pvAPIMutex);
103369 +
103370 +       return bRet;
103371 +}
103372 +
103373 +void IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
103374 +{
103375 +
103376 +       HostAquireMutex(g_pvAPIMutex);
103377 +
103378 +       DBGDrivOverrideMode(psStream, ui32Mode);
103379 +
103380 +
103381 +       HostReleaseMutex(g_pvAPIMutex);
103382 +
103383 +       return;
103384 +}
103385 +
103386 +void IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream)
103387 +{
103388 +
103389 +       HostAquireMutex(g_pvAPIMutex);
103390 +
103391 +       DBGDrivDefaultMode(psStream);
103392 +
103393 +
103394 +       HostReleaseMutex(g_pvAPIMutex);
103395 +
103396 +       return;
103397 +}
103398 +
103399 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
103400 +{
103401 +       IMG_UINT32      ui32Ret;
103402 +
103403 +
103404 +       HostAquireMutex(g_pvAPIMutex);
103405 +
103406 +       ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
103407 +
103408 +
103409 +       HostReleaseMutex(g_pvAPIMutex);
103410 +
103411 +       return ui32Ret;
103412 +}
103413 +
103414 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
103415 +{
103416 +       IMG_UINT32      ui32Ret;
103417 +
103418 +
103419 +       HostAquireMutex(g_pvAPIMutex);
103420 +
103421 +       ui32Ret=DBGDrivWriteStringCM(psStream, pszString, ui32Level);
103422 +
103423 +
103424 +       HostReleaseMutex(g_pvAPIMutex);
103425 +
103426 +       return ui32Ret;
103427 +}
103428 +
103429 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
103430 +{
103431 +       IMG_UINT32      ui32Ret;
103432 +
103433 +
103434 +       HostAquireMutex(g_pvAPIMutex);
103435 +
103436 +       ui32Ret=DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
103437 +
103438 +
103439 +       HostReleaseMutex(g_pvAPIMutex);
103440 +
103441 +       return ui32Ret;
103442 +}
103443 +
103444 +void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
103445 +{
103446 +
103447 +       HostAquireMutex(g_pvAPIMutex);
103448 +
103449 +       DBGDrivSetMarker(psStream, ui32Marker);
103450 +
103451 +
103452 +       HostReleaseMutex(g_pvAPIMutex);
103453 +
103454 +       return;
103455 +}
103456 +
103457 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream)
103458 +{
103459 +       IMG_UINT32      ui32Marker;
103460 +
103461 +
103462 +       HostAquireMutex(g_pvAPIMutex);
103463 +
103464 +       ui32Marker = DBGDrivGetMarker(psStream);
103465 +
103466 +
103467 +       HostReleaseMutex(g_pvAPIMutex);
103468 +
103469 +       return ui32Marker;
103470 +}
103471 +
103472 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
103473 +{
103474 +       IMG_UINT32      ui32Ret;
103475 +
103476 +
103477 +       HostAquireMutex(g_pvAPIMutex);
103478 +
103479 +       ui32Ret = DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level, ui32Flags);
103480 +
103481 +
103482 +       HostReleaseMutex(g_pvAPIMutex);
103483 +
103484 +       return ui32Ret;
103485 +}
103486 +
103487 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
103488 +{
103489 +       IMG_UINT32 ui32Ret;
103490 +
103491 +
103492 +       HostAquireMutex(g_pvAPIMutex);
103493 +
103494 +       ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf);
103495 +
103496 +
103497 +       HostReleaseMutex(g_pvAPIMutex);
103498 +
103499 +       return ui32Ret;
103500 +}
103501 +
103502 +
103503 +IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream)
103504 +{
103505 +
103506 +       HostAquireMutex(g_pvAPIMutex);
103507 +
103508 +       DBGDrivStartInitPhase(psStream);
103509 +
103510 +
103511 +       HostReleaseMutex(g_pvAPIMutex);
103512 +
103513 +       return;
103514 +}
103515 +
103516 +IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream)
103517 +{
103518 +
103519 +       HostAquireMutex(g_pvAPIMutex);
103520 +
103521 +       DBGDrivStopInitPhase(psStream);
103522 +
103523 +
103524 +       HostReleaseMutex(g_pvAPIMutex);
103525 +
103526 +       return;
103527 +}
103528 +
103529 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream)
103530 +{
103531 +       IMG_UINT32 ui32Ret;
103532 +
103533 +
103534 +       HostAquireMutex(g_pvAPIMutex);
103535 +
103536 +       ui32Ret = DBGDrivGetStreamOffset(psStream);
103537 +
103538 +
103539 +       HostReleaseMutex(g_pvAPIMutex);
103540 +
103541 +       return ui32Ret;
103542 +}
103543 +
103544 +IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset)
103545 +{
103546 +
103547 +       HostAquireMutex(g_pvAPIMutex);
103548 +
103549 +       DBGDrivSetStreamOffset(psStream, ui32StreamOffset);
103550 +
103551 +
103552 +       HostReleaseMutex(g_pvAPIMutex);
103553 +}
103554 +
103555 +IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent)
103556 +{
103557 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
103558 +       DBGDrivWaitForEvent(eEvent);
103559 +#else
103560 +       PVR_UNREFERENCED_PARAMETER(eEvent);
103561 +#endif
103562 +}
103563 +
103564 +IMG_UINT32 AtoI(IMG_CHAR *szIn)
103565 +{
103566 +       IMG_INT         iLen = 0;
103567 +       IMG_UINT32      ui32Value = 0;
103568 +       IMG_UINT32      ui32Digit=1;
103569 +       IMG_UINT32      ui32Base=10;
103570 +       IMG_INT         iPos;
103571 +       IMG_CHAR        bc;
103572 +
103573 +
103574 +       while (szIn[iLen] > 0)
103575 +       {
103576 +               iLen ++;
103577 +       }
103578 +
103579 +
103580 +       if (iLen == 0)
103581 +       {
103582 +               return (0);
103583 +       }
103584 +
103585 +
103586 +       iPos=0;
103587 +       while (szIn[iPos] == '0')
103588 +       {
103589 +               iPos++;
103590 +       }
103591 +       if (szIn[iPos] == '\0')
103592 +       {
103593 +               return 0;
103594 +       }
103595 +       if (szIn[iPos] == 'x' || szIn[iPos] == 'X')
103596 +       {
103597 +               ui32Base=16;
103598 +               szIn[iPos]='0';
103599 +       }
103600 +
103601 +
103602 +       for (iPos = iLen - 1; iPos >= 0; iPos --)
103603 +       {
103604 +               bc = szIn[iPos];
103605 +
103606 +               if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16)
103607 +               {
103608 +                       bc -= 'a' - 0xa;
103609 +               }
103610 +               else
103611 +               if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16)
103612 +               {
103613 +                       bc -= 'A' - 0xa;
103614 +               }
103615 +               else
103616 +               if ((bc >= '0') && (bc <= '9'))
103617 +               {
103618 +                       bc -= '0';
103619 +               }
103620 +               else
103621 +                       return (0);
103622 +
103623 +               ui32Value += (IMG_UINT32)bc  * ui32Digit;
103624 +
103625 +               ui32Digit = ui32Digit * ui32Base;
103626 +       }
103627 +       return (ui32Value);
103628 +}
103629 +
103630 +
103631 +IMG_BOOL StreamValid(PDBG_STREAM psStream)
103632 +{
103633 +       PDBG_STREAM     psThis;
103634 +
103635 +       psThis = g_psStreamList;
103636 +
103637 +       while (psThis)
103638 +       {
103639 +               if (psStream && (psThis == psStream))
103640 +               {
103641 +                       return(IMG_TRUE);
103642 +               }
103643 +               else
103644 +               {
103645 +                       psThis = psThis->psNext;
103646 +               }
103647 +       }
103648 +
103649 +       return(IMG_FALSE);
103650 +}
103651 +
103652 +
103653 +void Write(PDBG_STREAM psStream,IMG_UINT8 * pui8Data,IMG_UINT32 ui32InBuffSize)
103654 +{
103655 +
103656 +
103657 +       if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size)
103658 +       {
103659 +               IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
103660 +               IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1;
103661 +
103662 +
103663 +               HostMemCopy((IMG_VOID *)(psStream->ui32Base + psStream->ui32WPtr),
103664 +                               (IMG_VOID *) pui8Data,
103665 +                               ui32B1);
103666 +
103667 +
103668 +               HostMemCopy((IMG_VOID *)psStream->ui32Base,
103669 +                               (IMG_VOID *)((IMG_UINT32) pui8Data + ui32B1),
103670 +                               ui32B2);
103671 +
103672 +
103673 +               psStream->ui32WPtr = ui32B2;
103674 +       }
103675 +       else
103676 +       {
103677 +               HostMemCopy((IMG_VOID *)(psStream->ui32Base + psStream->ui32WPtr),
103678 +                               (IMG_VOID *) pui8Data,
103679 +                               ui32InBuffSize);
103680 +
103681 +               psStream->ui32WPtr += ui32InBuffSize;
103682 +
103683 +               if (psStream->ui32WPtr == psStream->ui32Size)
103684 +               {
103685 +                       psStream->ui32WPtr = 0;
103686 +               }
103687 +       }
103688 +       psStream->ui32DataWritten += ui32InBuffSize;
103689 +}
103690 +
103691 +
103692 +void MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine)
103693 +{
103694 +       IMG_UINT32      i;
103695 +       IMG_CHAR *      pScreen;
103696 +
103697 +       pScreen = (IMG_CHAR *) DBGDRIV_MONOBASE;
103698 +
103699 +       pScreen += g_ui32Line * 160;
103700 +
103701 +
103702 +
103703 +       i=0;
103704 +       do
103705 +       {
103706 +               pScreen[g_ui32LOff + (i*2)] = pszString[i];
103707 +               pScreen[g_ui32LOff + (i*2)+1] = 127;
103708 +               i++;
103709 +       }
103710 +       while ((pszString[i] != 0) && (i < 4096));
103711 +
103712 +       g_ui32LOff += i * 2;
103713 +
103714 +       if (bNewLine)
103715 +       {
103716 +               g_ui32LOff = 0;
103717 +               g_ui32Line++;
103718 +       }
103719 +
103720 +
103721 +
103722 +       if (g_ui32Line == g_ui32MonoLines)
103723 +       {
103724 +               g_ui32Line = g_ui32MonoLines - 1;
103725 +
103726 +               HostMemCopy((IMG_VOID *)DBGDRIV_MONOBASE,(IMG_VOID *)(DBGDRIV_MONOBASE + 160),160 * (g_ui32MonoLines - 1));
103727 +
103728 +               HostMemSet((IMG_VOID *)(DBGDRIV_MONOBASE + (160 * (g_ui32MonoLines - 1))),0,160);
103729 +       }
103730 +}
103731 +
103732 +
103733 +
103734 +void AppendName(IMG_CHAR * pszOut,IMG_CHAR * pszBase,IMG_CHAR * pszName)
103735 +{
103736 +       IMG_UINT32 i;
103737 +       IMG_UINT32 ui32Off;
103738 +
103739 +       i = 0;
103740 +
103741 +       while (pszBase[i] != 0)
103742 +       {
103743 +               pszOut[i] = pszBase[i];
103744 +               i++;
103745 +       }
103746 +
103747 +       ui32Off = i;
103748 +       i = 0;
103749 +
103750 +       while (pszName[i] != 0)
103751 +       {
103752 +               pszOut[ui32Off+i] = pszName[i];
103753 +               i++;
103754 +       }
103755 +
103756 +       pszOut[ui32Off+i] = pszName[i];
103757 +}
103758 +
103759 +
103760 +IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *         pszName,
103761 +                                                                  IMG_UINT32   ui32CapMode,
103762 +                                                                  IMG_UINT32   ui32OutMode,
103763 +                                                                  IMG_UINT32   ui32Flags,
103764 +                                                                  IMG_UINT32   ui32Size)
103765 +{
103766 +       PDBG_STREAM     psStream;
103767 +       PDBG_STREAM     psInitStream;
103768 +       PDBG_LASTFRAME_BUFFER   psLFBuffer;
103769 +       IMG_UINT32              ui32Off;
103770 +       IMG_VOID *              pvBase;
103771 +
103772 +
103773 +
103774 +
103775 +       psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE);
103776 +
103777 +       if (psStream)
103778 +       {
103779 +               return ((IMG_VOID *) psStream);
103780 +       }
103781 +
103782 +
103783 +
103784 +       psStream = HostNonPageablePageAlloc(1);
103785 +       psInitStream = HostNonPageablePageAlloc(1);
103786 +       psLFBuffer = HostNonPageablePageAlloc(1);
103787 +       if      (
103788 +                       (!psStream) ||
103789 +                       (!psInitStream) ||
103790 +                       (!psLFBuffer)
103791 +               )
103792 +       {
103793 +               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc control structs\n\r"));
103794 +               return((IMG_VOID *) 0);
103795 +       }
103796 +
103797 +
103798 +       if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
103799 +       {
103800 +               pvBase = HostNonPageablePageAlloc(ui32Size);
103801 +       }
103802 +       else
103803 +       {
103804 +               pvBase = HostPageablePageAlloc(ui32Size);
103805 +       }
103806 +
103807 +       if (!pvBase)
103808 +       {
103809 +               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc Stream buffer\n\r"));
103810 +               HostNonPageablePageFree(psStream);
103811 +               return((IMG_VOID *) 0);
103812 +       }
103813 +
103814 +
103815 +
103816 +       psStream->psNext = 0;
103817 +       psStream->ui32Flags = ui32Flags;
103818 +       psStream->ui32Base = (IMG_UINT32)pvBase;
103819 +       psStream->ui32Size = ui32Size * 4096UL;
103820 +       psStream->ui32RPtr = 0;
103821 +       psStream->ui32WPtr = 0;
103822 +       psStream->ui32DataWritten = 0;
103823 +       psStream->ui32CapMode = ui32CapMode;
103824 +       psStream->ui32OutMode = ui32OutMode;
103825 +       psStream->ui32DebugLevel = DEBUG_LEVEL_0;
103826 +       psStream->ui32DefaultMode = ui32CapMode;
103827 +       psStream->ui32Start = 0;
103828 +       psStream->ui32End = 0;
103829 +       psStream->ui32Current = 0;
103830 +       psStream->ui32SampleRate = 1;
103831 +       psStream->ui32Access = 0;
103832 +       psStream->ui32Timeout = 0;
103833 +       psStream->ui32Marker = 0;
103834 +       psStream->bInitPhaseComplete = IMG_FALSE;
103835 +
103836 +
103837 +       if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
103838 +       {
103839 +               pvBase = HostNonPageablePageAlloc(ui32Size);
103840 +       }
103841 +       else
103842 +       {
103843 +               pvBase = HostPageablePageAlloc(ui32Size);
103844 +       }
103845 +
103846 +       if (!pvBase)
103847 +       {
103848 +               PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc InitStream buffer\n\r"));
103849 +
103850 +               if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
103851 +               {
103852 +                       HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base);
103853 +               }
103854 +               else
103855 +               {
103856 +                       HostPageablePageFree((IMG_VOID *)psStream->ui32Base);
103857 +               }
103858 +               HostNonPageablePageFree(psStream);
103859 +               return((IMG_VOID *) 0);
103860 +       }
103861 +
103862 +       psInitStream->psNext = 0;
103863 +       psInitStream->ui32Flags = ui32Flags;
103864 +       psInitStream->ui32Base = (IMG_UINT32)pvBase;
103865 +       psInitStream->ui32Size = ui32Size * 4096UL;
103866 +       psInitStream->ui32RPtr = 0;
103867 +       psInitStream->ui32WPtr = 0;
103868 +       psInitStream->ui32DataWritten = 0;
103869 +       psInitStream->ui32CapMode = ui32CapMode;
103870 +       psInitStream->ui32OutMode = ui32OutMode;
103871 +       psInitStream->ui32DebugLevel = DEBUG_LEVEL_0;
103872 +       psInitStream->ui32DefaultMode = ui32CapMode;
103873 +       psInitStream->ui32Start = 0;
103874 +       psInitStream->ui32End = 0;
103875 +       psInitStream->ui32Current = 0;
103876 +       psInitStream->ui32SampleRate = 1;
103877 +       psInitStream->ui32Access = 0;
103878 +       psInitStream->ui32Timeout = 0;
103879 +       psInitStream->ui32Marker = 0;
103880 +       psInitStream->bInitPhaseComplete = IMG_FALSE;
103881 +
103882 +       psStream->psInitStream = psInitStream;
103883 +
103884 +
103885 +       psLFBuffer->psStream = psStream;
103886 +       psLFBuffer->ui32BufLen = 0UL;
103887 +
103888 +       g_bHotkeyMiddump = IMG_FALSE;
103889 +       g_ui32HotkeyMiddumpStart = 0xffffffffUL;
103890 +       g_ui32HotkeyMiddumpEnd = 0xffffffffUL;
103891 +
103892 +
103893 +
103894 +       ui32Off = 0;
103895 +
103896 +       do
103897 +       {
103898 +               psStream->szName[ui32Off] = pszName[ui32Off];
103899 +
103900 +               ui32Off++;
103901 +       }
103902 +       while ((pszName[ui32Off] != 0) && (ui32Off < (4096UL - sizeof(DBG_STREAM))));
103903 +
103904 +       psStream->szName[ui32Off] = pszName[ui32Off];
103905 +
103906 +
103907 +
103908 +       psStream->psNext = g_psStreamList;
103909 +       g_psStreamList = psStream;
103910 +
103911 +       psLFBuffer->psNext = g_psLFBufferList;
103912 +       g_psLFBufferList = psLFBuffer;
103913 +
103914 +
103915 +       return((IMG_VOID *) psStream);
103916 +}
103917 +
103918 +void IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream)
103919 +{
103920 +       PDBG_STREAM     psStreamThis;
103921 +       PDBG_STREAM     psStreamPrev;
103922 +       PDBG_LASTFRAME_BUFFER   psLFBuffer;
103923 +       PDBG_LASTFRAME_BUFFER   psLFThis;
103924 +       PDBG_LASTFRAME_BUFFER   psLFPrev;
103925 +
103926 +       PVR_DPF((PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n", psStream->szName ));
103927 +
103928 +
103929 +
103930 +       if (!StreamValid(psStream))
103931 +       {
103932 +               return;
103933 +       }
103934 +
103935 +       psLFBuffer = FindLFBuf(psStream);
103936 +
103937 +
103938 +
103939 +       psStreamThis = g_psStreamList;
103940 +       psStreamPrev = 0;
103941 +
103942 +       while (psStreamThis)
103943 +       {
103944 +               if (psStreamThis == psStream)
103945 +               {
103946 +                       if (psStreamPrev)
103947 +                       {
103948 +                               psStreamPrev->psNext = psStreamThis->psNext;
103949 +                       }
103950 +                       else
103951 +                       {
103952 +                               g_psStreamList = psStreamThis->psNext;
103953 +                       }
103954 +
103955 +                       psStreamThis = 0;
103956 +               }
103957 +               else
103958 +               {
103959 +                       psStreamPrev = psStreamThis;
103960 +                       psStreamThis = psStreamThis->psNext;
103961 +               }
103962 +       }
103963 +
103964 +       psLFThis = g_psLFBufferList;
103965 +       psLFPrev = 0;
103966 +
103967 +       while (psLFThis)
103968 +       {
103969 +               if (psLFThis == psLFBuffer)
103970 +               {
103971 +                       if (psLFPrev)
103972 +                       {
103973 +                               psLFPrev->psNext = psLFThis->psNext;
103974 +                       }
103975 +                       else
103976 +                       {
103977 +                               g_psLFBufferList = psLFThis->psNext;
103978 +                       }
103979 +
103980 +                       psLFThis = 0;
103981 +               }
103982 +               else
103983 +               {
103984 +                       psLFPrev = psLFThis;
103985 +                       psLFThis = psLFThis->psNext;
103986 +               }
103987 +       }
103988 +
103989 +
103990 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
103991 +       {
103992 +               DeactivateHotKeys();
103993 +       }
103994 +
103995 +
103996 +
103997 +       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
103998 +       {
103999 +               HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base);
104000 +               HostNonPageablePageFree((IMG_VOID *)psStream->psInitStream->ui32Base);
104001 +       }
104002 +       else
104003 +       {
104004 +               HostPageablePageFree((IMG_VOID *)psStream->ui32Base);
104005 +               HostPageablePageFree((IMG_VOID *)psStream->psInitStream->ui32Base);
104006 +       }
104007 +
104008 +       HostNonPageablePageFree(psStream->psInitStream);
104009 +       HostNonPageablePageFree(psStream);
104010 +       HostNonPageablePageFree(psLFBuffer);
104011 +
104012 +       if (g_psStreamList == 0)
104013 +       {
104014 +               PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" ));
104015 +       }
104016 +
104017 +       return;
104018 +}
104019 +
104020 +IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
104021 +{
104022 +       PDBG_STREAM     psStream;
104023 +       PDBG_STREAM     psThis;
104024 +       IMG_UINT32      ui32Off;
104025 +       IMG_BOOL        bAreSame;
104026 +
104027 +       psStream = 0;
104028 +
104029 +
104030 +
104031 +       for (psThis = g_psStreamList; psThis != IMG_NULL; psThis = psThis->psNext)
104032 +       {
104033 +               bAreSame = IMG_TRUE;
104034 +               ui32Off = 0;
104035 +
104036 +               if (strlen(psThis->szName) == strlen(pszName))
104037 +               {
104038 +                       while ((psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && (ui32Off < 128) && bAreSame)
104039 +                       {
104040 +                               if (psThis->szName[ui32Off] != pszName[ui32Off])
104041 +                               {
104042 +                                       bAreSame = IMG_FALSE;
104043 +                               }
104044 +
104045 +                               ui32Off++;
104046 +                       }
104047 +               }
104048 +               else
104049 +               {
104050 +                       bAreSame = IMG_FALSE;
104051 +               }
104052 +
104053 +               if (bAreSame)
104054 +               {
104055 +                       psStream = psThis;
104056 +                       break;
104057 +               }
104058 +       }
104059 +
104060 +       if(bResetStream && psStream)
104061 +       {
104062 +               static IMG_CHAR szComment[] = "-- Init phase terminated\r\n";
104063 +               psStream->psInitStream->ui32RPtr = 0;
104064 +               psStream->ui32RPtr = 0;
104065 +               psStream->ui32WPtr = 0;
104066 +               psStream->ui32DataWritten = psStream->psInitStream->ui32DataWritten;
104067 +               if (psStream->bInitPhaseComplete == IMG_FALSE)
104068 +               {
104069 +                       if (psStream->ui32Flags & DEBUG_FLAGS_TEXTSTREAM)
104070 +                       {
104071 +                               DBGDrivWrite2(psStream, (IMG_UINT8 *)szComment, sizeof(szComment) - 1, 0x01);
104072 +                       }
104073 +                       psStream->bInitPhaseComplete = IMG_TRUE;
104074 +               }
104075 +       }
104076 +
104077 +       return((IMG_VOID *) psStream);
104078 +}
104079 +
104080 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
104081 +{
104082 +
104083 +
104084 +       if (!StreamValid(psStream))
104085 +       {
104086 +               return(0xFFFFFFFFUL);
104087 +       }
104088 +
104089 +
104090 +
104091 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
104092 +       {
104093 +               if      ((psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
104094 +               {
104095 +                       return(0);
104096 +               }
104097 +       }
104098 +       else
104099 +       {
104100 +               if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
104101 +               {
104102 +                       if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
104103 +                       {
104104 +                               return(0);
104105 +                       }
104106 +               }
104107 +       }
104108 +
104109 +       return(DBGDrivWriteString(psStream,pszString,ui32Level));
104110 +
104111 +}
104112 +
104113 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
104114 +{
104115 +       IMG_UINT32      ui32Len;
104116 +       IMG_UINT32      ui32Space;
104117 +       IMG_UINT32      ui32WPtr;
104118 +       IMG_UINT8 *     pui8Buffer;
104119 +
104120 +
104121 +
104122 +       if (!StreamValid(psStream))
104123 +       {
104124 +               return(0xFFFFFFFFUL);
104125 +       }
104126 +
104127 +
104128 +
104129 +       if ((psStream->ui32DebugLevel & ui32Level) == 0)
104130 +       {
104131 +               return(0xFFFFFFFFUL);
104132 +       }
104133 +
104134 +
104135 +
104136 +
104137 +       if ((psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC) == 0)
104138 +       {
104139 +               if (psStream->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG)
104140 +               {
104141 +                       PVR_DPF((PVR_DBG_MESSAGE,"%s: %s\r\n",psStream->szName, pszString));
104142 +               }
104143 +
104144 +
104145 +
104146 +               if (psStream->ui32OutMode & DEBUG_OUTMODE_MONO)
104147 +               {
104148 +                       MonoOut(psStream->szName,IMG_FALSE);
104149 +                       MonoOut(": ",IMG_FALSE);
104150 +                       MonoOut(pszString,IMG_TRUE);
104151 +               }
104152 +       }
104153 +
104154 +
104155 +
104156 +       if      (
104157 +                       !(
104158 +                               ((psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) != 0) ||
104159 +                               ((psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC) != 0)
104160 +                       )
104161 +               )
104162 +       {
104163 +               return(0xFFFFFFFFUL);
104164 +       }
104165 +
104166 +
104167 +
104168 +       ui32Space=SpaceInStream(psStream);
104169 +
104170 +       if(ui32Space > 0)
104171 +       {
104172 +               ui32Space--;
104173 +       }
104174 +
104175 +       ui32Len         = 0;
104176 +       ui32WPtr        = psStream->ui32WPtr;
104177 +       pui8Buffer      = (IMG_UINT8 *) psStream->ui32Base;
104178 +
104179 +       while((pszString[ui32Len] != 0) && (ui32Len < ui32Space))
104180 +       {
104181 +               pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
104182 +               ui32Len++;
104183 +               ui32WPtr++;
104184 +               if (ui32WPtr == psStream->ui32Size)
104185 +               {
104186 +                       ui32WPtr = 0;
104187 +               }
104188 +       }
104189 +
104190 +       if (ui32Len < ui32Space)
104191 +       {
104192 +
104193 +               pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
104194 +               ui32Len++;
104195 +               ui32WPtr++;
104196 +               if (ui32WPtr == psStream->ui32Size)
104197 +               {
104198 +                       ui32WPtr = 0;
104199 +               }
104200 +
104201 +
104202 +               psStream->ui32WPtr = ui32WPtr;
104203 +               psStream->ui32DataWritten+= ui32Len;
104204 +       } else
104205 +       {
104206 +               ui32Len = 0;
104207 +       }
104208 +
104209 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
104210 +       if (ui32Len)
104211 +       {
104212 +               HostSignalEvent(DBG_EVENT_STREAM_DATA);
104213 +       }
104214 +#endif
104215 +
104216 +       return(ui32Len);
104217 +}
104218 +
104219 +IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
104220 +{
104221 +       IMG_UINT32                              ui32OutLen;
104222 +       IMG_UINT32                              ui32Len;
104223 +       IMG_UINT32                              ui32Offset;
104224 +       IMG_UINT8                               *pui8Buff;
104225 +
104226 +
104227 +
104228 +       if (!StreamValid(psStream))
104229 +       {
104230 +               return(0);
104231 +       }
104232 +
104233 +
104234 +
104235 +       pui8Buff = (IMG_UINT8 *) psStream->ui32Base;
104236 +       ui32Offset = psStream->ui32RPtr;
104237 +
104238 +       if (psStream->ui32RPtr == psStream->ui32WPtr)
104239 +       {
104240 +               return(0);
104241 +       }
104242 +
104243 +
104244 +
104245 +       ui32Len = 0;
104246 +       while((pui8Buff[ui32Offset] != 0) && (ui32Offset != psStream->ui32WPtr))
104247 +       {
104248 +               ui32Offset++;
104249 +               ui32Len++;
104250 +
104251 +
104252 +
104253 +               if (ui32Offset == psStream->ui32Size)
104254 +               {
104255 +                       ui32Offset = 0;
104256 +               }
104257 +       }
104258 +
104259 +       ui32OutLen = ui32Len + 1;
104260 +
104261 +
104262 +
104263 +       if (ui32Len > ui32Limit)
104264 +       {
104265 +               return(0);
104266 +       }
104267 +
104268 +
104269 +
104270 +       ui32Offset = psStream->ui32RPtr;
104271 +       ui32Len = 0;
104272 +
104273 +       while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit))
104274 +       {
104275 +               pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
104276 +               ui32Offset++;
104277 +               ui32Len++;
104278 +
104279 +
104280 +
104281 +               if (ui32Offset == psStream->ui32Size)
104282 +               {
104283 +                       ui32Offset = 0;
104284 +               }
104285 +       }
104286 +
104287 +       pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
104288 +
104289 +       psStream->ui32RPtr = ui32Offset + 1;
104290 +
104291 +       if (psStream->ui32RPtr == psStream->ui32Size)
104292 +       {
104293 +               psStream->ui32RPtr = 0;
104294 +       }
104295 +
104296 +       return(ui32OutLen);
104297 +}
104298 +
104299 +IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
104300 +{
104301 +       IMG_UINT32                              ui32Space;
104302 +       DBG_STREAM *psStream;
104303 +
104304 +
104305 +
104306 +       if (!StreamValid(psMainStream))
104307 +       {
104308 +               return(0xFFFFFFFFUL);
104309 +       }
104310 +
104311 +
104312 +
104313 +       if ((psMainStream->ui32DebugLevel & ui32Level) == 0)
104314 +       {
104315 +               return(0xFFFFFFFFUL);
104316 +       }
104317 +
104318 +
104319 +
104320 +       if (psMainStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
104321 +       {
104322 +               if      ((psMainStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
104323 +               {
104324 +                       return(0xFFFFFFFFUL);
104325 +               }
104326 +       }
104327 +       else if (psMainStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
104328 +       {
104329 +               if ((psMainStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
104330 +                       return(0xFFFFFFFFUL);
104331 +       }
104332 +
104333 +       if(psMainStream->bInitPhaseComplete)
104334 +       {
104335 +               psStream = psMainStream;
104336 +       }
104337 +       else
104338 +       {
104339 +               psStream = psMainStream->psInitStream;
104340 +       }
104341 +
104342 +
104343 +
104344 +       ui32Space=SpaceInStream(psStream);
104345 +
104346 +
104347 +
104348 +       if ((psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
104349 +       {
104350 +               return(0);
104351 +       }
104352 +
104353 +       if (ui32Space < 8)
104354 +       {
104355 +               return(0);
104356 +       }
104357 +
104358 +
104359 +
104360 +       if (ui32Space <= (ui32InBuffSize + 4))
104361 +       {
104362 +               ui32InBuffSize = ui32Space - 8;
104363 +       }
104364 +
104365 +
104366 +
104367 +       Write(psStream,(IMG_UINT8 *) &ui32InBuffSize,4);
104368 +       Write(psStream,pui8InBuf,ui32InBuffSize);
104369 +
104370 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
104371 +       if (ui32InBuffSize)
104372 +       {
104373 +               HostSignalEvent(DBG_EVENT_STREAM_DATA);
104374 +       }
104375 +#endif
104376 +       return(ui32InBuffSize);
104377 +}
104378 +
104379 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
104380 +{
104381 +
104382 +
104383 +       if (!StreamValid(psStream))
104384 +       {
104385 +               return(0xFFFFFFFFUL);
104386 +       }
104387 +
104388 +
104389 +
104390 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
104391 +       {
104392 +               if      ((psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
104393 +               {
104394 +                       return(0xFFFFFFFFUL);
104395 +               }
104396 +       }
104397 +       else
104398 +       {
104399 +               if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
104400 +               {
104401 +                       if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
104402 +                       {
104403 +                               return(0xFFFFFFFFUL);
104404 +                       }
104405 +               }
104406 +       }
104407 +
104408 +       return(DBGDrivWrite2(psStream,pui8InBuf,ui32InBuffSize,ui32Level));
104409 +}
104410 +
104411 +IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
104412 +{
104413 +       IMG_UINT32      ui32Space;
104414 +       DBG_STREAM      *psStream;
104415 +
104416 +
104417 +
104418 +       if (!StreamValid(psMainStream))
104419 +       {
104420 +               return(0xFFFFFFFFUL);
104421 +       }
104422 +
104423 +
104424 +
104425 +       if ((psMainStream->ui32DebugLevel & ui32Level) == 0)
104426 +       {
104427 +               return(0xFFFFFFFFUL);
104428 +       }
104429 +
104430 +       if(psMainStream->bInitPhaseComplete)
104431 +       {
104432 +               psStream = psMainStream;
104433 +       }
104434 +       else
104435 +       {
104436 +               psStream = psMainStream->psInitStream;
104437 +       }
104438 +
104439 +
104440 +
104441 +       ui32Space=SpaceInStream(psStream);
104442 +
104443 +
104444 +
104445 +       if ((psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
104446 +       {
104447 +               return(0);
104448 +       }
104449 +
104450 +
104451 +
104452 +       if (psStream->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION)
104453 +       {
104454 +
104455 +
104456 +
104457 +               if (ui32Space < 32)
104458 +               {
104459 +                       return(0);
104460 +               }
104461 +       }
104462 +       else
104463 +       {
104464 +               if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4)))
104465 +               {
104466 +                       IMG_UINT32      ui32NewBufSize;
104467 +
104468 +
104469 +
104470 +                       ui32NewBufSize = 2 * psStream->ui32Size;
104471 +
104472 +                       if (ui32InBuffSize > psStream->ui32Size)
104473 +                       {
104474 +                               ui32NewBufSize += ui32InBuffSize;
104475 +                       }
104476 +
104477 +
104478 +
104479 +                       if (!ExpandStreamBuffer(psStream,ui32NewBufSize))
104480 +                       {
104481 +                               if (ui32Space < 32)
104482 +                               {
104483 +                                       return(0);
104484 +                               }
104485 +                       }
104486 +
104487 +
104488 +
104489 +                       ui32Space = SpaceInStream(psStream);
104490 +               }
104491 +       }
104492 +
104493 +
104494 +
104495 +       if (ui32Space <= (ui32InBuffSize + 4))
104496 +       {
104497 +               ui32InBuffSize = ui32Space - 4;
104498 +       }
104499 +
104500 +
104501 +
104502 +       Write(psStream,pui8InBuf,ui32InBuffSize);
104503 +
104504 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
104505 +       if (ui32InBuffSize)
104506 +       {
104507 +               HostSignalEvent(DBG_EVENT_STREAM_DATA);
104508 +       }
104509 +#endif
104510 +       return(ui32InBuffSize);
104511 +}
104512 +
104513 +IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
104514 +{
104515 +       IMG_UINT32 ui32Data;
104516 +       DBG_STREAM *psStream;
104517 +
104518 +
104519 +
104520 +       if (!StreamValid(psMainStream))
104521 +       {
104522 +               return(0);
104523 +       }
104524 +
104525 +       if(bReadInitBuffer)
104526 +       {
104527 +               psStream = psMainStream->psInitStream;
104528 +       }
104529 +       else
104530 +       {
104531 +               psStream = psMainStream;
104532 +       }
104533 +
104534 +       if (psStream->ui32RPtr == psStream->ui32WPtr)
104535 +       {
104536 +               return(0);
104537 +       }
104538 +
104539 +
104540 +
104541 +       if (psStream->ui32RPtr <= psStream->ui32WPtr)
104542 +       {
104543 +               ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
104544 +       }
104545 +       else
104546 +       {
104547 +               ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr);
104548 +       }
104549 +
104550 +
104551 +
104552 +       if (ui32Data > ui32OutBuffSize)
104553 +       {
104554 +               ui32Data = ui32OutBuffSize;
104555 +       }
104556 +
104557 +
104558 +
104559 +       if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size)
104560 +       {
104561 +               IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
104562 +               IMG_UINT32 ui32B2 = ui32Data - ui32B1;
104563 +
104564 +
104565 +               HostMemCopy((IMG_VOID *) pui8OutBuf,
104566 +                               (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr),
104567 +                               ui32B1);
104568 +
104569 +
104570 +               HostMemCopy((IMG_VOID *)((IMG_UINT32) pui8OutBuf + ui32B1),
104571 +                               (IMG_VOID *)psStream->ui32Base,
104572 +                               ui32B2);
104573 +
104574 +
104575 +               psStream->ui32RPtr = ui32B2;
104576 +       }
104577 +       else
104578 +       {
104579 +               HostMemCopy((IMG_VOID *) pui8OutBuf,
104580 +                               (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr),
104581 +                               ui32Data);
104582 +
104583 +
104584 +               psStream->ui32RPtr += ui32Data;
104585 +
104586 +
104587 +               if (psStream->ui32RPtr == psStream->ui32Size)
104588 +               {
104589 +                       psStream->ui32RPtr = 0;
104590 +               }
104591 +       }
104592 +
104593 +       return(ui32Data);
104594 +}
104595 +
104596 +void IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
104597 +{
104598 +
104599 +
104600 +       if (!StreamValid(psStream))
104601 +       {
104602 +               return;
104603 +       }
104604 +
104605 +       psStream->ui32CapMode = ui32Mode;
104606 +       psStream->ui32DefaultMode = ui32Mode;
104607 +       psStream->ui32Start = ui32Start;
104608 +       psStream->ui32End = ui32End;
104609 +       psStream->ui32SampleRate = ui32SampleRate;
104610 +
104611 +
104612 +
104613 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
104614 +       {
104615 +               ActivateHotKeys(psStream);
104616 +       }
104617 +}
104618 +
104619 +void IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
104620 +{
104621 +
104622 +
104623 +       if (!StreamValid(psStream))
104624 +       {
104625 +               return;
104626 +       }
104627 +
104628 +       psStream->ui32OutMode = ui32OutMode;
104629 +}
104630 +
104631 +void IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
104632 +{
104633 +
104634 +
104635 +       if (!StreamValid(psStream))
104636 +       {
104637 +               return;
104638 +       }
104639 +
104640 +       psStream->ui32DebugLevel = ui32DebugLevel;
104641 +}
104642 +
104643 +void IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
104644 +{
104645 +
104646 +
104647 +       if (!StreamValid(psStream))
104648 +       {
104649 +               return;
104650 +       }
104651 +
104652 +       psStream->ui32Current = ui32Frame;
104653 +
104654 +       if ((ui32Frame >= psStream->ui32Start) &&
104655 +               (ui32Frame <= psStream->ui32End) &&
104656 +               (((ui32Frame - psStream->ui32Start) % psStream->ui32SampleRate) == 0))
104657 +       {
104658 +               psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
104659 +       }
104660 +       else
104661 +       {
104662 +               psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
104663 +       }
104664 +
104665 +       if (g_bHotkeyMiddump)
104666 +       {
104667 +               if ((ui32Frame >= g_ui32HotkeyMiddumpStart) &&
104668 +                       (ui32Frame <= g_ui32HotkeyMiddumpEnd) &&
104669 +                       (((ui32Frame - g_ui32HotkeyMiddumpStart) % psStream->ui32SampleRate) == 0))
104670 +               {
104671 +                       psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
104672 +               }
104673 +               else
104674 +               {
104675 +                       psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
104676 +                       if (psStream->ui32Current > g_ui32HotkeyMiddumpEnd)
104677 +                       {
104678 +                               g_bHotkeyMiddump = IMG_FALSE;
104679 +                       }
104680 +               }
104681 +       }
104682 +
104683 +
104684 +       if (g_bHotKeyRegistered)
104685 +       {
104686 +               g_bHotKeyRegistered = IMG_FALSE;
104687 +
104688 +               PVR_DPF((PVR_DBG_MESSAGE,"Hotkey pressed (%08x)!\n",psStream));
104689 +
104690 +               if (!g_bHotKeyPressed)
104691 +               {
104692 +
104693 +
104694 +                       g_ui32HotKeyFrame = psStream->ui32Current + 2;
104695 +
104696 +
104697 +
104698 +                       g_bHotKeyPressed = IMG_TRUE;
104699 +               }
104700 +
104701 +
104702 +
104703 +               if (((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
104704 +                       ((psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY) != 0))
104705 +               {
104706 +                       if (!g_bHotkeyMiddump)
104707 +                       {
104708 +
104709 +                               g_ui32HotkeyMiddumpStart = g_ui32HotKeyFrame + 1;
104710 +                               g_ui32HotkeyMiddumpEnd = 0xffffffff;
104711 +                               g_bHotkeyMiddump = IMG_TRUE;
104712 +                               PVR_DPF((PVR_DBG_MESSAGE,"Sampling every %d frame(s)\n", psStream->ui32SampleRate));
104713 +                       }
104714 +                       else
104715 +                       {
104716 +
104717 +                               g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame;
104718 +                               PVR_DPF((PVR_DBG_MESSAGE,"Turning off sampling\n"));
104719 +                       }
104720 +               }
104721 +
104722 +       }
104723 +
104724 +
104725 +
104726 +       if (psStream->ui32Current > g_ui32HotKeyFrame)
104727 +       {
104728 +               g_bHotKeyPressed = IMG_FALSE;
104729 +       }
104730 +}
104731 +
104732 +IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream)
104733 +{
104734 +
104735 +
104736 +       if (!StreamValid(psStream))
104737 +       {
104738 +               return(0);
104739 +       }
104740 +
104741 +       return(psStream->ui32Current);
104742 +}
104743 +
104744 +IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
104745 +{
104746 +       IMG_UINT32      ui32NextFrame;
104747 +
104748 +
104749 +
104750 +       if (!StreamValid(psStream))
104751 +       {
104752 +               return IMG_FALSE;
104753 +       }
104754 +
104755 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
104756 +       {
104757 +               ui32NextFrame = psStream->ui32Current + psStream->ui32SampleRate;
104758 +               if (ui32NextFrame > psStream->ui32End)
104759 +               {
104760 +                       return IMG_TRUE;
104761 +               }
104762 +       }
104763 +       return IMG_FALSE;
104764 +}
104765 +
104766 +IMG_BOOL IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
104767 +{
104768 +       IMG_UINT32 ui32FrameShift = bCheckPreviousFrame ? 1UL : 0UL;
104769 +
104770 +
104771 +
104772 +       if (!StreamValid(psStream))
104773 +       {
104774 +               return IMG_FALSE;
104775 +       }
104776 +
104777 +       if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
104778 +       {
104779 +
104780 +               if (g_bHotkeyMiddump)
104781 +               {
104782 +                       if ((psStream->ui32Current >= (g_ui32HotkeyMiddumpStart - ui32FrameShift)) &&
104783 +                               (psStream->ui32Current <= (g_ui32HotkeyMiddumpEnd - ui32FrameShift)) &&
104784 +                               ((((psStream->ui32Current + ui32FrameShift) - g_ui32HotkeyMiddumpStart) % psStream->ui32SampleRate) == 0))
104785 +                       {
104786 +                               return IMG_TRUE;
104787 +                       }
104788 +               }
104789 +               else
104790 +               {
104791 +                       if ((psStream->ui32Current >= (psStream->ui32Start - ui32FrameShift)) &&
104792 +                               (psStream->ui32Current <= (psStream->ui32End - ui32FrameShift)) &&
104793 +                               ((((psStream->ui32Current + ui32FrameShift) - psStream->ui32Start) % psStream->ui32SampleRate) == 0))
104794 +                       {
104795 +                               return IMG_TRUE;
104796 +                       }
104797 +               }
104798 +       }
104799 +       else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
104800 +       {
104801 +               if ((psStream->ui32Current == (g_ui32HotKeyFrame-ui32FrameShift)) && (g_bHotKeyPressed))
104802 +               {
104803 +                       return IMG_TRUE;
104804 +               }
104805 +       }
104806 +       return IMG_FALSE;
104807 +}
104808 +
104809 +void IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
104810 +{
104811 +
104812 +
104813 +       if (!StreamValid(psStream))
104814 +       {
104815 +               return;
104816 +       }
104817 +
104818 +       psStream->ui32CapMode = ui32Mode;
104819 +}
104820 +
104821 +void IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream)
104822 +{
104823 +
104824 +
104825 +       if (!StreamValid(psStream))
104826 +       {
104827 +               return;
104828 +       }
104829 +
104830 +       psStream->ui32CapMode = psStream->ui32DefaultMode;
104831 +}
104832 +
104833 +void IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
104834 +{
104835 +
104836 +
104837 +       if (!StreamValid(psStream))
104838 +       {
104839 +               return;
104840 +       }
104841 +
104842 +       psStream->ui32Marker = ui32Marker;
104843 +}
104844 +
104845 +IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream)
104846 +{
104847 +
104848 +
104849 +       if (!StreamValid(psStream))
104850 +       {
104851 +               return 0;
104852 +       }
104853 +
104854 +       return psStream->ui32Marker;
104855 +}
104856 +
104857 +
104858 +IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psMainStream)
104859 +{
104860 +       PDBG_STREAM psStream;
104861 +
104862 +
104863 +
104864 +       if (!StreamValid(psMainStream))
104865 +       {
104866 +               return 0;
104867 +       }
104868 +
104869 +       if(psMainStream->bInitPhaseComplete)
104870 +       {
104871 +               psStream = psMainStream;
104872 +       }
104873 +       else
104874 +       {
104875 +               psStream = psMainStream->psInitStream;
104876 +       }
104877 +
104878 +       return psStream->ui32DataWritten;
104879 +}
104880 +
104881 +IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psMainStream, IMG_UINT32 ui32StreamOffset)
104882 +{
104883 +       PDBG_STREAM psStream;
104884 +
104885 +
104886 +
104887 +       if (!StreamValid(psMainStream))
104888 +       {
104889 +               return;
104890 +       }
104891 +
104892 +       if(psMainStream->bInitPhaseComplete)
104893 +       {
104894 +               psStream = psMainStream;
104895 +       }
104896 +       else
104897 +       {
104898 +               psStream = psMainStream->psInitStream;
104899 +       }
104900 +
104901 +       psStream->ui32DataWritten = ui32StreamOffset;
104902 +}
104903 +
104904 +IMG_UINT32 IMG_CALLCONV DBGDrivGetServiceTable(void)
104905 +{
104906 +       return((IMG_UINT32) &g_sDBGKMServices);
104907 +}
104908 +
104909 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
104910 +{
104911 +       PDBG_LASTFRAME_BUFFER   psLFBuffer;
104912 +
104913 +
104914 +
104915 +       if (!StreamValid(psStream))
104916 +       {
104917 +               return(0xFFFFFFFFUL);
104918 +       }
104919 +
104920 +
104921 +
104922 +       if ((psStream->ui32DebugLevel & ui32Level) == 0)
104923 +       {
104924 +               return(0xFFFFFFFFUL);
104925 +       }
104926 +
104927 +
104928 +
104929 +       if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0)
104930 +       {
104931 +               if      ((psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
104932 +               {
104933 +                       return(0xFFFFFFFFUL);
104934 +               }
104935 +       }
104936 +       else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
104937 +       {
104938 +               if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
104939 +                       return(0xFFFFFFFFUL);
104940 +       }
104941 +
104942 +       psLFBuffer = FindLFBuf(psStream);
104943 +
104944 +       if (ui32Flags & WRITELF_FLAGS_RESETBUF)
104945 +       {
104946 +
104947 +
104948 +               ui32InBuffSize = (ui32InBuffSize > LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE : ui32InBuffSize;
104949 +               HostMemCopy((IMG_VOID *)psLFBuffer->ui8Buffer, (IMG_VOID *)pui8InBuf, ui32InBuffSize);
104950 +               psLFBuffer->ui32BufLen = ui32InBuffSize;
104951 +       }
104952 +       else
104953 +       {
104954 +
104955 +
104956 +               ui32InBuffSize = ((psLFBuffer->ui32BufLen + ui32InBuffSize) > LAST_FRAME_BUF_SIZE) ? (LAST_FRAME_BUF_SIZE - psLFBuffer->ui32BufLen) : ui32InBuffSize;
104957 +               HostMemCopy((IMG_VOID *)(&psLFBuffer->ui8Buffer[psLFBuffer->ui32BufLen]), (IMG_VOID *)pui8InBuf, ui32InBuffSize);
104958 +               psLFBuffer->ui32BufLen += ui32InBuffSize;
104959 +       }
104960 +
104961 +       return(ui32InBuffSize);
104962 +}
104963 +
104964 +IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
104965 +{
104966 +       PDBG_LASTFRAME_BUFFER   psLFBuffer;
104967 +       IMG_UINT32      ui32Data;
104968 +
104969 +
104970 +
104971 +       if (!StreamValid(psStream))
104972 +       {
104973 +               return(0);
104974 +       }
104975 +
104976 +       psLFBuffer = FindLFBuf(psStream);
104977 +
104978 +
104979 +
104980 +       ui32Data = (ui32OutBuffSize < psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen;
104981 +
104982 +
104983 +
104984 +       HostMemCopy((IMG_VOID *)pui8OutBuf, (IMG_VOID *)psLFBuffer->ui8Buffer, ui32Data);
104985 +
104986 +       return ui32Data;
104987 +}
104988 +
104989 +IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream)
104990 +{
104991 +       psStream->bInitPhaseComplete = IMG_FALSE;
104992 +}
104993 +
104994 +IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream)
104995 +{
104996 +       psStream->bInitPhaseComplete = IMG_TRUE;
104997 +}
104998 +
104999 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
105000 +IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent)
105001 +{
105002 +       HostWaitForEvent(eEvent);
105003 +}
105004 +#endif
105005 +
105006 +IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize)
105007 +{
105008 +       IMG_VOID *      pvNewBuf;
105009 +       IMG_UINT32      ui32NewSizeInPages;
105010 +       IMG_UINT32      ui32NewWOffset;
105011 +       IMG_UINT32      ui32SpaceInOldBuf;
105012 +
105013 +
105014 +
105015 +       if (psStream->ui32Size >= ui32NewSize)
105016 +       {
105017 +               return IMG_FALSE;
105018 +       }
105019 +
105020 +
105021 +
105022 +       ui32SpaceInOldBuf = SpaceInStream(psStream);
105023 +
105024 +
105025 +
105026 +       ui32NewSizeInPages = ((ui32NewSize + 0xfffUL) & ~0xfffUL) / 4096UL;
105027 +
105028 +       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
105029 +       {
105030 +               pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
105031 +       }
105032 +       else
105033 +       {
105034 +               pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
105035 +       }
105036 +
105037 +       if (pvNewBuf == IMG_NULL)
105038 +       {
105039 +               return IMG_FALSE;
105040 +       }
105041 +
105042 +
105043 +
105044 +
105045 +       if (psStream->ui32RPtr <= psStream->ui32WPtr)
105046 +       {
105047 +
105048 +
105049 +               HostMemCopy((IMG_VOID *)pvNewBuf, (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), psStream->ui32WPtr - psStream->ui32RPtr);
105050 +       }
105051 +       else
105052 +       {
105053 +               IMG_UINT32      ui32FirstCopySize;
105054 +
105055 +
105056 +
105057 +               ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
105058 +
105059 +               HostMemCopy((IMG_VOID *)pvNewBuf, (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), ui32FirstCopySize);
105060 +
105061 +
105062 +
105063 +               HostMemCopy((IMG_VOID *)((IMG_UINT32)pvNewBuf + ui32FirstCopySize), (IMG_VOID *)psStream->ui32Base, psStream->ui32WPtr);
105064 +       }
105065 +
105066 +
105067 +
105068 +       ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
105069 +
105070 +
105071 +
105072 +       if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
105073 +       {
105074 +               HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base);
105075 +       }
105076 +       else
105077 +       {
105078 +               HostPageablePageFree((IMG_VOID *)psStream->ui32Base);
105079 +       }
105080 +
105081 +
105082 +
105083 +       psStream->ui32Base = (IMG_UINT32)pvNewBuf;
105084 +       psStream->ui32RPtr = 0;
105085 +       psStream->ui32WPtr = ui32NewWOffset;
105086 +       psStream->ui32Size = ui32NewSizeInPages * 4096;
105087 +
105088 +       return IMG_TRUE;
105089 +}
105090 +
105091 +IMG_UINT32 SpaceInStream(PDBG_STREAM psStream)
105092 +{
105093 +       IMG_UINT32      ui32Space;
105094 +
105095 +       if (psStream->ui32RPtr > psStream->ui32WPtr)
105096 +       {
105097 +               ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
105098 +       }
105099 +       else
105100 +       {
105101 +               ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr);
105102 +       }
105103 +
105104 +       return ui32Space;
105105 +}
105106 +
105107 +
105108 +void DestroyAllStreams(void)
105109 +{
105110 +       while (g_psStreamList != IMG_NULL)
105111 +       {
105112 +               DBGDrivDestroyStream(g_psStreamList);
105113 +       }
105114 +       return;
105115 +}
105116 +
105117 +PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream)
105118 +{
105119 +       PDBG_LASTFRAME_BUFFER   psLFBuffer;
105120 +
105121 +       psLFBuffer = g_psLFBufferList;
105122 +
105123 +       while (psLFBuffer)
105124 +       {
105125 +               if (psLFBuffer->psStream == psStream)
105126 +               {
105127 +                       break;
105128 +               }
105129 +
105130 +               psLFBuffer = psLFBuffer->psNext;
105131 +       }
105132 +
105133 +       return psLFBuffer;
105134 +}
105135 +
105136 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h
105137 new file mode 100644
105138 index 0000000..1c9b1c5
105139 --- /dev/null
105140 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/dbgdriv.h
105141 @@ -0,0 +1,116 @@
105142 +/**********************************************************************
105143 + *
105144 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105145 + *
105146 + * This program is free software; you can redistribute it and/or modify it
105147 + * under the terms and conditions of the GNU General Public License,
105148 + * version 2, as published by the Free Software Foundation.
105149 + *
105150 + * This program is distributed in the hope it will be useful but, except
105151 + * as otherwise stated in writing, without any warranty; without even the
105152 + * implied warranty of merchantability or fitness for a particular purpose.
105153 + * See the GNU General Public License for more details.
105154 + *
105155 + * You should have received a copy of the GNU General Public License along with
105156 + * this program; if not, write to the Free Software Foundation, Inc.,
105157 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105158 + *
105159 + * The full GNU General Public License is included in this distribution in
105160 + * the file called "COPYING".
105161 + *
105162 + * Contact Information:
105163 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105164 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
105165 + *
105166 + ******************************************************************************/
105167 +
105168 +#ifndef _DBGDRIV_
105169 +#define _DBGDRIV_
105170 +
105171 +#define BUFFER_SIZE 64*PAGESIZE
105172 +
105173 +#define DBGDRIV_VERSION        0x100
105174 +#define MAX_PROCESSES          2
105175 +#define BLOCK_USED                     0x01
105176 +#define BLOCK_LOCKED           0x02
105177 +#define DBGDRIV_MONOBASE       0x000B0000
105178 +
105179 +
105180 +extern IMG_VOID *      g_pvAPIMutex;
105181 +
105182 +IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR *         pszName,
105183 +                                                                  IMG_UINT32   ui32CapMode,
105184 +                                                                  IMG_UINT32   ui32OutMode,
105185 +                                                                  IMG_UINT32   ui32Flags,
105186 +                                                                  IMG_UINT32   ui32Pages);
105187 +IMG_VOID   IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream);
105188 +IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR *pszName, IMG_BOOL bResetStream);
105189 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream, IMG_CHAR *pszString, IMG_UINT32 ui32Level);
105190 +IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR *pszString, IMG_UINT32 ui32Limit);
105191 +IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level);
105192 +IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level);
105193 +IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize, IMG_UINT8 *pui8OutBuf);
105194 +IMG_VOID   IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream, IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32Stop, IMG_UINT32 ui32SampleRate);
105195 +IMG_VOID   IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream, IMG_UINT32 ui32OutMode);
105196 +IMG_VOID   IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream, IMG_UINT32 ui32DebugLevel);
105197 +IMG_VOID   IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
105198 +IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream);
105199 +IMG_VOID   IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream, IMG_UINT32 ui32Mode);
105200 +IMG_VOID   IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream);
105201 +IMG_UINT32 IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID);
105202 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream, IMG_CHAR *pszString, IMG_UINT32 ui32Level);
105203 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
105204 +IMG_VOID   IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
105205 +IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
105206 +IMG_BOOL   IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
105207 +IMG_BOOL   IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
105208 +IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
105209 +IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
105210 +IMG_VOID   IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream);
105211 +IMG_VOID   IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream);
105212 +IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psStream);
105213 +IMG_VOID   IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
105214 +IMG_VOID   IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent);
105215 +
105216 +IMG_VOID DestroyAllStreams(IMG_VOID);
105217 +
105218 +IMG_UINT32 AtoI(IMG_CHAR *szIn);
105219 +
105220 +IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size);
105221 +IMG_VOID HostMemCopy(IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_UINT32 ui32Size);
105222 +IMG_BOOL StreamValid(PDBG_STREAM psStream);
105223 +IMG_VOID Write(PDBG_STREAM psStream,IMG_UINT8 *pui8Data, IMG_UINT32 ui32InBuffSize);
105224 +IMG_VOID MonoOut(IMG_CHAR *pszString, IMG_BOOL bNewLine);
105225 +
105226 +
105227 +IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR *pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size);
105228 +IMG_VOID   IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream);
105229 +IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR *pszName, IMG_BOOL bResetStream);
105230 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR *pszString, IMG_UINT32 ui32Level);
105231 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR *pszString, IMG_UINT32 ui32Limit);
105232 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level);
105233 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 *pui8OutBuf);
105234 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream, IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32End, IMG_UINT32 ui32SampleRate);
105235 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream, IMG_UINT32 ui32OutMode);
105236 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream, IMG_UINT32 ui32DebugLevel);
105237 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame);
105238 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream);
105239 +IMG_VOID   IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream, IMG_UINT32 ui32Mode);
105240 +IMG_VOID   IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream);
105241 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level);
105242 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level);
105243 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
105244 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
105245 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream);
105246 +IMG_VOID   IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream);
105247 +IMG_VOID   IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream);
105248 +IMG_BOOL   IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
105249 +IMG_BOOL   IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame);
105250 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags);
105251 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf);
105252 +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream);
105253 +IMG_VOID   IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset);
105254 +IMG_VOID   IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent);
105255 +
105256 +#endif
105257 +
105258 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h
105259 new file mode 100644
105260 index 0000000..3a29db6
105261 --- /dev/null
105262 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hostfunc.h
105263 @@ -0,0 +1,58 @@
105264 +/**********************************************************************
105265 + *
105266 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105267 + * 
105268 + * This program is free software; you can redistribute it and/or modify it
105269 + * under the terms and conditions of the GNU General Public License,
105270 + * version 2, as published by the Free Software Foundation.
105271 + * 
105272 + * This program is distributed in the hope it will be useful but, except 
105273 + * as otherwise stated in writing, without any warranty; without even the 
105274 + * implied warranty of merchantability or fitness for a particular purpose. 
105275 + * See the GNU General Public License for more details.
105276 + * 
105277 + * You should have received a copy of the GNU General Public License along with
105278 + * this program; if not, write to the Free Software Foundation, Inc.,
105279 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105280 + * 
105281 + * The full GNU General Public License is included in this distribution in
105282 + * the file called "COPYING".
105283 + *
105284 + * Contact Information:
105285 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105286 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
105287 + *
105288 + ******************************************************************************/
105289 +
105290 +#ifndef _HOSTFUNC_
105291 +#define _HOSTFUNC_
105292 +
105293 +#define HOST_PAGESIZE                  (4096)
105294 +#define DBG_MEMORY_INITIALIZER (0xe2)
105295 +
105296 +IMG_UINT32 HostReadRegistryDWORDFromString(IMG_CHAR *pcKey, IMG_CHAR *pcValueName, IMG_UINT32 *pui32Data);
105297 +
105298 +IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages);
105299 +IMG_VOID HostPageablePageFree(IMG_VOID * pvBase);
105300 +IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages);
105301 +IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase);
105302 +
105303 +IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID * *ppvMdl);
105304 +IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess);
105305 +
105306 +IMG_VOID HostCreateRegDeclStreams(IMG_VOID);
105307 +
105308 +IMG_VOID * HostCreateMutex(IMG_VOID);
105309 +IMG_VOID HostAquireMutex(IMG_VOID * pvMutex);
105310 +IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex);
105311 +IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex);
105312 +
105313 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
105314 +IMG_INT32 HostCreateEventObjects(IMG_VOID);
105315 +IMG_VOID HostWaitForEvent(DBG_EVENT eEvent);
105316 +IMG_VOID HostSignalEvent(DBG_EVENT eEvent);
105317 +IMG_VOID HostDestroyEventObjects(IMG_VOID);
105318 +#endif 
105319 +
105320 +#endif
105321 +
105322 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.c b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.c
105323 new file mode 100644
105324 index 0000000..1997ad0
105325 --- /dev/null
105326 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.c
105327 @@ -0,0 +1,135 @@
105328 +/**********************************************************************
105329 + *
105330 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105331 + *
105332 + * This program is free software; you can redistribute it and/or modify it
105333 + * under the terms and conditions of the GNU General Public License,
105334 + * version 2, as published by the Free Software Foundation.
105335 + *
105336 + * This program is distributed in the hope it will be useful but, except
105337 + * as otherwise stated in writing, without any warranty; without even the
105338 + * implied warranty of merchantability or fitness for a particular purpose.
105339 + * See the GNU General Public License for more details.
105340 + *
105341 + * You should have received a copy of the GNU General Public License along with
105342 + * this program; if not, write to the Free Software Foundation, Inc.,
105343 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105344 + *
105345 + * The full GNU General Public License is included in this distribution in
105346 + * the file called "COPYING".
105347 + *
105348 + * Contact Information:
105349 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105350 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
105351 + *
105352 + ******************************************************************************/
105353 +
105354 +
105355 +#if !defined(LINUX)
105356 +#include <ntddk.h>
105357 +#include <windef.h>
105358 +#endif
105359 +
105360 +#include "img_types.h"
105361 +#include "pvr_debug.h"
105362 +#include "dbgdrvif.h"
105363 +#include "dbgdriv.h"
105364 +#include "hotkey.h"
105365 +#include "hostfunc.h"
105366 +
105367 +
105368 +
105369 +
105370 +
105371 +IMG_UINT32     g_ui32HotKeyFrame = 0xFFFFFFFF;
105372 +IMG_BOOL       g_bHotKeyPressed = IMG_FALSE;
105373 +IMG_BOOL       g_bHotKeyRegistered = IMG_FALSE;
105374 +
105375 +PRIVATEHOTKEYDATA    g_PrivateHotKeyData;
105376 +
105377 +
105378 +IMG_VOID ReadInHotKeys(IMG_VOID)
105379 +{
105380 +       g_PrivateHotKeyData.ui32ScanCode = 0x58;
105381 +       g_PrivateHotKeyData.ui32ShiftState = 0x0;
105382 +
105383 +
105384 +
105385 +#if 0
105386 +       if (_RegOpenKey(HKEY_LOCAL_MACHINE,pszRegPath,&hKey) == ERROR_SUCCESS)
105387 +       {
105388 +
105389 +
105390 +               QueryReg(hKey,"ui32ScanCode",&g_PrivateHotKeyData.ui32ScanCode);
105391 +               QueryReg(hKey,"ui32ShiftState",&g_PrivateHotKeyData.ui32ShiftState);
105392 +       }
105393 +#else
105394 +       HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ScanCode"  , &g_PrivateHotKeyData.ui32ScanCode);
105395 +       HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ShiftState", &g_PrivateHotKeyData.ui32ShiftState);
105396 +#endif
105397 +}
105398 +
105399 +IMG_VOID RegisterKeyPressed(IMG_UINT32 dwui32ScanCode, PHOTKEYINFO pInfo)
105400 +{
105401 +       PDBG_STREAM     psStream;
105402 +
105403 +       PVR_UNREFERENCED_PARAMETER(pInfo);
105404 +
105405 +       if (dwui32ScanCode == g_PrivateHotKeyData.ui32ScanCode)
105406 +       {
105407 +               PVR_DPF((PVR_DBG_MESSAGE,"PDUMP Hotkey pressed !\n"));
105408 +
105409 +               psStream = (PDBG_STREAM) g_PrivateHotKeyData.sHotKeyInfo.pvStream;
105410 +
105411 +               if (!g_bHotKeyPressed)
105412 +               {
105413 +
105414 +
105415 +                       g_ui32HotKeyFrame = psStream->ui32Current + 2;
105416 +
105417 +
105418 +
105419 +                       g_bHotKeyPressed = IMG_TRUE;
105420 +               }
105421 +       }
105422 +}
105423 +
105424 +IMG_VOID ActivateHotKeys(PDBG_STREAM psStream)
105425 +{
105426 +
105427 +
105428 +       ReadInHotKeys();
105429 +
105430 +
105431 +
105432 +       if (!g_PrivateHotKeyData.sHotKeyInfo.hHotKey)
105433 +       {
105434 +               if (g_PrivateHotKeyData.ui32ScanCode != 0)
105435 +               {
105436 +                       PVR_DPF((PVR_DBG_MESSAGE,"Activate HotKey for PDUMP.\n"));
105437 +
105438 +
105439 +
105440 +                       g_PrivateHotKeyData.sHotKeyInfo.pvStream = psStream;
105441 +
105442 +                       DefineHotKey(g_PrivateHotKeyData.ui32ScanCode, g_PrivateHotKeyData.ui32ShiftState, &g_PrivateHotKeyData.sHotKeyInfo);
105443 +               }
105444 +               else
105445 +               {
105446 +                       g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
105447 +               }
105448 +       }
105449 +}
105450 +
105451 +IMG_VOID DeactivateHotKeys(IMG_VOID)
105452 +{
105453 +       if (g_PrivateHotKeyData.sHotKeyInfo.hHotKey != 0)
105454 +       {
105455 +               PVR_DPF((PVR_DBG_MESSAGE,"Deactivate HotKey.\n"));
105456 +
105457 +               RemoveHotKey(g_PrivateHotKeyData.sHotKeyInfo.hHotKey);
105458 +               g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
105459 +       }
105460 +}
105461 +
105462 +
105463 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.h b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.h
105464 new file mode 100644
105465 index 0000000..d9c9458
105466 --- /dev/null
105467 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/hotkey.h
105468 @@ -0,0 +1,60 @@
105469 +/**********************************************************************
105470 + *
105471 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105472 + *
105473 + * This program is free software; you can redistribute it and/or modify it
105474 + * under the terms and conditions of the GNU General Public License,
105475 + * version 2, as published by the Free Software Foundation.
105476 + *
105477 + * This program is distributed in the hope it will be useful but, except
105478 + * as otherwise stated in writing, without any warranty; without even the
105479 + * implied warranty of merchantability or fitness for a particular purpose.
105480 + * See the GNU General Public License for more details.
105481 + *
105482 + * You should have received a copy of the GNU General Public License along with
105483 + * this program; if not, write to the Free Software Foundation, Inc.,
105484 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105485 + *
105486 + * The full GNU General Public License is included in this distribution in
105487 + * the file called "COPYING".
105488 + *
105489 + * Contact Information:
105490 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105491 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
105492 + *
105493 + ******************************************************************************/
105494 +
105495 +#ifndef _HOTKEY_
105496 +#define _HOTKEY_
105497 +
105498 +
105499 +typedef struct _hotkeyinfo
105500 +{
105501 +       IMG_UINT8 ui8ScanCode;
105502 +       IMG_UINT8 ui8Type;
105503 +       IMG_UINT8 ui8Flag;
105504 +       IMG_UINT8 ui8Filler1;
105505 +       IMG_UINT32 ui32ShiftState;
105506 +       IMG_UINT32 ui32HotKeyProc;
105507 +       IMG_VOID *pvStream;
105508 +       IMG_UINT32 hHotKey;
105509 +} HOTKEYINFO, *PHOTKEYINFO;
105510 +
105511 +typedef struct _privatehotkeydata
105512 +{
105513 +       IMG_UINT32              ui32ScanCode;
105514 +       IMG_UINT32              ui32ShiftState;
105515 +       HOTKEYINFO      sHotKeyInfo;
105516 +} PRIVATEHOTKEYDATA, *PPRIVATEHOTKEYDATA;
105517 +
105518 +
105519 +IMG_VOID ReadInHotKeys (IMG_VOID);
105520 +IMG_VOID ActivateHotKeys(PDBG_STREAM psStream);
105521 +IMG_VOID DeactivateHotKeys(IMG_VOID);
105522 +
105523 +IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey);
105524 +IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo);
105525 +IMG_VOID RegisterKeyPressed (IMG_UINT32 ui32ScanCode, PHOTKEYINFO psInfo);
105526 +
105527 +#endif
105528 +
105529 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.c b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.c
105530 new file mode 100644
105531 index 0000000..a624635
105532 --- /dev/null
105533 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.c
105534 @@ -0,0 +1,371 @@
105535 +/**********************************************************************
105536 + *
105537 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105538 + * 
105539 + * This program is free software; you can redistribute it and/or modify it
105540 + * under the terms and conditions of the GNU General Public License,
105541 + * version 2, as published by the Free Software Foundation.
105542 + * 
105543 + * This program is distributed in the hope it will be useful but, except 
105544 + * as otherwise stated in writing, without any warranty; without even the 
105545 + * implied warranty of merchantability or fitness for a particular purpose. 
105546 + * See the GNU General Public License for more details.
105547 + * 
105548 + * You should have received a copy of the GNU General Public License along with
105549 + * this program; if not, write to the Free Software Foundation, Inc.,
105550 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105551 + * 
105552 + * The full GNU General Public License is included in this distribution in
105553 + * the file called "COPYING".
105554 + *
105555 + * Contact Information:
105556 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105557 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
105558 + *
105559 + ******************************************************************************/
105560 +
105561 +
105562 +
105563 +#ifdef LINUX
105564 +#include <asm/uaccess.h>
105565 +#endif 
105566 +
105567 +#include "img_types.h"
105568 +#include "dbgdrvif.h"
105569 +#include "dbgdriv.h"
105570 +#include "hotkey.h"
105571 +
105572 +
105573 +IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105574 +{
105575 +       PDBG_IN_CREATESTREAM psIn;
105576 +       IMG_VOID * *ppvOut;
105577 +       #ifdef LINUX
105578 +       static IMG_CHAR name[32];
105579 +       #endif
105580 +
105581 +       psIn = (PDBG_IN_CREATESTREAM) pvInBuffer;
105582 +       ppvOut = (IMG_VOID * *) pvOutBuffer;
105583 +
105584 +       #ifdef LINUX
105585 +
105586 +       if(copy_from_user(name, psIn->pszName, 32) != 0)
105587 +       {
105588 +               return IMG_FALSE;
105589 +       }
105590 +
105591 +       *ppvOut = ExtDBGDrivCreateStream(name, psIn->ui32CapMode, psIn->ui32OutMode, 0, psIn->ui32Pages);
105592 +
105593 +       #else
105594 +       *ppvOut = ExtDBGDrivCreateStream(psIn->pszName, psIn->ui32CapMode, psIn->ui32OutMode, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages);
105595 +       #endif
105596 +
105597 +
105598 +       return(IMG_TRUE);
105599 +}
105600 +
105601 +IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105602 +{
105603 +       IMG_UINT32 *            pStream;
105604 +       PDBG_STREAM     psStream;
105605 +
105606 +       pStream = (IMG_UINT32 *) pvInBuffer;
105607 +       psStream = (PDBG_STREAM) *pStream;
105608 +
105609 +       PVR_UNREFERENCED_PARAMETER(     pvOutBuffer);
105610 +
105611 +       ExtDBGDrivDestroyStream(psStream);
105612 +
105613 +       return(IMG_TRUE);
105614 +}
105615 +
105616 +IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105617 +{
105618 +       PDBG_IN_FINDSTREAM psParams;
105619 +       IMG_UINT32 *    pui32Stream;
105620 +
105621 +       psParams                = (PDBG_IN_FINDSTREAM)pvInBuffer;
105622 +       pui32Stream     = (IMG_UINT32 *)pvOutBuffer;
105623 +
105624 +       *pui32Stream = (IMG_UINT32)ExtDBGDrivFindStream(psParams->pszName, psParams->bResetStream);
105625 +
105626 +       return(IMG_TRUE);
105627 +}
105628 +
105629 +IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105630 +{
105631 +       PDBG_IN_WRITESTRING psParams;
105632 +       IMG_UINT32 *                            pui32OutLen;
105633 +
105634 +       psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
105635 +       pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
105636 +
105637 +       *pui32OutLen = ExtDBGDrivWriteString((PDBG_STREAM) psParams->pvStream,psParams->pszString,psParams->ui32Level);
105638 +
105639 +       return(IMG_TRUE);
105640 +}
105641 +
105642 +IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105643 +{
105644 +       PDBG_IN_WRITESTRING psParams;
105645 +       IMG_UINT32 *                            pui32OutLen;
105646 +
105647 +       psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
105648 +       pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
105649 +
105650 +       *pui32OutLen = ExtDBGDrivWriteStringCM((PDBG_STREAM) psParams->pvStream,psParams->pszString,psParams->ui32Level);
105651 +
105652 +       return(IMG_TRUE);
105653 +}
105654 +
105655 +IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105656 +{
105657 +       IMG_UINT32 *                            pui32OutLen;
105658 +       PDBG_IN_READSTRING      psParams;
105659 +
105660 +       psParams = (PDBG_IN_READSTRING) pvInBuffer;
105661 +       pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
105662 +
105663 +       *pui32OutLen = ExtDBGDrivReadString(psParams->pvStream,psParams->pszString,psParams->ui32StringLen);
105664 +
105665 +       return(IMG_TRUE);
105666 +}
105667 +
105668 +IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105669 +{
105670 +       IMG_UINT32 *                            pui32BytesCopied;
105671 +       PDBG_IN_WRITE           psInParams;
105672 +
105673 +       psInParams = (PDBG_IN_WRITE) pvInBuffer;
105674 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105675 +
105676 +       *pui32BytesCopied = ExtDBGDrivWrite((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level);
105677 +
105678 +       return(IMG_TRUE);
105679 +}
105680 +
105681 +IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105682 +{
105683 +       IMG_UINT32 *                            pui32BytesCopied;
105684 +       PDBG_IN_WRITE           psInParams;
105685 +
105686 +       psInParams = (PDBG_IN_WRITE) pvInBuffer;
105687 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105688 +
105689 +       *pui32BytesCopied = ExtDBGDrivWrite2((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level);
105690 +
105691 +       return(IMG_TRUE);
105692 +}
105693 +
105694 +IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105695 +{
105696 +       IMG_UINT32 *                            pui32BytesCopied;
105697 +       PDBG_IN_WRITE           psInParams;
105698 +
105699 +       psInParams = (PDBG_IN_WRITE) pvInBuffer;
105700 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105701 +
105702 +       *pui32BytesCopied = ExtDBGDrivWriteCM((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level);
105703 +
105704 +       return(IMG_TRUE);
105705 +}
105706 +
105707 +IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105708 +{
105709 +       IMG_UINT32 *                            pui32BytesCopied;
105710 +       PDBG_IN_READ            psInParams;
105711 +
105712 +       psInParams = (PDBG_IN_READ) pvInBuffer;
105713 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105714 +
105715 +       *pui32BytesCopied = ExtDBGDrivRead((PDBG_STREAM) psInParams->pvStream,psInParams->bReadInitBuffer, psInParams->ui32OutBufferSize,psInParams->pui8OutBuffer);
105716 +
105717 +       return(IMG_TRUE);
105718 +}
105719 +
105720 +IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105721 +{
105722 +       PDBG_IN_SETDEBUGMODE    psParams;
105723 +
105724 +       psParams = (PDBG_IN_SETDEBUGMODE) pvInBuffer;
105725 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105726 +
105727 +       ExtDBGDrivSetCaptureMode((PDBG_STREAM) psParams->pvStream,
105728 +                                                 psParams->ui32Mode,
105729 +                                                 psParams->ui32Start,
105730 +                                                 psParams->ui32End,
105731 +                                                 psParams->ui32SampleRate);
105732 +
105733 +       return(IMG_TRUE);
105734 +}
105735 +
105736 +IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105737 +{
105738 +       PDBG_IN_SETDEBUGOUTMODE psParams;
105739 +
105740 +       psParams = (PDBG_IN_SETDEBUGOUTMODE) pvInBuffer;
105741 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105742 +
105743 +       ExtDBGDrivSetOutputMode((PDBG_STREAM) psParams->pvStream,psParams->ui32Mode);
105744 +
105745 +       return(IMG_TRUE);
105746 +}
105747 +
105748 +IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105749 +{
105750 +       PDBG_IN_SETDEBUGLEVEL psParams;
105751 +
105752 +       psParams = (PDBG_IN_SETDEBUGLEVEL) pvInBuffer;
105753 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105754 +
105755 +       ExtDBGDrivSetDebugLevel((PDBG_STREAM) psParams->pvStream,psParams->ui32Level);
105756 +
105757 +       return(IMG_TRUE);
105758 +}
105759 +
105760 +IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105761 +{
105762 +       PDBG_IN_SETFRAME        psParams;
105763 +
105764 +       psParams = (PDBG_IN_SETFRAME) pvInBuffer;
105765 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105766 +
105767 +       ExtDBGDrivSetFrame((PDBG_STREAM) psParams->pvStream,psParams->ui32Frame);
105768 +
105769 +       return(IMG_TRUE);
105770 +}
105771 +
105772 +IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105773 +{
105774 +       IMG_UINT32 *            pStream;
105775 +       PDBG_STREAM     psStream;
105776 +       IMG_UINT32 *            pui32Current;
105777 +
105778 +       pStream = (IMG_UINT32 *) pvInBuffer;
105779 +       psStream = (PDBG_STREAM) *pStream;
105780 +       pui32Current = (IMG_UINT32 *) pvOutBuffer;
105781 +
105782 +       *pui32Current = ExtDBGDrivGetFrame(psStream);
105783 +
105784 +       return(IMG_TRUE);
105785 +}
105786 +
105787 +IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105788 +{
105789 +       PDBG_IN_ISCAPTUREFRAME psParams;
105790 +       IMG_UINT32 *            pui32Current;
105791 +
105792 +       psParams = (PDBG_IN_ISCAPTUREFRAME) pvInBuffer;
105793 +       pui32Current = (IMG_UINT32 *) pvOutBuffer;
105794 +
105795 +       *pui32Current = ExtDBGDrivIsCaptureFrame((PDBG_STREAM) psParams->pvStream, psParams->bCheckPreviousFrame);
105796 +
105797 +       return(IMG_TRUE);
105798 +}
105799 +
105800 +IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105801 +{
105802 +       PDBG_IN_OVERRIDEMODE    psParams;
105803 +
105804 +       psParams = (PDBG_IN_OVERRIDEMODE) pvInBuffer;
105805 +       PVR_UNREFERENCED_PARAMETER(     pvOutBuffer);
105806 +
105807 +       ExtDBGDrivOverrideMode((PDBG_STREAM) psParams->pvStream,psParams->ui32Mode);
105808 +
105809 +       return(IMG_TRUE);
105810 +}
105811 +
105812 +IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105813 +{
105814 +       IMG_UINT32 *            pStream;
105815 +       PDBG_STREAM     psStream;
105816 +
105817 +       pStream = (IMG_UINT32 *) pvInBuffer;
105818 +       psStream = (PDBG_STREAM) *pStream;
105819 +
105820 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105821 +
105822 +       ExtDBGDrivDefaultMode(psStream);
105823 +
105824 +       return(IMG_TRUE);
105825 +}
105826 +
105827 +IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105828 +{
105829 +       PDBG_IN_SETMARKER       psParams;
105830 +
105831 +       psParams = (PDBG_IN_SETMARKER) pvInBuffer;
105832 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105833 +
105834 +       ExtDBGDrivSetMarker((PDBG_STREAM) psParams->pvStream, psParams->ui32Marker);
105835 +
105836 +       return(IMG_TRUE);
105837 +}
105838 +
105839 +IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105840 +{
105841 +       IMG_UINT32 *            pStream;
105842 +       PDBG_STREAM     psStream;
105843 +       IMG_UINT32 *            pui32Current;
105844 +
105845 +       pStream = (IMG_UINT32 *) pvInBuffer;
105846 +       psStream = (PDBG_STREAM) *pStream;
105847 +       pui32Current = (IMG_UINT32 *) pvOutBuffer;
105848 +
105849 +       *pui32Current = ExtDBGDrivGetMarker(psStream);
105850 +
105851 +       return(IMG_TRUE);
105852 +}
105853 +
105854 +IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105855 +{
105856 +       IMG_UINT32 *    pui32Out;
105857 +
105858 +       PVR_UNREFERENCED_PARAMETER(pvInBuffer);
105859 +       pui32Out = (IMG_UINT32 *) pvOutBuffer;
105860 +
105861 +       *pui32Out = DBGDrivGetServiceTable();
105862 +
105863 +    return(IMG_TRUE);
105864 +}
105865 +
105866 +IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105867 +{
105868 +       PDBG_IN_WRITE_LF        psInParams;
105869 +       IMG_UINT32 *                            pui32BytesCopied;
105870 +
105871 +       psInParams = (PDBG_IN_WRITE_LF) pvInBuffer;
105872 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105873 +
105874 +       *pui32BytesCopied = ExtDBGDrivWriteLF(psInParams->pvStream,
105875 +                                                                               psInParams->pui8InBuffer,
105876 +                                                                               psInParams->ui32BufferSize,
105877 +                                                                               psInParams->ui32Level,
105878 +                                                                               psInParams->ui32Flags);
105879 +
105880 +       return IMG_TRUE;
105881 +}
105882 +
105883 +IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105884 +{
105885 +       IMG_UINT32 *                            pui32BytesCopied;
105886 +       PDBG_IN_READ            psInParams;
105887 +
105888 +       psInParams = (PDBG_IN_READ) pvInBuffer;
105889 +       pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
105890 +
105891 +       *pui32BytesCopied = ExtDBGDrivReadLF((PDBG_STREAM) psInParams->pvStream,psInParams->ui32OutBufferSize,psInParams->pui8OutBuffer);
105892 +
105893 +       return(IMG_TRUE);
105894 +}
105895 +
105896 +IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
105897 +{
105898 +       DBG_EVENT eEvent = (DBG_EVENT)(*(IMG_UINT32 *)pvInBuffer);
105899 +
105900 +       PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
105901 +
105902 +       ExtDBGDrivWaitForEvent(eEvent);
105903 +
105904 +       return(IMG_TRUE);
105905 +}
105906 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.h b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.h
105907 new file mode 100644
105908 index 0000000..061be9a
105909 --- /dev/null
105910 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/common/ioctl.h
105911 @@ -0,0 +1,87 @@
105912 +/**********************************************************************
105913 + *
105914 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
105915 + * 
105916 + * This program is free software; you can redistribute it and/or modify it
105917 + * under the terms and conditions of the GNU General Public License,
105918 + * version 2, as published by the Free Software Foundation.
105919 + * 
105920 + * This program is distributed in the hope it will be useful but, except 
105921 + * as otherwise stated in writing, without any warranty; without even the 
105922 + * implied warranty of merchantability or fitness for a particular purpose. 
105923 + * See the GNU General Public License for more details.
105924 + * 
105925 + * You should have received a copy of the GNU General Public License along with
105926 + * this program; if not, write to the Free Software Foundation, Inc.,
105927 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
105928 + * 
105929 + * The full GNU General Public License is included in this distribution in
105930 + * the file called "COPYING".
105931 + *
105932 + * Contact Information:
105933 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
105934 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
105935 + *
105936 + ******************************************************************************/
105937 +
105938 +#ifndef _IOCTL_
105939 +#define _IOCTL_
105940 +
105941 +
105942 +IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID *, IMG_VOID *);
105943 +IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID *, IMG_VOID *);
105944 +IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID *, IMG_VOID *);
105945 +IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID *, IMG_VOID *);
105946 +IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID *, IMG_VOID *);
105947 +IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID *, IMG_VOID *);
105948 +IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID *, IMG_VOID *);
105949 +IMG_UINT32 DBGDIOCDrivRead(IMG_VOID *, IMG_VOID *);
105950 +IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID *, IMG_VOID *);
105951 +IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID *, IMG_VOID *);
105952 +IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID *, IMG_VOID *);
105953 +IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID *, IMG_VOID *);
105954 +IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID *, IMG_VOID *);
105955 +IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID *, IMG_VOID *);
105956 +IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID *, IMG_VOID *);
105957 +IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID *, IMG_VOID *);
105958 +IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID *, IMG_VOID *);
105959 +IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID *, IMG_VOID *);
105960 +IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID *, IMG_VOID *);
105961 +IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID *, IMG_VOID *);
105962 +IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID *, IMG_VOID *);
105963 +IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID *, IMG_VOID *);
105964 +IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID *, IMG_VOID *);
105965 +IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID*, IMG_VOID *);
105966 +
105967 +IMG_UINT32 (*g_DBGDrivProc[])(IMG_VOID *, IMG_VOID *) =
105968 +{
105969 +       DBGDIOCDrivCreateStream,
105970 +       DBGDIOCDrivDestroyStream,
105971 +       DBGDIOCDrivGetStream,
105972 +       DBGDIOCDrivWriteString,
105973 +       DBGDIOCDrivReadString,
105974 +       DBGDIOCDrivWrite,
105975 +       DBGDIOCDrivRead,
105976 +       DBGDIOCDrivSetCaptureMode,
105977 +       DBGDIOCDrivSetOutMode,
105978 +       DBGDIOCDrivSetDebugLevel,
105979 +       DBGDIOCDrivSetFrame,
105980 +       DBGDIOCDrivGetFrame,
105981 +       DBGDIOCDrivOverrideMode,
105982 +       DBGDIOCDrivDefaultMode,
105983 +       DBGDIOCDrivGetServiceTable,
105984 +       DBGDIOCDrivWrite2,
105985 +       DBGDIOCDrivWriteStringCM,
105986 +       DBGDIOCDrivWriteCM,
105987 +       DBGDIOCDrivSetMarker,
105988 +       DBGDIOCDrivGetMarker,
105989 +       DBGDIOCDrivIsCaptureFrame,
105990 +       DBGDIOCDrivWriteLF,
105991 +       DBGDIOCDrivReadLF,
105992 +       DBGDIOCDrivWaitForEvent
105993 +};
105994 +
105995 +#define MAX_DBGVXD_W32_API (sizeof(g_DBGDrivProc)/sizeof(IMG_UINT32))
105996 +
105997 +#endif
105998 +
105999 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c
106000 new file mode 100644
106001 index 0000000..3ccec84
106002 --- /dev/null
106003 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/hostfunc.c
106004 @@ -0,0 +1,302 @@
106005 +/**********************************************************************
106006 + *
106007 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
106008 + *
106009 + * This program is free software; you can redistribute it and/or modify it
106010 + * under the terms and conditions of the GNU General Public License,
106011 + * version 2, as published by the Free Software Foundation.
106012 + *
106013 + * This program is distributed in the hope it will be useful but, except
106014 + * as otherwise stated in writing, without any warranty; without even the
106015 + * implied warranty of merchantability or fitness for a particular purpose.
106016 + * See the GNU General Public License for more details.
106017 + *
106018 + * You should have received a copy of the GNU General Public License along with
106019 + * this program; if not, write to the Free Software Foundation, Inc.,
106020 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
106021 + *
106022 + * The full GNU General Public License is included in this distribution in
106023 + * the file called "COPYING".
106024 + *
106025 + * Contact Information:
106026 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
106027 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
106028 + *
106029 + ******************************************************************************/
106030 +
106031 +#include <linux/version.h>
106032 +#include <linux/errno.h>
106033 +#include <linux/module.h>
106034 +#include <linux/fs.h>
106035 +#include <linux/kernel.h>
106036 +#include <linux/mm.h>
106037 +#include <linux/string.h>
106038 +#include <asm/page.h>
106039 +#include <linux/vmalloc.h>
106040 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
106041 +#include <linux/mutex.h>
106042 +#else
106043 +#include <asm/semaphore.h>
106044 +#endif
106045 +#include <linux/hardirq.h>
106046 +
106047 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
106048 +#include <linux/sched.h>
106049 +#include <linux/wait.h>
106050 +#include <linux/jiffies.h>
106051 +#include <linux/delay.h>
106052 +#endif
106053 +
106054 +#include "img_types.h"
106055 +#include "pvr_debug.h"
106056 +
106057 +#include "dbgdrvif.h"
106058 +#include "dbgdriv/common/hostfunc.h"
106059 +
106060 +#if !defined(SUPPORT_DRI_DRM)
106061 +IMG_UINT32     gPVRDebugLevel = DBGPRIV_WARNING;
106062 +
106063 +#define PVR_STRING_TERMINATOR          '\0'
106064 +#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
106065 +
106066 +void PVRSRVDebugPrintf (
106067 +                                               IMG_UINT32      ui32DebugLevel,
106068 +                                               const IMG_CHAR* pszFileName,
106069 +                                               IMG_UINT32      ui32Line,
106070 +                                               const IMG_CHAR* pszFormat,
106071 +                                               ...
106072 +                                       )
106073 +{
106074 +       IMG_BOOL bTrace, bDebug;
106075 +#if !defined(__sh__)
106076 +       IMG_CHAR *pszLeafName;
106077 +
106078 +       pszLeafName = (char *)strrchr (pszFileName, '\\');
106079 +
106080 +       if (pszLeafName)
106081 +       {
106082 +               pszFileName = pszLeafName;
106083 +       }
106084 +#endif
106085 +
106086 +       bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE;
106087 +       bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel);
106088 +
106089 +       if (bTrace || bDebug)
106090 +       {
106091 +               va_list vaArgs;
106092 +               static char szBuffer[256];
106093 +
106094 +               va_start (vaArgs, pszFormat);
106095 +
106096 +
106097 +               if (bDebug)
106098 +               {
106099 +                       switch(ui32DebugLevel)
106100 +                       {
106101 +                               case DBGPRIV_FATAL:
106102 +                               {
106103 +                                       strncpy (szBuffer, "PVR_K:(Fatal): ", sizeof(szBuffer));
106104 +                                       break;
106105 +                               }
106106 +                               case DBGPRIV_ERROR:
106107 +                               {
106108 +                                       strncpy (szBuffer, "PVR_K:(Error): ", sizeof(szBuffer));
106109 +                                       break;
106110 +                               }
106111 +                               case DBGPRIV_WARNING:
106112 +                               {
106113 +                                       strncpy (szBuffer, "PVR_K:(Warning): ", sizeof(szBuffer));
106114 +                                       break;
106115 +                               }
106116 +                               case DBGPRIV_MESSAGE:
106117 +                               {
106118 +                                       strncpy (szBuffer, "PVR_K:(Message): ", sizeof(szBuffer));
106119 +                                       break;
106120 +                               }
106121 +                               case DBGPRIV_VERBOSE:
106122 +                               {
106123 +                                       strncpy (szBuffer, "PVR_K:(Verbose): ", sizeof(szBuffer));
106124 +                                       break;
106125 +                               }
106126 +                               default:
106127 +                               {
106128 +                                       strncpy (szBuffer, "PVR_K:(Unknown message level)", sizeof(szBuffer));
106129 +                                       break;
106130 +                               }
106131 +                       }
106132 +               }
106133 +               else
106134 +               {
106135 +                       strncpy (szBuffer, "PVR_K: ", sizeof(szBuffer));
106136 +               }
106137 +
106138 +               vsnprintf (&szBuffer[strlen(szBuffer)], sizeof(szBuffer), pszFormat, vaArgs);
106139 +
106140 +
106141 +
106142 +               if (!bTrace)
106143 +               {
106144 +                       snprintf (&szBuffer[strlen(szBuffer)], sizeof(szBuffer), " [%d, %s]", (int)ui32Line, pszFileName);
106145 +               }
106146 +
106147 +               printk(KERN_INFO "%s\r\n", szBuffer);
106148 +
106149 +               va_end (vaArgs);
106150 +       }
106151 +}
106152 +#endif
106153 +
106154 +IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
106155 +{
106156 +       memset(pvDest, (int) ui8Value, (size_t) ui32Size);
106157 +}
106158 +
106159 +IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
106160 +{
106161 +#if defined(USE_UNOPTIMISED_MEMCPY)
106162 +    unsigned char *src,*dst;
106163 +    int i;
106164 +
106165 +    src=(unsigned char *)pvSrc;
106166 +    dst=(unsigned char *)pvDst;
106167 +    for(i=0;i<ui32Size;i++)
106168 +    {
106169 +        dst[i]=src[i];
106170 +    }
106171 +#else
106172 +    memcpy(pvDst, pvSrc, ui32Size);
106173 +#endif
106174 +}
106175 +
106176 +IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data)
106177 +{
106178 +
106179 +       return 0;
106180 +}
106181 +
106182 +IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
106183 +{
106184 +    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
106185 +}
106186 +
106187 +IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
106188 +{
106189 +    vfree(pvBase);
106190 +}
106191 +
106192 +IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
106193 +{
106194 +    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
106195 +}
106196 +
106197 +IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
106198 +{
106199 +    vfree(pvBase);
106200 +}
106201 +
106202 +IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
106203 +{
106204 +
106205 +       return IMG_NULL;
106206 +}
106207 +
106208 +IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
106209 +{
106210 +
106211 +}
106212 +
106213 +IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
106214 +{
106215 +
106216 +}
106217 +
106218 +IMG_VOID * HostCreateMutex(IMG_VOID)
106219 +{
106220 +       struct semaphore *psSem;
106221 +
106222 +       psSem = kmalloc(sizeof(*psSem), GFP_KERNEL);
106223 +       if (psSem)
106224 +       {
106225 +               init_MUTEX(psSem);
106226 +       }
106227 +
106228 +       return psSem;
106229 +}
106230 +
106231 +IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
106232 +{
106233 +       BUG_ON(in_interrupt());
106234 +
106235 +#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
106236 +       if (down_trylock((struct semaphore *)pvMutex))
106237 +       {
106238 +               printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
106239 +               down((struct semaphore *)pvMutex);
106240 +       }
106241 +#else
106242 +       down((struct semaphore *)pvMutex);
106243 +#endif
106244 +}
106245 +
106246 +IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
106247 +{
106248 +       up((struct semaphore *)pvMutex);
106249 +}
106250 +
106251 +IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex)
106252 +{
106253 +       if (pvMutex)
106254 +       {
106255 +               kfree(pvMutex);
106256 +       }
106257 +}
106258 +
106259 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
106260 +
106261 +#define        EVENT_WAIT_TIMEOUT_MS   500
106262 +#define        EVENT_WAIT_TIMEOUT_JIFFIES      (EVENT_WAIT_TIMEOUT_MS * HZ / 1000)
106263 +
106264 +static int iStreamData;
106265 +static wait_queue_head_t sStreamDataEvent;
106266 +
106267 +IMG_INT32 HostCreateEventObjects(IMG_VOID)
106268 +{
106269 +       init_waitqueue_head(&sStreamDataEvent);
106270 +
106271 +       return 0;
106272 +}
106273 +
106274 +IMG_VOID HostWaitForEvent(DBG_EVENT eEvent)
106275 +{
106276 +       switch(eEvent)
106277 +       {
106278 +               case DBG_EVENT_STREAM_DATA:
106279 +
106280 +                       wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
106281 +                       iStreamData = 0;
106282 +                       break;
106283 +               default:
106284 +
106285 +                       msleep_interruptible(EVENT_WAIT_TIMEOUT_MS);
106286 +                       break;
106287 +       }
106288 +}
106289 +
106290 +IMG_VOID HostSignalEvent(DBG_EVENT eEvent)
106291 +{
106292 +       switch(eEvent)
106293 +       {
106294 +               case DBG_EVENT_STREAM_DATA:
106295 +                       iStreamData = 1;
106296 +                       wake_up_interruptible(&sStreamDataEvent);
106297 +                       break;
106298 +               default:
106299 +                       break;
106300 +       }
106301 +}
106302 +
106303 +IMG_VOID HostDestroyEventObjects(IMG_VOID)
106304 +{
106305 +}
106306 +#endif
106307 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
106308 new file mode 100644
106309 index 0000000..5fb9b1e
106310 --- /dev/null
106311 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
106312 @@ -0,0 +1,35 @@
106313 +#
106314 +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
106315 +# 
106316 +# This program is free software; you can redistribute it and/or modify it
106317 +# under the terms and conditions of the GNU General Public License,
106318 +# version 2, as published by the Free Software Foundation.
106319 +# 
106320 +# This program is distributed in the hope it will be useful but, except 
106321 +# as otherwise stated in writing, without any warranty; without even the 
106322 +# implied warranty of merchantability or fitness for a particular purpose. 
106323 +# See the GNU General Public License for more details.
106324 +# 
106325 +# You should have received a copy of the GNU General Public License along with
106326 +# this program; if not, write to the Free Software Foundation, Inc.,
106327 +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
106328 +# 
106329 +# The full GNU General Public License is included in this distribution in
106330 +# the file called "COPYING".
106331 +#
106332 +# Contact Information:
106333 +# Imagination Technologies Ltd. <gpl-support@imgtec.com>
106334 +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
106335 +# 
106336 +#
106337 +#
106338 +
106339 +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common
106340 +
106341 +MODULE         = dbgdrv
106342 +
106343 +INCLUDES =
106344 +
106345 +SOURCES        =
106346 +                               
106347 +include $(EURASIAROOT)/tools/intern/debug/dbgdriv/linux/makefile.linux.common
106348 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/main.c b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/main.c
106349 new file mode 100644
106350 index 0000000..b57cc43
106351 --- /dev/null
106352 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/main.c
106353 @@ -0,0 +1,298 @@
106354 +/**********************************************************************
106355 + *
106356 + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
106357 + *
106358 + * This program is free software; you can redistribute it and/or modify it
106359 + * under the terms and conditions of the GNU General Public License,
106360 + * version 2, as published by the Free Software Foundation.
106361 + *
106362 + * This program is distributed in the hope it will be useful but, except
106363 + * as otherwise stated in writing, without any warranty; without even the
106364 + * implied warranty of merchantability or fitness for a particular purpose.
106365 + * See the GNU General Public License for more details.
106366 + *
106367 + * You should have received a copy of the GNU General Public License along with
106368 + * this program; if not, write to the Free Software Foundation, Inc.,
106369 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
106370 + *
106371 + * The full GNU General Public License is included in this distribution in
106372 + * the file called "COPYING".
106373 + *
106374 + * Contact Information:
106375 + * Imagination Technologies Ltd. <gpl-support@imgtec.com>
106376 + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
106377 + *
106378 + ******************************************************************************/
106379 +
106380 +#include <linux/errno.h>
106381 +#include <linux/module.h>
106382 +#include <linux/fs.h>
106383 +#include <linux/kernel.h>
106384 +#include <linux/kdev_t.h>
106385 +#include <linux/pci.h>
106386 +#include <linux/list.h>
106387 +#include <linux/init.h>
106388 +#include <linux/vmalloc.h>
106389 +#include <linux/version.h>
106390 +
106391 +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM)
106392 +#include <linux/platform_device.h>
106393 +#endif
106394 +
106395 +#if defined(LDM_PCI) && !defined(SUPPORT_DRI_DRM)
106396 +#include <linux/pci.h>
106397 +#endif
106398 +
106399 +#include <asm/uaccess.h>
106400 +
106401 +#if defined(SUPPORT_DRI_DRM)
106402 +#include "drmP.h"
106403 +#include "drm.h"
106404 +#endif
106405 +
106406 +#include "img_types.h"
106407 +#include "client/linuxsrv.h"
106408 +#include "dbgdriv/common/ioctl.h"
106409 +#include "dbgdrvif.h"
106410 +#include "dbgdriv/common/dbgdriv.h"
106411 +#include "dbgdriv/common/hostfunc.h"
106412 +#include "pvr_debug.h"
106413 +#include "pvrmodule.h"
106414 +
106415 +#if defined(SUPPORT_DRI_DRM)
106416 +
106417 +#include "pvr_drm_shared.h"
106418 +#include "pvr_drm.h"
106419 +
106420 +#else
106421 +
106422 +#define DRVNAME "dbgdrv"
106423 +MODULE_SUPPORTED_DEVICE(DRVNAME);
106424 +
106425 +#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
106426 +static struct class *psDbgDrvClass;
106427 +#endif
106428 +
106429 +static int AssignedMajorNumber = 0;
106430 +
106431 +long dbgdrv_ioctl(struct file *, unsigned int, unsigned long);
106432 +
106433 +static int dbgdrv_open(struct inode unref__ * pInode, struct file unref__ * pFile)
106434 +{
106435 +       return 0;
106436 +}
106437 +
106438 +static int dbgdrv_release(struct inode unref__ * pInode, struct file unref__ * pFile)
106439 +{
106440 +       return 0;
106441 +}
106442 +
106443 +static int dbgdrv_mmap(struct file* pFile, struct vm_area_struct* ps_vma)
106444 +{
106445 +       return 0;
106446 +}
106447 +
106448 +static struct file_operations dbgdrv_fops = {
106449 +       .owner          = THIS_MODULE,
106450 +       .unlocked_ioctl = dbgdrv_ioctl,
106451 +       .open           = dbgdrv_open,
106452 +       .release        = dbgdrv_release,
106453 +       .mmap           = dbgdrv_mmap,
106454 +};
106455 +
106456 +#endif
106457 +
106458 +void DBGDrvGetServiceTable(void **fn_table)
106459 +{
106460 +       extern DBGKM_SERVICE_TABLE g_sDBGKMServices;
106461 +
106462 +       *fn_table = &g_sDBGKMServices;
106463 +}
106464 +
106465 +#if defined(SUPPORT_DRI_DRM)
106466 +void dbgdrv_cleanup(void)
106467 +#else
106468 +void cleanup_module(void)
106469 +#endif
106470 +{
106471 +#if !defined(SUPPORT_DRI_DRM)
106472 +#if defined(LDM_PLATFORM) || defined(LDM_PCI)
106473 +       device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
106474 +       class_destroy(psDbgDrvClass);
106475 +#endif
106476 +       unregister_chrdev(AssignedMajorNumber, DRVNAME);
106477 +#endif
106478 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
106479 +       HostDestroyEventObjects();
106480 +#endif
106481 +       HostDestroyMutex(g_pvAPIMutex);
106482 +       return;
106483 +}
106484 +
106485 +#if defined(SUPPORT_DRI_DRM)
106486 +IMG_INT dbgdrv_init(void)
106487 +#else
106488 +int init_module(void)
106489 +#endif
106490 +{
106491 +#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
106492 +       struct device *psDev;
106493 +#endif
106494 +
106495 +#if !defined(SUPPORT_DRI_DRM)
106496 +       int err = -EBUSY;
106497 +#endif
106498 +
106499 +
106500 +       if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL)
106501 +       {
106502 +               return -ENOMEM;
106503 +       }
106504 +
106505 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
106506 +
106507 +       (void) HostCreateEventObjects();
106508 +#endif
106509 +
106510 +#if !defined(SUPPORT_DRI_DRM)
106511 +       AssignedMajorNumber =
106512 +       register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
106513 +
106514 +       if (AssignedMajorNumber <= 0)
106515 +       {
106516 +               PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
106517 +               goto ErrDestroyEventObjects;
106518 +       }
106519 +
106520 +#if defined(LDM_PLATFORM) || defined(LDM_PCI)
106521 +
106522 +       psDbgDrvClass = class_create(THIS_MODULE, DRVNAME);
106523 +       if (IS_ERR(psDbgDrvClass))
106524 +       {
106525 +               PVR_DPF((PVR_DBG_ERROR, "%s: unable to create class (%ld)",
106526 +                                __func__, PTR_ERR(psDbgDrvClass)));
106527 +               goto ErrUnregisterCharDev;
106528 +       }
106529 +
106530 +       psDev = device_create(psDbgDrvClass, NULL, MKDEV(AssignedMajorNumber, 0),
106531 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
106532 +                                                 NULL,
106533 +#endif
106534 +                                                 DRVNAME);
106535 +       if (IS_ERR(psDev))
106536 +       {
106537 +               PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
106538 +                                                               __func__, PTR_ERR(psDev)));
106539 +               goto ErrDestroyClass;
106540 +       }
106541 +#endif
106542 +#endif
106543 +
106544 +       return 0;
106545 +
106546 +#if !defined(SUPPORT_DRI_DRM)
106547 +ErrDestroyEventObjects:
106548 +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
106549 +       HostDestroyEventObjects();
106550 +#endif
106551 +#if defined(LDM_PLATFORM) || defined(LDM_PCI)
106552 +ErrUnregisterCharDev:
106553 +       unregister_chrdev(AssignedMajorNumber, DRVNAME);
106554 +ErrDestroyClass:
106555 +       class_destroy(psDbgDrvClass);
106556 +#endif
106557 +       return err;
106558 +#endif
106559 +}
106560 +
106561 +#if defined(SUPPORT_DRI_DRM)
106562 +IMG_INT dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
106563 +#else
106564 +long dbgdrv_ioctl(struct file *file, unsigned int ioctlCmd, unsigned long arg)
106565 +#endif
106566 +{
106567 +       IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
106568 +       char *buffer, *in, *out;
106569 +       unsigned int cmd;
106570 +
106571 +       if((pIP->ui32InBufferSize > (PAGE_SIZE >> 1) ) || (pIP->ui32OutBufferSize > (PAGE_SIZE >> 1)))
106572 +       {
106573 +               PVR_DPF((PVR_DBG_ERROR,"Sizes of the buffers are too large, cannot do ioctl\n"));
106574 +               return -1;
106575 +       }
106576 +
106577 +       buffer = (char *) HostPageablePageAlloc(1);
106578 +       if(!buffer)
106579 +       {
106580 +               PVR_DPF((PVR_DBG_ERROR,"Failed to allocate buffer, cannot do ioctl\n"));
106581 +               return -EFAULT;
106582 +       }
106583 +
106584 +       in = buffer;
106585 +       out = buffer + (PAGE_SIZE >>1);
106586 +
106587 +       if(copy_from_user(in, pIP->pInBuffer, pIP->ui32InBufferSize) != 0)
106588 +       {
106589 +               goto init_failed;
106590 +       }
106591 +
106592 +       cmd = ((pIP->ui32Cmd >> 2) & 0xFFF) - 0x801;
106593 +
106594 +       if(pIP->ui32Cmd == DEBUG_SERVICE_READ)
106595 +       {
106596 +               IMG_CHAR *ui8Tmp;
106597 +               IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
106598 +               DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in;
106599 +
106600 +               ui8Tmp = vmalloc(psReadInParams->ui32OutBufferSize);
106601 +
106602 +               if(!ui8Tmp)
106603 +               {
106604 +                       goto init_failed;
106605 +               }
106606 +
106607 +               *pui32BytesCopied = ExtDBGDrivRead((DBG_STREAM *)psReadInParams->pvStream,
106608 +                                                                                  psReadInParams->bReadInitBuffer,
106609 +                                                                                  psReadInParams->ui32OutBufferSize,
106610 +                                                                                  ui8Tmp);
106611 +
106612 +               if(copy_to_user(psReadInParams->pui8OutBuffer,
106613 +                                               ui8Tmp,
106614 +                                               *pui32BytesCopied) != 0)
106615 +               {
106616 +                       vfree(ui8Tmp);
106617 +                       goto init_failed;
106618 +               }
106619 +
106620 +               vfree(ui8Tmp);
106621 +       }
106622 +       else
106623 +       {
106624 +               (g_DBGDrivProc[cmd])(in, out);
106625 +       }
106626 +
106627 +       if(copy_to_user(pIP->pOutBuffer, out, pIP->ui32OutBufferSize) != 0)
106628 +       {
106629 +               goto init_failed;
106630 +       }
106631 +
106632 +       HostPageablePageFree((IMG_VOID *)buffer);
106633 +       return 0;
106634 +
106635 +init_failed:
106636 +       HostPageablePageFree((IMG_VOID *)buffer);
106637 +       return -EFAULT;
106638 +}
106639 +
106640 +
106641 +void RemoveHotKey(unsigned hHotKey)
106642 +{
106643 +
106644 +}
106645 +
106646 +void DefineHotKey(unsigned ScanCode, unsigned ShiftState, void *pInfo)
106647 +{
106648 +
106649 +}
106650 +
106651 +EXPORT_SYMBOL(DBGDrvGetServiceTable);
106652 diff --git a/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common
106653 new file mode 100644
106654 index 0000000..105197f
106655 --- /dev/null
106656 +++ b/drivers/gpu/drm/mrst/pvr/tools/intern/debug/dbgdriv/linux/makefile.linux.common
106657 @@ -0,0 +1,40 @@
106658 +#
106659 +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
106660 +#
106661 +# This program is free software; you can redistribute it and/or modify it
106662 +# under the terms and conditions of the GNU General Public License,
106663 +# version 2, as published by the Free Software Foundation.
106664 +#
106665 +# This program is distributed in the hope it will be useful but, except
106666 +# as otherwise stated in writing, without any warranty; without even the
106667 +# implied warranty of merchantability or fitness for a particular purpose.
106668 +# See the GNU General Public License for more details.
106669 +#
106670 +# You should have received a copy of the GNU General Public License along with
106671 +# this program; if not, write to the Free Software Foundation, Inc.,
106672 +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
106673 +#
106674 +# The full GNU General Public License is included in this distribution in
106675 +# the file called "COPYING".
106676 +#
106677 +# Contact Information:
106678 +# Imagination Technologies Ltd. <gpl-support@imgtec.com>
106679 +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
106680 +#
106681 +#
106682 +#
106683 +
106684 +ifeq ($(SUPPORT_DRI_DRM),1)
106685 +DBGDRV_SOURCES_ROOT = $(KBUILDROOT)/../tools/intern/debug/dbgdriv
106686 +else
106687 +DBGDRV_SOURCES_ROOT = ../..
106688 +endif
106689 +
106690 +INCLUDES +=    -I$(EURASIAROOT)/include4 \
106691 +                       -I$(EURASIAROOT)/tools/intern/debug
106692 +
106693 +SOURCES        +=      $(DBGDRV_SOURCES_ROOT)/linux/main.c \
106694 +                               $(DBGDRV_SOURCES_ROOT)/common/dbgdriv.c \
106695 +                               $(DBGDRV_SOURCES_ROOT)/common/ioctl.c \
106696 +                               $(DBGDRV_SOURCES_ROOT)/linux/hostfunc.c \
106697 +                               $(DBGDRV_SOURCES_ROOT)/common/hotkey.c
106698 diff --git a/include/drm/drmP.h b/include/drm/drmP.h
106699 index ffac157..e8673fd 100644
106700 --- a/include/drm/drmP.h
106701 +++ b/include/drm/drmP.h
106702 @@ -1131,6 +1131,8 @@ extern int drm_init(struct drm_driver *driver);
106703  extern void drm_exit(struct drm_driver *driver);
106704  extern long drm_ioctl(struct file *filp,
106705                       unsigned int cmd, unsigned long arg);
106706 +extern long drm_unlocked_ioctl(struct file *filp,
106707 +                              unsigned int cmd, unsigned long arg);
106708  extern long drm_compat_ioctl(struct file *filp,
106709                              unsigned int cmd, unsigned long arg);
106710  extern int drm_lastclose(struct drm_device *dev);
106711 @@ -1558,5 +1560,25 @@ static __inline void drm_free_large(void *ptr)
106712  }
106713  /*@}*/
106714  
106715 +enum drm_global_types {
106716 +       DRM_GLOBAL_TTM_MEM = 0,
106717 +       DRM_GLOBAL_TTM_BO,
106718 +       DRM_GLOBAL_TTM_OBJECT,
106719 +       DRM_GLOBAL_NUM
106720 +};
106721 +
106722 +struct drm_global_reference {
106723 +       enum drm_global_types global_type;
106724 +       size_t size;
106725 +       void *object;
106726 +       int (*init) (struct drm_global_reference *);
106727 +       void (*release) (struct drm_global_reference *);
106728 +};
106729 +
106730 +extern void drm_global_init(void);
106731 +extern void drm_global_release(void);
106732 +extern int drm_global_item_ref(struct drm_global_reference *ref);
106733 +extern void drm_global_item_unref(struct drm_global_reference *ref);
106734 +
106735  #endif                         /* __KERNEL__ */
106736  #endif
106737 diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
106738 index c5ba163..e107b17 100644
106739 --- a/include/drm/drm_mode.h
106740 +++ b/include/drm/drm_mode.h
106741 @@ -124,6 +124,7 @@ struct drm_mode_crtc {
106742  #define DRM_MODE_ENCODER_TMDS  2
106743  #define DRM_MODE_ENCODER_LVDS  3
106744  #define DRM_MODE_ENCODER_TVDAC 4
106745 +#define DRM_MODE_ENCODER_MIPI  5
106746  
106747  struct drm_mode_get_encoder {
106748         __u32 encoder_id;
106749 @@ -161,6 +162,7 @@ struct drm_mode_get_encoder {
106750  #define DRM_MODE_CONNECTOR_HDMIB       12
106751  #define DRM_MODE_CONNECTOR_TV          13
106752  #define DRM_MODE_CONNECTOR_eDP         14
106753 +#define DRM_MODE_CONNECTOR_MIPI                15
106754  
106755  struct drm_mode_get_connector {
106756  
106757 diff --git a/include/linux/backlight.h b/include/linux/backlight.h
106758 index 8c4f884..05ff433 100644
106759 --- a/include/linux/backlight.h
106760 +++ b/include/linux/backlight.h
106761 @@ -92,6 +92,9 @@ struct backlight_device {
106762         struct notifier_block fb_notif;
106763  
106764         struct device dev;
106765 +
106766 +       /* Private Backlight Data */
106767 +       void *priv;
106768  };
106769  
106770  static inline void backlight_update_status(struct backlight_device *bd)
106771 -- 
106772 1.6.2.5
106773