~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/gpu/pvr/queue.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 *
 
3
 * Copyright (C) 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 "services_headers.h"
 
28
 
 
29
#include "lists.h"
 
30
#include "ttrace.h"
 
31
 
 
32
#define DC_NUM_COMMANDS_PER_TYPE                1
 
33
 
 
34
typedef struct _DEVICE_COMMAND_DATA_
 
35
{
 
36
        PFN_CMD_PROC                    pfnCmdProc;
 
37
        PCOMMAND_COMPLETE_DATA  apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE];
 
38
        IMG_UINT32                              ui32CCBOffset;
 
39
} DEVICE_COMMAND_DATA;
 
40
 
 
41
 
 
42
#if defined(__linux__) && defined(__KERNEL__)
 
43
 
 
44
#include "proc.h"
 
45
 
 
46
void ProcSeqShowQueue(struct seq_file *sfile,void* el)
 
47
{
 
48
        PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el;
 
49
        IMG_INT cmds = 0;
 
50
        IMG_SIZE_T ui32ReadOffset;
 
51
        IMG_SIZE_T ui32WriteOffset;
 
52
        PVRSRV_COMMAND *psCmd;
 
53
 
 
54
        if(el == PVR_PROC_SEQ_START_TOKEN)
 
55
        {
 
56
                seq_printf( sfile,
 
57
                                        "Command Queues\n"
 
58
                                        "Queue    CmdPtr      Pid Command Size DevInd  DSC  SSC  #Data ...\n");
 
59
                return;
 
60
        }
 
61
 
 
62
        ui32ReadOffset = psQueue->ui32ReadOffset;
 
63
        ui32WriteOffset = psQueue->ui32WriteOffset;
 
64
 
 
65
        while (ui32ReadOffset != ui32WriteOffset)
 
66
        {
 
67
                psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
 
68
 
 
69
                seq_printf(sfile, "%x %x  %5u  %6u  %3u  %5u   %2u   %2u    %3u  \n",
 
70
                                                        (IMG_UINTPTR_T)psQueue,
 
71
                                                        (IMG_UINTPTR_T)psCmd,
 
72
                                                        psCmd->ui32ProcessID,
 
73
                                                        psCmd->CommandType,
 
74
                                                        psCmd->uCmdSize,
 
75
                                                        psCmd->ui32DevIndex,
 
76
                                                        psCmd->ui32DstSyncCount,
 
77
                                                        psCmd->ui32SrcSyncCount,
 
78
                                                        psCmd->uDataSize);
 
79
                {
 
80
                        IMG_UINT32 i;
 
81
                        for (i = 0; i < psCmd->ui32SrcSyncCount; i++)
 
82
                        {
 
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",
 
85
                                                                        i,
 
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);
 
92
                        }
 
93
                }
 
94
 
 
95
                
 
96
                ui32ReadOffset += psCmd->uCmdSize;
 
97
                ui32ReadOffset &= psQueue->ui32QueueSize - 1;
 
98
                cmds++;
 
99
        }
 
100
 
 
101
        if (cmds == 0)
 
102
        {
 
103
                seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
 
104
        }
 
105
}
 
106
 
 
107
void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
 
108
{
 
109
        PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
 
110
        SYS_DATA *psSysData;
 
111
 
 
112
        PVR_UNREFERENCED_PARAMETER(sfile);
 
113
 
 
114
        if(!off)
 
115
        {
 
116
                return PVR_PROC_SEQ_START_TOKEN;
 
117
        }
 
118
 
 
119
 
 
120
        psSysData = SysAcquireDataNoCheck();
 
121
        if (psSysData != IMG_NULL)
 
122
        {
 
123
                for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
 
124
        }
 
125
 
 
126
        return psQueue;
 
127
}
 
128
#endif 
 
129
 
 
130
#define GET_SPACE_IN_CMDQ(psQueue)                                                                              \
 
131
        ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset)                              \
 
132
        + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
 
133
 
 
134
#define UPDATE_QUEUE_WOFF(psQueue, ui32Size)                                                    \
 
135
        (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size))  \
 
136
        & ((psQueue)->ui32QueueSize - 1);
 
137
 
 
138
#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending)                                  \
 
139
        ((ui32OpsComplete) >= (ui32OpsPending))
 
140
 
 
141
 
 
142
static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
 
143
                                                                         IMG_UINT32                             i,
 
144
                                                                         IMG_BOOL                               bIsSrc)
 
145
{
 
146
        PVRSRV_SYNC_OBJECT      *psSyncObject;
 
147
 
 
148
        psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
 
149
 
 
150
        if (psCmdCompleteData->bInUse)
 
151
        {
 
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))
 
160
        }
 
161
        else
 
162
        {
 
163
                PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
 
164
        }
 
165
}
 
166
 
 
167
 
 
168
static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
169
{
 
170
        if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
 
171
        {
 
172
                IMG_UINT32                              ui32CmdCounter, ui32SyncCounter;
 
173
                SYS_DATA                                *psSysData;
 
174
                DEVICE_COMMAND_DATA             *psDeviceCommandData;
 
175
                PCOMMAND_COMPLETE_DATA  psCmdCompleteData;
 
176
 
 
177
                SysAcquireData(&psSysData);
 
178
 
 
179
                psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex];
 
180
 
 
181
                if (psDeviceCommandData != IMG_NULL)
 
182
                {
 
183
                        for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
 
184
                        {
 
185
                                psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter];
 
186
 
 
187
                                PVR_LOG(("Flip Command Complete Data %u for display device %u:",
 
188
                                                ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex))
 
189
 
 
190
                                for (ui32SyncCounter = 0;
 
191
                                         ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount;
 
192
                                         ui32SyncCounter++)
 
193
                                {
 
194
                                        QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE);
 
195
                                }
 
196
 
 
197
                                for (ui32SyncCounter = 0;
 
198
                                         ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount;
 
199
                                         ui32SyncCounter++)
 
200
                                {
 
201
                                        QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE);
 
202
                                }
 
203
                        }
 
204
                }
 
205
                else
 
206
                {
 
207
                        PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
 
208
                }
 
209
        }
 
210
}
 
211
 
 
212
 
 
213
IMG_VOID QueueDumpDebugInfo(IMG_VOID)
 
214
{
 
215
        SYS_DATA        *psSysData;
 
216
        SysAcquireData(&psSysData);
 
217
        List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
 
218
}
 
219
 
 
220
 
 
221
static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
 
222
{
 
223
        IMG_SIZE_T ui32Temp, ui32Result = 1;
 
224
 
 
225
        if(!ui32Value)
 
226
                return 0;
 
227
 
 
228
        ui32Temp = ui32Value - 1;
 
229
        while(ui32Temp)
 
230
        {
 
231
                ui32Result <<= 1;
 
232
                ui32Temp >>= 1;
 
233
        }
 
234
 
 
235
        return ui32Result;
 
236
}
 
237
 
 
238
 
 
239
IMG_EXPORT
 
240
PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
 
241
                                                                                                         PVRSRV_QUEUE_INFO **ppsQueueInfo)
 
242
{
 
243
        PVRSRV_QUEUE_INFO       *psQueueInfo;
 
244
        IMG_SIZE_T                      ui32Power2QueueSize = NearestPower2(ui32QueueSize);
 
245
        SYS_DATA                        *psSysData;
 
246
        PVRSRV_ERROR            eError;
 
247
        IMG_HANDLE                      hMemBlock;
 
248
 
 
249
        SysAcquireData(&psSysData);
 
250
 
 
251
        
 
252
        eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
253
                                         sizeof(PVRSRV_QUEUE_INFO),
 
254
                                         (IMG_VOID **)&psQueueInfo, &hMemBlock,
 
255
                                         "Queue Info");
 
256
        if (eError != PVRSRV_OK)
 
257
        {
 
258
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
 
259
                goto ErrorExit;
 
260
        }
 
261
        OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
 
262
 
 
263
        psQueueInfo->hMemBlock[0] = hMemBlock;
 
264
        psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
 
265
 
 
266
        
 
267
        eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
268
                                         ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
 
269
                                         &psQueueInfo->pvLinQueueKM, &hMemBlock,
 
270
                                         "Command Queue");
 
271
        if (eError != PVRSRV_OK)
 
272
        {
 
273
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
 
274
                goto ErrorExit;
 
275
        }
 
276
 
 
277
        psQueueInfo->hMemBlock[1] = hMemBlock;
 
278
        psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
 
279
 
 
280
        
 
281
        PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
 
282
        PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
 
283
 
 
284
        psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
 
285
 
 
286
        
 
287
        if (psSysData->psQueueList == IMG_NULL)
 
288
        {
 
289
                eError = OSCreateResource(&psSysData->sQProcessResource);
 
290
                if (eError != PVRSRV_OK)
 
291
                {
 
292
                        goto ErrorExit;
 
293
                }
 
294
        }
 
295
 
 
296
        
 
297
        eError = OSLockResource(&psSysData->sQProcessResource,
 
298
                                                        KERNEL_ID);
 
299
        if (eError != PVRSRV_OK)
 
300
        {
 
301
                goto ErrorExit;
 
302
        }
 
303
 
 
304
        psQueueInfo->psNextKM = psSysData->psQueueList;
 
305
        psSysData->psQueueList = psQueueInfo;
 
306
 
 
307
        eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
 
308
        if (eError != PVRSRV_OK)
 
309
        {
 
310
                goto ErrorExit;
 
311
        }
 
312
 
 
313
        *ppsQueueInfo = psQueueInfo;
 
314
 
 
315
        return PVRSRV_OK;
 
316
 
 
317
ErrorExit:
 
318
 
 
319
        if(psQueueInfo)
 
320
        {
 
321
                if(psQueueInfo->pvLinQueueKM)
 
322
                {
 
323
                        OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
324
                                                psQueueInfo->ui32QueueSize,
 
325
                                                psQueueInfo->pvLinQueueKM,
 
326
                                                psQueueInfo->hMemBlock[1]);
 
327
                        psQueueInfo->pvLinQueueKM = IMG_NULL;
 
328
                }
 
329
 
 
330
                OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
331
                                        sizeof(PVRSRV_QUEUE_INFO),
 
332
                                        psQueueInfo,
 
333
                                        psQueueInfo->hMemBlock[0]);
 
334
                
 
335
        }
 
336
 
 
337
        return eError;
 
338
}
 
339
 
 
340
 
 
341
IMG_EXPORT
 
342
PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
 
343
{
 
344
        PVRSRV_QUEUE_INFO       *psQueue;
 
345
        SYS_DATA                        *psSysData;
 
346
        PVRSRV_ERROR            eError;
 
347
        IMG_BOOL                        bTimeout = IMG_TRUE;
 
348
 
 
349
        SysAcquireData(&psSysData);
 
350
 
 
351
        psQueue = psSysData->psQueueList;
 
352
 
 
353
         
 
354
        LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
 
355
        {
 
356
                if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
 
357
                {
 
358
                        bTimeout = IMG_FALSE;
 
359
                        break;
 
360
                }
 
361
                OSSleepms(1);
 
362
        } END_LOOP_UNTIL_TIMEOUT();
 
363
 
 
364
        if (bTimeout)
 
365
        {
 
366
                
 
367
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
 
368
                eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
 
369
                goto ErrorExit;
 
370
        }
 
371
 
 
372
        
 
373
        eError = OSLockResource(&psSysData->sQProcessResource,
 
374
                                                                KERNEL_ID);
 
375
        if (eError != PVRSRV_OK)
 
376
        {
 
377
                goto ErrorExit;
 
378
        }
 
379
 
 
380
        if(psQueue == psQueueInfo)
 
381
        {
 
382
                psSysData->psQueueList = psQueueInfo->psNextKM;
 
383
 
 
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),
 
391
                                        psQueueInfo,
 
392
                                        psQueueInfo->hMemBlock[0]);
 
393
                 
 
394
                psQueueInfo = IMG_NULL; 
 
395
        }
 
396
        else
 
397
        {
 
398
                while(psQueue)
 
399
                {
 
400
                        if(psQueue->psNextKM == psQueueInfo)
 
401
                        {
 
402
                                psQueue->psNextKM = psQueueInfo->psNextKM;
 
403
 
 
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),
 
411
                                                        psQueueInfo,
 
412
                                                        psQueueInfo->hMemBlock[0]);
 
413
                                 
 
414
                                psQueueInfo = IMG_NULL; 
 
415
                                break;
 
416
                        }
 
417
                        psQueue = psQueue->psNextKM;
 
418
                }
 
419
 
 
420
                if(!psQueue)
 
421
                {
 
422
                        eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
 
423
                        if (eError != PVRSRV_OK)
 
424
                        {
 
425
                                goto ErrorExit;
 
426
                        }
 
427
                        eError = PVRSRV_ERROR_INVALID_PARAMS;
 
428
                        goto ErrorExit;
 
429
                }
 
430
        }
 
431
 
 
432
        
 
433
        eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
 
434
        if (eError != PVRSRV_OK)
 
435
        {
 
436
                goto ErrorExit;
 
437
        }
 
438
 
 
439
        
 
440
        if (psSysData->psQueueList == IMG_NULL)
 
441
        {
 
442
                eError = OSDestroyResource(&psSysData->sQProcessResource);
 
443
                if (eError != PVRSRV_OK)
 
444
                {
 
445
                        goto ErrorExit;
 
446
                }
 
447
        }
 
448
 
 
449
ErrorExit:
 
450
 
 
451
        return eError;
 
452
}
 
453
 
 
454
 
 
455
IMG_EXPORT
 
456
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
 
457
                                                                                                IMG_SIZE_T ui32ParamSize,
 
458
                                                                                                IMG_VOID **ppvSpace)
 
459
{
 
460
        IMG_BOOL bTimeout = IMG_TRUE;
 
461
 
 
462
        
 
463
        ui32ParamSize =  (ui32ParamSize+3) & 0xFFFFFFFC;
 
464
 
 
465
        if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
 
466
        {
 
467
                PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
 
468
                return PVRSRV_ERROR_CMD_TOO_BIG;
 
469
        }
 
470
 
 
471
         
 
472
        LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
 
473
        {
 
474
                if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
 
475
                {
 
476
                        bTimeout = IMG_FALSE;
 
477
                        break;
 
478
                }
 
479
                OSSleepms(1);
 
480
        } END_LOOP_UNTIL_TIMEOUT();
 
481
 
 
482
        if (bTimeout == IMG_TRUE)
 
483
        {
 
484
                *ppvSpace = IMG_NULL;
 
485
 
 
486
                return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
 
487
        }
 
488
        else
 
489
        {
 
490
                *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
 
491
        }
 
492
 
 
493
        return PVRSRV_OK;
 
494
}
 
495
 
 
496
 
 
497
IMG_EXPORT
 
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 )
 
507
{
 
508
        PVRSRV_ERROR    eError;
 
509
        PVRSRV_COMMAND  *psCommand;
 
510
        IMG_SIZE_T              ui32CommandSize;
 
511
        IMG_UINT32              i;
 
512
 
 
513
        
 
514
        ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
 
515
 
 
516
        
 
517
        ui32CommandSize = sizeof(PVRSRV_COMMAND)
 
518
                                        + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
 
519
                                        + ui32DataByteSize;
 
520
 
 
521
        
 
522
        eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
 
523
        if(eError != PVRSRV_OK)
 
524
        {
 
525
                return eError;
 
526
        }
 
527
 
 
528
        psCommand->ui32ProcessID        = OSGetCurrentProcessIDKM();
 
529
 
 
530
        
 
531
        psCommand->uCmdSize             = ui32CommandSize; 
 
532
        psCommand->ui32DevIndex         = ui32DevIndex;
 
533
        psCommand->CommandType          = CommandType;
 
534
        psCommand->ui32DstSyncCount     = ui32DstSyncCount;
 
535
        psCommand->ui32SrcSyncCount     = ui32SrcSyncCount;
 
536
        
 
537
        
 
538
        psCommand->psDstSync            = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
 
539
 
 
540
 
 
541
        psCommand->psSrcSync            = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
 
542
                                                                + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
 
543
 
 
544
        psCommand->pvData                       = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
 
545
                                                                + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
 
546
        psCommand->uDataSize            = ui32DataByteSize;
 
547
 
 
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);
 
551
 
 
552
        
 
553
        for (i=0; i<ui32DstSyncCount; i++)
 
554
        {
 
555
                PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
 
556
                                                apsDstSync[i], PVRSRV_SYNCOP_SAMPLE);
 
557
 
 
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);
 
561
 
 
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));
 
567
        }
 
568
 
 
569
        
 
570
        for (i=0; i<ui32SrcSyncCount; i++)
 
571
        {
 
572
                PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
 
573
                                                apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE);
 
574
 
 
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);
 
578
 
 
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));
 
584
        }
 
585
        PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM);
 
586
 
 
587
        
 
588
        *ppsCommand = psCommand;
 
589
 
 
590
        return PVRSRV_OK;
 
591
}
 
592
 
 
593
 
 
594
IMG_EXPORT
 
595
PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
 
596
                                                                                                PVRSRV_COMMAND *psCommand)
 
597
{
 
598
        
 
599
        
 
600
        
 
601
        if (psCommand->ui32DstSyncCount > 0)
 
602
        {
 
603
                psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
 
604
                                                                        + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
 
605
        }
 
606
 
 
607
        if (psCommand->ui32SrcSyncCount > 0)
 
608
        {
 
609
                psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
 
610
                                                                        + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
 
611
                                                                        + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
 
612
        }
 
613
 
 
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)));
 
618
 
 
619
        
 
620
        UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize);
 
621
 
 
622
        return PVRSRV_OK;
 
623
}
 
624
 
 
625
 
 
626
 
 
627
static
 
628
PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA                      *psSysData,
 
629
                                                                  PVRSRV_COMMAND        *psCommand,
 
630
                                                                  IMG_BOOL                      bFlush)
 
631
{
 
632
        PVRSRV_SYNC_OBJECT              *psWalkerObj;
 
633
        PVRSRV_SYNC_OBJECT              *psEndObj;
 
634
        IMG_UINT32                              i;
 
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;
 
641
 
 
642
        
 
643
        psWalkerObj = psCommand->psDstSync;
 
644
        psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
 
645
        while (psWalkerObj < psEndObj)
 
646
        {
 
647
                PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
 
648
 
 
649
                ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
 
650
                ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
 
651
                
 
652
                if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
 
653
                ||      (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
 
654
                {
 
655
                        if (!bFlush ||
 
656
                                !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
 
657
                                !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
 
658
                        {
 
659
                                return PVRSRV_ERROR_FAILED_DEPENDENCIES;
 
660
                        }
 
661
                }
 
662
 
 
663
                psWalkerObj++;
 
664
        }
 
665
 
 
666
        
 
667
        psWalkerObj = psCommand->psSrcSync;
 
668
        psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
 
669
        while (psWalkerObj < psEndObj)
 
670
        {
 
671
                PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
 
672
 
 
673
                ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
 
674
                ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
 
675
                
 
676
                if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
 
677
                || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
 
678
                {
 
679
                        if (!bFlush &&
 
680
                                SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
 
681
                                SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
 
682
                        {
 
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));
 
686
                        }
 
687
 
 
688
                        if (!bFlush ||
 
689
                                !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
 
690
                                !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
 
691
                        {
 
692
                                return PVRSRV_ERROR_FAILED_DEPENDENCIES;
 
693
                        }
 
694
                }
 
695
                psWalkerObj++;
 
696
        }
 
697
 
 
698
        
 
699
        if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
 
700
        {
 
701
                PVR_DPF((PVR_DBG_ERROR,
 
702
                                        "PVRSRVProcessCommand: invalid DeviceType 0x%x",
 
703
                                        psCommand->ui32DevIndex));
 
704
                return PVRSRV_ERROR_INVALID_PARAMS;
 
705
        }
 
706
 
 
707
        
 
708
        psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
 
709
        ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset;
 
710
        psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset];
 
711
        if (psCmdCompleteData->bInUse)
 
712
        {
 
713
                
 
714
                return PVRSRV_ERROR_FAILED_DEPENDENCIES;
 
715
        }
 
716
 
 
717
        
 
718
        psCmdCompleteData->bInUse = IMG_TRUE;
 
719
 
 
720
        
 
721
        psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
 
722
        for (i=0; i<psCommand->ui32DstSyncCount; i++)
 
723
        {
 
724
                psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
 
725
 
 
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,
 
731
                                ui32CCBOffset));
 
732
        }
 
733
 
 
734
 
 
735
        
 
736
        psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
 
737
        for (i=0; i<psCommand->ui32SrcSyncCount; i++)
 
738
        {
 
739
                psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
 
740
 
 
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,
 
746
                                ui32CCBOffset));
 
747
        }
 
748
 
 
749
        
 
750
 
 
751
 
 
752
 
 
753
 
 
754
 
 
755
 
 
756
 
 
757
 
 
758
 
 
759
        if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData,
 
760
                                                                                                                           (IMG_UINT32)psCommand->uDataSize,
 
761
                                                                                                                           psCommand->pvData) == IMG_FALSE)
 
762
        {
 
763
                
 
764
 
 
765
 
 
766
                psCmdCompleteData->bInUse = IMG_FALSE;
 
767
                eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
 
768
        }
 
769
        
 
770
        
 
771
        psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE;
 
772
 
 
773
        return eError;
 
774
}
 
775
 
 
776
 
 
777
static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
778
{
 
779
        if (psDeviceNode->bReProcessDeviceCommandComplete &&
 
780
                psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
 
781
        {
 
782
                (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
 
783
        }
 
784
}
 
785
 
 
786
IMG_EXPORT
 
787
PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL       bFlush)
 
788
{
 
789
        PVRSRV_QUEUE_INFO       *psQueue;
 
790
        SYS_DATA                        *psSysData;
 
791
        PVRSRV_COMMAND          *psCommand;
 
792
        SysAcquireData(&psSysData);
 
793
 
 
794
        
 
795
 
 
796
        while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK)
 
797
        {
 
798
                OSWaitus(1);
 
799
        };
 
800
        
 
801
        psQueue = psSysData->psQueueList;
 
802
 
 
803
        if(!psQueue)
 
804
        {
 
805
                PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
 
806
        }
 
807
 
 
808
        if (bFlush)
 
809
        {
 
810
                PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
 
811
        }
 
812
 
 
813
        while (psQueue)
 
814
        {
 
815
                while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
 
816
                {
 
817
                        psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
 
818
 
 
819
                        if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
 
820
                        {
 
821
                                
 
822
                                UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize)
 
823
                                continue;
 
824
                        }
 
825
 
 
826
                        break;
 
827
                }
 
828
                psQueue = psQueue->psNextKM;
 
829
        }
 
830
 
 
831
        if (bFlush)
 
832
        {
 
833
                PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
 
834
        }
 
835
 
 
836
        
 
837
        List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
 
838
                                                                        &PVRSRVProcessQueues_ForEachCb);
 
839
 
 
840
        OSUnlockResource(&psSysData->sQProcessResource, ISR_ID);
 
841
 
 
842
        return PVRSRV_OK;
 
843
}
 
844
 
 
845
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
 
846
IMG_INTERNAL
 
847
IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE   hCmdCookie,
 
848
                                                                                   IMG_BOOL             bScheduleMISR)
 
849
{
 
850
        COMMAND_COMPLETE_DATA   *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
 
851
        SYS_DATA                                *psSysData;
 
852
 
 
853
        SysAcquireData(&psSysData);
 
854
 
 
855
        
 
856
        psCmdCompleteData->bInUse = IMG_FALSE;
 
857
 
 
858
        
 
859
        PVRSRVScheduleDeviceCallbacks();
 
860
 
 
861
        if(bScheduleMISR)
 
862
        {
 
863
                OSScheduleMISR(psSysData);
 
864
        }
 
865
}
 
866
 
 
867
#endif 
 
868
 
 
869
 
 
870
IMG_EXPORT
 
871
IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE     hCmdCookie,
 
872
                                                                 IMG_BOOL       bScheduleMISR)
 
873
{
 
874
        IMG_UINT32                              i;
 
875
        COMMAND_COMPLETE_DATA   *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
 
876
        SYS_DATA                                *psSysData;
 
877
 
 
878
        SysAcquireData(&psSysData);
 
879
 
 
880
        PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START,
 
881
                        QUEUE_TOKEN_COMMAND_COMPLETE);
 
882
 
 
883
        
 
884
        for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
 
885
        {
 
886
                psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
 
887
 
 
888
                PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
 
889
                                          psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
 
890
                                          PVRSRV_SYNCOP_COMPLETE);
 
891
 
 
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));
 
897
        }
 
898
 
 
899
        
 
900
        for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
 
901
        {
 
902
                psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
 
903
 
 
904
                PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
 
905
                                          psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
 
906
                                          PVRSRV_SYNCOP_COMPLETE);
 
907
 
 
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));
 
913
        }
 
914
 
 
915
        PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END,
 
916
                        QUEUE_TOKEN_COMMAND_COMPLETE);
 
917
 
 
918
        
 
919
        psCmdCompleteData->bInUse = IMG_FALSE;
 
920
 
 
921
        
 
922
        PVRSRVScheduleDeviceCallbacks();
 
923
 
 
924
        if(bScheduleMISR)
 
925
        {
 
926
                OSScheduleMISR(psSysData);
 
927
        }
 
928
}
 
929
 
 
930
 
 
931
 
 
932
 
 
933
IMG_EXPORT
 
934
PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32             ui32DevIndex,
 
935
                                                                                 PFN_CMD_PROC   *ppfnCmdProcList,
 
936
                                                                                 IMG_UINT32             ui32MaxSyncsPerCmd[][2],
 
937
                                                                                 IMG_UINT32             ui32CmdCount)
 
938
{
 
939
        SYS_DATA                                *psSysData;
 
940
        PVRSRV_ERROR                    eError;
 
941
        IMG_UINT32                              ui32CmdCounter, ui32CmdTypeCounter;
 
942
        IMG_SIZE_T                              ui32AllocSize;
 
943
        DEVICE_COMMAND_DATA             *psDeviceCommandData;
 
944
        COMMAND_COMPLETE_DATA   *psCmdCompleteData;
 
945
 
 
946
        
 
947
        if(ui32DevIndex >= SYS_DEVICE_COUNT)
 
948
        {
 
949
                PVR_DPF((PVR_DBG_ERROR,
 
950
                                        "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
 
951
                                        ui32DevIndex));
 
952
                return PVRSRV_ERROR_INVALID_PARAMS;
 
953
        }
 
954
 
 
955
        
 
956
        SysAcquireData(&psSysData);
 
957
 
 
958
        
 
959
        ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
 
960
        eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
961
                                                ui32AllocSize,
 
962
                                                (IMG_VOID **)&psDeviceCommandData, IMG_NULL,
 
963
                                                "Array of Pointers for Command Store");
 
964
        if (eError != PVRSRV_OK)
 
965
        {
 
966
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
 
967
                goto ErrorExit;
 
968
        }
 
969
 
 
970
        psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData;
 
971
 
 
972
        for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
 
973
        {
 
974
                psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter];
 
975
                psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0;
 
976
                
 
977
                for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
 
978
                {
 
979
                        
 
980
 
 
981
                        ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) 
 
982
                                                  + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]
 
983
                                                  +     ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1])
 
984
                                                  * sizeof(PVRSRV_SYNC_OBJECT));         
 
985
 
 
986
                        eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
987
                                                                ui32AllocSize,
 
988
                                                                (IMG_VOID **)&psCmdCompleteData,
 
989
                                                                IMG_NULL,
 
990
                                                                "Command Complete Data");
 
991
                        if (eError != PVRSRV_OK)
 
992
                        {
 
993
                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter));
 
994
                                goto ErrorExit;
 
995
                        }
 
996
                        
 
997
                        psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData;
 
998
                        
 
999
                        
 
1000
                        OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize);
 
1001
 
 
1002
                        
 
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]));
 
1009
 
 
1010
                        psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize;
 
1011
                }
 
1012
        }
 
1013
 
 
1014
        return PVRSRV_OK;
 
1015
 
 
1016
ErrorExit:
 
1017
 
 
1018
        
 
1019
        if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK)
 
1020
        {
 
1021
                PVR_DPF((PVR_DBG_ERROR,
 
1022
                                "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x",
 
1023
                                ui32DevIndex));
 
1024
        }
 
1025
        
 
1026
        return eError;
 
1027
}
 
1028
 
 
1029
 
 
1030
IMG_EXPORT
 
1031
PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
 
1032
                                                                           IMG_UINT32 ui32CmdCount)
 
1033
{
 
1034
        SYS_DATA                                *psSysData;
 
1035
        IMG_UINT32                              ui32CmdTypeCounter, ui32CmdCounter;
 
1036
        DEVICE_COMMAND_DATA             *psDeviceCommandData;
 
1037
        COMMAND_COMPLETE_DATA   *psCmdCompleteData;
 
1038
        IMG_SIZE_T                              ui32AllocSize;
 
1039
 
 
1040
        
 
1041
        if(ui32DevIndex >= SYS_DEVICE_COUNT)
 
1042
        {
 
1043
                PVR_DPF((PVR_DBG_ERROR,
 
1044
                                "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
 
1045
                                ui32DevIndex));
 
1046
                return PVRSRV_ERROR_INVALID_PARAMS;
 
1047
        }
 
1048
 
 
1049
        
 
1050
        SysAcquireData(&psSysData);
 
1051
 
 
1052
        psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
 
1053
        if(psDeviceCommandData != IMG_NULL)
 
1054
        {
 
1055
                for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
 
1056
                {
 
1057
                        for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
 
1058
                        {
 
1059
                                psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter];
 
1060
                                
 
1061
                                
 
1062
                                if (psCmdCompleteData != IMG_NULL)
 
1063
                                {
 
1064
                                        OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
 
1065
                                                          psCmdCompleteData, IMG_NULL);
 
1066
                                        psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
 
1067
                                }
 
1068
                        }
 
1069
                }
 
1070
 
 
1071
                
 
1072
                ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
 
1073
                OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL);
 
1074
                psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL;
 
1075
        }
 
1076
 
 
1077
        return PVRSRV_OK;
 
1078
}
 
1079