diff options
Diffstat (limited to 'drivers/gpu/pvr/sgx/sgxutils.c')
-rw-r--r-- | drivers/gpu/pvr/sgx/sgxutils.c | 955 |
1 files changed, 955 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c new file mode 100644 index 00000000000..3365af66425 --- /dev/null +++ b/drivers/gpu/pvr/sgx/sgxutils.c | |||
@@ -0,0 +1,955 @@ | |||
1 | /********************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful but, except | ||
10 | * as otherwise stated in writing, without any warranty; without even the | ||
11 | * implied warranty of merchantability or fitness for a particular purpose. | ||
12 | * See the GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in | ||
19 | * the file called "COPYING". | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Imagination Technologies Ltd. <gpl-support@imgtec.com> | ||
23 | * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK | ||
24 | * | ||
25 | ******************************************************************************/ | ||
26 | |||
27 | #include <stddef.h> | ||
28 | |||
29 | #include "sgxdefs.h" | ||
30 | #include "services_headers.h" | ||
31 | #include "buffer_manager.h" | ||
32 | #include "sgx_bridge_km.h" | ||
33 | #include "sgxapi_km.h" | ||
34 | #include "sgxinfo.h" | ||
35 | #include "sgx_mkif_km.h" | ||
36 | #include "sysconfig.h" | ||
37 | #include "pdump_km.h" | ||
38 | #include "mmu.h" | ||
39 | #include "pvr_bridge_km.h" | ||
40 | #include "osfunc.h" | ||
41 | #include "pvr_debug.h" | ||
42 | #include "sgxutils.h" | ||
43 | |||
44 | #ifdef __linux__ | ||
45 | #include <linux/kernel.h> | ||
46 | #include <linux/string.h> | ||
47 | #else | ||
48 | #include <stdio.h> | ||
49 | #endif | ||
50 | |||
51 | |||
52 | #if defined(SYS_CUSTOM_POWERDOWN) | ||
53 | PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID); | ||
54 | #endif | ||
55 | |||
56 | |||
57 | |||
58 | static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, | ||
59 | IMG_UINT32 ui32CallerID) | ||
60 | { | ||
61 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
62 | SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; | ||
63 | |||
64 | |||
65 | psSGXHostCtl->ui32NumActivePowerEvents++; | ||
66 | |||
67 | if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) | ||
68 | { | ||
69 | |||
70 | |||
71 | |||
72 | if (ui32CallerID == ISR_ID) | ||
73 | { | ||
74 | psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | SGXScheduleProcessQueuesKM(psDeviceNode); | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | |||
84 | IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, | ||
85 | IMG_UINT32 ui32CallerID) | ||
86 | { | ||
87 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
88 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
89 | SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; | ||
90 | |||
91 | if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) && | ||
92 | ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0)) | ||
93 | { | ||
94 | |||
95 | psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; | ||
96 | |||
97 | |||
98 | PDUMPSUSPEND(); | ||
99 | |||
100 | #if defined(SYS_CUSTOM_POWERDOWN) | ||
101 | |||
102 | |||
103 | |||
104 | eError = SysPowerDownMISR(psDeviceNode, ui32CallerID); | ||
105 | #else | ||
106 | eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, | ||
107 | PVRSRV_DEV_POWER_STATE_OFF, | ||
108 | ui32CallerID, IMG_FALSE); | ||
109 | if (eError == PVRSRV_OK) | ||
110 | { | ||
111 | SGXPostActivePowerEvent(psDeviceNode, ui32CallerID); | ||
112 | } | ||
113 | #endif | ||
114 | if (eError == PVRSRV_ERROR_RETRY) | ||
115 | { | ||
116 | |||
117 | |||
118 | psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; | ||
119 | eError = PVRSRV_OK; | ||
120 | } | ||
121 | |||
122 | |||
123 | PDUMPRESUME(); | ||
124 | } | ||
125 | |||
126 | if (eError != PVRSRV_OK) | ||
127 | { | ||
128 | PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | |||
133 | #ifdef INLINE_IS_PRAGMA | ||
134 | #pragma inline(SGXAcquireKernelCCBSlot) | ||
135 | #endif | ||
136 | static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB) | ||
137 | { | ||
138 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
139 | { | ||
140 | if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset) | ||
141 | { | ||
142 | return &psCCB->psCommands[*psCCB->pui32WriteOffset]; | ||
143 | } | ||
144 | |||
145 | OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); | ||
146 | } END_LOOP_UNTIL_TIMEOUT(); | ||
147 | |||
148 | |||
149 | return IMG_NULL; | ||
150 | } | ||
151 | |||
152 | PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
153 | SGXMKIF_CMD_TYPE eCmdType, | ||
154 | SGXMKIF_COMMAND *psCommandData, | ||
155 | IMG_UINT32 ui32CallerID, | ||
156 | IMG_UINT32 ui32PDumpFlags) | ||
157 | { | ||
158 | PVRSRV_SGX_CCB_INFO *psKernelCCB; | ||
159 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
160 | SGXMKIF_COMMAND *psSGXCommand; | ||
161 | SYS_DATA *psSysData; | ||
162 | #if defined(PDUMP) | ||
163 | IMG_VOID *pvDumpCommand; | ||
164 | IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); | ||
165 | IMG_BOOL bPersistentProcess = IMG_FALSE; | ||
166 | #else | ||
167 | PVR_UNREFERENCED_PARAMETER(ui32CallerID); | ||
168 | PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); | ||
169 | #endif | ||
170 | |||
171 | #if defined(PDUMP) | ||
172 | |||
173 | { | ||
174 | PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); | ||
175 | if(psPerProc != IMG_NULL) | ||
176 | { | ||
177 | bPersistentProcess = psPerProc->bPDumpPersistent; | ||
178 | } | ||
179 | } | ||
180 | #endif | ||
181 | psKernelCCB = psDevInfo->psKernelCCBInfo; | ||
182 | |||
183 | psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB); | ||
184 | |||
185 | |||
186 | if(!psSGXCommand) | ||
187 | { | ||
188 | eError = PVRSRV_ERROR_TIMEOUT; | ||
189 | goto Exit; | ||
190 | } | ||
191 | |||
192 | |||
193 | psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl; | ||
194 | |||
195 | #if defined(PDUMP) | ||
196 | |||
197 | psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl; | ||
198 | #endif | ||
199 | |||
200 | |||
201 | psDevInfo->ui32CacheControl = 0; | ||
202 | |||
203 | |||
204 | *psSGXCommand = *psCommandData; | ||
205 | |||
206 | if (eCmdType >= SGXMKIF_CMD_MAX) | ||
207 | { | ||
208 | PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCmdType)) ; | ||
209 | eError = PVRSRV_ERROR_INVALID_CCB_COMMAND; | ||
210 | goto Exit; | ||
211 | } | ||
212 | |||
213 | |||
214 | SysAcquireData(&psSysData); | ||
215 | |||
216 | if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) | ||
217 | { | ||
218 | OSFlushCPUCacheKM(); | ||
219 | } | ||
220 | else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) | ||
221 | { | ||
222 | OSCleanCPUCacheKM(); | ||
223 | } | ||
224 | |||
225 | |||
226 | psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; | ||
227 | |||
228 | PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX); | ||
229 | psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType]; | ||
230 | |||
231 | #if defined(PDUMP) | ||
232 | if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && | ||
233 | (bPersistentProcess == IMG_FALSE) ) | ||
234 | { | ||
235 | |||
236 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n"); | ||
237 | PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, | ||
238 | offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), | ||
239 | (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, | ||
240 | 0xff, | ||
241 | PDUMP_POLL_OPERATOR_NOTEQUAL, | ||
242 | ui32PDumpFlags, | ||
243 | MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); | ||
244 | |||
245 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType); | ||
246 | pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND))); | ||
247 | |||
248 | PDUMPMEM(pvDumpCommand, | ||
249 | psKernelCCB->psCCBMemInfo, | ||
250 | psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND), | ||
251 | sizeof(SGXMKIF_COMMAND), | ||
252 | ui32PDumpFlags, | ||
253 | MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); | ||
254 | |||
255 | |||
256 | PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl, | ||
257 | psKernelCCB->psCCBMemInfo, | ||
258 | psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) + | ||
259 | offsetof(SGXMKIF_COMMAND, ui32CacheControl), | ||
260 | sizeof(IMG_UINT32), | ||
261 | ui32PDumpFlags, | ||
262 | MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); | ||
263 | |||
264 | if (PDumpIsCaptureFrameKM() | ||
265 | || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) | ||
266 | { | ||
267 | |||
268 | psDevInfo->sPDContext.ui32CacheControl = 0; | ||
269 | } | ||
270 | } | ||
271 | #endif | ||
272 | |||
273 | #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) | ||
274 | |||
275 | eError = PollForValueKM (psKernelCCB->pui32ReadOffset, | ||
276 | *psKernelCCB->pui32WriteOffset, | ||
277 | 0xFF, | ||
278 | MAX_HW_TIME_US/WAIT_TRY_COUNT, | ||
279 | WAIT_TRY_COUNT); | ||
280 | if (eError != PVRSRV_OK) | ||
281 | { | ||
282 | eError = PVRSRV_ERROR_TIMEOUT; | ||
283 | goto Exit; | ||
284 | } | ||
285 | #endif | ||
286 | |||
287 | |||
288 | |||
289 | *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255; | ||
290 | |||
291 | #if defined(PDUMP) | ||
292 | if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && | ||
293 | (bPersistentProcess == IMG_FALSE) ) | ||
294 | { | ||
295 | #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) | ||
296 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n"); | ||
297 | PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, | ||
298 | offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), | ||
299 | (psKernelCCB->ui32CCBDumpWOff), | ||
300 | 0xFF, | ||
301 | PDUMP_POLL_OPERATOR_EQUAL, | ||
302 | ui32PDumpFlags, | ||
303 | MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); | ||
304 | #endif | ||
305 | |||
306 | if (PDumpIsCaptureFrameKM() | ||
307 | || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) | ||
308 | { | ||
309 | psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF; | ||
310 | psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF; | ||
311 | } | ||
312 | |||
313 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n"); | ||
314 | PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, | ||
315 | psKernelCCB->psCCBCtlMemInfo, | ||
316 | offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset), | ||
317 | sizeof(IMG_UINT32), | ||
318 | ui32PDumpFlags, | ||
319 | MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); | ||
320 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n"); | ||
321 | PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, | ||
322 | psDevInfo->psKernelCCBEventKickerMemInfo, | ||
323 | 0, | ||
324 | sizeof(IMG_UINT32), | ||
325 | ui32PDumpFlags, | ||
326 | MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); | ||
327 | PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n"); | ||
328 | #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) | ||
329 | PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags); | ||
330 | #else | ||
331 | PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags); | ||
332 | #endif | ||
333 | } | ||
334 | #endif | ||
335 | |||
336 | *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; | ||
337 | |||
338 | OSWriteMemoryBarrier(); | ||
339 | |||
340 | #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) | ||
341 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, | ||
342 | SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), | ||
343 | EUR_CR_EVENT_KICK2_NOW_MASK); | ||
344 | #else | ||
345 | OSWriteHWReg(psDevInfo->pvRegsBaseKM, | ||
346 | SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), | ||
347 | EUR_CR_EVENT_KICK_NOW_MASK); | ||
348 | #endif | ||
349 | |||
350 | OSMemoryBarrier(); | ||
351 | |||
352 | #if defined(NO_HARDWARE) | ||
353 | |||
354 | *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255; | ||
355 | #endif | ||
356 | |||
357 | Exit: | ||
358 | return eError; | ||
359 | } | ||
360 | |||
361 | |||
362 | PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, | ||
363 | SGXMKIF_CMD_TYPE eCmdType, | ||
364 | SGXMKIF_COMMAND *psCommandData, | ||
365 | IMG_UINT32 ui32CallerID, | ||
366 | IMG_UINT32 ui32PDumpFlags) | ||
367 | { | ||
368 | PVRSRV_ERROR eError; | ||
369 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
370 | |||
371 | |||
372 | PDUMPSUSPEND(); | ||
373 | |||
374 | |||
375 | eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, | ||
376 | PVRSRV_DEV_POWER_STATE_ON, | ||
377 | ui32CallerID, | ||
378 | IMG_TRUE); | ||
379 | |||
380 | PDUMPRESUME(); | ||
381 | |||
382 | if (eError == PVRSRV_OK) | ||
383 | { | ||
384 | psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE; | ||
385 | } | ||
386 | else | ||
387 | { | ||
388 | if (eError == PVRSRV_ERROR_RETRY) | ||
389 | { | ||
390 | if (ui32CallerID == ISR_ID) | ||
391 | { | ||
392 | |||
393 | |||
394 | |||
395 | psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; | ||
396 | eError = PVRSRV_OK; | ||
397 | } | ||
398 | else | ||
399 | { | ||
400 | |||
401 | |||
402 | } | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " | ||
407 | "ui32CallerID:%d eError:%u", ui32CallerID, eError)); | ||
408 | } | ||
409 | |||
410 | return eError; | ||
411 | } | ||
412 | |||
413 | eError = SGXScheduleCCBCommand(psDevInfo, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags); | ||
414 | |||
415 | PVRSRVPowerUnlock(ui32CallerID); | ||
416 | |||
417 | |||
418 | if (ui32CallerID != ISR_ID) | ||
419 | { | ||
420 | |||
421 | |||
422 | |||
423 | SGXTestActivePowerEvent(psDeviceNode, ui32CallerID); | ||
424 | } | ||
425 | |||
426 | return eError; | ||
427 | } | ||
428 | |||
429 | |||
430 | PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) | ||
431 | { | ||
432 | PVRSRV_ERROR eError; | ||
433 | PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; | ||
434 | SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; | ||
435 | IMG_UINT32 ui32PowerStatus; | ||
436 | SGXMKIF_COMMAND sCommand = {0}; | ||
437 | |||
438 | ui32PowerStatus = psHostCtl->ui32PowerStatus; | ||
439 | if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) | ||
440 | { | ||
441 | |||
442 | return PVRSRV_OK; | ||
443 | } | ||
444 | |||
445 | eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0); | ||
446 | if (eError != PVRSRV_OK) | ||
447 | { | ||
448 | PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError)); | ||
449 | return eError; | ||
450 | } | ||
451 | |||
452 | return PVRSRV_OK; | ||
453 | } | ||
454 | |||
455 | |||
456 | IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode) | ||
457 | { | ||
458 | return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex); | ||
459 | } | ||
460 | |||
461 | IMG_EXPORT | ||
462 | PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, | ||
463 | SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo) | ||
464 | { | ||
465 | PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; | ||
466 | |||
467 | psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags; | ||
468 | psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff; | ||
469 | |||
470 | |||
471 | psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle = | ||
472 | (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo; | ||
473 | |||
474 | return PVRSRV_OK; | ||
475 | } | ||
476 | |||
477 | |||
478 | IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, | ||
479 | IMG_DEV_VIRTADDR *psHWDataDevVAddr, | ||
480 | IMG_UINT32 ui32CleanupType) | ||
481 | { | ||
482 | PVRSRV_ERROR eError; | ||
483 | PVRSRV_SGXDEV_INFO *psSGXDevInfo = psDeviceNode->pvDevice; | ||
484 | PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo; | ||
485 | SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM; | ||
486 | |||
487 | if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) | ||
488 | { | ||
489 | |||
490 | } | ||
491 | else | ||
492 | { | ||
493 | SGXMKIF_COMMAND sCommand = {0}; | ||
494 | |||
495 | PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resouce clean-up"); | ||
496 | sCommand.ui32Data[0] = ui32CleanupType; | ||
497 | sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr; | ||
498 | |||
499 | eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0); | ||
500 | if (eError != PVRSRV_OK) | ||
501 | { | ||
502 | PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command")); | ||
503 | PVR_DBG_BREAK; | ||
504 | } | ||
505 | |||
506 | |||
507 | #if !defined(NO_HARDWARE) | ||
508 | if(PollForValueKM(&psSGXHostCtl->ui32CleanupStatus, | ||
509 | PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, | ||
510 | PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, | ||
511 | 2 * MAX_HW_TIME_US/WAIT_TRY_COUNT, | ||
512 | WAIT_TRY_COUNT) != PVRSRV_OK) | ||
513 | { | ||
514 | PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType)); | ||
515 | PVR_DBG_BREAK; | ||
516 | } | ||
517 | #endif | ||
518 | |||
519 | #if defined(PDUMP) | ||
520 | |||
521 | PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete"); | ||
522 | PDUMPMEMPOL(psSGXHostCtlMemInfo, | ||
523 | offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), | ||
524 | PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, | ||
525 | PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, | ||
526 | PDUMP_POLL_OPERATOR_EQUAL, | ||
527 | 0, | ||
528 | MAKEUNIQUETAG(psSGXHostCtlMemInfo)); | ||
529 | #endif | ||
530 | |||
531 | psSGXHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE); | ||
532 | PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo)); | ||
533 | |||
534 | |||
535 | #if defined(SGX_FEATURE_SYSTEM_CACHE) | ||
536 | psSGXDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA); | ||
537 | #else | ||
538 | psSGXDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA; | ||
539 | #endif | ||
540 | } | ||
541 | } | ||
542 | |||
543 | |||
544 | typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ | ||
545 | { | ||
546 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
547 | IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; | ||
548 | IMG_HANDLE hBlockAlloc; | ||
549 | PRESMAN_ITEM psResItem; | ||
550 | } SGX_HW_RENDER_CONTEXT_CLEANUP; | ||
551 | |||
552 | |||
553 | static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam, | ||
554 | IMG_UINT32 ui32Param) | ||
555 | { | ||
556 | SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam; | ||
557 | |||
558 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
559 | |||
560 | SGXCleanupRequest(psCleanup->psDeviceNode, | ||
561 | &psCleanup->sHWRenderContextDevVAddr, | ||
562 | PVRSRV_CLEANUPCMD_RC); | ||
563 | |||
564 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
565 | sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), | ||
566 | psCleanup, | ||
567 | psCleanup->hBlockAlloc); | ||
568 | |||
569 | |||
570 | return PVRSRV_OK; | ||
571 | } | ||
572 | |||
573 | typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_ | ||
574 | { | ||
575 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
576 | IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; | ||
577 | IMG_HANDLE hBlockAlloc; | ||
578 | PRESMAN_ITEM psResItem; | ||
579 | } SGX_HW_TRANSFER_CONTEXT_CLEANUP; | ||
580 | |||
581 | |||
582 | static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam, | ||
583 | IMG_UINT32 ui32Param) | ||
584 | { | ||
585 | SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam; | ||
586 | |||
587 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
588 | |||
589 | SGXCleanupRequest(psCleanup->psDeviceNode, | ||
590 | &psCleanup->sHWTransferContextDevVAddr, | ||
591 | PVRSRV_CLEANUPCMD_TC); | ||
592 | |||
593 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
594 | sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), | ||
595 | psCleanup, | ||
596 | psCleanup->hBlockAlloc); | ||
597 | |||
598 | |||
599 | return PVRSRV_OK; | ||
600 | } | ||
601 | |||
602 | IMG_EXPORT | ||
603 | IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, | ||
604 | IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, | ||
605 | PVRSRV_PER_PROCESS_DATA *psPerProc) | ||
606 | { | ||
607 | PVRSRV_ERROR eError; | ||
608 | IMG_HANDLE hBlockAlloc; | ||
609 | SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; | ||
610 | PRESMAN_ITEM psResItem; | ||
611 | |||
612 | eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
613 | sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), | ||
614 | (IMG_VOID **)&psCleanup, | ||
615 | &hBlockAlloc, | ||
616 | "SGX Hardware Render Context Cleanup"); | ||
617 | |||
618 | if (eError != PVRSRV_OK) | ||
619 | { | ||
620 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure")); | ||
621 | return IMG_NULL; | ||
622 | } | ||
623 | |||
624 | psCleanup->hBlockAlloc = hBlockAlloc; | ||
625 | psCleanup->psDeviceNode = psDeviceNode; | ||
626 | psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr; | ||
627 | |||
628 | psResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
629 | RESMAN_TYPE_HW_RENDER_CONTEXT, | ||
630 | (IMG_VOID *)psCleanup, | ||
631 | 0, | ||
632 | &SGXCleanupHWRenderContextCallback); | ||
633 | |||
634 | if (psResItem == IMG_NULL) | ||
635 | { | ||
636 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed")); | ||
637 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
638 | sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), | ||
639 | psCleanup, | ||
640 | psCleanup->hBlockAlloc); | ||
641 | |||
642 | |||
643 | return IMG_NULL; | ||
644 | } | ||
645 | |||
646 | psCleanup->psResItem = psResItem; | ||
647 | |||
648 | return (IMG_HANDLE)psCleanup; | ||
649 | } | ||
650 | |||
651 | IMG_EXPORT | ||
652 | PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext) | ||
653 | { | ||
654 | PVRSRV_ERROR eError; | ||
655 | SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; | ||
656 | |||
657 | PVR_ASSERT(hHWRenderContext != IMG_NULL); | ||
658 | |||
659 | psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; | ||
660 | |||
661 | if (psCleanup == IMG_NULL) | ||
662 | { | ||
663 | PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter")); | ||
664 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
665 | } | ||
666 | |||
667 | eError = ResManFreeResByPtr(psCleanup->psResItem); | ||
668 | |||
669 | return eError; | ||
670 | } | ||
671 | |||
672 | |||
673 | IMG_EXPORT | ||
674 | IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, | ||
675 | IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, | ||
676 | PVRSRV_PER_PROCESS_DATA *psPerProc) | ||
677 | { | ||
678 | PVRSRV_ERROR eError; | ||
679 | IMG_HANDLE hBlockAlloc; | ||
680 | SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; | ||
681 | PRESMAN_ITEM psResItem; | ||
682 | |||
683 | eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
684 | sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), | ||
685 | (IMG_VOID **)&psCleanup, | ||
686 | &hBlockAlloc, | ||
687 | "SGX Hardware Transfer Context Cleanup"); | ||
688 | |||
689 | if (eError != PVRSRV_OK) | ||
690 | { | ||
691 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure")); | ||
692 | return IMG_NULL; | ||
693 | } | ||
694 | |||
695 | psCleanup->hBlockAlloc = hBlockAlloc; | ||
696 | psCleanup->psDeviceNode = psDeviceNode; | ||
697 | psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr; | ||
698 | |||
699 | psResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
700 | RESMAN_TYPE_HW_TRANSFER_CONTEXT, | ||
701 | psCleanup, | ||
702 | 0, | ||
703 | &SGXCleanupHWTransferContextCallback); | ||
704 | |||
705 | if (psResItem == IMG_NULL) | ||
706 | { | ||
707 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed")); | ||
708 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
709 | sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), | ||
710 | psCleanup, | ||
711 | psCleanup->hBlockAlloc); | ||
712 | |||
713 | |||
714 | return IMG_NULL; | ||
715 | } | ||
716 | |||
717 | psCleanup->psResItem = psResItem; | ||
718 | |||
719 | return (IMG_HANDLE)psCleanup; | ||
720 | } | ||
721 | |||
722 | IMG_EXPORT | ||
723 | PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext) | ||
724 | { | ||
725 | PVRSRV_ERROR eError; | ||
726 | SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; | ||
727 | |||
728 | PVR_ASSERT(hHWTransferContext != IMG_NULL); | ||
729 | |||
730 | psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; | ||
731 | |||
732 | if (psCleanup == IMG_NULL) | ||
733 | { | ||
734 | PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter")); | ||
735 | return PVRSRV_ERROR_INVALID_PARAMS; | ||
736 | } | ||
737 | |||
738 | eError = ResManFreeResByPtr(psCleanup->psResItem); | ||
739 | |||
740 | return eError; | ||
741 | } | ||
742 | |||
743 | #if defined(SGX_FEATURE_2D_HARDWARE) | ||
744 | typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_ | ||
745 | { | ||
746 | PVRSRV_DEVICE_NODE *psDeviceNode; | ||
747 | IMG_DEV_VIRTADDR sHW2DContextDevVAddr; | ||
748 | IMG_HANDLE hBlockAlloc; | ||
749 | PRESMAN_ITEM psResItem; | ||
750 | } SGX_HW_2D_CONTEXT_CLEANUP; | ||
751 | |||
752 | static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) | ||
753 | { | ||
754 | SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam; | ||
755 | |||
756 | PVR_UNREFERENCED_PARAMETER(ui32Param); | ||
757 | |||
758 | SGXCleanupRequest(psCleanup->psDeviceNode, | ||
759 | &psCleanup->sHW2DContextDevVAddr, | ||
760 | PVRSRV_CLEANUPCMD_2DC); | ||
761 | |||
762 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
763 | sizeof(SGX_HW_2D_CONTEXT_CLEANUP), | ||
764 | psCleanup, | ||
765 | psCleanup->hBlockAlloc); | ||
766 | |||
767 | |||
768 | return PVRSRV_OK; | ||
769 | } | ||
770 | |||
771 | IMG_EXPORT | ||
772 | IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, | ||
773 | IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, | ||
774 | PVRSRV_PER_PROCESS_DATA *psPerProc) | ||
775 | { | ||
776 | PVRSRV_ERROR eError; | ||
777 | IMG_HANDLE hBlockAlloc; | ||
778 | SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; | ||
779 | PRESMAN_ITEM psResItem; | ||
780 | |||
781 | eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
782 | sizeof(SGX_HW_2D_CONTEXT_CLEANUP), | ||
783 | (IMG_VOID **)&psCleanup, | ||
784 | &hBlockAlloc, | ||
785 | "SGX Hardware 2D Context Cleanup"); | ||
786 | |||
787 | if (eError != PVRSRV_OK) | ||
788 | { | ||
789 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure")); | ||
790 | return IMG_NULL; | ||
791 | } | ||
792 | |||
793 | psCleanup->hBlockAlloc = hBlockAlloc; | ||
794 | psCleanup->psDeviceNode = psDeviceNode; | ||
795 | psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr; | ||
796 | |||
797 | psResItem = ResManRegisterRes(psPerProc->hResManContext, | ||
798 | RESMAN_TYPE_HW_2D_CONTEXT, | ||
799 | psCleanup, | ||
800 | 0, | ||
801 | &SGXCleanupHW2DContextCallback); | ||
802 | |||
803 | if (psResItem == IMG_NULL) | ||
804 | { | ||
805 | PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed")); | ||
806 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, | ||
807 | sizeof(SGX_HW_2D_CONTEXT_CLEANUP), | ||
808 | psCleanup, | ||
809 | psCleanup->hBlockAlloc); | ||
810 | |||
811 | |||
812 | return IMG_NULL; | ||
813 | } | ||
814 | |||
815 | psCleanup->psResItem = psResItem; | ||
816 | |||
817 | return (IMG_HANDLE)psCleanup; | ||
818 | } | ||
819 | |||
820 | IMG_EXPORT | ||
821 | PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext) | ||
822 | { | ||
823 | PVRSRV_ERROR eError; | ||
824 | SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; | ||
825 | |||
826 | PVR_ASSERT(hHW2DContext != IMG_NULL); | ||
827 | |||
828 | if (hHW2DContext == IMG_NULL) | ||
829 | { | ||
830 | return (PVRSRV_ERROR_INVALID_PARAMS); | ||
831 | } | ||
832 | |||
833 | psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext; | ||
834 | |||
835 | eError = ResManFreeResByPtr(psCleanup->psResItem); | ||
836 | |||
837 | return eError; | ||
838 | } | ||
839 | #endif | ||
840 | |||
841 | #ifdef INLINE_IS_PRAGMA | ||
842 | #pragma inline(SGX2DQuerySyncOpsComplete) | ||
843 | #endif | ||
844 | static INLINE | ||
845 | IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, | ||
846 | IMG_UINT32 ui32ReadOpsPending, | ||
847 | IMG_UINT32 ui32WriteOpsPending) | ||
848 | { | ||
849 | PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; | ||
850 | |||
851 | return (IMG_BOOL)( | ||
852 | (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) && | ||
853 | (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending) | ||
854 | ); | ||
855 | } | ||
856 | |||
857 | IMG_EXPORT | ||
858 | PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
859 | PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, | ||
860 | IMG_BOOL bWaitForComplete) | ||
861 | { | ||
862 | IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending; | ||
863 | |||
864 | PVR_UNREFERENCED_PARAMETER(psDevInfo); | ||
865 | |||
866 | PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start")); | ||
867 | |||
868 | ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending; | ||
869 | ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; | ||
870 | |||
871 | if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) | ||
872 | { | ||
873 | |||
874 | PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete.")); | ||
875 | return PVRSRV_OK; | ||
876 | } | ||
877 | |||
878 | |||
879 | if (!bWaitForComplete) | ||
880 | { | ||
881 | |||
882 | PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending.")); | ||
883 | return PVRSRV_ERROR_CMD_NOT_PROCESSED; | ||
884 | } | ||
885 | |||
886 | |||
887 | PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling.")); | ||
888 | |||
889 | LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) | ||
890 | { | ||
891 | OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); | ||
892 | |||
893 | if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) | ||
894 | { | ||
895 | |||
896 | PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete.")); | ||
897 | return PVRSRV_OK; | ||
898 | } | ||
899 | |||
900 | OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); | ||
901 | } END_LOOP_UNTIL_TIMEOUT(); | ||
902 | |||
903 | |||
904 | PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); | ||
905 | |||
906 | #if defined(DEBUG) | ||
907 | { | ||
908 | PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; | ||
909 | |||
910 | PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x", | ||
911 | (IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)psSyncData)); | ||
912 | |||
913 | PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending)); | ||
914 | PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending)); | ||
915 | |||
916 | } | ||
917 | #endif | ||
918 | |||
919 | return PVRSRV_ERROR_TIMEOUT; | ||
920 | } | ||
921 | |||
922 | |||
923 | IMG_EXPORT | ||
924 | IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr) | ||
925 | { | ||
926 | PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); | ||
927 | |||
928 | SGXCleanupRequest(psDeviceNode, | ||
929 | &sHWRTDataSetDevVAddr, | ||
930 | PVRSRV_CLEANUPCMD_RT); | ||
931 | } | ||
932 | |||
933 | |||
934 | IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, | ||
935 | IMG_UINT32 ui32TimeWraps, | ||
936 | IMG_UINT32 ui32Time) | ||
937 | { | ||
938 | #if defined(EUR_CR_TIMER) | ||
939 | PVR_UNREFERENCED_PARAMETER(psDevInfo); | ||
940 | PVR_UNREFERENCED_PARAMETER(ui32TimeWraps); | ||
941 | return ui32Time; | ||
942 | #else | ||
943 | IMG_UINT64 ui64Clocks; | ||
944 | IMG_UINT32 ui32Clocksx16; | ||
945 | |||
946 | ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) + | ||
947 | (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK)); | ||
948 | ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16); | ||
949 | |||
950 | return ui32Clocksx16; | ||
951 | #endif | ||
952 | } | ||
953 | |||
954 | |||
955 | |||