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

« back to all changes in this revision

Viewing changes to drivers/gpu/pvr/pvrsrv.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 <linux/slab.h>
 
28
#include "services_headers.h"
 
29
#include "buffer_manager.h"
 
30
#include "pvr_bridge_km.h"
 
31
#include "handle.h"
 
32
#include "perproc.h"
 
33
#include "pdump_km.h"
 
34
#include "deviceid.h"
 
35
#include "ra.h"
 
36
#if defined(TTRACE)
 
37
#include "ttrace.h"
 
38
#endif
 
39
 
 
40
#include "pvrversion.h"
 
41
 
 
42
#include "lists.h"
 
43
 
 
44
IMG_UINT32      g_ui32InitFlags;
 
45
 
 
46
#define         INIT_DATA_ENABLE_PDUMPINIT      0x1U
 
47
#define         INIT_DATA_ENABLE_TTARCE         0x2U
 
48
 
 
49
PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
 
50
{
 
51
        SYS_DEVICE_ID* psDeviceWalker;
 
52
        SYS_DEVICE_ID* psDeviceEnd;
 
53
 
 
54
        if (!psSysData) {
 
55
                pr_err("NULL psSysData\n");
 
56
                WARN_ON(1);
 
57
                return -1;
 
58
        }
 
59
 
 
60
        psDeviceWalker = &psSysData->sDeviceID[0];
 
61
        psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
 
62
 
 
63
        
 
64
        while (psDeviceWalker < psDeviceEnd)
 
65
        {
 
66
                if (!psDeviceWalker->bInUse)
 
67
                {
 
68
                        psDeviceWalker->bInUse = IMG_TRUE;
 
69
                        *pui32DevID = psDeviceWalker->uiID;
 
70
                        return PVRSRV_OK;
 
71
                }
 
72
                psDeviceWalker++;
 
73
        }
 
74
 
 
75
        PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
 
76
 
 
77
        
 
78
        PVR_ASSERT(psDeviceWalker < psDeviceEnd);
 
79
 
 
80
        return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
 
81
}
 
82
 
 
83
 
 
84
PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
 
85
{
 
86
        SYS_DEVICE_ID* psDeviceWalker;
 
87
        SYS_DEVICE_ID* psDeviceEnd;
 
88
 
 
89
        psDeviceWalker = &psSysData->sDeviceID[0];
 
90
        psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
 
91
 
 
92
        
 
93
        while (psDeviceWalker < psDeviceEnd)
 
94
        {
 
95
                
 
96
                if      (
 
97
                                (psDeviceWalker->uiID == ui32DevID) &&
 
98
                                (psDeviceWalker->bInUse)
 
99
                        )
 
100
                {
 
101
                        psDeviceWalker->bInUse = IMG_FALSE;
 
102
                        return PVRSRV_OK;
 
103
                }
 
104
                psDeviceWalker++;
 
105
        }
 
106
 
 
107
        PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
 
108
 
 
109
        
 
110
        PVR_ASSERT(psDeviceWalker < psDeviceEnd);
 
111
 
 
112
        return PVRSRV_ERROR_INVALID_DEVICEID;
 
113
}
 
114
 
 
115
 
 
116
#ifndef ReadHWReg
 
117
IMG_EXPORT
 
118
IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
 
119
{
 
120
        return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
 
121
}
 
122
#endif
 
123
 
 
124
 
 
125
#ifndef WriteHWReg
 
126
IMG_EXPORT
 
127
IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
 
128
{
 
129
        PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
 
130
                        (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
 
131
 
 
132
        *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
 
133
}
 
134
#endif
 
135
 
 
136
 
 
137
#ifndef WriteHWRegs
 
138
IMG_EXPORT
 
139
IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
 
140
{
 
141
        while (ui32Count)
 
142
        {
 
143
                WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
 
144
                psHWRegs++;
 
145
                ui32Count--;
 
146
        }
 
147
}
 
148
#endif
 
149
 
 
150
static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
 
151
{
 
152
        IMG_UINT *pui32DevCount;
 
153
        PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
 
154
 
 
155
        pui32DevCount = va_arg(va, IMG_UINT*);
 
156
        ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
 
157
 
 
158
        if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
 
159
        {
 
160
                *(*ppsDevIdList) = psDeviceNode->sDevId;
 
161
                (*ppsDevIdList)++;
 
162
                (*pui32DevCount)++;
 
163
        }
 
164
}
 
165
 
 
166
 
 
167
 
 
168
IMG_EXPORT
 
169
PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
 
170
                                                                                                   PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
 
171
{
 
172
        SYS_DATA                        *psSysData;
 
173
        IMG_UINT32                      i;
 
174
 
 
175
        if (!pui32NumDevices || !psDevIdList)
 
176
        {
 
177
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
 
178
                return PVRSRV_ERROR_INVALID_PARAMS;
 
179
        }
 
180
 
 
181
        SysAcquireData(&psSysData);
 
182
 
 
183
        
 
184
 
 
185
        for (i=0; i<PVRSRV_MAX_DEVICES; i++)
 
186
        {
 
187
                psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
 
188
        }
 
189
 
 
190
        
 
191
        *pui32NumDevices = 0;
 
192
 
 
193
        
 
194
 
 
195
 
 
196
 
 
197
        List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
 
198
                                                                           &PVRSRVEnumerateDevicesKM_ForEachVaCb,
 
199
                                                                           pui32NumDevices,
 
200
                                                                           &psDevIdList);
 
201
 
 
202
 
 
203
        return PVRSRV_OK;
 
204
}
 
205
 
 
206
 
 
207
PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
 
208
{
 
209
        PVRSRV_ERROR    eError;
 
210
 
 
211
        
 
212
        eError = ResManInit();
 
213
        if (eError != PVRSRV_OK)
 
214
        {
 
215
                goto Error;
 
216
        }
 
217
 
 
218
        eError = PVRSRVPerProcessDataInit();
 
219
        if(eError != PVRSRV_OK)
 
220
        {
 
221
                goto Error;
 
222
        }
 
223
 
 
224
        
 
225
        eError = PVRSRVHandleInit();
 
226
        if(eError != PVRSRV_OK)
 
227
        {
 
228
                goto Error;
 
229
        }
 
230
 
 
231
        
 
232
        eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
 
233
        if (eError != PVRSRV_OK)
 
234
        {
 
235
                goto Error;
 
236
        }
 
237
 
 
238
        
 
239
        psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
 
240
        psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
 
241
 
 
242
        
 
243
        if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
 
244
                                         sizeof(PVRSRV_EVENTOBJECT) ,
 
245
                                         (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
 
246
                                         "Event Object") != PVRSRV_OK)
 
247
        {
 
248
 
 
249
                goto Error;
 
250
        }
 
251
 
 
252
        if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
 
253
        {
 
254
                goto Error;
 
255
        }
 
256
 
 
257
        
 
258
        psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
 
259
        psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
 
260
        psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
 
261
 
 
262
#if defined(TTRACE)
 
263
        eError = PVRSRVTimeTraceInit();
 
264
        if (eError != PVRSRV_OK)
 
265
                goto Error;
 
266
        g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE;
 
267
#endif
 
268
 
 
269
        
 
270
        PDUMPINIT();
 
271
        g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
 
272
 
 
273
        return eError;
 
274
 
 
275
Error:
 
276
        PVRSRVDeInit(psSysData);
 
277
        return eError;
 
278
}
 
279
 
 
280
 
 
281
 
 
282
IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
 
283
{
 
284
        PVRSRV_ERROR    eError;
 
285
 
 
286
        PVR_UNREFERENCED_PARAMETER(psSysData);
 
287
 
 
288
        if (psSysData == IMG_NULL)
 
289
        {
 
290
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
 
291
                return;
 
292
        }
 
293
#if defined(TTRACE)
 
294
        
 
295
        if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0)
 
296
        {
 
297
                PVRSRVTimeTraceDeinit();
 
298
        }
 
299
#endif
 
300
        
 
301
        if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
 
302
        {
 
303
                PDUMPDEINIT();
 
304
        }
 
305
        
 
306
        
 
307
        if(psSysData->psGlobalEventObject)
 
308
        {
 
309
                OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
 
310
                OSFreeMem( PVRSRV_PAGEABLE_SELECT,
 
311
                                                 sizeof(PVRSRV_EVENTOBJECT),
 
312
                                                 psSysData->psGlobalEventObject,
 
313
                                                 0);
 
314
                psSysData->psGlobalEventObject = IMG_NULL;
 
315
        }
 
316
 
 
317
        eError = PVRSRVHandleDeInit();
 
318
        if (eError != PVRSRV_OK)
 
319
        {
 
320
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
 
321
        }
 
322
 
 
323
        eError = PVRSRVPerProcessDataDeInit();
 
324
        if (eError != PVRSRV_OK)
 
325
        {
 
326
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
 
327
        }
 
328
 
 
329
        ResManDeInit();
 
330
}
 
331
 
 
332
 
 
333
PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
 
334
                                                                                          PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
 
335
                                                                                          IMG_UINT32 ui32SOCInterruptBit,
 
336
                                                                                          IMG_UINT32 *pui32DeviceIndex)
 
337
{
 
338
        PVRSRV_ERROR            eError;
 
339
        PVRSRV_DEVICE_NODE      *psDeviceNode;
 
340
 
 
341
        
 
342
        if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
 
343
                                         sizeof(PVRSRV_DEVICE_NODE),
 
344
                                         (IMG_VOID **)&psDeviceNode, IMG_NULL,
 
345
                                         "Device Node") != PVRSRV_OK)
 
346
        {
 
347
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
 
348
                return (PVRSRV_ERROR_OUT_OF_MEMORY);
 
349
        }
 
350
        OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
 
351
 
 
352
        eError = pfnRegisterDevice(psDeviceNode);
 
353
        if (eError != PVRSRV_OK)
 
354
        {
 
355
                OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
356
                                        sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
 
357
                
 
358
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
 
359
                return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
 
360
        }
 
361
 
 
362
        
 
363
 
 
364
 
 
365
 
 
366
 
 
367
        psDeviceNode->ui32RefCount = 1;
 
368
        psDeviceNode->psSysData = psSysData;
 
369
        psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
 
370
 
 
371
        
 
372
        AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
 
373
 
 
374
        
 
375
        List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
 
376
 
 
377
        
 
378
        *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
 
379
 
 
380
        return PVRSRV_OK;
 
381
}
 
382
 
 
383
 
 
384
PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
 
385
{
 
386
        PVRSRV_DEVICE_NODE      *psDeviceNode;
 
387
        SYS_DATA                        *psSysData;
 
388
        PVRSRV_ERROR            eError;
 
389
 
 
390
        PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
 
391
 
 
392
        SysAcquireData(&psSysData);
 
393
 
 
394
        
 
395
        psDeviceNode = (PVRSRV_DEVICE_NODE*)
 
396
                                         List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
 
397
                                                                                                        &MatchDeviceKM_AnyVaCb,
 
398
                                                                                                        ui32DevIndex,
 
399
                                                                                                        IMG_TRUE);
 
400
        if(!psDeviceNode)
 
401
        {
 
402
                
 
403
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
 
404
                return PVRSRV_ERROR_INIT_FAILURE;
 
405
        }
 
406
        PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
 
407
 
 
408
        
 
409
 
 
410
        eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
 
411
        if (eError != PVRSRV_OK)
 
412
        {
 
413
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
 
414
                return eError;
 
415
        }
 
416
 
 
417
        
 
418
        if(psDeviceNode->pfnInitDevice != IMG_NULL)
 
419
        {
 
420
                eError = psDeviceNode->pfnInitDevice(psDeviceNode);
 
421
                if (eError != PVRSRV_OK)
 
422
                {
 
423
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
 
424
                        return eError;
 
425
                }
 
426
        }
 
427
 
 
428
        return PVRSRV_OK;
 
429
}
 
430
 
 
431
 
 
432
static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
433
{
 
434
        PVRSRV_ERROR eError;
 
435
        eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
 
436
                                                                                 PVRSRV_DEV_POWER_STATE_DEFAULT,
 
437
                                                                                 KERNEL_ID, IMG_FALSE);
 
438
        if (eError != PVRSRV_OK)
 
439
        {
 
440
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
 
441
        }
 
442
        return eError;
 
443
}
 
444
 
 
445
static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
446
{
 
447
        PVRSRV_ERROR eError;
 
448
        eError = PVRSRVDevInitCompatCheck(psDeviceNode);
 
449
        if (eError != PVRSRV_OK)
 
450
        {
 
451
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
 
452
        }
 
453
        return eError;
 
454
}
 
455
 
 
456
 
 
457
PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
 
458
{
 
459
        SYS_DATA                *psSysData;
 
460
        PVRSRV_ERROR            eError;
 
461
 
 
462
        PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
 
463
 
 
464
        SysAcquireData(&psSysData);
 
465
 
 
466
        if (bInitSuccessful)
 
467
        {
 
468
                eError = SysFinalise();
 
469
                if (eError != PVRSRV_OK)
 
470
                {
 
471
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
 
472
                        return eError;
 
473
                }
 
474
 
 
475
                
 
476
                eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
 
477
                                                                                                                &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
 
478
                if (eError != PVRSRV_OK)
 
479
                {
 
480
                        return eError;
 
481
                }
 
482
 
 
483
                
 
484
                eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
 
485
                                                                                                        &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
 
486
                if (eError != PVRSRV_OK)
 
487
                {
 
488
                        return eError;
 
489
                }
 
490
        }
 
491
 
 
492
        
 
493
 
 
494
 
 
495
 
 
496
        PDUMPENDINITPHASE();
 
497
 
 
498
        return PVRSRV_OK;
 
499
}
 
500
 
 
501
 
 
502
PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
 
503
{
 
504
        
 
505
        if (psDeviceNode->pfnInitDeviceCompatCheck)
 
506
                return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
 
507
        else
 
508
                return PVRSRV_OK;
 
509
}
 
510
 
 
511
static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
 
512
{
 
513
        PVRSRV_DEVICE_TYPE eDeviceType;
 
514
        IMG_UINT32 ui32DevIndex;
 
515
 
 
516
        eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
 
517
        ui32DevIndex = va_arg(va, IMG_UINT32);
 
518
 
 
519
        if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
 
520
                psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
 
521
                (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
 
522
                 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
 
523
        {
 
524
                return psDeviceNode;
 
525
        }
 
526
        else
 
527
        {
 
528
                return IMG_NULL;
 
529
        }
 
530
}
 
531
 
 
532
IMG_EXPORT
 
533
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32                 ui32DevIndex,
 
534
                                                                                                         PVRSRV_DEVICE_TYPE     eDeviceType,
 
535
                                                                                                         IMG_HANDLE                     *phDevCookie)
 
536
{
 
537
        PVRSRV_DEVICE_NODE      *psDeviceNode;
 
538
        SYS_DATA                        *psSysData;
 
539
 
 
540
        PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
 
541
 
 
542
        SysAcquireData(&psSysData);
 
543
 
 
544
        
 
545
        psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
 
546
                                                                                                &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
 
547
                                                                                                eDeviceType,
 
548
                                                                                                ui32DevIndex);
 
549
 
 
550
 
 
551
        if (!psDeviceNode)
 
552
        {
 
553
                
 
554
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
 
555
                return PVRSRV_ERROR_INIT_FAILURE;
 
556
        }
 
557
 
 
558
        PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
 
559
 
 
560
        
 
561
        if (phDevCookie)
 
562
        {
 
563
                *phDevCookie = (IMG_HANDLE)psDeviceNode;
 
564
        }
 
565
 
 
566
        return PVRSRV_OK;
 
567
}
 
568
 
 
569
 
 
570
PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
 
571
{
 
572
        PVRSRV_DEVICE_NODE      *psDeviceNode;
 
573
        SYS_DATA                        *psSysData;
 
574
        PVRSRV_ERROR            eError;
 
575
 
 
576
        SysAcquireData(&psSysData);
 
577
 
 
578
        psDeviceNode = (PVRSRV_DEVICE_NODE*)
 
579
                                         List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
 
580
                                                                                                        &MatchDeviceKM_AnyVaCb,
 
581
                                                                                                        ui32DevIndex,
 
582
                                                                                                        IMG_TRUE);
 
583
 
 
584
        if (!psDeviceNode)
 
585
        {
 
586
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
 
587
                return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
 
588
        }
 
589
 
 
590
        
 
591
 
 
592
        eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
 
593
                                                                                 PVRSRV_DEV_POWER_STATE_OFF,
 
594
                                                                                 KERNEL_ID,
 
595
                                                                                 IMG_FALSE);
 
596
        if (eError != PVRSRV_OK)
 
597
        {
 
598
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
 
599
                return eError;
 
600
        }
 
601
 
 
602
        
 
603
 
 
604
        eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
 
605
                                                                         RESMAN_CRITERIA_RESTYPE,
 
606
                                                                         RESMAN_TYPE_DEVICEMEM_ALLOCATION,
 
607
                                                                         IMG_NULL, 0);
 
608
        if (eError != PVRSRV_OK)
 
609
        {
 
610
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
 
611
                return eError;
 
612
        }
 
613
 
 
614
        
 
615
 
 
616
        if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
 
617
        {
 
618
                eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
 
619
                if (eError != PVRSRV_OK)
 
620
                {
 
621
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
 
622
                        return eError;
 
623
                }
 
624
        }
 
625
 
 
626
        
 
627
 
 
628
        PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
 
629
        psDeviceNode->hResManContext = IMG_NULL;
 
630
 
 
631
        
 
632
        List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
 
633
 
 
634
        
 
635
        (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
 
636
        OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
 
637
                                sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
 
638
        
 
639
 
 
640
        return (PVRSRV_OK);
 
641
}
 
642
 
 
643
 
 
644
IMG_EXPORT
 
645
PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32*  pui32LinMemAddr,
 
646
                                                                                  IMG_UINT32                    ui32Value,
 
647
                                                                                  IMG_UINT32                    ui32Mask,
 
648
                                                                                  IMG_UINT32                    ui32Timeoutus,
 
649
                                                                                  IMG_UINT32                    ui32PollPeriodus,
 
650
                                                                                  IMG_BOOL                              bAllowPreemption)
 
651
{
 
652
        {
 
653
                IMG_UINT32      ui32ActualValue = 0xFFFFFFFFU; 
 
654
 
 
655
                if (bAllowPreemption)
 
656
                {
 
657
                        PVR_ASSERT(ui32PollPeriodus >= 1000);
 
658
                }
 
659
 
 
660
                 
 
661
                LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
 
662
                {
 
663
                        ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
 
664
                        if(ui32ActualValue == ui32Value)
 
665
                        {
 
666
                                return PVRSRV_OK;
 
667
                        }
 
668
                        
 
669
                        if (bAllowPreemption)
 
670
                        {
 
671
                                OSSleepms(ui32PollPeriodus / 1000);
 
672
                        }
 
673
                        else
 
674
                        {
 
675
                                OSWaitus(ui32PollPeriodus);
 
676
                        }
 
677
                } END_LOOP_UNTIL_TIMEOUT();
 
678
        
 
679
                PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
 
680
                                ui32Value, ui32ActualValue, ui32Mask));
 
681
        }
 
682
 
 
683
        return PVRSRV_ERROR_TIMEOUT;
 
684
}
 
685
 
 
686
 
 
687
static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
 
688
{
 
689
        IMG_CHAR **ppszStr;
 
690
        IMG_UINT32 *pui32StrLen;
 
691
        IMG_UINT32 ui32Mode;
 
692
        PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
 
693
 
 
694
        ppszStr = va_arg(va, IMG_CHAR**);
 
695
        pui32StrLen = va_arg(va, IMG_UINT32*);
 
696
        ui32Mode = va_arg(va, IMG_UINT32);
 
697
 
 
698
        
 
699
        switch(ui32Mode)
 
700
        {
 
701
                case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
 
702
                        pfnGetStats = &RA_GetStats;
 
703
                        break;
 
704
                case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
 
705
                        pfnGetStats = &RA_GetStatsFreeMem;
 
706
                        break;
 
707
                default:
 
708
                        return;
 
709
        }
 
710
 
 
711
        if(psBMHeap->pImportArena)
 
712
        {
 
713
                pfnGetStats(psBMHeap->pImportArena,
 
714
                                        ppszStr,
 
715
                                        pui32StrLen);
 
716
        }
 
717
 
 
718
        if(psBMHeap->pVMArena)
 
719
        {
 
720
                pfnGetStats(psBMHeap->pVMArena,
 
721
                                        ppszStr,
 
722
                                        pui32StrLen);
 
723
        }
 
724
}
 
725
 
 
726
static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
 
727
{
 
728
 
 
729
        IMG_UINT32 *pui32StrLen;
 
730
        IMG_INT32 *pi32Count;
 
731
        IMG_CHAR **ppszStr;
 
732
        IMG_UINT32 ui32Mode;
 
733
 
 
734
        pui32StrLen = va_arg(va, IMG_UINT32*);
 
735
        pi32Count = va_arg(va, IMG_INT32*);
 
736
        ppszStr = va_arg(va, IMG_CHAR**);
 
737
        ui32Mode = va_arg(va, IMG_UINT32);
 
738
 
 
739
        CHECK_SPACE(*pui32StrLen);
 
740
        *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
 
741
                                                        (IMG_HANDLE)psBMContext);
 
742
        UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
 
743
 
 
744
        List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
 
745
                                                        &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
 
746
                                                        ppszStr,
 
747
                                                        pui32StrLen,
 
748
                                                        ui32Mode);
 
749
        return PVRSRV_OK;
 
750
}
 
751
 
 
752
 
 
753
static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
 
754
{
 
755
        IMG_UINT32 *pui32StrLen;
 
756
        IMG_INT32 *pi32Count;
 
757
        IMG_CHAR **ppszStr;
 
758
        IMG_UINT32 ui32Mode;
 
759
 
 
760
        pui32StrLen = va_arg(va, IMG_UINT32*);
 
761
        pi32Count = va_arg(va, IMG_INT32*);
 
762
        ppszStr = va_arg(va, IMG_CHAR**);
 
763
        ui32Mode = va_arg(va, IMG_UINT32);
 
764
 
 
765
        CHECK_SPACE(*pui32StrLen);
 
766
        *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
 
767
        UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
 
768
 
 
769
        
 
770
        if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
 
771
        {
 
772
                CHECK_SPACE(*pui32StrLen);
 
773
                *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
 
774
                UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
 
775
 
 
776
                List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
 
777
                                                                &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
 
778
                                                                ppszStr,
 
779
                                                                pui32StrLen,
 
780
                                                                ui32Mode);
 
781
        }
 
782
 
 
783
        
 
784
        return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
 
785
                                                                                                &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
 
786
                                                                                                pui32StrLen,
 
787
                                                                                                pi32Count,
 
788
                                                                                                ppszStr,
 
789
                                                                                                ui32Mode);
 
790
}
 
791
 
 
792
 
 
793
IMG_EXPORT
 
794
#if defined (SUPPORT_SID_INTERFACE)
 
795
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo)
 
796
#else
 
797
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
 
798
#endif
 
799
{
 
800
        SYS_DATA *psSysData;
 
801
 
 
802
        if(!psMiscInfo)
 
803
        {
 
804
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
 
805
                return PVRSRV_ERROR_INVALID_PARAMS;
 
806
        }
 
807
 
 
808
        psMiscInfo->ui32StatePresent = 0;
 
809
 
 
810
        
 
811
        if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
 
812
                                                                                |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
 
813
                                                                                |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
 
814
                                                                                |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
 
815
                                                                                |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
 
816
                                                                                |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
 
817
                                                                                |PVRSRV_MISC_INFO_RESET_PRESENT
 
818
                                                                                |PVRSRV_MISC_INFO_FREEMEM_PRESENT))
 
819
        {
 
820
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
 
821
                return PVRSRV_ERROR_INVALID_PARAMS;
 
822
        }
 
823
 
 
824
        SysAcquireData(&psSysData);
 
825
 
 
826
        
 
827
        if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
 
828
                (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
 
829
        {
 
830
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
 
831
                psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
 
832
                psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
 
833
        }
 
834
        else
 
835
        {
 
836
                psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
 
837
                psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
 
838
        }
 
839
 
 
840
        
 
841
        if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
 
842
                (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
 
843
        {
 
844
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
 
845
                psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
 
846
                psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
 
847
        }
 
848
 
 
849
        
 
850
        if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
 
851
                (psMiscInfo->pszMemoryStr != IMG_NULL))
 
852
        {
 
853
                RA_ARENA                        **ppArena;
 
854
                IMG_CHAR                        *pszStr;
 
855
                IMG_UINT32                      ui32StrLen;
 
856
                IMG_INT32                       i32Count;
 
857
 
 
858
                pszStr = psMiscInfo->pszMemoryStr;
 
859
                ui32StrLen = psMiscInfo->ui32MemoryStrLen;
 
860
 
 
861
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
 
862
 
 
863
                
 
864
                ppArena = &psSysData->apsLocalDevMemArena[0];
 
865
                while(*ppArena)
 
866
                {
 
867
                        CHECK_SPACE(ui32StrLen);
 
868
                        i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
 
869
                        UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
 
870
 
 
871
                        RA_GetStats(*ppArena,
 
872
                                                        &pszStr,
 
873
                                                        &ui32StrLen);
 
874
                        
 
875
                        ppArena++;
 
876
                }
 
877
 
 
878
                
 
879
                
 
880
                List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
 
881
                                                                                                        &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
 
882
                                                                                                        &ui32StrLen,
 
883
                                                                                                        &i32Count,
 
884
                                                                                                        &pszStr,
 
885
                                                                                                        PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
 
886
 
 
887
                
 
888
                i32Count = OSSNPrintf(pszStr, 100, "\n");
 
889
                UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
 
890
        }
 
891
 
 
892
        
 
893
        if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
 
894
                && psMiscInfo->pszMemoryStr)
 
895
        {
 
896
                IMG_CHAR                        *pszStr;
 
897
                IMG_UINT32                      ui32StrLen;
 
898
                IMG_INT32                       i32Count;
 
899
                
 
900
                pszStr = psMiscInfo->pszMemoryStr;
 
901
                ui32StrLen = psMiscInfo->ui32MemoryStrLen;
 
902
  
 
903
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
 
904
 
 
905
                
 
906
                List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
 
907
                                                                                                        &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
 
908
                                                                                                        &ui32StrLen,
 
909
                                                                                                        &i32Count,
 
910
                                                                                                        &pszStr,
 
911
                                                                                                        PVRSRV_MISC_INFO_FREEMEM_PRESENT);
 
912
                
 
913
                i32Count = OSSNPrintf(pszStr, 100, "\n");
 
914
                UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
 
915
        }
 
916
 
 
917
        if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
 
918
                (psSysData->psGlobalEventObject != IMG_NULL))
 
919
        {
 
920
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
 
921
                psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
 
922
        }
 
923
 
 
924
        
 
925
 
 
926
        if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
 
927
                && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
 
928
                && (psMiscInfo->pszMemoryStr != IMG_NULL))
 
929
        {
 
930
                IMG_CHAR        *pszStr;
 
931
                IMG_UINT32      ui32StrLen;
 
932
                IMG_UINT32      ui32LenStrPerNum = 12; 
 
933
                IMG_INT32       i32Count;
 
934
                IMG_INT i;
 
935
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
 
936
 
 
937
                
 
938
                psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
 
939
                psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
 
940
                psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
 
941
                psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
 
942
 
 
943
                pszStr = psMiscInfo->pszMemoryStr;
 
944
                ui32StrLen = psMiscInfo->ui32MemoryStrLen;
 
945
 
 
946
                for (i=0; i<4; i++)
 
947
                {
 
948
                        if (ui32StrLen < ui32LenStrPerNum)
 
949
                        {
 
950
                                return PVRSRV_ERROR_INVALID_PARAMS;
 
951
                        }
 
952
 
 
953
                        i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
 
954
                        UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
 
955
                        if (i != 3)
 
956
                        {
 
957
                                i32Count = OSSNPrintf(pszStr, 2, ".");
 
958
                                UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
 
959
                        }
 
960
                }
 
961
        }
 
962
 
 
963
        if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
 
964
        {
 
965
                psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
 
966
 
 
967
                if(psMiscInfo->sCacheOpCtl.bDeferOp)
 
968
                {
 
969
                        
 
970
                        psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
 
971
                }
 
972
                else
 
973
                {
 
974
#if defined (SUPPORT_SID_INTERFACE)
 
975
                        PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo;
 
976
 
 
977
                        if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo)
 
978
#else
 
979
                        PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
 
980
                        PVRSRV_PER_PROCESS_DATA *psPerProc;
 
981
 
 
982
                        if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
 
983
#endif
 
984
                        {
 
985
                                PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
 
986
                                                 "Ignoring non-deferred cache op with no meminfo"));
 
987
                                return PVRSRV_ERROR_INVALID_PARAMS;
 
988
                        }
 
989
 
 
990
                        if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
 
991
                        {
 
992
                                PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
 
993
                                                 "Deferred cache op is pending. It is unlikely you want "
 
994
                                                 "to combine deferred cache ops with immediate ones"));
 
995
                        }
 
996
 
 
997
#if defined (SUPPORT_SID_INTERFACE)
 
998
                        PVR_DBG_BREAK
 
999
#else
 
1000
                        
 
1001
                        psPerProc = PVRSRVFindPerProcessData();
 
1002
 
 
1003
                        if(PVRSRVLookupHandle(psPerProc->psHandleBase,
 
1004
                                                                  (IMG_PVOID *)&psKernelMemInfo,
 
1005
                                                                  psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
 
1006
                                                                  PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
 
1007
                        {
 
1008
                                PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
 
1009
                                                 "Can't find kernel meminfo"));
 
1010
                                return PVRSRV_ERROR_INVALID_PARAMS;
 
1011
                        }
 
1012
#endif
 
1013
 
 
1014
                        if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
 
1015
                        {
 
1016
                                if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
 
1017
                                                                                   psMiscInfo->sCacheOpCtl.pvBaseVAddr,
 
1018
                                                                                   psMiscInfo->sCacheOpCtl.ui32Length))
 
1019
                                {
 
1020
                                        return PVRSRV_ERROR_CACHEOP_FAILED;
 
1021
                                }
 
1022
                        }
 
1023
                        else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
 
1024
                        {
 
1025
                                if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
 
1026
                                                                                   psMiscInfo->sCacheOpCtl.pvBaseVAddr,
 
1027
                                                                                   psMiscInfo->sCacheOpCtl.ui32Length))
 
1028
                                {
 
1029
                                        return PVRSRV_ERROR_CACHEOP_FAILED;
 
1030
                                }
 
1031
                        }
 
1032
/* FIXME: Temporary fix needs to be revisited
 
1033
 * LinuxMemArea struct listing is not registered for memory areas
 
1034
 * wrapped through PVR2DMemWrap() call. For now, we are doing
 
1035
 * cache flush/inv by grabbing the physical pages through
 
1036
 * get_user_pages() for every blt call.
 
1037
 */
 
1038
                        else if (psMiscInfo->sCacheOpCtl.eCacheOpType ==
 
1039
                                                PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_FLUSH)
 
1040
                        {
 
1041
#if defined(CONFIG_OUTER_CACHE) && defined(PVR_NO_FULL_CACHE_OPS)
 
1042
                                if (1)
 
1043
                                {
 
1044
                                        IMG_SIZE_T      uPageOffset, uPageCount;
 
1045
                                        IMG_VOID        *pvPageAlignedCPUVAddr;
 
1046
                                        IMG_SYS_PHYADDR         *psIntSysPAddr = IMG_NULL;
 
1047
                                        IMG_HANDLE      hOSWrapMem = IMG_NULL;
 
1048
                                        PVRSRV_ERROR eError;
 
1049
                                        int i;
 
1050
 
 
1051
                                        uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1);
 
1052
                                        uPageCount =
 
1053
                                                HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE();
 
1054
                                        pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset);
 
1055
 
 
1056
                                        if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
 
1057
                                                uPageCount * sizeof(IMG_SYS_PHYADDR),
 
1058
                                                (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
 
1059
                                                "Array of Page Addresses") != PVRSRV_OK)
 
1060
                                        {
 
1061
                                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
 
1062
                                                return PVRSRV_ERROR_OUT_OF_MEMORY;
 
1063
                                        }
 
1064
 
 
1065
                                        eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
 
1066
                                                                                uPageCount * HOST_PAGESIZE(),
 
1067
                                                                                psIntSysPAddr,
 
1068
                                                                                &hOSWrapMem);
 
1069
                                        for (i = 0; i < uPageCount; i++)
 
1070
                                        {
 
1071
                                                outer_flush_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1);
 
1072
                                        }
 
1073
 
 
1074
                                        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
 
1075
                                                uPageCount * sizeof(IMG_SYS_PHYADDR),
 
1076
                                                psIntSysPAddr, IMG_NULL);
 
1077
 
 
1078
                                        kfree(hOSWrapMem);
 
1079
 
 
1080
                                }
 
1081
#else
 
1082
                                OSFlushCPUCacheKM();
 
1083
#endif /* CONFIG_OUTER_CACHE && PVR_NO_FULL_CACHE_OPS*/
 
1084
                        }
 
1085
                        else if (psMiscInfo->sCacheOpCtl.eCacheOpType ==
 
1086
                                                        PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_INV)
 
1087
                        {
 
1088
#if defined(CONFIG_OUTER_CACHE)
 
1089
                                /* TODO: Need to check full cache invalidation, but
 
1090
                                 * currently it is not exported through
 
1091
                                 * outer_cache interface.
 
1092
                                 */
 
1093
                                if (1)
 
1094
                                {
 
1095
                                        IMG_SIZE_T      uPageOffset, uPageCount;
 
1096
                                        IMG_VOID        *pvPageAlignedCPUVAddr;
 
1097
                                        IMG_SYS_PHYADDR         *psIntSysPAddr = IMG_NULL;
 
1098
                                        IMG_HANDLE      hOSWrapMem = IMG_NULL;
 
1099
                                        PVRSRV_ERROR eError;
 
1100
                                        int i;
 
1101
 
 
1102
                                        uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1);
 
1103
                                        uPageCount =
 
1104
                                                HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE();
 
1105
                                        pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset);
 
1106
 
 
1107
                                        if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
 
1108
                                                uPageCount * sizeof(IMG_SYS_PHYADDR),
 
1109
                                                (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
 
1110
                                                "Array of Page Addresses") != PVRSRV_OK)
 
1111
                                        {
 
1112
                                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
 
1113
                                                return PVRSRV_ERROR_OUT_OF_MEMORY;
 
1114
                                        }
 
1115
 
 
1116
                                        eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
 
1117
                                                                                uPageCount * HOST_PAGESIZE(),
 
1118
                                                                                psIntSysPAddr,
 
1119
                                                                                &hOSWrapMem);
 
1120
                                        for (i = 0; i < uPageCount; i++)
 
1121
                                        {
 
1122
                                                outer_inv_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1);
 
1123
                                        }
 
1124
 
 
1125
                                        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
 
1126
                                                uPageCount * sizeof(IMG_SYS_PHYADDR),
 
1127
                                                psIntSysPAddr, IMG_NULL);
 
1128
 
 
1129
                                        kfree(hOSWrapMem);
 
1130
 
 
1131
                                }
 
1132
 
 
1133
#endif /* CONFIG_OUTER_CACHE */
 
1134
                        }
 
1135
 
 
1136
                }
 
1137
        }
 
1138
 
 
1139
#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
 
1140
        if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
 
1141
        {
 
1142
                PVR_LOG(("User requested OS reset"));
 
1143
                OSPanic();
 
1144
        }
 
1145
#endif 
 
1146
 
 
1147
        return PVRSRV_OK;
 
1148
}
 
1149
 
 
1150
 
 
1151
IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
 
1152
{
 
1153
        SYS_DATA                        *psSysData;
 
1154
        IMG_BOOL                        bStatus = IMG_FALSE;
 
1155
        IMG_UINT32                      ui32InterruptSource;
 
1156
 
 
1157
        if(!psDeviceNode)
 
1158
        {
 
1159
                PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
 
1160
                goto out;
 
1161
        }
 
1162
        psSysData = psDeviceNode->psSysData;
 
1163
 
 
1164
        
 
1165
        ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
 
1166
        if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
 
1167
        {
 
1168
                if(psDeviceNode->pfnDeviceISR != IMG_NULL)
 
1169
                {
 
1170
                        bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
 
1171
                }
 
1172
 
 
1173
                SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
 
1174
        }
 
1175
 
 
1176
out:
 
1177
        return bStatus;
 
1178
}
 
1179
 
 
1180
static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
 
1181
{
 
1182
 
 
1183
        IMG_BOOL *pbStatus;
 
1184
        IMG_UINT32 *pui32InterruptSource;
 
1185
        IMG_UINT32 *pui32ClearInterrupts;
 
1186
 
 
1187
        pbStatus = va_arg(va, IMG_BOOL*);
 
1188
        pui32InterruptSource = va_arg(va, IMG_UINT32*);
 
1189
        pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
 
1190
 
 
1191
 
 
1192
        if(psDeviceNode->pfnDeviceISR != IMG_NULL)
 
1193
        {
 
1194
                if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
 
1195
                {
 
1196
                        if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
 
1197
                        {
 
1198
                                
 
1199
                                *pbStatus = IMG_TRUE;
 
1200
                        }
 
1201
                        
 
1202
                        *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
 
1203
                }
 
1204
        }
 
1205
}
 
1206
 
 
1207
IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
 
1208
{
 
1209
        SYS_DATA                        *psSysData = pvSysData;
 
1210
        IMG_BOOL                        bStatus = IMG_FALSE;
 
1211
        IMG_UINT32                      ui32InterruptSource;
 
1212
        IMG_UINT32                      ui32ClearInterrupts = 0;
 
1213
        if(!psSysData)
 
1214
        {
 
1215
                PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
 
1216
        }
 
1217
        else
 
1218
        {
 
1219
                
 
1220
                ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
 
1221
 
 
1222
                
 
1223
                if(ui32InterruptSource)
 
1224
                {
 
1225
                        
 
1226
                        List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
 
1227
                                                                                                &PVRSRVSystemLISR_ForEachVaCb,
 
1228
                                                                                                &bStatus,
 
1229
                                                                                                &ui32InterruptSource,
 
1230
                                                                                                &ui32ClearInterrupts);
 
1231
 
 
1232
                        SysClearInterrupts(psSysData, ui32ClearInterrupts);
 
1233
                }
 
1234
        }
 
1235
        return bStatus;
 
1236
}
 
1237
 
 
1238
 
 
1239
static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
1240
{
 
1241
        if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
 
1242
        {
 
1243
                (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
 
1244
        }
 
1245
}
 
1246
 
 
1247
IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
 
1248
{
 
1249
        SYS_DATA                        *psSysData = pvSysData;
 
1250
        if(!psSysData)
 
1251
        {
 
1252
                PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
 
1253
                return;
 
1254
        }
 
1255
 
 
1256
        
 
1257
        List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
 
1258
                                                                        &PVRSRVMISR_ForEachCb);
 
1259
 
 
1260
        
 
1261
        if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
 
1262
        {
 
1263
                PVRSRVProcessQueues(IMG_FALSE);
 
1264
        }
 
1265
 
 
1266
        
 
1267
        if (psSysData->psGlobalEventObject)
 
1268
        {
 
1269
                IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
 
1270
                if(hOSEventKM)
 
1271
                {
 
1272
                        OSEventObjectSignalKM(hOSEventKM);
 
1273
                }
 
1274
        }
 
1275
}
 
1276
 
 
1277
 
 
1278
IMG_EXPORT
 
1279
PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32       ui32PID, IMG_UINT32 ui32Flags)
 
1280
{
 
1281
        return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
 
1282
}
 
1283
 
 
1284
 
 
1285
IMG_EXPORT
 
1286
IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32        ui32PID)
 
1287
{
 
1288
        PVRSRVPerProcessDataDisconnect(ui32PID);
 
1289
}
 
1290
 
 
1291
 
 
1292
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
 
1293
                                                                                                                IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
 
1294
{
 
1295
        IMG_SIZE_T         uiBytesSaved = 0;
 
1296
        IMG_PVOID          pvLocalMemCPUVAddr;
 
1297
        RA_SEGMENT_DETAILS sSegDetails;
 
1298
 
 
1299
        if (hArena == IMG_NULL)
 
1300
        {
 
1301
                return (PVRSRV_ERROR_INVALID_PARAMS);
 
1302
        }
 
1303
 
 
1304
        sSegDetails.uiSize = 0;
 
1305
        sSegDetails.sCpuPhyAddr.uiAddr = 0;
 
1306
        sSegDetails.hSegment = 0;
 
1307
 
 
1308
        
 
1309
        while (RA_GetNextLiveSegment(hArena, &sSegDetails))
 
1310
        {
 
1311
                if (pbyBuffer == IMG_NULL)
 
1312
                {
 
1313
                        
 
1314
                        uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
 
1315
                }
 
1316
                else
 
1317
                {
 
1318
                        if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
 
1319
                        {
 
1320
                                return (PVRSRV_ERROR_OUT_OF_MEMORY);
 
1321
                        }
 
1322
 
 
1323
                        PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
 
1324
 
 
1325
                        
 
1326
                        pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
 
1327
                                                                        sSegDetails.uiSize,
 
1328
                                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
 
1329
                                                                        IMG_NULL);
 
1330
                        if (pvLocalMemCPUVAddr == IMG_NULL)
 
1331
                        {
 
1332
                                PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
 
1333
                                return (PVRSRV_ERROR_OUT_OF_MEMORY);
 
1334
                        }
 
1335
 
 
1336
                        if (bSave)
 
1337
                        {
 
1338
                                
 
1339
                                OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
 
1340
                                pbyBuffer += sizeof(sSegDetails.uiSize);
 
1341
 
 
1342
                                OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
 
1343
                                pbyBuffer += sSegDetails.uiSize;
 
1344
                        }
 
1345
                        else
 
1346
                        {
 
1347
                                IMG_UINT32 uiSize;
 
1348
                                
 
1349
                                OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
 
1350
 
 
1351
                                if (uiSize != sSegDetails.uiSize)
 
1352
                                {
 
1353
                                        PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
 
1354
                                }
 
1355
                                else
 
1356
                                {
 
1357
                                        pbyBuffer += sizeof(sSegDetails.uiSize);
 
1358
 
 
1359
                                        OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
 
1360
                                        pbyBuffer += sSegDetails.uiSize;
 
1361
                                }
 
1362
                        }
 
1363
 
 
1364
 
 
1365
                        uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
 
1366
 
 
1367
                        OSUnMapPhysToLin(pvLocalMemCPUVAddr,
 
1368
                                     sSegDetails.uiSize,
 
1369
                                     PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
 
1370
                                     IMG_NULL);
 
1371
                }
 
1372
        }
 
1373
 
 
1374
        if (pbyBuffer == IMG_NULL)
 
1375
        {
 
1376
                *puiBufSize = uiBytesSaved;
 
1377
        }
 
1378
 
 
1379
        return (PVRSRV_OK);
 
1380
}
 
1381
 
 
1382
 
 
1383
IMG_EXPORT
 
1384
const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
 
1385
 
1386
 
 
1387
#include "pvrsrv_errors.h"
 
1388
}
 
1389
 
 
1390
static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
 
1391
{
 
1392
        if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
 
1393
        {
 
1394
                
 
1395
                (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
 
1396
        }
 
1397
}
 
1398
 
 
1399
IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
 
1400
{
 
1401
        SYS_DATA                                *psSysData;
 
1402
        SysAcquireData(&psSysData);
 
1403
 
 
1404
        
 
1405
        List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
 
1406
                                                                        &PVRSRVCommandCompleteCallbacks_ForEachCb);
 
1407
}
 
1408
 
 
1409
IMG_EXPORT
 
1410
IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
 
1411
{
 
1412
        PVRSRVScheduleDeviceCallbacks();
 
1413
}