diff options
Diffstat (limited to 'drivers/gpu/pvr/sgx/sgxinit.c')
-rw-r--r-- | drivers/gpu/pvr/sgx/sgxinit.c | 2507 |
1 files changed, 2507 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c new file mode 100644 index 00000000000..2471915d10f --- /dev/null +++ b/drivers/gpu/pvr/sgx/sgxinit.c | |||
@@ -0,0 +1,2507 @@ | |||
1 | /********************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful but, except | ||
10 | * as otherwise stated in writing, without any warranty; without even the | ||
11 | * implied warranty of merchantability or fitness for a particular purpose. | ||
12 | * See the GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in | ||
19 | * the file called "COPYING". | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Imagination Technologies Ltd. <gpl-support@imgtec.com> | ||
23 | * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK | ||
24 | * | ||
25 | ******************************************************************************/ | ||
26 | |||
27 | #include <stddef.h> | ||
28 | |||
29 | #include "sgxdefs.h" | ||
30 | #include "sgxmmu.h" | ||
31 | #include "services_headers.h" | ||
32 | #include "buffer_manager.h" | ||
33 | #include "sgxapi_km.h" | ||
34 | #include "sgxinfo.h" | ||
35 | #include "sgx_mkif_km.h" | ||
36 | #include "sgxconfig.h" | ||
37 | #include "sysconfig.h" | ||
38 | #include "pvr_bridge_km.h" | ||
39 | |||
40 | #include "sgx_bridge_km.h" | ||
41 | |||
42 | #include "pdump_km.h" | ||
43 | #include "ra.h" | ||
44 | #include "mmu.h" | ||
45 | #include "handle.h" | ||
46 | #include "perproc.h" | ||
47 | |||
48 | #include "sgxutils.h" | ||
49 | #include "pvrversion.h" | ||
50 | #include "sgx_options.h" | ||
51 | |||
52 | #include "lists.h" | ||
53 | #include "srvkm.h" | ||
54 | |||
55 | #define VAR(x) #x | ||
56 | |||
57 | |||
58 | #define CHECK_SIZE(NAME) \ | ||
59 | { \ | ||
60 | if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \ | ||
61 | { \ | ||
62 | PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \ | ||
63 | VAR(NAME), \ | ||
64 | psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \ | ||
65 | psSGXStructSizes->ui32Sizeof_##NAME )); \ | ||
66 | bStructSizesFailed = IMG_TRUE; \ | ||
67 | } \ | ||
68 | } | ||
69 | |||
70 | #if defined (SYS_USING_INTERRUPTS) | ||
71 | IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); | ||
72 | #endif | ||
73 | |||
74 | |||
75 | static | ||
76 | PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
77 | PVRSRV_DEVICE_NODE *psDeviceNode); | ||
78 | #if defined(PDUMP) | ||
79 | static | ||
80 | PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode); | ||
81 | #endif | ||
82 | |||
83 | static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) | ||
84 | { | ||
85 | #if defined(OS_SUPPORTS_IN_LISR) | ||
86 | if (OSInLISR(psDeviceNode->psSysData)) | ||
87 | { | ||
88 | |||
89 | psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; | ||
90 | } | ||
91 | else | ||
92 | { | ||
93 | SGXScheduleProcessQueuesKM(psDeviceNode); | ||
94 | } | ||
95 | #else | ||
96 | SGXScheduleProcessQueuesKM(psDeviceNode); | ||
97 | #endif | ||
98 | } | ||
99 | |||
100 | static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo) | ||
101 | { | ||
102 | if (psDevInfo->psKernelCCBInfo != IMG_NULL) | ||
103 | { | ||
104 | |||
105 | |||
106 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL); | ||
107 | } | ||
108 | |||
109 | return PVRSRV_OK; | ||
110 | } | ||
111 | |||
112 | static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
113 | PVRSRV_DEVICE_NODE *psDeviceNode, | ||
114 | SGX_BRIDGE_INIT_INFO *psInitInfo) | ||
115 | { | ||
116 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; | ||
117 | PVRSRV_ERROR eError; | ||
118 | |||
119 | PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL; | ||
120 | |||
121 | PVR_UNREFERENCED_PARAMETER(psPerProc); | ||
122 | psDevInfo->sScripts = psInitInfo->sScripts; | ||
123 | |||
124 | psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo; | ||
125 | psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM; | ||
126 | |||
127 | psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo; | ||
128 | psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM; | ||
129 | |||
130 | psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo; | ||
131 | psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM; | ||
132 | |||
133 | psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo; | ||
134 | psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; | ||
135 | |||
136 | psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo; | ||
137 | |||
138 | psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo; | ||
139 | |||
140 | #if defined(SGX_SUPPORT_HWPROFILING) | ||
141 | psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; | ||
142 | #endif | ||
143 | #if defined(SUPPORT_SGX_HWPERF) | ||
144 | psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; | ||
145 | #endif | ||
146 | psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo; | ||
147 | psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo; | ||
148 | #if defined(FIX_HW_BRN_29702) | ||
149 | psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo; | ||
150 | #endif | ||
151 | #if defined(FIX_HW_BRN_29823) | ||
152 | psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo; | ||
153 | #endif | ||
154 | #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) | ||
155 | psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo; | ||
156 | #endif | ||
157 | #if defined(SGX_FEATURE_OVERLAPPED_SPM) | ||
158 | psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo; | ||
159 | #endif | ||
160 | #if defined(SGX_FEATURE_SPM_MODE_0) | ||
161 | psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo; | ||
162 | #endif | ||
163 | |||
164 | psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions; | ||
165 | |||
166 | |||
167 | psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes; | ||
168 | |||
169 | |||
170 | |||
171 | eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
172 | sizeof(PVRSRV_SGX_CCB_INFO), | ||
173 | (IMG_VOID **)&psKernelCCBInfo, 0, | ||
174 | "SGX Circular Command Buffer Info"); | ||
175 | if (eError != PVRSRV_OK) | ||
176 | { | ||
177 | PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); | ||
178 | goto failed_allockernelccb; | ||
179 | } | ||
180 | |||
181 | |||
182 | OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO)); | ||
183 | psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo; | ||
184 | psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo; | ||
185 | psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands; | ||
186 | psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset; | ||
187 | psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset; | ||
188 | psDevInfo->psKernelCCBInfo = psKernelCCBInfo; | ||
189 | |||
190 | |||
191 | |||
192 | OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr, | ||
193 | SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0])); | ||
194 | |||
195 | psDevInfo->bForcePTOff = IMG_FALSE; | ||
196 | |||
197 | psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl; | ||
198 | |||
199 | psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; | ||
200 | psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; | ||
201 | psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg; | ||
202 | psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; | ||
203 | #if defined(SGX_FEATURE_MP) | ||
204 | psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg; | ||
205 | psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask; | ||
206 | psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg; | ||
207 | psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask; | ||
208 | #endif | ||
209 | |||
210 | |||
211 | |||
212 | OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData)); | ||
213 | |||
214 | return PVRSRV_OK; | ||
215 | |||
216 | failed_allockernelccb: | ||
217 | DeinitDevInfo(psDevInfo); | ||
218 | |||
219 | return eError; | ||
220 | } | ||
221 | |||
222 | |||
223 | |||
224 | |||
225 | static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) | ||
226 | { | ||
227 | IMG_UINT32 ui32PC; | ||
228 | SGX_INIT_COMMAND *psComm; | ||
229 | |||
230 | for (ui32PC = 0, psComm = psScript; | ||
231 | ui32PC < ui32NumInitCommands; | ||
232 | ui32PC++, psComm++) | ||
233 | { | ||
234 | switch (psComm->eOp) | ||
235 | { | ||
236 | case SGX_INIT_OP_WRITE_HW_REG: | ||
237 | { | ||
238 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); | ||
239 | PDUMPCOMMENT("SGXRunScript: Write HW reg operation"); | ||
240 | PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); | ||
241 | break; | ||
242 | } | ||
243 | #if defined(PDUMP) | ||
244 | case SGX_INIT_OP_PDUMP_HW_REG: | ||
245 | { | ||
246 | PDUMPCOMMENT("SGXRunScript: Dump HW reg operation"); | ||
247 | PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value); | ||
248 | break; | ||
249 | } | ||
250 | #endif | ||
251 | case SGX_INIT_OP_HALT: | ||
252 | { | ||
253 | return PVRSRV_OK; | ||
254 | } | ||
255 | case SGX_INIT_OP_ILLEGAL: | ||
256 | |||
257 | default: | ||
258 | { | ||
259 | PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp)); | ||
260 | return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | } | ||
265 | |||
266 | return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION; | ||
267 | } | ||
268 | |||
269 | PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
270 | IMG_BOOL bHardwareRecovery) | ||
271 | { | ||
272 | PVRSRV_ERROR eError; | ||
273 | PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; | ||
274 | SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM; | ||
275 | static IMG_BOOL bFirstTime = IMG_TRUE; | ||
276 | #if defined(PDUMP) | ||
277 | IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); | ||
278 | #endif | ||
279 | |||
280 | |||
281 | |||
282 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n"); | ||
283 | eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS); | ||
284 | if (eError != PVRSRV_OK) | ||
285 | { | ||
286 | PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError)); | ||
287 | return eError; | ||
288 | } | ||
289 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n"); | ||
290 | |||
291 | |||
292 | SGXReset(psDevInfo, bFirstTime || bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS); | ||
293 | |||
294 | #if defined(EUR_CR_POWER) | ||
295 | #if defined(SGX531) | ||
296 | |||
297 | |||
298 | |||
299 | |||
300 | |||
301 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1); | ||
302 | PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1); | ||
303 | #else | ||
304 | |||
305 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0); | ||
306 | PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0); | ||
307 | #endif | ||
308 | #endif | ||
309 | |||
310 | |||
311 | *psDevInfo->pui32KernelCCBEventKicker = 0; | ||
312 | #if defined(PDUMP) | ||
313 | if (!bPDumpIsSuspended) | ||
314 | { | ||
315 | psDevInfo->ui32KernelCCBEventKickerDumpVal = 0; | ||
316 | PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, | ||
317 | psDevInfo->psKernelCCBEventKickerMemInfo, 0, | ||
318 | sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, | ||
319 | MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); | ||
320 | } | ||
321 | #endif | ||
322 | |||
323 | |||
324 | |||
325 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n"); | ||
326 | eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS); | ||
327 | if (eError != PVRSRV_OK) | ||
328 | { | ||
329 | PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError)); | ||
330 | return eError; | ||
331 | } | ||
332 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n"); | ||
333 | |||
334 | |||
335 | psSGXHostCtl->ui32HostClock = OSClockus(); | ||
336 | |||
337 | psSGXHostCtl->ui32InitStatus = 0; | ||
338 | #if defined(PDUMP) | ||
339 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, | ||
340 | "Reset the SGX microkernel initialisation status\n"); | ||
341 | PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, | ||
342 | offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), | ||
343 | sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, | ||
344 | MAKEUNIQUETAG(psSGXHostCtlMemInfo)); | ||
345 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, | ||
346 | "Initialise the microkernel\n"); | ||
347 | #endif | ||
348 | |||
349 | #if defined(SGX_FEATURE_MULTI_EVENT_KICK) | ||
350 | OSWriteMemoryBarrier(); | ||
351 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, | ||
352 | SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), | ||
353 | EUR_CR_EVENT_KICK2_NOW_MASK); | ||
354 | #else | ||
355 | *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; | ||
356 | OSWriteMemoryBarrier(); | ||
357 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, | ||
358 | SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), | ||
359 | EUR_CR_EVENT_KICK_NOW_MASK); | ||
360 | #endif | ||
361 | |||
362 | OSMemoryBarrier(); | ||
363 | |||
364 | #if defined(PDUMP) | ||
365 | |||
366 | |||
367 | if (!bPDumpIsSuspended) | ||
368 | { | ||
369 | #if defined(SGX_FEATURE_MULTI_EVENT_KICK) | ||
370 | PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK); | ||
371 | #else | ||
372 | psDevInfo->ui32KernelCCBEventKickerDumpVal = 1; | ||
373 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, | ||
374 | "First increment of the SGX event kicker value\n"); | ||
375 | PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, | ||
376 | psDevInfo->psKernelCCBEventKickerMemInfo, | ||
377 | 0, | ||
378 | sizeof(IMG_UINT32), | ||
379 | PDUMP_FLAGS_CONTINUOUS, | ||
380 | MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); | ||
381 | PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK); | ||
382 | #endif | ||
383 | } | ||
384 | #endif | ||
385 | |||
386 | #if !defined(NO_HARDWARE) | ||
387 | |||
388 | |||
389 | if (PollForValueKM(&psSGXHostCtl->ui32InitStatus, | ||
390 | PVRSRV_USSE_EDM_INIT_COMPLETE, | ||
391 | PVRSRV_USSE_EDM_INIT_COMPLETE, | ||
392 | MAX_HW_TIME_US/WAIT_TRY_COUNT, | ||
393 | WAIT_TRY_COUNT) != PVRSRV_OK) | ||
394 | { | ||
395 | PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed")); | ||
396 | PVR_DBG_BREAK; | ||
397 | return PVRSRV_ERROR_RETRY; | ||
398 | } | ||
399 | #endif | ||
400 | |||
401 | #if defined(PDUMP) | ||
402 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, | ||
403 | "Wait for the SGX microkernel initialisation to complete"); | ||
404 | PDUMPMEMPOL(psSGXHostCtlMemInfo, | ||
405 | offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), | ||
406 | PVRSRV_USSE_EDM_INIT_COMPLETE, | ||
407 | PVRSRV_USSE_EDM_INIT_COMPLETE, | ||
408 | PDUMP_POLL_OPERATOR_EQUAL, | ||
409 | PDUMP_FLAGS_CONTINUOUS, | ||
410 | MAKEUNIQUETAG(psSGXHostCtlMemInfo)); | ||
411 | #endif | ||
412 | |||
413 | #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) | ||
414 | |||
415 | |||
416 | |||
417 | WorkaroundBRN22997ReadHostPort(psDevInfo); | ||
418 | #endif | ||
419 | |||
420 | PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset); | ||
421 | |||
422 | bFirstTime = IMG_FALSE; | ||
423 | |||
424 | return PVRSRV_OK; | ||
425 | } | ||
426 | |||
427 | PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie) | ||
428 | |||
429 | { | ||
430 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie; | ||
431 | PVRSRV_ERROR eError; | ||
432 | |||
433 | |||
434 | if (psDevInfo->pvRegsBaseKM == IMG_NULL) | ||
435 | { | ||
436 | return PVRSRV_OK; | ||
437 | } | ||
438 | |||
439 | eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS); | ||
440 | if (eError != PVRSRV_OK) | ||
441 | { | ||
442 | PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError)); | ||
443 | return eError; | ||
444 | } | ||
445 | |||
446 | return PVRSRV_OK; | ||
447 | } | ||
448 | |||
449 | |||
450 | static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) | ||
451 | { | ||
452 | IMG_HANDLE hDevMemHeap = IMG_NULL; | ||
453 | PVRSRV_SGXDEV_INFO *psDevInfo; | ||
454 | IMG_HANDLE hKernelDevMemContext; | ||
455 | IMG_DEV_PHYADDR sPDDevPAddr; | ||
456 | IMG_UINT32 i; | ||
457 | PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; | ||
458 | DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; | ||
459 | PVRSRV_ERROR eError; | ||
460 | |||
461 | |||
462 | PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME); | ||
463 | |||
464 | #if defined(SGX_FEATURE_MP) | ||
465 | PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT); | ||
466 | #endif | ||
467 | |||
468 | #if (SGX_CORE_REV == 0) | ||
469 | PDUMPCOMMENT("SGX Core Revision Information: head RTL"); | ||
470 | #else | ||
471 | PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV); | ||
472 | #endif | ||
473 | |||
474 | #if defined(SGX_FEATURE_SYSTEM_CACHE) | ||
475 | PDUMPCOMMENT("SGX System Level Cache is present\r\n"); | ||
476 | #if defined(SGX_BYPASS_SYSTEM_CACHE) | ||
477 | PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n"); | ||
478 | #endif | ||
479 | #endif | ||
480 | |||
481 | PDUMPCOMMENT("SGX Initialisation Part 1"); | ||
482 | |||
483 | |||
484 | if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, | ||
485 | sizeof(PVRSRV_SGXDEV_INFO), | ||
486 | (IMG_VOID **)&psDevInfo, IMG_NULL, | ||
487 | "SGX Device Info") != PVRSRV_OK) | ||
488 | { | ||
489 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo")); | ||
490 | return (PVRSRV_ERROR_OUT_OF_MEMORY); | ||
491 | } | ||
492 | OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO)); | ||
493 | |||
494 | |||
495 | psDevInfo->eDeviceType = DEV_DEVICE_TYPE; | ||
496 | psDevInfo->eDeviceClass = DEV_DEVICE_CLASS; | ||
497 | |||
498 | |||
499 | psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo; | ||
500 | |||
501 | |||
502 | psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap; | ||
503 | |||
504 | |||
505 | hKernelDevMemContext = BM_CreateContext(psDeviceNode, | ||
506 | &sPDDevPAddr, | ||
507 | IMG_NULL, | ||
508 | IMG_NULL); | ||
509 | if (hKernelDevMemContext == IMG_NULL) | ||
510 | { | ||
511 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext")); | ||
512 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
513 | } | ||
514 | |||
515 | psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; | ||
516 | |||
517 | |||
518 | for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++) | ||
519 | { | ||
520 | switch(psDeviceMemoryHeap[i].DevMemHeapType) | ||
521 | { | ||
522 | case DEVICE_MEMORY_HEAP_KERNEL: | ||
523 | case DEVICE_MEMORY_HEAP_SHARED: | ||
524 | case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: | ||
525 | { | ||
526 | hDevMemHeap = BM_CreateHeap (hKernelDevMemContext, | ||
527 | &psDeviceMemoryHeap[i]); | ||
528 | |||
529 | |||
530 | |||
531 | psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap; | ||
532 | break; | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | #if defined(PDUMP) | ||
537 | if(hDevMemHeap) | ||
538 | { | ||
539 | |||
540 | psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib; | ||
541 | } | ||
542 | #endif | ||
543 | eError = MMU_BIFResetPDAlloc(psDevInfo); | ||
544 | if (eError != PVRSRV_OK) | ||
545 | { | ||
546 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset")); | ||
547 | return eError; | ||
548 | } | ||
549 | |||
550 | return PVRSRV_OK; | ||
551 | } | ||
552 | |||
553 | IMG_EXPORT | ||
554 | PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo) | ||
555 | { | ||
556 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
557 | PVRSRV_SGXDEV_INFO *psDevInfo; | ||
558 | PVRSRV_ERROR eError; | ||
559 | |||
560 | PDUMPCOMMENT("SGXGetInfoForSrvinit"); | ||
561 | |||
562 | psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; | ||
563 | psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; | ||
564 | |||
565 | psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr; | ||
566 | |||
567 | eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]); | ||
568 | if (eError != PVRSRV_OK) | ||
569 | { | ||
570 | PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError)); | ||
571 | return eError; | ||
572 | } | ||
573 | |||
574 | return eError; | ||
575 | } | ||
576 | |||
577 | IMG_EXPORT | ||
578 | PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc, | ||
579 | IMG_HANDLE hDevHandle, | ||
580 | SGX_BRIDGE_INIT_INFO *psInitInfo) | ||
581 | { | ||
582 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
583 | PVRSRV_SGXDEV_INFO *psDevInfo; | ||
584 | PVRSRV_ERROR eError; | ||
585 | SGX_DEVICE_MAP *psSGXDeviceMap; | ||
586 | PVRSRV_DEV_POWER_STATE eDefaultPowerState; | ||
587 | |||
588 | PDUMPCOMMENT("SGX Initialisation Part 2"); | ||
589 | |||
590 | psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; | ||
591 | psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; | ||
592 | |||
593 | |||
594 | |||
595 | eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo); | ||
596 | if (eError != PVRSRV_OK) | ||
597 | { | ||
598 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program")); | ||
599 | goto failed_init_dev_info; | ||
600 | } | ||
601 | |||
602 | |||
603 | eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, | ||
604 | (IMG_VOID**)&psSGXDeviceMap); | ||
605 | if (eError != PVRSRV_OK) | ||
606 | { | ||
607 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!")); | ||
608 | return PVRSRV_ERROR_INIT_FAILURE; | ||
609 | } | ||
610 | |||
611 | |||
612 | if (psSGXDeviceMap->pvRegsCpuVBase) | ||
613 | { | ||
614 | psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase; | ||
615 | } | ||
616 | else | ||
617 | { | ||
618 | |||
619 | psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase, | ||
620 | psSGXDeviceMap->ui32RegsSize, | ||
621 | PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, | ||
622 | IMG_NULL); | ||
623 | if (!psDevInfo->pvRegsBaseKM) | ||
624 | { | ||
625 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n")); | ||
626 | return PVRSRV_ERROR_BAD_MAPPING; | ||
627 | } | ||
628 | } | ||
629 | psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize; | ||
630 | psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase; | ||
631 | |||
632 | |||
633 | #if defined(SGX_FEATURE_HOST_PORT) | ||
634 | if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) | ||
635 | { | ||
636 | |||
637 | psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase, | ||
638 | psSGXDeviceMap->ui32HPSize, | ||
639 | PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, | ||
640 | IMG_NULL); | ||
641 | if (!psDevInfo->pvHostPortBaseKM) | ||
642 | { | ||
643 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n")); | ||
644 | return PVRSRV_ERROR_BAD_MAPPING; | ||
645 | } | ||
646 | psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize; | ||
647 | psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase; | ||
648 | } | ||
649 | #endif | ||
650 | |||
651 | #if defined (SYS_USING_INTERRUPTS) | ||
652 | |||
653 | |||
654 | psDeviceNode->pvISRData = psDeviceNode; | ||
655 | |||
656 | PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler); | ||
657 | |||
658 | #endif | ||
659 | |||
660 | |||
661 | psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK; | ||
662 | eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF; | ||
663 | |||
664 | eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex, | ||
665 | &SGXPrePowerState, &SGXPostPowerState, | ||
666 | &SGXPreClockSpeedChange, &SGXPostClockSpeedChange, | ||
667 | (IMG_HANDLE)psDeviceNode, | ||
668 | PVRSRV_DEV_POWER_STATE_OFF, | ||
669 | eDefaultPowerState); | ||
670 | if (eError != PVRSRV_OK) | ||
671 | { | ||
672 | PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager")); | ||
673 | return eError; | ||
674 | } | ||
675 | |||
676 | #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) | ||
677 | eError = WorkaroundBRN22997Alloc(psDeviceNode); | ||
678 | if (eError != PVRSRV_OK) | ||
679 | { | ||
680 | PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround")); | ||
681 | return eError; | ||
682 | } | ||
683 | #endif | ||
684 | |||
685 | #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) | ||
686 | |||
687 | psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize; | ||
688 | psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase; | ||
689 | eError = MMU_MapExtSystemCacheRegs(psDeviceNode); | ||
690 | if (eError != PVRSRV_OK) | ||
691 | { | ||
692 | PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers")); | ||
693 | return eError; | ||
694 | } | ||
695 | #endif | ||
696 | |||
697 | |||
698 | |||
699 | OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); | ||
700 | OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL)); | ||
701 | OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker)); | ||
702 | PDUMPCOMMENT("Initialise Kernel CCB"); | ||
703 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo)); | ||
704 | PDUMPCOMMENT("Initialise Kernel CCB Control"); | ||
705 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo)); | ||
706 | PDUMPCOMMENT("Initialise Kernel CCB Event Kicker"); | ||
707 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); | ||
708 | |||
709 | return PVRSRV_OK; | ||
710 | |||
711 | failed_init_dev_info: | ||
712 | return eError; | ||
713 | } | ||
714 | |||
715 | static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode) | ||
716 | { | ||
717 | PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; | ||
718 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; | ||
719 | PVRSRV_ERROR eError; | ||
720 | IMG_UINT32 ui32Heap; | ||
721 | DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; | ||
722 | SGX_DEVICE_MAP *psSGXDeviceMap; | ||
723 | |||
724 | if (!psDevInfo) | ||
725 | { | ||
726 | |||
727 | PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo")); | ||
728 | return PVRSRV_OK; | ||
729 | } | ||
730 | |||
731 | #if defined(SUPPORT_HW_RECOVERY) | ||
732 | if (psDevInfo->hTimer) | ||
733 | { | ||
734 | eError = OSRemoveTimer(psDevInfo->hTimer); | ||
735 | if (eError != PVRSRV_OK) | ||
736 | { | ||
737 | PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); | ||
738 | return eError; | ||
739 | } | ||
740 | psDevInfo->hTimer = IMG_NULL; | ||
741 | } | ||
742 | #endif | ||
743 | |||
744 | #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) | ||
745 | |||
746 | eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode); | ||
747 | if (eError != PVRSRV_OK) | ||
748 | { | ||
749 | PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers")); | ||
750 | return eError; | ||
751 | } | ||
752 | #endif | ||
753 | |||
754 | #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) | ||
755 | WorkaroundBRN22997Free(psDeviceNode); | ||
756 | #endif | ||
757 | |||
758 | MMU_BIFResetPDFree(psDevInfo); | ||
759 | |||
760 | |||
761 | |||
762 | DeinitDevInfo(psDevInfo); | ||
763 | |||
764 | |||
765 | psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap; | ||
766 | for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++) | ||
767 | { | ||
768 | switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType) | ||
769 | { | ||
770 | case DEVICE_MEMORY_HEAP_KERNEL: | ||
771 | case DEVICE_MEMORY_HEAP_SHARED: | ||
772 | case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: | ||
773 | { | ||
774 | if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL) | ||
775 | { | ||
776 | BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap); | ||
777 | } | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | |||
783 | |||
784 | eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL); | ||
785 | if (eError != PVRSRV_OK) | ||
786 | { | ||
787 | PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context")); | ||
788 | return eError; | ||
789 | } | ||
790 | |||
791 | |||
792 | eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex); | ||
793 | if (eError != PVRSRV_OK) | ||
794 | { | ||
795 | return eError; | ||
796 | } | ||
797 | |||
798 | eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, | ||
799 | (IMG_VOID**)&psSGXDeviceMap); | ||
800 | if (eError != PVRSRV_OK) | ||
801 | { | ||
802 | PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!")); | ||
803 | return eError; | ||
804 | } | ||
805 | |||
806 | |||
807 | if (!psSGXDeviceMap->pvRegsCpuVBase) | ||
808 | { | ||
809 | |||
810 | if (psDevInfo->pvRegsBaseKM != IMG_NULL) | ||
811 | { | ||
812 | OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, | ||
813 | psDevInfo->ui32RegSize, | ||
814 | PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, | ||
815 | IMG_NULL); | ||
816 | } | ||
817 | } | ||
818 | |||
819 | #if defined(SGX_FEATURE_HOST_PORT) | ||
820 | if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) | ||
821 | { | ||
822 | |||
823 | if (psDevInfo->pvHostPortBaseKM != IMG_NULL) | ||
824 | { | ||
825 | OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, | ||
826 | psDevInfo->ui32HPSize, | ||
827 | PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, | ||
828 | IMG_NULL); | ||
829 | } | ||
830 | } | ||
831 | #endif | ||
832 | |||
833 | |||
834 | |||
835 | OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, | ||
836 | sizeof(PVRSRV_SGXDEV_INFO), | ||
837 | psDevInfo, | ||
838 | 0); | ||
839 | |||
840 | psDeviceNode->pvDevice = IMG_NULL; | ||
841 | |||
842 | if (psDeviceMemoryHeap != IMG_NULL) | ||
843 | { | ||
844 | |||
845 | OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, | ||
846 | sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, | ||
847 | psDeviceMemoryHeap, | ||
848 | 0); | ||
849 | } | ||
850 | |||
851 | return PVRSRV_OK; | ||
852 | } | ||
853 | |||
854 | |||
855 | static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo, | ||
856 | IMG_UINT32 ui32CoreNum, | ||
857 | IMG_CHAR *pszName, | ||
858 | IMG_UINT32 ui32RegAddr) | ||
859 | { | ||
860 | IMG_UINT32 ui32RegVal; | ||
861 | ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum)); | ||
862 | PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal)); | ||
863 | } | ||
864 | |||
865 | static IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo, | ||
866 | IMG_BOOL bDumpSGXRegs) | ||
867 | { | ||
868 | IMG_UINT32 ui32CoreNum; | ||
869 | |||
870 | PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING)); | ||
871 | |||
872 | if (bDumpSGXRegs) | ||
873 | { | ||
874 | PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM)); | ||
875 | PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr)); | ||
876 | |||
877 | for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++) | ||
878 | { | ||
879 | |||
880 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS); | ||
881 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2); | ||
882 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL); | ||
883 | #if defined(EUR_CR_BIF_BANK0) | ||
884 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0); | ||
885 | #endif | ||
886 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT); | ||
887 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT); | ||
888 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT); | ||
889 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL); | ||
890 | #if defined(EUR_CR_PDS_PC_BASE) | ||
891 | SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE); | ||
892 | #endif | ||
893 | } | ||
894 | } | ||
895 | |||
896 | |||
897 | |||
898 | QueueDumpDebugInfo(); | ||
899 | |||
900 | { | ||
901 | |||
902 | |||
903 | IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psDevInfo->psSGXHostCtl; | ||
904 | IMG_UINT32 ui32LoopCounter; | ||
905 | |||
906 | PVR_LOG(("SGX Host control:")); | ||
907 | |||
908 | for (ui32LoopCounter = 0; | ||
909 | ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer); | ||
910 | ui32LoopCounter += 4) | ||
911 | { | ||
912 | PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer), | ||
913 | pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1], | ||
914 | pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3])); | ||
915 | } | ||
916 | } | ||
917 | |||
918 | { | ||
919 | |||
920 | |||
921 | IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM; | ||
922 | IMG_UINT32 ui32LoopCounter; | ||
923 | |||
924 | PVR_LOG(("SGX TA/3D control:")); | ||
925 | |||
926 | for (ui32LoopCounter = 0; | ||
927 | ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->ui32AllocSize / sizeof(*pui32TA3DCtlBuffer); | ||
928 | ui32LoopCounter += 4) | ||
929 | { | ||
930 | PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer), | ||
931 | pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1], | ||
932 | pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3])); | ||
933 | } | ||
934 | } | ||
935 | |||
936 | #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) | ||
937 | { | ||
938 | IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM; | ||
939 | IMG_UINT32 ui32LastStatusCode, ui32WriteOffset; | ||
940 | |||
941 | ui32LastStatusCode = *pui32MKTraceBuffer; | ||
942 | pui32MKTraceBuffer++; | ||
943 | ui32WriteOffset = *pui32MKTraceBuffer; | ||
944 | pui32MKTraceBuffer++; | ||
945 | |||
946 | PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode)); | ||
947 | |||
948 | #if defined(PVRSRV_DUMP_MK_TRACE) | ||
949 | |||
950 | |||
951 | { | ||
952 | IMG_UINT32 ui32LoopCounter; | ||
953 | |||
954 | for (ui32LoopCounter = 0; | ||
955 | ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE; | ||
956 | ui32LoopCounter++) | ||
957 | { | ||
958 | IMG_UINT32 *pui32BufPtr; | ||
959 | pui32BufPtr = pui32MKTraceBuffer + | ||
960 | (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4); | ||
961 | PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter, | ||
962 | pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0])); | ||
963 | } | ||
964 | } | ||
965 | #endif | ||
966 | } | ||
967 | #endif | ||
968 | |||
969 | { | ||
970 | |||
971 | |||
972 | PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X", | ||
973 | psDevInfo->psKernelCCBCtl->ui32WriteOffset, | ||
974 | psDevInfo->psKernelCCBCtl->ui32ReadOffset)); | ||
975 | |||
976 | #if defined(PVRSRV_DUMP_KERNEL_CCB) | ||
977 | { | ||
978 | IMG_UINT32 ui32LoopCounter; | ||
979 | |||
980 | for (ui32LoopCounter = 0; | ||
981 | ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) / | ||
982 | sizeof(psDevInfo->psKernelCCB->asCommands[0]); | ||
983 | ui32LoopCounter++) | ||
984 | { | ||
985 | SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter]; | ||
986 | |||
987 | PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter, | ||
988 | psCommand->ui32ServiceAddress, psCommand->ui32CacheControl, | ||
989 | psCommand->ui32Data[0], psCommand->ui32Data[1], | ||
990 | psCommand->ui32Data[2], psCommand->ui32Data[3])); | ||
991 | } | ||
992 | } | ||
993 | #endif | ||
994 | } | ||
995 | } | ||
996 | |||
997 | |||
998 | #if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) | ||
999 | static | ||
1000 | IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, | ||
1001 | IMG_UINT32 ui32Component, | ||
1002 | IMG_UINT32 ui32CallerID) | ||
1003 | { | ||
1004 | PVRSRV_ERROR eError; | ||
1005 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; | ||
1006 | SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; | ||
1007 | |||
1008 | PVR_UNREFERENCED_PARAMETER(ui32Component); | ||
1009 | |||
1010 | |||
1011 | |||
1012 | eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); | ||
1013 | if(eError != PVRSRV_OK) | ||
1014 | { | ||
1015 | |||
1016 | |||
1017 | |||
1018 | PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); | ||
1019 | return; | ||
1020 | } | ||
1021 | |||
1022 | psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; | ||
1023 | |||
1024 | PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered")); | ||
1025 | |||
1026 | SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE); | ||
1027 | |||
1028 | |||
1029 | PDUMPSUSPEND(); | ||
1030 | |||
1031 | |||
1032 | eError = SGXInitialise(psDevInfo, IMG_TRUE); | ||
1033 | if (eError != PVRSRV_OK) | ||
1034 | { | ||
1035 | PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | PDUMPRESUME(); | ||
1040 | |||
1041 | PVRSRVPowerUnlock(ui32CallerID); | ||
1042 | |||
1043 | |||
1044 | SGXScheduleProcessQueuesKM(psDeviceNode); | ||
1045 | |||
1046 | |||
1047 | |||
1048 | PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); | ||
1049 | } | ||
1050 | #endif | ||
1051 | |||
1052 | |||
1053 | #if defined(SUPPORT_HW_RECOVERY) | ||
1054 | IMG_VOID SGXOSTimer(IMG_VOID *pvData) | ||
1055 | { | ||
1056 | PVRSRV_DEVICE_NODE *psDeviceNode = pvData; | ||
1057 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
1058 | static IMG_UINT32 ui32EDMTasks = 0; | ||
1059 | static IMG_UINT32 ui32LockupCounter = 0; | ||
1060 | static IMG_UINT32 ui32NumResets = 0; | ||
1061 | IMG_UINT32 ui32CurrentEDMTasks; | ||
1062 | IMG_BOOL bLockup = IMG_FALSE; | ||
1063 | IMG_BOOL bPoweredDown; | ||
1064 | |||
1065 | |||
1066 | psDevInfo->ui32TimeStamp++; | ||
1067 | |||
1068 | #if defined(NO_HARDWARE) | ||
1069 | bPoweredDown = IMG_TRUE; | ||
1070 | #else | ||
1071 | bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE; | ||
1072 | #endif | ||
1073 | |||
1074 | |||
1075 | |||
1076 | if (bPoweredDown) | ||
1077 | { | ||
1078 | ui32LockupCounter = 0; | ||
1079 | } | ||
1080 | else | ||
1081 | { | ||
1082 | |||
1083 | ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0); | ||
1084 | if (psDevInfo->ui32EDMTaskReg1 != 0) | ||
1085 | { | ||
1086 | ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1); | ||
1087 | } | ||
1088 | if ((ui32CurrentEDMTasks == ui32EDMTasks) && | ||
1089 | (psDevInfo->ui32NumResets == ui32NumResets)) | ||
1090 | { | ||
1091 | ui32LockupCounter++; | ||
1092 | if (ui32LockupCounter == 3) | ||
1093 | { | ||
1094 | ui32LockupCounter = 0; | ||
1095 | PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks)); | ||
1096 | |||
1097 | bLockup = IMG_TRUE; | ||
1098 | } | ||
1099 | } | ||
1100 | else | ||
1101 | { | ||
1102 | ui32LockupCounter = 0; | ||
1103 | ui32EDMTasks = ui32CurrentEDMTasks; | ||
1104 | ui32NumResets = psDevInfo->ui32NumResets; | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | if (bLockup) | ||
1109 | { | ||
1110 | SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; | ||
1111 | |||
1112 | |||
1113 | psSGXHostCtl->ui32HostDetectedLockups ++; | ||
1114 | |||
1115 | |||
1116 | HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID); | ||
1117 | } | ||
1118 | } | ||
1119 | #endif | ||
1120 | |||
1121 | |||
1122 | #if defined(SYS_USING_INTERRUPTS) | ||
1123 | |||
1124 | IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData) | ||
1125 | { | ||
1126 | IMG_BOOL bInterruptProcessed = IMG_FALSE; | ||
1127 | |||
1128 | |||
1129 | |||
1130 | { | ||
1131 | IMG_UINT32 ui32EventStatus, ui32EventEnable; | ||
1132 | IMG_UINT32 ui32EventClear = 0; | ||
1133 | #if defined(SGX_FEATURE_DATA_BREAKPOINTS) | ||
1134 | IMG_UINT32 ui32EventStatus2, ui32EventEnable2; | ||
1135 | #endif | ||
1136 | IMG_UINT32 ui32EventClear2 = 0; | ||
1137 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
1138 | PVRSRV_SGXDEV_INFO *psDevInfo; | ||
1139 | |||
1140 | |||
1141 | if(pvData == IMG_NULL) | ||
1142 | { | ||
1143 | PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n")); | ||
1144 | return bInterruptProcessed; | ||
1145 | } | ||
1146 | |||
1147 | psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; | ||
1148 | psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; | ||
1149 | |||
1150 | ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); | ||
1151 | ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE); | ||
1152 | |||
1153 | |||
1154 | ui32EventStatus &= ui32EventEnable; | ||
1155 | |||
1156 | #if defined(SGX_FEATURE_DATA_BREAKPOINTS) | ||
1157 | ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); | ||
1158 | ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2); | ||
1159 | |||
1160 | |||
1161 | ui32EventStatus2 &= ui32EventEnable2; | ||
1162 | #endif | ||
1163 | |||
1164 | |||
1165 | |||
1166 | if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK) | ||
1167 | { | ||
1168 | ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; | ||
1169 | } | ||
1170 | |||
1171 | #if defined(SGX_FEATURE_DATA_BREAKPOINTS) | ||
1172 | if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK) | ||
1173 | { | ||
1174 | ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK; | ||
1175 | } | ||
1176 | |||
1177 | if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK) | ||
1178 | { | ||
1179 | ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK; | ||
1180 | } | ||
1181 | #endif | ||
1182 | |||
1183 | if (ui32EventClear || ui32EventClear2) | ||
1184 | { | ||
1185 | bInterruptProcessed = IMG_TRUE; | ||
1186 | |||
1187 | |||
1188 | ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK; | ||
1189 | |||
1190 | |||
1191 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear); | ||
1192 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2); | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | return bInterruptProcessed; | ||
1197 | } | ||
1198 | |||
1199 | |||
1200 | static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) | ||
1201 | { | ||
1202 | PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; | ||
1203 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; | ||
1204 | SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; | ||
1205 | |||
1206 | if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) && | ||
1207 | ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL)) | ||
1208 | { | ||
1209 | HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); | ||
1210 | } | ||
1211 | |||
1212 | #if defined(OS_SUPPORTS_IN_LISR) | ||
1213 | if (psDeviceNode->bReProcessDeviceCommandComplete) | ||
1214 | { | ||
1215 | SGXScheduleProcessQueuesKM(psDeviceNode); | ||
1216 | } | ||
1217 | #endif | ||
1218 | |||
1219 | SGXTestActivePowerEvent(psDeviceNode, ISR_ID); | ||
1220 | } | ||
1221 | #endif | ||
1222 | |||
1223 | |||
1224 | |||
1225 | #if defined(SUPPORT_MEMORY_TILING) | ||
1226 | PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode, | ||
1227 | PVRSRV_KERNEL_MEM_INFO *psMemInfo, | ||
1228 | IMG_UINT32 ui32TilingStride, | ||
1229 | IMG_UINT32 *pui32RangeIndex) | ||
1230 | { | ||
1231 | #if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS) | ||
1232 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
1233 | IMG_UINT32 i; | ||
1234 | IMG_UINT32 ui32Start; | ||
1235 | IMG_UINT32 ui32End; | ||
1236 | IMG_UINT32 ui32Offset; | ||
1237 | IMG_UINT32 ui32Val; | ||
1238 | |||
1239 | |||
1240 | for(i=0; i<10; i++) | ||
1241 | { | ||
1242 | if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0) | ||
1243 | { | ||
1244 | |||
1245 | psDevInfo->ui32MemTilingUsage |= 1U << i; | ||
1246 | |||
1247 | *pui32RangeIndex = i; | ||
1248 | goto RangeAllocated; | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use")); | ||
1253 | return PVRSRV_ERROR_EXCEEDED_HW_LIMITS; | ||
1254 | |||
1255 | RangeAllocated: | ||
1256 | ui32Offset = EUR_CR_BIF_TILE0 + (i<<2); | ||
1257 | |||
1258 | ui32Start = psMemInfo->sDevVAddr.uiAddr; | ||
1259 | ui32End = ui32Start + psMemInfo->ui32AllocSize + SGX_MMU_PAGE_SIZE - 1; | ||
1260 | |||
1261 | ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK) | ||
1262 | | (((ui32End>>20) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK) | ||
1263 | | (((ui32Start>>20) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK) | ||
1264 | | (0x8 << EUR_CR_BIF_TILE0_CFG_SHIFT); | ||
1265 | |||
1266 | |||
1267 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); | ||
1268 | PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); | ||
1269 | |||
1270 | ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2); | ||
1271 | |||
1272 | ui32Val = (((ui32End>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK) | ||
1273 | | (((ui32Start>>12) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK); | ||
1274 | |||
1275 | |||
1276 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); | ||
1277 | PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); | ||
1278 | |||
1279 | return PVRSRV_OK; | ||
1280 | #else | ||
1281 | PVR_UNREFERENCED_PARAMETER(psDeviceNode); | ||
1282 | PVR_UNREFERENCED_PARAMETER(psMemInfo); | ||
1283 | PVR_UNREFERENCED_PARAMETER(ui32TilingStride); | ||
1284 | PVR_UNREFERENCED_PARAMETER(pui32RangeIndex); | ||
1285 | |||
1286 | PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: device does not support memory tiling")); | ||
1287 | return PVRSRV_ERROR_NOT_SUPPORTED; | ||
1288 | #endif | ||
1289 | } | ||
1290 | |||
1291 | PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode, | ||
1292 | IMG_UINT32 ui32RangeIndex) | ||
1293 | { | ||
1294 | #if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS) | ||
1295 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
1296 | IMG_UINT32 ui32Offset; | ||
1297 | IMG_UINT32 ui32Val; | ||
1298 | |||
1299 | if(ui32RangeIndex >= 10) | ||
1300 | { | ||
1301 | PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index ")); | ||
1302 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1303 | } | ||
1304 | |||
1305 | |||
1306 | psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex); | ||
1307 | |||
1308 | |||
1309 | ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2); | ||
1310 | ui32Val = 0; | ||
1311 | |||
1312 | |||
1313 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); | ||
1314 | PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); | ||
1315 | |||
1316 | return PVRSRV_OK; | ||
1317 | #else | ||
1318 | PVR_UNREFERENCED_PARAMETER(psDeviceNode); | ||
1319 | PVR_UNREFERENCED_PARAMETER(ui32RangeIndex); | ||
1320 | |||
1321 | PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: device does not support memory tiling")); | ||
1322 | return PVRSRV_ERROR_NOT_SUPPORTED; | ||
1323 | #endif | ||
1324 | } | ||
1325 | #endif | ||
1326 | |||
1327 | |||
1328 | PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode) | ||
1329 | { | ||
1330 | DEVICE_MEMORY_INFO *psDevMemoryInfo; | ||
1331 | DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; | ||
1332 | |||
1333 | |||
1334 | psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; | ||
1335 | psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS; | ||
1336 | #if defined(PDUMP) | ||
1337 | { | ||
1338 | |||
1339 | SGX_DEVICE_MAP *psSGXDeviceMemMap; | ||
1340 | SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, | ||
1341 | (IMG_VOID**)&psSGXDeviceMemMap); | ||
1342 | |||
1343 | psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName; | ||
1344 | PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL); | ||
1345 | } | ||
1346 | |||
1347 | psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME; | ||
1348 | #endif | ||
1349 | |||
1350 | psDeviceNode->pfnInitDevice = &DevInitSGXPart1; | ||
1351 | psDeviceNode->pfnDeInitDevice = &DevDeInitSGX; | ||
1352 | |||
1353 | psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck; | ||
1354 | #if defined(PDUMP) | ||
1355 | psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump; | ||
1356 | psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID; | ||
1357 | #endif | ||
1358 | |||
1359 | |||
1360 | psDeviceNode->pfnMMUInitialise = &MMU_Initialise; | ||
1361 | psDeviceNode->pfnMMUFinalise = &MMU_Finalise; | ||
1362 | psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap; | ||
1363 | psDeviceNode->pfnMMUCreate = &MMU_Create; | ||
1364 | psDeviceNode->pfnMMUDelete = &MMU_Delete; | ||
1365 | psDeviceNode->pfnMMUAlloc = &MMU_Alloc; | ||
1366 | psDeviceNode->pfnMMUFree = &MMU_Free; | ||
1367 | psDeviceNode->pfnMMUMapPages = &MMU_MapPages; | ||
1368 | psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow; | ||
1369 | psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages; | ||
1370 | psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter; | ||
1371 | psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr; | ||
1372 | psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr; | ||
1373 | |||
1374 | #if defined (SYS_USING_INTERRUPTS) | ||
1375 | |||
1376 | |||
1377 | psDeviceNode->pfnDeviceISR = SGX_ISRHandler; | ||
1378 | psDeviceNode->pfnDeviceMISR = SGX_MISRHandler; | ||
1379 | #endif | ||
1380 | |||
1381 | #if defined(SUPPORT_MEMORY_TILING) | ||
1382 | psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange; | ||
1383 | psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange; | ||
1384 | #endif | ||
1385 | |||
1386 | |||
1387 | |||
1388 | psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete; | ||
1389 | |||
1390 | |||
1391 | |||
1392 | psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; | ||
1393 | |||
1394 | psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE; | ||
1395 | |||
1396 | |||
1397 | psDevMemoryInfo->ui32Flags = 0; | ||
1398 | |||
1399 | |||
1400 | if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
1401 | sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, | ||
1402 | (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0, | ||
1403 | "Array of Device Memory Heap Info") != PVRSRV_OK) | ||
1404 | { | ||
1405 | PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO")); | ||
1406 | return (PVRSRV_ERROR_OUT_OF_MEMORY); | ||
1407 | } | ||
1408 | OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID); | ||
1409 | |||
1410 | psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; | ||
1411 | |||
1412 | |||
1413 | |||
1414 | |||
1415 | |||
1416 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID); | ||
1417 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE; | ||
1418 | psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE; | ||
1419 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1420 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1421 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1422 | psDeviceMemoryHeap->pszName = "General"; | ||
1423 | psDeviceMemoryHeap->pszBSName = "General BS"; | ||
1424 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1425 | |||
1426 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1427 | #if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) | ||
1428 | |||
1429 | psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); | ||
1430 | #endif | ||
1431 | psDeviceMemoryHeap++; | ||
1432 | |||
1433 | |||
1434 | |||
1435 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID); | ||
1436 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE; | ||
1437 | psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE; | ||
1438 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1439 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1440 | | PVRSRV_HAP_MULTI_PROCESS; | ||
1441 | psDeviceMemoryHeap->pszName = "TA Data"; | ||
1442 | psDeviceMemoryHeap->pszBSName = "TA Data BS"; | ||
1443 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1444 | |||
1445 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1446 | psDeviceMemoryHeap++; | ||
1447 | |||
1448 | |||
1449 | |||
1450 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID); | ||
1451 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE; | ||
1452 | psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE; | ||
1453 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1454 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1455 | | PVRSRV_HAP_MULTI_PROCESS; | ||
1456 | psDeviceMemoryHeap->pszName = "Kernel Code"; | ||
1457 | psDeviceMemoryHeap->pszBSName = "Kernel Code BS"; | ||
1458 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1459 | |||
1460 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1461 | psDeviceMemoryHeap++; | ||
1462 | |||
1463 | |||
1464 | |||
1465 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID); | ||
1466 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE; | ||
1467 | psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE; | ||
1468 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1469 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1470 | | PVRSRV_HAP_MULTI_PROCESS; | ||
1471 | psDeviceMemoryHeap->pszName = "KernelData"; | ||
1472 | psDeviceMemoryHeap->pszBSName = "KernelData BS"; | ||
1473 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1474 | |||
1475 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1476 | psDeviceMemoryHeap++; | ||
1477 | |||
1478 | |||
1479 | |||
1480 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID); | ||
1481 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE; | ||
1482 | |||
1483 | |||
1484 | |||
1485 | |||
1486 | |||
1487 | |||
1488 | psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000); | ||
1489 | PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE); | ||
1490 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1491 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1492 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1493 | psDeviceMemoryHeap->pszName = "PixelShaderUSSE"; | ||
1494 | psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS"; | ||
1495 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1496 | |||
1497 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1498 | psDeviceMemoryHeap++; | ||
1499 | |||
1500 | |||
1501 | |||
1502 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID); | ||
1503 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE; | ||
1504 | |||
1505 | psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000); | ||
1506 | PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE); | ||
1507 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1508 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1509 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1510 | psDeviceMemoryHeap->pszName = "VertexShaderUSSE"; | ||
1511 | psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS"; | ||
1512 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1513 | |||
1514 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1515 | psDeviceMemoryHeap++; | ||
1516 | |||
1517 | |||
1518 | |||
1519 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID); | ||
1520 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE; | ||
1521 | psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE; | ||
1522 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1523 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1524 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1525 | psDeviceMemoryHeap->pszName = "PDSPixelCodeData"; | ||
1526 | psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS"; | ||
1527 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1528 | |||
1529 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1530 | psDeviceMemoryHeap++; | ||
1531 | |||
1532 | |||
1533 | |||
1534 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID); | ||
1535 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE; | ||
1536 | psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE; | ||
1537 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1538 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1539 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1540 | psDeviceMemoryHeap->pszName = "PDSVertexCodeData"; | ||
1541 | psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS"; | ||
1542 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1543 | |||
1544 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1545 | psDeviceMemoryHeap++; | ||
1546 | |||
1547 | |||
1548 | |||
1549 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID); | ||
1550 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE; | ||
1551 | psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE; | ||
1552 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1553 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1554 | | PVRSRV_HAP_MULTI_PROCESS; | ||
1555 | psDeviceMemoryHeap->pszName = "CacheCoherent"; | ||
1556 | psDeviceMemoryHeap->pszBSName = "CacheCoherent BS"; | ||
1557 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1558 | |||
1559 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1560 | |||
1561 | psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); | ||
1562 | psDeviceMemoryHeap++; | ||
1563 | |||
1564 | |||
1565 | |||
1566 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID); | ||
1567 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE; | ||
1568 | psDeviceMemoryHeap->ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE; | ||
1569 | psDeviceMemoryHeap->pszName = "3DParameters"; | ||
1570 | psDeviceMemoryHeap->pszBSName = "3DParameters BS"; | ||
1571 | #if defined(SUPPORT_PERCONTEXT_PB) | ||
1572 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1573 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1574 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1575 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1576 | #else | ||
1577 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1578 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1579 | | PVRSRV_HAP_MULTI_PROCESS; | ||
1580 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1581 | #endif | ||
1582 | |||
1583 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1584 | psDeviceMemoryHeap++; | ||
1585 | |||
1586 | |||
1587 | #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) | ||
1588 | |||
1589 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID); | ||
1590 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; | ||
1591 | psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; | ||
1592 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS; | ||
1593 | psDeviceMemoryHeap->pszName = "GeneralMapping"; | ||
1594 | psDeviceMemoryHeap->pszBSName = "GeneralMapping BS"; | ||
1595 | #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) | ||
1596 | |||
1597 | |||
1598 | |||
1599 | |||
1600 | |||
1601 | |||
1602 | |||
1603 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1604 | #else | ||
1605 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1606 | #endif | ||
1607 | |||
1608 | |||
1609 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1610 | |||
1611 | psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); | ||
1612 | psDeviceMemoryHeap++; | ||
1613 | #endif | ||
1614 | |||
1615 | |||
1616 | #if defined(SGX_FEATURE_2D_HARDWARE) | ||
1617 | |||
1618 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID); | ||
1619 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE; | ||
1620 | psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE; | ||
1621 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1622 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1623 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1624 | psDeviceMemoryHeap->pszName = "2D"; | ||
1625 | psDeviceMemoryHeap->pszBSName = "2D BS"; | ||
1626 | |||
1627 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; | ||
1628 | |||
1629 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1630 | psDeviceMemoryHeap++; | ||
1631 | #endif | ||
1632 | |||
1633 | |||
1634 | #if defined(FIX_HW_BRN_26915) | ||
1635 | |||
1636 | |||
1637 | psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID); | ||
1638 | psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE; | ||
1639 | psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE; | ||
1640 | psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | ||
1641 | | PVRSRV_MEM_RAM_BACKED_ALLOCATION | ||
1642 | | PVRSRV_HAP_SINGLE_PROCESS; | ||
1643 | psDeviceMemoryHeap->pszName = "CGBuffer"; | ||
1644 | psDeviceMemoryHeap->pszBSName = "CGBuffer BS"; | ||
1645 | |||
1646 | psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; | ||
1647 | |||
1648 | psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; | ||
1649 | psDeviceMemoryHeap++; | ||
1650 | #endif | ||
1651 | |||
1652 | |||
1653 | psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); | ||
1654 | |||
1655 | return PVRSRV_OK; | ||
1656 | } | ||
1657 | |||
1658 | #if defined(PDUMP) | ||
1659 | static | ||
1660 | PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode) | ||
1661 | { | ||
1662 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice); | ||
1663 | psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0; | ||
1664 | PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset.")); | ||
1665 | |||
1666 | return PVRSRV_OK; | ||
1667 | } | ||
1668 | #endif | ||
1669 | |||
1670 | |||
1671 | IMG_EXPORT | ||
1672 | PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, | ||
1673 | SGX_CLIENT_INFO* psClientInfo) | ||
1674 | { | ||
1675 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; | ||
1676 | |||
1677 | |||
1678 | |||
1679 | psDevInfo->ui32ClientRefCount++; | ||
1680 | |||
1681 | |||
1682 | |||
1683 | psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); | ||
1684 | |||
1685 | |||
1686 | |||
1687 | OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); | ||
1688 | |||
1689 | |||
1690 | return PVRSRV_OK; | ||
1691 | } | ||
1692 | |||
1693 | |||
1694 | IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo) | ||
1695 | { | ||
1696 | PVR_LOG(("SGX panic")); | ||
1697 | SGXDumpDebugInfo(psDevInfo, IMG_FALSE); | ||
1698 | OSPanic(); | ||
1699 | } | ||
1700 | |||
1701 | |||
1702 | PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) | ||
1703 | { | ||
1704 | PVRSRV_ERROR eError; | ||
1705 | PVRSRV_SGXDEV_INFO *psDevInfo; | ||
1706 | IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; | ||
1707 | #if !defined(NO_HARDWARE) | ||
1708 | PPVRSRV_KERNEL_MEM_INFO psMemInfo; | ||
1709 | PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; | ||
1710 | PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; | ||
1711 | SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; | ||
1712 | IMG_BOOL bStructSizesFailed; | ||
1713 | |||
1714 | |||
1715 | IMG_BOOL bCheckCoreRev; | ||
1716 | const IMG_UINT32 aui32CoreRevExceptions[] = | ||
1717 | { | ||
1718 | 0x10100, 0x10101 | ||
1719 | }; | ||
1720 | const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32)); | ||
1721 | IMG_UINT i; | ||
1722 | #endif | ||
1723 | |||
1724 | |||
1725 | if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX) | ||
1726 | { | ||
1727 | PVR_LOG(("(FAIL) SGXInit: Device not of type SGX")); | ||
1728 | eError = PVRSRV_ERROR_INVALID_PARAMS; | ||
1729 | goto chk_exit; | ||
1730 | } | ||
1731 | |||
1732 | psDevInfo = psDeviceNode->pvDevice; | ||
1733 | |||
1734 | |||
1735 | |||
1736 | ui32BuildOptions = (SGX_BUILD_OPTIONS); | ||
1737 | if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions) | ||
1738 | { | ||
1739 | ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions; | ||
1740 | if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0) | ||
1741 | { | ||
1742 | PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " | ||
1743 | "extra options present in client-side driver: (0x%x). Please check sgx_options.h", | ||
1744 | psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch )); | ||
1745 | } | ||
1746 | |||
1747 | if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) | ||
1748 | { | ||
1749 | PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " | ||
1750 | "extra options present in KM: (0x%x). Please check sgx_options.h", | ||
1751 | ui32BuildOptions & ui32BuildOptionsMismatch )); | ||
1752 | } | ||
1753 | eError = PVRSRV_ERROR_BUILD_MISMATCH; | ||
1754 | goto chk_exit; | ||
1755 | } | ||
1756 | else | ||
1757 | { | ||
1758 | PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]")); | ||
1759 | } | ||
1760 | |||
1761 | #if !defined (NO_HARDWARE) | ||
1762 | psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; | ||
1763 | |||
1764 | |||
1765 | psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; | ||
1766 | psSGXMiscInfoInt->ui32MiscInfoFlags = 0; | ||
1767 | psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES; | ||
1768 | eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); | ||
1769 | |||
1770 | |||
1771 | if(eError != PVRSRV_OK) | ||
1772 | { | ||
1773 | PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version")); | ||
1774 | goto chk_exit; | ||
1775 | } | ||
1776 | psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; | ||
1777 | if( (psSGXFeatures->ui32DDKVersion != | ||
1778 | ((PVRVERSION_MAJ << 16) | | ||
1779 | (PVRVERSION_MIN << 8) | | ||
1780 | PVRVERSION_BRANCH) ) || | ||
1781 | (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) ) | ||
1782 | { | ||
1783 | PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).", | ||
1784 | PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); | ||
1785 | eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; | ||
1786 | PVR_DBG_BREAK; | ||
1787 | goto chk_exit; | ||
1788 | } | ||
1789 | else | ||
1790 | { | ||
1791 | PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]", | ||
1792 | PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); | ||
1793 | } | ||
1794 | |||
1795 | |||
1796 | if (psSGXFeatures->ui32CoreRevSW == 0) | ||
1797 | { | ||
1798 | |||
1799 | |||
1800 | PVR_LOG(("SGXInit: HW core rev (%x) check skipped.", | ||
1801 | psSGXFeatures->ui32CoreRev)); | ||
1802 | } | ||
1803 | else | ||
1804 | { | ||
1805 | |||
1806 | bCheckCoreRev = IMG_TRUE; | ||
1807 | for(i=0; i<ui32NumCoreExceptions; i+=2) | ||
1808 | { | ||
1809 | if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) && | ||
1810 | (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) ) | ||
1811 | { | ||
1812 | PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.", | ||
1813 | psSGXFeatures->ui32CoreRev, | ||
1814 | psSGXFeatures->ui32CoreRevSW)); | ||
1815 | bCheckCoreRev = IMG_FALSE; | ||
1816 | } | ||
1817 | } | ||
1818 | |||
1819 | if (bCheckCoreRev) | ||
1820 | { | ||
1821 | if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW) | ||
1822 | { | ||
1823 | PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).", | ||
1824 | psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); | ||
1825 | eError = PVRSRV_ERROR_BUILD_MISMATCH; | ||
1826 | goto chk_exit; | ||
1827 | } | ||
1828 | else | ||
1829 | { | ||
1830 | PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]", | ||
1831 | psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); | ||
1832 | } | ||
1833 | } | ||
1834 | } | ||
1835 | |||
1836 | |||
1837 | psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes; | ||
1838 | |||
1839 | bStructSizesFailed = IMG_FALSE; | ||
1840 | |||
1841 | CHECK_SIZE(HOST_CTL); | ||
1842 | CHECK_SIZE(COMMAND); | ||
1843 | #if defined(SGX_FEATURE_2D_HARDWARE) | ||
1844 | CHECK_SIZE(2DCMD); | ||
1845 | CHECK_SIZE(2DCMD_SHARED); | ||
1846 | #endif | ||
1847 | CHECK_SIZE(CMDTA); | ||
1848 | CHECK_SIZE(CMDTA_SHARED); | ||
1849 | CHECK_SIZE(TRANSFERCMD); | ||
1850 | CHECK_SIZE(TRANSFERCMD_SHARED); | ||
1851 | |||
1852 | CHECK_SIZE(3DREGISTERS); | ||
1853 | CHECK_SIZE(HWPBDESC); | ||
1854 | CHECK_SIZE(HWRENDERCONTEXT); | ||
1855 | CHECK_SIZE(HWRENDERDETAILS); | ||
1856 | CHECK_SIZE(HWRTDATA); | ||
1857 | CHECK_SIZE(HWRTDATASET); | ||
1858 | CHECK_SIZE(HWTRANSFERCONTEXT); | ||
1859 | |||
1860 | if (bStructSizesFailed == IMG_TRUE) | ||
1861 | { | ||
1862 | PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes.")); | ||
1863 | eError = PVRSRV_ERROR_BUILD_MISMATCH; | ||
1864 | goto chk_exit; | ||
1865 | } | ||
1866 | else | ||
1867 | { | ||
1868 | PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]")); | ||
1869 | } | ||
1870 | |||
1871 | |||
1872 | ui32BuildOptions = psSGXFeatures->ui32BuildOptions; | ||
1873 | if (ui32BuildOptions != (SGX_BUILD_OPTIONS)) | ||
1874 | { | ||
1875 | ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS); | ||
1876 | if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0) | ||
1877 | { | ||
1878 | PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " | ||
1879 | "extra options present in driver: (0x%x). Please check sgx_options.h", | ||
1880 | (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch )); | ||
1881 | } | ||
1882 | |||
1883 | if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) | ||
1884 | { | ||
1885 | PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " | ||
1886 | "extra options present in microkernel: (0x%x). Please check sgx_options.h", | ||
1887 | ui32BuildOptions & ui32BuildOptionsMismatch )); | ||
1888 | } | ||
1889 | eError = PVRSRV_ERROR_BUILD_MISMATCH; | ||
1890 | goto chk_exit; | ||
1891 | } | ||
1892 | else | ||
1893 | { | ||
1894 | PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]")); | ||
1895 | } | ||
1896 | #endif | ||
1897 | |||
1898 | eError = PVRSRV_OK; | ||
1899 | chk_exit: | ||
1900 | #if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK) | ||
1901 | return PVRSRV_OK; | ||
1902 | #else | ||
1903 | return eError; | ||
1904 | #endif | ||
1905 | } | ||
1906 | |||
1907 | static | ||
1908 | PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
1909 | PVRSRV_DEVICE_NODE *psDeviceNode) | ||
1910 | { | ||
1911 | PVRSRV_ERROR eError; | ||
1912 | SGXMKIF_COMMAND sCommandData; | ||
1913 | PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; | ||
1914 | PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; | ||
1915 | SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; | ||
1916 | |||
1917 | PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; | ||
1918 | |||
1919 | if (! psMemInfo->pvLinAddrKM) | ||
1920 | { | ||
1921 | PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address.")); | ||
1922 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
1923 | } | ||
1924 | psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; | ||
1925 | psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures; | ||
1926 | psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes; | ||
1927 | |||
1928 | psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY; | ||
1929 | |||
1930 | |||
1931 | OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures)); | ||
1932 | OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes)); | ||
1933 | |||
1934 | |||
1935 | sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; | ||
1936 | |||
1937 | PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo"); | ||
1938 | eError = SGXScheduleCCBCommandKM(psDeviceNode, | ||
1939 | SGXMKIF_CMD_GETMISCINFO, | ||
1940 | &sCommandData, | ||
1941 | KERNEL_ID, | ||
1942 | 0); | ||
1943 | |||
1944 | if (eError != PVRSRV_OK) | ||
1945 | { | ||
1946 | PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed.")); | ||
1947 | return eError; | ||
1948 | } | ||
1949 | |||
1950 | |||
1951 | #if !defined(NO_HARDWARE) | ||
1952 | { | ||
1953 | IMG_BOOL bExit; | ||
1954 | |||
1955 | bExit = IMG_FALSE; | ||
1956 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
1957 | { | ||
1958 | if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0) | ||
1959 | { | ||
1960 | bExit = IMG_TRUE; | ||
1961 | break; | ||
1962 | } | ||
1963 | } END_LOOP_UNTIL_TIMEOUT(); | ||
1964 | |||
1965 | |||
1966 | if (!bExit) | ||
1967 | { | ||
1968 | PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info.")); | ||
1969 | return PVRSRV_ERROR_TIMEOUT; | ||
1970 | } | ||
1971 | } | ||
1972 | #endif | ||
1973 | |||
1974 | return PVRSRV_OK; | ||
1975 | } | ||
1976 | |||
1977 | |||
1978 | |||
1979 | IMG_EXPORT | ||
1980 | PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
1981 | SGX_MISC_INFO *psMiscInfo, | ||
1982 | PVRSRV_DEVICE_NODE *psDeviceNode, | ||
1983 | IMG_HANDLE hDevMemContext) | ||
1984 | { | ||
1985 | PVRSRV_ERROR eError; | ||
1986 | PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; | ||
1987 | IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags; | ||
1988 | |||
1989 | |||
1990 | *pui32MiscInfoFlags = 0; | ||
1991 | |||
1992 | #if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) | ||
1993 | PVR_UNREFERENCED_PARAMETER(hDevMemContext); | ||
1994 | #endif | ||
1995 | |||
1996 | switch(psMiscInfo->eRequest) | ||
1997 | { | ||
1998 | #if defined(SGX_FEATURE_DATA_BREAKPOINTS) | ||
1999 | case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT: | ||
2000 | { | ||
2001 | IMG_UINT32 ui32MaskDM; | ||
2002 | IMG_UINT32 ui32CtrlWEnable; | ||
2003 | IMG_UINT32 ui32CtrlREnable; | ||
2004 | IMG_UINT32 ui32CtrlTrapEnable; | ||
2005 | IMG_UINT32 ui32RegVal; | ||
2006 | IMG_UINT32 ui32StartRegVal; | ||
2007 | IMG_UINT32 ui32EndRegVal; | ||
2008 | SGXMKIF_COMMAND sCommandData; | ||
2009 | |||
2010 | |||
2011 | if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable) | ||
2012 | { | ||
2013 | |||
2014 | IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr; | ||
2015 | IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd; | ||
2016 | |||
2017 | |||
2018 | ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK; | ||
2019 | ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK; | ||
2020 | |||
2021 | ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask; | ||
2022 | ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite; | ||
2023 | ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead; | ||
2024 | ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped; | ||
2025 | |||
2026 | |||
2027 | ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) | | ||
2028 | ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) | | ||
2029 | ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) | | ||
2030 | ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK); | ||
2031 | } | ||
2032 | else | ||
2033 | { | ||
2034 | |||
2035 | ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0; | ||
2036 | } | ||
2037 | |||
2038 | |||
2039 | sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex; | ||
2040 | sCommandData.ui32Data[1] = ui32StartRegVal; | ||
2041 | sCommandData.ui32Data[2] = ui32EndRegVal; | ||
2042 | sCommandData.ui32Data[3] = ui32RegVal; | ||
2043 | |||
2044 | |||
2045 | psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; | ||
2046 | |||
2047 | PDUMPCOMMENT("Microkernel kick for setting a data breakpoint"); | ||
2048 | eError = SGXScheduleCCBCommandKM(psDeviceNode, | ||
2049 | SGXMKIF_CMD_DATABREAKPOINT, | ||
2050 | &sCommandData, | ||
2051 | KERNEL_ID, | ||
2052 | 0); | ||
2053 | |||
2054 | if (eError != PVRSRV_OK) | ||
2055 | { | ||
2056 | PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed.")); | ||
2057 | return eError; | ||
2058 | } | ||
2059 | |||
2060 | #if defined(NO_HARDWARE) | ||
2061 | |||
2062 | psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; | ||
2063 | #else | ||
2064 | { | ||
2065 | IMG_BOOL bExit; | ||
2066 | |||
2067 | bExit = IMG_FALSE; | ||
2068 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
2069 | { | ||
2070 | if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0) | ||
2071 | { | ||
2072 | bExit = IMG_TRUE; | ||
2073 | |||
2074 | psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; | ||
2075 | break; | ||
2076 | } | ||
2077 | } END_LOOP_UNTIL_TIMEOUT(); | ||
2078 | |||
2079 | |||
2080 | if (!bExit) | ||
2081 | { | ||
2082 | PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear")); | ||
2083 | return PVRSRV_ERROR_TIMEOUT; | ||
2084 | } | ||
2085 | } | ||
2086 | #endif | ||
2087 | |||
2088 | return PVRSRV_OK; | ||
2089 | } | ||
2090 | |||
2091 | case SGX_MISC_INFO_REQUEST_WAIT_FOR_BREAKPOINT: | ||
2092 | { | ||
2093 | |||
2094 | |||
2095 | PDUMPCOMMENT("Wait for data breakpoint hit"); | ||
2096 | |||
2097 | #if defined(NO_HARDWARE) && defined(PDUMP) | ||
2098 | { | ||
2099 | PDUMPREGPOL(SGX_PDUMPREG_NAME, | ||
2100 | EUR_CR_EVENT_STATUS2, | ||
2101 | EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK, | ||
2102 | EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK); | ||
2103 | |||
2104 | PDUMPREG(SGX_PDUMPREG_NAME, | ||
2105 | EUR_CR_EVENT_HOST_CLEAR2, | ||
2106 | EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK); | ||
2107 | |||
2108 | PDUMPCOMMENT("Breakpoint detected. Wait a bit to show that pipeline stops in simulation"); | ||
2109 | PDUMPIDL(2000); | ||
2110 | |||
2111 | PDUMPCOMMENT("Now we can resume"); | ||
2112 | PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BREAKPOINT_TRAP, EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK); | ||
2113 | } | ||
2114 | #else | ||
2115 | { | ||
2116 | |||
2117 | } | ||
2118 | #endif | ||
2119 | return PVRSRV_OK; | ||
2120 | } | ||
2121 | |||
2122 | case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT: | ||
2123 | { | ||
2124 | |||
2125 | |||
2126 | |||
2127 | |||
2128 | |||
2129 | |||
2130 | |||
2131 | #if !defined(NO_HARDWARE) | ||
2132 | IMG_BOOL bTrappedBPMaster; | ||
2133 | IMG_BOOL abTrappedBPPerCore[SGX_FEATURE_MP_CORE_COUNT]; | ||
2134 | IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum; | ||
2135 | IMG_BOOL bTrappedBPAny; | ||
2136 | |||
2137 | ui32TrappedBPCoreNum = 0; | ||
2138 | bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT)); | ||
2139 | bTrappedBPAny = bTrappedBPMaster; | ||
2140 | for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT; ui32CoreNum++) | ||
2141 | { | ||
2142 | abTrappedBPPerCore[ui32CoreNum] = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum))); | ||
2143 | if (abTrappedBPPerCore[ui32CoreNum]) | ||
2144 | { | ||
2145 | bTrappedBPAny = IMG_TRUE; | ||
2146 | ui32TrappedBPCoreNum = ui32CoreNum; | ||
2147 | } | ||
2148 | } | ||
2149 | |||
2150 | psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny; | ||
2151 | |||
2152 | if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP) | ||
2153 | { | ||
2154 | IMG_UINT32 ui32Info0, ui32Info1; | ||
2155 | |||
2156 | ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum)); | ||
2157 | ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum)); | ||
2158 | |||
2159 | psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT; | ||
2160 | psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK; | ||
2161 | psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT; | ||
2162 | psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK); | ||
2163 | psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT; | ||
2164 | psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT; | ||
2165 | psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum; | ||
2166 | } | ||
2167 | #endif | ||
2168 | return PVRSRV_OK; | ||
2169 | } | ||
2170 | |||
2171 | case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT: | ||
2172 | { | ||
2173 | |||
2174 | |||
2175 | |||
2176 | #if !defined(NO_HARDWARE) | ||
2177 | IMG_UINT32 ui32CoreNum; | ||
2178 | IMG_BOOL bMaster; | ||
2179 | IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum; | ||
2180 | |||
2181 | ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum; | ||
2182 | bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT; | ||
2183 | if (bMaster) | ||
2184 | { | ||
2185 | |||
2186 | |||
2187 | ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT); | ||
2188 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK); | ||
2189 | do | ||
2190 | { | ||
2191 | ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT); | ||
2192 | } | ||
2193 | while (ui32OldSeqNum == ui32NewSeqNum); | ||
2194 | } | ||
2195 | else | ||
2196 | { | ||
2197 | |||
2198 | ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)); | ||
2199 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK); | ||
2200 | do | ||
2201 | { | ||
2202 | ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)); | ||
2203 | } | ||
2204 | while (ui32OldSeqNum == ui32NewSeqNum); | ||
2205 | } | ||
2206 | #endif | ||
2207 | return PVRSRV_OK; | ||
2208 | } | ||
2209 | #endif | ||
2210 | |||
2211 | case SGX_MISC_INFO_REQUEST_CLOCKSPEED: | ||
2212 | { | ||
2213 | psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; | ||
2214 | return PVRSRV_OK; | ||
2215 | } | ||
2216 | |||
2217 | case SGX_MISC_INFO_REQUEST_ACTIVEPOWER: | ||
2218 | { | ||
2219 | psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents; | ||
2220 | return PVRSRV_OK; | ||
2221 | } | ||
2222 | |||
2223 | case SGX_MISC_INFO_REQUEST_LOCKUPS: | ||
2224 | { | ||
2225 | #if defined(SUPPORT_HW_RECOVERY) | ||
2226 | psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups; | ||
2227 | psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups; | ||
2228 | #else | ||
2229 | psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0; | ||
2230 | psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0; | ||
2231 | #endif | ||
2232 | return PVRSRV_OK; | ||
2233 | } | ||
2234 | |||
2235 | case SGX_MISC_INFO_REQUEST_SPM: | ||
2236 | { | ||
2237 | |||
2238 | return PVRSRV_OK; | ||
2239 | } | ||
2240 | |||
2241 | case SGX_MISC_INFO_REQUEST_SGXREV: | ||
2242 | { | ||
2243 | PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; | ||
2244 | eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); | ||
2245 | if(eError != PVRSRV_OK) | ||
2246 | { | ||
2247 | PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", | ||
2248 | eError)); | ||
2249 | return eError; | ||
2250 | } | ||
2251 | psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; | ||
2252 | |||
2253 | |||
2254 | psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; | ||
2255 | |||
2256 | |||
2257 | PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n", | ||
2258 | psSGXFeatures->ui32CoreRev, | ||
2259 | psSGXFeatures->ui32CoreIdSW, | ||
2260 | psSGXFeatures->ui32CoreRevSW)); | ||
2261 | PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n", | ||
2262 | psSGXFeatures->ui32DDKVersion, | ||
2263 | psSGXFeatures->ui32DDKBuild)); | ||
2264 | |||
2265 | |||
2266 | return PVRSRV_OK; | ||
2267 | } | ||
2268 | |||
2269 | case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV: | ||
2270 | { | ||
2271 | PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; | ||
2272 | |||
2273 | psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; | ||
2274 | |||
2275 | |||
2276 | OSMemSet(psMemInfo->pvLinAddrKM, 0, | ||
2277 | sizeof(PVRSRV_SGX_MISCINFO_INFO)); | ||
2278 | |||
2279 | psSGXFeatures->ui32DDKVersion = | ||
2280 | (PVRVERSION_MAJ << 16) | | ||
2281 | (PVRVERSION_MIN << 8) | | ||
2282 | PVRVERSION_BRANCH; | ||
2283 | psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD; | ||
2284 | |||
2285 | |||
2286 | psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS); | ||
2287 | |||
2288 | #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) | ||
2289 | |||
2290 | psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr; | ||
2291 | psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM; | ||
2292 | #endif | ||
2293 | |||
2294 | |||
2295 | psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; | ||
2296 | return PVRSRV_OK; | ||
2297 | } | ||
2298 | |||
2299 | #if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) | ||
2300 | case SGX_MISC_INFO_REQUEST_MEMREAD: | ||
2301 | case SGX_MISC_INFO_REQUEST_MEMCOPY: | ||
2302 | { | ||
2303 | PVRSRV_ERROR eError; | ||
2304 | PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; | ||
2305 | PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc; | ||
2306 | PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest; | ||
2307 | |||
2308 | { | ||
2309 | |||
2310 | *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD; | ||
2311 | psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc; | ||
2312 | |||
2313 | if(psMiscInfo->sDevVAddrSrc.uiAddr != 0) | ||
2314 | { | ||
2315 | psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc; | ||
2316 | } | ||
2317 | else | ||
2318 | { | ||
2319 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
2320 | } | ||
2321 | } | ||
2322 | |||
2323 | if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY) | ||
2324 | { | ||
2325 | |||
2326 | *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE; | ||
2327 | psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest; | ||
2328 | |||
2329 | if(psMiscInfo->sDevVAddrDest.uiAddr != 0) | ||
2330 | { | ||
2331 | psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest; | ||
2332 | } | ||
2333 | else | ||
2334 | { | ||
2335 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
2336 | } | ||
2337 | } | ||
2338 | |||
2339 | |||
2340 | if(psMiscInfo->hDevMemContext != IMG_NULL) | ||
2341 | { | ||
2342 | SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr); | ||
2343 | |||
2344 | |||
2345 | psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr; | ||
2346 | } | ||
2347 | else | ||
2348 | { | ||
2349 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
2350 | } | ||
2351 | |||
2352 | |||
2353 | eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); | ||
2354 | if(eError != PVRSRV_OK) | ||
2355 | { | ||
2356 | PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", | ||
2357 | eError)); | ||
2358 | return eError; | ||
2359 | } | ||
2360 | psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; | ||
2361 | |||
2362 | #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) | ||
2363 | if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL) | ||
2364 | { | ||
2365 | return PVRSRV_ERROR_INVALID_MISCINFO; | ||
2366 | } | ||
2367 | #endif | ||
2368 | |||
2369 | psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; | ||
2370 | return PVRSRV_OK; | ||
2371 | } | ||
2372 | #endif | ||
2373 | |||
2374 | #if defined(SUPPORT_SGX_HWPERF) | ||
2375 | case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS: | ||
2376 | { | ||
2377 | PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus; | ||
2378 | const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS | | ||
2379 | PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON | | ||
2380 | PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON | | ||
2381 | PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON; | ||
2382 | SGXMKIF_COMMAND sCommandData = {0}; | ||
2383 | |||
2384 | |||
2385 | if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0) | ||
2386 | { | ||
2387 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
2388 | } | ||
2389 | |||
2390 | #if defined(PDUMP) | ||
2391 | PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, | ||
2392 | "SGX ukernel HWPerf status %u\n", | ||
2393 | psSetHWPerfStatus->ui32NewHWPerfStatus); | ||
2394 | #endif | ||
2395 | |||
2396 | |||
2397 | #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) | ||
2398 | OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0], | ||
2399 | &psSetHWPerfStatus->aui32PerfGroup[0], | ||
2400 | sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup)); | ||
2401 | OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0], | ||
2402 | &psSetHWPerfStatus->aui32PerfBit[0], | ||
2403 | sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit)); | ||
2404 | #if defined(PDUMP) | ||
2405 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, | ||
2406 | offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup), | ||
2407 | sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup), | ||
2408 | PDUMP_FLAGS_CONTINUOUS, | ||
2409 | MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); | ||
2410 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, | ||
2411 | offsetof(SGXMKIF_HOST_CTL, aui32PerfBit), | ||
2412 | sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit), | ||
2413 | PDUMP_FLAGS_CONTINUOUS, | ||
2414 | MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); | ||
2415 | #endif | ||
2416 | #else | ||
2417 | psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup; | ||
2418 | #if defined(PDUMP) | ||
2419 | PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, | ||
2420 | offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup), | ||
2421 | sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup), | ||
2422 | PDUMP_FLAGS_CONTINUOUS, | ||
2423 | MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); | ||
2424 | #endif | ||
2425 | #endif | ||
2426 | |||
2427 | |||
2428 | sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus; | ||
2429 | eError = SGXScheduleCCBCommandKM(psDeviceNode, | ||
2430 | SGXMKIF_CMD_SETHWPERFSTATUS, | ||
2431 | &sCommandData, | ||
2432 | KERNEL_ID, | ||
2433 | 0); | ||
2434 | return eError; | ||
2435 | } | ||
2436 | #endif | ||
2437 | |||
2438 | case SGX_MISC_INFO_DUMP_DEBUG_INFO: | ||
2439 | { | ||
2440 | PVR_LOG(("User requested SGX debug info")); | ||
2441 | |||
2442 | |||
2443 | SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE); | ||
2444 | |||
2445 | return PVRSRV_OK; | ||
2446 | } | ||
2447 | |||
2448 | case SGX_MISC_INFO_PANIC: | ||
2449 | { | ||
2450 | PVR_LOG(("User requested SGX panic")); | ||
2451 | |||
2452 | SGXPanic(psDeviceNode->pvDevice); | ||
2453 | |||
2454 | return PVRSRV_OK; | ||
2455 | } | ||
2456 | |||
2457 | default: | ||
2458 | { | ||
2459 | |||
2460 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
2461 | } | ||
2462 | } | ||
2463 | } | ||
2464 | |||
2465 | |||
2466 | IMG_EXPORT | ||
2467 | PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, | ||
2468 | IMG_UINT32 ui32ArraySize, | ||
2469 | PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry, | ||
2470 | IMG_UINT32 *pui32DataCount, | ||
2471 | IMG_UINT32 *pui32ClockSpeed, | ||
2472 | IMG_UINT32 *pui32HostTimeStamp) | ||
2473 | { | ||
2474 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
2475 | PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; | ||
2476 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
2477 | SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; | ||
2478 | IMG_UINT i; | ||
2479 | |||
2480 | for (i = 0; | ||
2481 | psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize; | ||
2482 | i++) | ||
2483 | { | ||
2484 | SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; | ||
2485 | |||
2486 | psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo; | ||
2487 | psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type; | ||
2488 | psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal; | ||
2489 | psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info; | ||
2490 | psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo, | ||
2491 | psMKPerfEntry->ui32TimeWraps, | ||
2492 | psMKPerfEntry->ui32Time); | ||
2493 | OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0], | ||
2494 | &psMKPerfEntry->ui32Counters[0][0], | ||
2495 | sizeof(psMKPerfEntry->ui32Counters)); | ||
2496 | |||
2497 | psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); | ||
2498 | } | ||
2499 | |||
2500 | *pui32DataCount = i; | ||
2501 | *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; | ||
2502 | *pui32HostTimeStamp = OSClockus(); | ||
2503 | |||
2504 | return eError; | ||
2505 | } | ||
2506 | |||
2507 | |||