1
/**********************************************************************
3
* Copyright (C) Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18
* The full GNU General Public License is included in this distribution in
19
* the file called "COPYING".
21
* Contact Information:
22
* Imagination Technologies Ltd. <gpl-support@imgtec.com>
23
* Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25
******************************************************************************/
27
#include "services_headers.h"
32
#define DC_NUM_COMMANDS_PER_TYPE 1
34
typedef struct _DEVICE_COMMAND_DATA_
36
PFN_CMD_PROC pfnCmdProc;
37
PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE];
38
IMG_UINT32 ui32CCBOffset;
39
} DEVICE_COMMAND_DATA;
42
#if defined(__linux__) && defined(__KERNEL__)
46
void ProcSeqShowQueue(struct seq_file *sfile,void* el)
48
PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el;
50
IMG_SIZE_T ui32ReadOffset;
51
IMG_SIZE_T ui32WriteOffset;
52
PVRSRV_COMMAND *psCmd;
54
if(el == PVR_PROC_SEQ_START_TOKEN)
58
"Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
62
ui32ReadOffset = psQueue->ui32ReadOffset;
63
ui32WriteOffset = psQueue->ui32WriteOffset;
65
while (ui32ReadOffset != ui32WriteOffset)
67
psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
69
seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n",
70
(IMG_UINTPTR_T)psQueue,
76
psCmd->ui32DstSyncCount,
77
psCmd->ui32SrcSyncCount,
81
for (i = 0; i < psCmd->ui32SrcSyncCount; i++)
83
PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData;
84
seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n",
86
psCmd->psSrcSync[i].ui32ReadOpsPending,
87
psSyncData->ui32ReadOpsComplete,
88
psCmd->psSrcSync[i].ui32WriteOpsPending,
89
psSyncData->ui32WriteOpsComplete,
90
psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
91
psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr);
96
ui32ReadOffset += psCmd->uCmdSize;
97
ui32ReadOffset &= psQueue->ui32QueueSize - 1;
103
seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
107
void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
109
PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
112
PVR_UNREFERENCED_PARAMETER(sfile);
116
return PVR_PROC_SEQ_START_TOKEN;
120
psSysData = SysAcquireDataNoCheck();
121
if (psSysData != IMG_NULL)
123
for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
130
#define GET_SPACE_IN_CMDQ(psQueue) \
131
((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \
132
+ ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
134
#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
135
(psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \
136
& ((psQueue)->ui32QueueSize - 1);
138
#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
139
((ui32OpsComplete) >= (ui32OpsPending))
142
static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
146
PVRSRV_SYNC_OBJECT *psSyncObject;
148
psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
150
if (psCmdCompleteData->bInUse)
152
PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x",
153
bIsSrc ? "SRC" : "DEST", i,
154
psSyncObject[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
155
psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsPending,
156
psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete,
157
psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
158
psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
159
psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete))
163
PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
168
static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
170
if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
172
IMG_UINT32 ui32CmdCounter, ui32SyncCounter;
174
DEVICE_COMMAND_DATA *psDeviceCommandData;
175
PCOMMAND_COMPLETE_DATA psCmdCompleteData;
177
SysAcquireData(&psSysData);
179
psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex];
181
if (psDeviceCommandData != IMG_NULL)
183
for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
185
psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter];
187
PVR_LOG(("Flip Command Complete Data %u for display device %u:",
188
ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex))
190
for (ui32SyncCounter = 0;
191
ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount;
194
QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE);
197
for (ui32SyncCounter = 0;
198
ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount;
201
QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE);
207
PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
213
IMG_VOID QueueDumpDebugInfo(IMG_VOID)
216
SysAcquireData(&psSysData);
217
List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
221
static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
223
IMG_SIZE_T ui32Temp, ui32Result = 1;
228
ui32Temp = ui32Value - 1;
240
PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
241
PVRSRV_QUEUE_INFO **ppsQueueInfo)
243
PVRSRV_QUEUE_INFO *psQueueInfo;
244
IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize);
247
IMG_HANDLE hMemBlock;
249
SysAcquireData(&psSysData);
252
eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
253
sizeof(PVRSRV_QUEUE_INFO),
254
(IMG_VOID **)&psQueueInfo, &hMemBlock,
256
if (eError != PVRSRV_OK)
258
PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
261
OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
263
psQueueInfo->hMemBlock[0] = hMemBlock;
264
psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
267
eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
268
ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
269
&psQueueInfo->pvLinQueueKM, &hMemBlock,
271
if (eError != PVRSRV_OK)
273
PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
277
psQueueInfo->hMemBlock[1] = hMemBlock;
278
psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
281
PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
282
PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
284
psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
287
if (psSysData->psQueueList == IMG_NULL)
289
eError = OSCreateResource(&psSysData->sQProcessResource);
290
if (eError != PVRSRV_OK)
297
eError = OSLockResource(&psSysData->sQProcessResource,
299
if (eError != PVRSRV_OK)
304
psQueueInfo->psNextKM = psSysData->psQueueList;
305
psSysData->psQueueList = psQueueInfo;
307
eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
308
if (eError != PVRSRV_OK)
313
*ppsQueueInfo = psQueueInfo;
321
if(psQueueInfo->pvLinQueueKM)
323
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
324
psQueueInfo->ui32QueueSize,
325
psQueueInfo->pvLinQueueKM,
326
psQueueInfo->hMemBlock[1]);
327
psQueueInfo->pvLinQueueKM = IMG_NULL;
330
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
331
sizeof(PVRSRV_QUEUE_INFO),
333
psQueueInfo->hMemBlock[0]);
342
PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
344
PVRSRV_QUEUE_INFO *psQueue;
347
IMG_BOOL bTimeout = IMG_TRUE;
349
SysAcquireData(&psSysData);
351
psQueue = psSysData->psQueueList;
354
LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
356
if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
358
bTimeout = IMG_FALSE;
362
} END_LOOP_UNTIL_TIMEOUT();
367
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
368
eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
373
eError = OSLockResource(&psSysData->sQProcessResource,
375
if (eError != PVRSRV_OK)
380
if(psQueue == psQueueInfo)
382
psSysData->psQueueList = psQueueInfo->psNextKM;
384
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
385
NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
386
psQueueInfo->pvLinQueueKM,
387
psQueueInfo->hMemBlock[1]);
388
psQueueInfo->pvLinQueueKM = IMG_NULL;
389
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
390
sizeof(PVRSRV_QUEUE_INFO),
392
psQueueInfo->hMemBlock[0]);
394
psQueueInfo = IMG_NULL;
400
if(psQueue->psNextKM == psQueueInfo)
402
psQueue->psNextKM = psQueueInfo->psNextKM;
404
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
405
psQueueInfo->ui32QueueSize,
406
psQueueInfo->pvLinQueueKM,
407
psQueueInfo->hMemBlock[1]);
408
psQueueInfo->pvLinQueueKM = IMG_NULL;
409
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
410
sizeof(PVRSRV_QUEUE_INFO),
412
psQueueInfo->hMemBlock[0]);
414
psQueueInfo = IMG_NULL;
417
psQueue = psQueue->psNextKM;
422
eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
423
if (eError != PVRSRV_OK)
427
eError = PVRSRV_ERROR_INVALID_PARAMS;
433
eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
434
if (eError != PVRSRV_OK)
440
if (psSysData->psQueueList == IMG_NULL)
442
eError = OSDestroyResource(&psSysData->sQProcessResource);
443
if (eError != PVRSRV_OK)
456
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
457
IMG_SIZE_T ui32ParamSize,
460
IMG_BOOL bTimeout = IMG_TRUE;
463
ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC;
465
if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
467
PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
468
return PVRSRV_ERROR_CMD_TOO_BIG;
472
LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
474
if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
476
bTimeout = IMG_FALSE;
480
} END_LOOP_UNTIL_TIMEOUT();
482
if (bTimeout == IMG_TRUE)
484
*ppvSpace = IMG_NULL;
486
return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
490
*ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
498
PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
499
PVRSRV_COMMAND **ppsCommand,
500
IMG_UINT32 ui32DevIndex,
501
IMG_UINT16 CommandType,
502
IMG_UINT32 ui32DstSyncCount,
503
PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
504
IMG_UINT32 ui32SrcSyncCount,
505
PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
506
IMG_SIZE_T ui32DataByteSize )
509
PVRSRV_COMMAND *psCommand;
510
IMG_SIZE_T ui32CommandSize;
514
ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
517
ui32CommandSize = sizeof(PVRSRV_COMMAND)
518
+ ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
522
eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
523
if(eError != PVRSRV_OK)
528
psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
531
psCommand->uCmdSize = ui32CommandSize;
532
psCommand->ui32DevIndex = ui32DevIndex;
533
psCommand->CommandType = CommandType;
534
psCommand->ui32DstSyncCount = ui32DstSyncCount;
535
psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
538
psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
541
psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
542
+ (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
544
psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
545
+ (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
546
psCommand->uDataSize = ui32DataByteSize;
548
PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM);
549
PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE,
550
QUEUE_TOKEN_COMMAND_TYPE, CommandType);
553
for (i=0; i<ui32DstSyncCount; i++)
555
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
556
apsDstSync[i], PVRSRV_SYNCOP_SAMPLE);
558
psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
559
psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
560
psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
562
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
563
i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
564
psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
565
psCommand->psDstSync[i].ui32ReadOpsPending,
566
psCommand->psDstSync[i].ui32WriteOpsPending));
570
for (i=0; i<ui32SrcSyncCount; i++)
572
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
573
apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE);
575
psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
576
psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
577
psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
579
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
580
i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
581
psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
582
psCommand->psSrcSync[i].ui32ReadOpsPending,
583
psCommand->psSrcSync[i].ui32WriteOpsPending));
585
PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM);
588
*ppsCommand = psCommand;
595
PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
596
PVRSRV_COMMAND *psCommand)
601
if (psCommand->ui32DstSyncCount > 0)
603
psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
604
+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
607
if (psCommand->ui32SrcSyncCount > 0)
609
psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
610
+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
611
+ (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
614
psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
615
+ psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
616
+ (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
617
+ (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
620
UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize);
628
PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData,
629
PVRSRV_COMMAND *psCommand,
632
PVRSRV_SYNC_OBJECT *psWalkerObj;
633
PVRSRV_SYNC_OBJECT *psEndObj;
635
COMMAND_COMPLETE_DATA *psCmdCompleteData;
636
PVRSRV_ERROR eError = PVRSRV_OK;
637
IMG_UINT32 ui32WriteOpsComplete;
638
IMG_UINT32 ui32ReadOpsComplete;
639
DEVICE_COMMAND_DATA *psDeviceCommandData;
640
IMG_UINT32 ui32CCBOffset;
643
psWalkerObj = psCommand->psDstSync;
644
psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
645
while (psWalkerObj < psEndObj)
647
PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
649
ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
650
ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
652
if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
653
|| (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
656
!SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
657
!SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
659
return PVRSRV_ERROR_FAILED_DEPENDENCIES;
667
psWalkerObj = psCommand->psSrcSync;
668
psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
669
while (psWalkerObj < psEndObj)
671
PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
673
ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
674
ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
676
if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
677
|| (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
680
SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
681
SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
683
PVR_DPF((PVR_DBG_WARNING,
684
"PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
685
(IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
689
!SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
690
!SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
692
return PVRSRV_ERROR_FAILED_DEPENDENCIES;
699
if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
701
PVR_DPF((PVR_DBG_ERROR,
702
"PVRSRVProcessCommand: invalid DeviceType 0x%x",
703
psCommand->ui32DevIndex));
704
return PVRSRV_ERROR_INVALID_PARAMS;
708
psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
709
ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset;
710
psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset];
711
if (psCmdCompleteData->bInUse)
714
return PVRSRV_ERROR_FAILED_DEPENDENCIES;
718
psCmdCompleteData->bInUse = IMG_TRUE;
721
psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
722
for (i=0; i<psCommand->ui32DstSyncCount; i++)
724
psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
726
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
727
i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
728
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
729
psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
730
psCmdCompleteData->psDstSync[i].ui32WriteOpsPending,
736
psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
737
for (i=0; i<psCommand->ui32SrcSyncCount; i++)
739
psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
741
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
742
i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
743
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
744
psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
745
psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending,
759
if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData,
760
(IMG_UINT32)psCommand->uDataSize,
761
psCommand->pvData) == IMG_FALSE)
766
psCmdCompleteData->bInUse = IMG_FALSE;
767
eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
771
psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE;
777
static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
779
if (psDeviceNode->bReProcessDeviceCommandComplete &&
780
psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
782
(*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
787
PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush)
789
PVRSRV_QUEUE_INFO *psQueue;
791
PVRSRV_COMMAND *psCommand;
792
SysAcquireData(&psSysData);
796
while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK)
801
psQueue = psSysData->psQueueList;
805
PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
810
PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
815
while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
817
psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
819
if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
822
UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize)
828
psQueue = psQueue->psNextKM;
833
PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
837
List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
838
&PVRSRVProcessQueues_ForEachCb);
840
OSUnlockResource(&psSysData->sQProcessResource, ISR_ID);
845
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
847
IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
848
IMG_BOOL bScheduleMISR)
850
COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
853
SysAcquireData(&psSysData);
856
psCmdCompleteData->bInUse = IMG_FALSE;
859
PVRSRVScheduleDeviceCallbacks();
863
OSScheduleMISR(psSysData);
871
IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
872
IMG_BOOL bScheduleMISR)
875
COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
878
SysAcquireData(&psSysData);
880
PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START,
881
QUEUE_TOKEN_COMMAND_COMPLETE);
884
for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
886
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
888
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
889
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
890
PVRSRV_SYNCOP_COMPLETE);
892
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
893
i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
894
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
895
psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
896
psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
900
for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
902
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
904
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
905
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
906
PVRSRV_SYNCOP_COMPLETE);
908
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
909
i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
910
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
911
psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
912
psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
915
PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END,
916
QUEUE_TOKEN_COMMAND_COMPLETE);
919
psCmdCompleteData->bInUse = IMG_FALSE;
922
PVRSRVScheduleDeviceCallbacks();
926
OSScheduleMISR(psSysData);
934
PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
935
PFN_CMD_PROC *ppfnCmdProcList,
936
IMG_UINT32 ui32MaxSyncsPerCmd[][2],
937
IMG_UINT32 ui32CmdCount)
941
IMG_UINT32 ui32CmdCounter, ui32CmdTypeCounter;
942
IMG_SIZE_T ui32AllocSize;
943
DEVICE_COMMAND_DATA *psDeviceCommandData;
944
COMMAND_COMPLETE_DATA *psCmdCompleteData;
947
if(ui32DevIndex >= SYS_DEVICE_COUNT)
949
PVR_DPF((PVR_DBG_ERROR,
950
"PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
952
return PVRSRV_ERROR_INVALID_PARAMS;
956
SysAcquireData(&psSysData);
959
ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
960
eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
962
(IMG_VOID **)&psDeviceCommandData, IMG_NULL,
963
"Array of Pointers for Command Store");
964
if (eError != PVRSRV_OK)
966
PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
970
psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData;
972
for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
974
psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter];
975
psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0;
977
for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
981
ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
982
+ ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]
983
+ ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1])
984
* sizeof(PVRSRV_SYNC_OBJECT));
986
eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
988
(IMG_VOID **)&psCmdCompleteData,
990
"Command Complete Data");
991
if (eError != PVRSRV_OK)
993
PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter));
997
psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData;
1000
OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize);
1003
psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
1004
(((IMG_UINTPTR_T)psCmdCompleteData)
1005
+ sizeof(COMMAND_COMPLETE_DATA));
1006
psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
1007
(((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
1008
+ (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]));
1010
psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize;
1019
if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK)
1021
PVR_DPF((PVR_DBG_ERROR,
1022
"PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x",
1031
PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
1032
IMG_UINT32 ui32CmdCount)
1034
SYS_DATA *psSysData;
1035
IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter;
1036
DEVICE_COMMAND_DATA *psDeviceCommandData;
1037
COMMAND_COMPLETE_DATA *psCmdCompleteData;
1038
IMG_SIZE_T ui32AllocSize;
1041
if(ui32DevIndex >= SYS_DEVICE_COUNT)
1043
PVR_DPF((PVR_DBG_ERROR,
1044
"PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
1046
return PVRSRV_ERROR_INVALID_PARAMS;
1050
SysAcquireData(&psSysData);
1052
psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
1053
if(psDeviceCommandData != IMG_NULL)
1055
for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
1057
for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
1059
psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter];
1062
if (psCmdCompleteData != IMG_NULL)
1064
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
1065
psCmdCompleteData, IMG_NULL);
1066
psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
1072
ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
1073
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL);
1074
psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL;