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