1
/**********************************************************************
3
* Copyright (C) Imagination Technologies Ltd. All rights reserved.
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
9
* This program is distributed in the hope it will be useful but, except
10
* as otherwise stated in writing, without any warranty; without even the
11
* implied warranty of merchantability or fitness for a particular purpose.
12
* See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along with
15
* this program; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
* The full GNU General Public License is included in this distribution in
19
* the file called "COPYING".
21
* Contact Information:
22
* Imagination Technologies Ltd. <gpl-support@imgtec.com>
23
* Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25
******************************************************************************/
27
#include <linux/slab.h>
28
#include "services_headers.h"
29
#include "buffer_manager.h"
30
#include "pvr_bridge_km.h"
40
#include "pvrversion.h"
44
IMG_UINT32 g_ui32InitFlags;
46
#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
47
#define INIT_DATA_ENABLE_TTARCE 0x2U
49
PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
51
SYS_DEVICE_ID* psDeviceWalker;
52
SYS_DEVICE_ID* psDeviceEnd;
55
pr_err("NULL psSysData\n");
60
psDeviceWalker = &psSysData->sDeviceID[0];
61
psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
64
while (psDeviceWalker < psDeviceEnd)
66
if (!psDeviceWalker->bInUse)
68
psDeviceWalker->bInUse = IMG_TRUE;
69
*pui32DevID = psDeviceWalker->uiID;
75
PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
78
PVR_ASSERT(psDeviceWalker < psDeviceEnd);
80
return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
84
PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
86
SYS_DEVICE_ID* psDeviceWalker;
87
SYS_DEVICE_ID* psDeviceEnd;
89
psDeviceWalker = &psSysData->sDeviceID[0];
90
psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
93
while (psDeviceWalker < psDeviceEnd)
97
(psDeviceWalker->uiID == ui32DevID) &&
98
(psDeviceWalker->bInUse)
101
psDeviceWalker->bInUse = IMG_FALSE;
107
PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
110
PVR_ASSERT(psDeviceWalker < psDeviceEnd);
112
return PVRSRV_ERROR_INVALID_DEVICEID;
118
IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
120
return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
127
IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
129
PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
130
(IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
132
*(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
139
IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
143
WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
150
static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
152
IMG_UINT *pui32DevCount;
153
PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
155
pui32DevCount = va_arg(va, IMG_UINT*);
156
ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
158
if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
160
*(*ppsDevIdList) = psDeviceNode->sDevId;
169
PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
170
PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
175
if (!pui32NumDevices || !psDevIdList)
177
PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
178
return PVRSRV_ERROR_INVALID_PARAMS;
181
SysAcquireData(&psSysData);
185
for (i=0; i<PVRSRV_MAX_DEVICES; i++)
187
psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
191
*pui32NumDevices = 0;
197
List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
198
&PVRSRVEnumerateDevicesKM_ForEachVaCb,
207
PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
212
eError = ResManInit();
213
if (eError != PVRSRV_OK)
218
eError = PVRSRVPerProcessDataInit();
219
if(eError != PVRSRV_OK)
225
eError = PVRSRVHandleInit();
226
if(eError != PVRSRV_OK)
232
eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
233
if (eError != PVRSRV_OK)
239
psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
240
psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
243
if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
244
sizeof(PVRSRV_EVENTOBJECT) ,
245
(IMG_VOID **)&psSysData->psGlobalEventObject, 0,
246
"Event Object") != PVRSRV_OK)
252
if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
258
psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
259
psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
260
psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
263
eError = PVRSRVTimeTraceInit();
264
if (eError != PVRSRV_OK)
266
g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE;
271
g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
276
PVRSRVDeInit(psSysData);
282
IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
286
PVR_UNREFERENCED_PARAMETER(psSysData);
288
if (psSysData == IMG_NULL)
290
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
295
if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0)
297
PVRSRVTimeTraceDeinit();
301
if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
307
if(psSysData->psGlobalEventObject)
309
OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
310
OSFreeMem( PVRSRV_PAGEABLE_SELECT,
311
sizeof(PVRSRV_EVENTOBJECT),
312
psSysData->psGlobalEventObject,
314
psSysData->psGlobalEventObject = IMG_NULL;
317
eError = PVRSRVHandleDeInit();
318
if (eError != PVRSRV_OK)
320
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
323
eError = PVRSRVPerProcessDataDeInit();
324
if (eError != PVRSRV_OK)
326
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
333
PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
334
PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
335
IMG_UINT32 ui32SOCInterruptBit,
336
IMG_UINT32 *pui32DeviceIndex)
339
PVRSRV_DEVICE_NODE *psDeviceNode;
342
if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
343
sizeof(PVRSRV_DEVICE_NODE),
344
(IMG_VOID **)&psDeviceNode, IMG_NULL,
345
"Device Node") != PVRSRV_OK)
347
PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
348
return (PVRSRV_ERROR_OUT_OF_MEMORY);
350
OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
352
eError = pfnRegisterDevice(psDeviceNode);
353
if (eError != PVRSRV_OK)
355
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
356
sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
358
PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
359
return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
367
psDeviceNode->ui32RefCount = 1;
368
psDeviceNode->psSysData = psSysData;
369
psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
372
AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
375
List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
378
*pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
384
PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
386
PVRSRV_DEVICE_NODE *psDeviceNode;
390
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
392
SysAcquireData(&psSysData);
395
psDeviceNode = (PVRSRV_DEVICE_NODE*)
396
List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
397
&MatchDeviceKM_AnyVaCb,
403
PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
404
return PVRSRV_ERROR_INIT_FAILURE;
406
PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
410
eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
411
if (eError != PVRSRV_OK)
413
PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
418
if(psDeviceNode->pfnInitDevice != IMG_NULL)
420
eError = psDeviceNode->pfnInitDevice(psDeviceNode);
421
if (eError != PVRSRV_OK)
423
PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
432
static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
435
eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
436
PVRSRV_DEV_POWER_STATE_DEFAULT,
437
KERNEL_ID, IMG_FALSE);
438
if (eError != PVRSRV_OK)
440
PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
445
static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
448
eError = PVRSRVDevInitCompatCheck(psDeviceNode);
449
if (eError != PVRSRV_OK)
451
PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
457
PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
462
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
464
SysAcquireData(&psSysData);
468
eError = SysFinalise();
469
if (eError != PVRSRV_OK)
471
PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
476
eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
477
&PVRSRVFinaliseSystem_SetPowerState_AnyCb);
478
if (eError != PVRSRV_OK)
484
eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
485
&PVRSRVFinaliseSystem_CompatCheck_AnyCb);
486
if (eError != PVRSRV_OK)
502
PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
505
if (psDeviceNode->pfnInitDeviceCompatCheck)
506
return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
511
static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
513
PVRSRV_DEVICE_TYPE eDeviceType;
514
IMG_UINT32 ui32DevIndex;
516
eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
517
ui32DevIndex = va_arg(va, IMG_UINT32);
519
if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
520
psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
521
(eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
522
psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
533
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
534
PVRSRV_DEVICE_TYPE eDeviceType,
535
IMG_HANDLE *phDevCookie)
537
PVRSRV_DEVICE_NODE *psDeviceNode;
540
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
542
SysAcquireData(&psSysData);
545
psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
546
&PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
554
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
555
return PVRSRV_ERROR_INIT_FAILURE;
558
PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
563
*phDevCookie = (IMG_HANDLE)psDeviceNode;
570
PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
572
PVRSRV_DEVICE_NODE *psDeviceNode;
576
SysAcquireData(&psSysData);
578
psDeviceNode = (PVRSRV_DEVICE_NODE*)
579
List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
580
&MatchDeviceKM_AnyVaCb,
586
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
587
return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
592
eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
593
PVRSRV_DEV_POWER_STATE_OFF,
596
if (eError != PVRSRV_OK)
598
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
604
eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
605
RESMAN_CRITERIA_RESTYPE,
606
RESMAN_TYPE_DEVICEMEM_ALLOCATION,
608
if (eError != PVRSRV_OK)
610
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
616
if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
618
eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
619
if (eError != PVRSRV_OK)
621
PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
628
PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
629
psDeviceNode->hResManContext = IMG_NULL;
632
List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
635
(IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
636
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
637
sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
645
PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
646
IMG_UINT32 ui32Value,
648
IMG_UINT32 ui32Timeoutus,
649
IMG_UINT32 ui32PollPeriodus,
650
IMG_BOOL bAllowPreemption)
653
IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU;
655
if (bAllowPreemption)
657
PVR_ASSERT(ui32PollPeriodus >= 1000);
661
LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
663
ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
664
if(ui32ActualValue == ui32Value)
669
if (bAllowPreemption)
671
OSSleepms(ui32PollPeriodus / 1000);
675
OSWaitus(ui32PollPeriodus);
677
} END_LOOP_UNTIL_TIMEOUT();
679
PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
680
ui32Value, ui32ActualValue, ui32Mask));
683
return PVRSRV_ERROR_TIMEOUT;
687
static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
690
IMG_UINT32 *pui32StrLen;
692
PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
694
ppszStr = va_arg(va, IMG_CHAR**);
695
pui32StrLen = va_arg(va, IMG_UINT32*);
696
ui32Mode = va_arg(va, IMG_UINT32);
701
case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
702
pfnGetStats = &RA_GetStats;
704
case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
705
pfnGetStats = &RA_GetStatsFreeMem;
711
if(psBMHeap->pImportArena)
713
pfnGetStats(psBMHeap->pImportArena,
718
if(psBMHeap->pVMArena)
720
pfnGetStats(psBMHeap->pVMArena,
726
static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
729
IMG_UINT32 *pui32StrLen;
730
IMG_INT32 *pi32Count;
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);
739
CHECK_SPACE(*pui32StrLen);
740
*pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
741
(IMG_HANDLE)psBMContext);
742
UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
744
List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
745
&PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
753
static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
755
IMG_UINT32 *pui32StrLen;
756
IMG_INT32 *pi32Count;
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);
765
CHECK_SPACE(*pui32StrLen);
766
*pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
767
UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
770
if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
772
CHECK_SPACE(*pui32StrLen);
773
*pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
774
UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
776
List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
777
&PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
784
return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
785
&PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
794
#if defined (SUPPORT_SID_INTERFACE)
795
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo)
797
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
804
PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
805
return PVRSRV_ERROR_INVALID_PARAMS;
808
psMiscInfo->ui32StatePresent = 0;
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))
820
PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
821
return PVRSRV_ERROR_INVALID_PARAMS;
824
SysAcquireData(&psSysData);
827
if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
828
(psSysData->pvSOCTimerRegisterKM != IMG_NULL))
830
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
831
psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
832
psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
836
psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
837
psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
841
if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
842
(psSysData->pvSOCClockGateRegsBase != IMG_NULL))
844
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
845
psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
846
psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
850
if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
851
(psMiscInfo->pszMemoryStr != IMG_NULL))
855
IMG_UINT32 ui32StrLen;
858
pszStr = psMiscInfo->pszMemoryStr;
859
ui32StrLen = psMiscInfo->ui32MemoryStrLen;
861
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
864
ppArena = &psSysData->apsLocalDevMemArena[0];
867
CHECK_SPACE(ui32StrLen);
868
i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
869
UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
871
RA_GetStats(*ppArena,
880
List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
881
&PVRSRVGetMiscInfoKM_Device_AnyVaCb,
885
PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
888
i32Count = OSSNPrintf(pszStr, 100, "\n");
889
UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
893
if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
894
&& psMiscInfo->pszMemoryStr)
897
IMG_UINT32 ui32StrLen;
900
pszStr = psMiscInfo->pszMemoryStr;
901
ui32StrLen = psMiscInfo->ui32MemoryStrLen;
903
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
906
List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
907
&PVRSRVGetMiscInfoKM_Device_AnyVaCb,
911
PVRSRV_MISC_INFO_FREEMEM_PRESENT);
913
i32Count = OSSNPrintf(pszStr, 100, "\n");
914
UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
917
if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
918
(psSysData->psGlobalEventObject != IMG_NULL))
920
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
921
psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
926
if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
927
&& ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
928
&& (psMiscInfo->pszMemoryStr != IMG_NULL))
931
IMG_UINT32 ui32StrLen;
932
IMG_UINT32 ui32LenStrPerNum = 12;
935
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
938
psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
939
psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
940
psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
941
psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
943
pszStr = psMiscInfo->pszMemoryStr;
944
ui32StrLen = psMiscInfo->ui32MemoryStrLen;
948
if (ui32StrLen < ui32LenStrPerNum)
950
return PVRSRV_ERROR_INVALID_PARAMS;
953
i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
954
UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
957
i32Count = OSSNPrintf(pszStr, 2, ".");
958
UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
963
if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
965
psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
967
if(psMiscInfo->sCacheOpCtl.bDeferOp)
970
psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
974
#if defined (SUPPORT_SID_INTERFACE)
975
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo;
977
if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo)
979
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
980
PVRSRV_PER_PROCESS_DATA *psPerProc;
982
if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
985
PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
986
"Ignoring non-deferred cache op with no meminfo"));
987
return PVRSRV_ERROR_INVALID_PARAMS;
990
if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
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"));
997
#if defined (SUPPORT_SID_INTERFACE)
1001
psPerProc = PVRSRVFindPerProcessData();
1003
if(PVRSRVLookupHandle(psPerProc->psHandleBase,
1004
(IMG_PVOID *)&psKernelMemInfo,
1005
psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
1006
PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
1008
PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
1009
"Can't find kernel meminfo"));
1010
return PVRSRV_ERROR_INVALID_PARAMS;
1014
if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
1016
if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
1017
psMiscInfo->sCacheOpCtl.pvBaseVAddr,
1018
psMiscInfo->sCacheOpCtl.ui32Length))
1020
return PVRSRV_ERROR_CACHEOP_FAILED;
1023
else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
1025
if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
1026
psMiscInfo->sCacheOpCtl.pvBaseVAddr,
1027
psMiscInfo->sCacheOpCtl.ui32Length))
1029
return PVRSRV_ERROR_CACHEOP_FAILED;
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.
1038
else if (psMiscInfo->sCacheOpCtl.eCacheOpType ==
1039
PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_FLUSH)
1041
#if defined(CONFIG_OUTER_CACHE) && defined(PVR_NO_FULL_CACHE_OPS)
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;
1051
uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1);
1053
HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE();
1054
pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset);
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)
1061
PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
1062
return PVRSRV_ERROR_OUT_OF_MEMORY;
1065
eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
1066
uPageCount * HOST_PAGESIZE(),
1069
for (i = 0; i < uPageCount; i++)
1071
outer_flush_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1);
1074
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1075
uPageCount * sizeof(IMG_SYS_PHYADDR),
1076
psIntSysPAddr, IMG_NULL);
1082
OSFlushCPUCacheKM();
1083
#endif /* CONFIG_OUTER_CACHE && PVR_NO_FULL_CACHE_OPS*/
1085
else if (psMiscInfo->sCacheOpCtl.eCacheOpType ==
1086
PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_INV)
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.
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;
1102
uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1);
1104
HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE();
1105
pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset);
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)
1112
PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
1113
return PVRSRV_ERROR_OUT_OF_MEMORY;
1116
eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
1117
uPageCount * HOST_PAGESIZE(),
1120
for (i = 0; i < uPageCount; i++)
1122
outer_inv_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1);
1125
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1126
uPageCount * sizeof(IMG_SYS_PHYADDR),
1127
psIntSysPAddr, IMG_NULL);
1133
#endif /* CONFIG_OUTER_CACHE */
1139
#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
1140
if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
1142
PVR_LOG(("User requested OS reset"));
1151
IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
1153
SYS_DATA *psSysData;
1154
IMG_BOOL bStatus = IMG_FALSE;
1155
IMG_UINT32 ui32InterruptSource;
1159
PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
1162
psSysData = psDeviceNode->psSysData;
1165
ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
1166
if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1168
if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1170
bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
1173
SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
1180
static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1184
IMG_UINT32 *pui32InterruptSource;
1185
IMG_UINT32 *pui32ClearInterrupts;
1187
pbStatus = va_arg(va, IMG_BOOL*);
1188
pui32InterruptSource = va_arg(va, IMG_UINT32*);
1189
pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
1192
if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1194
if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1196
if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
1199
*pbStatus = IMG_TRUE;
1202
*pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
1207
IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
1209
SYS_DATA *psSysData = pvSysData;
1210
IMG_BOOL bStatus = IMG_FALSE;
1211
IMG_UINT32 ui32InterruptSource;
1212
IMG_UINT32 ui32ClearInterrupts = 0;
1215
PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
1220
ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
1223
if(ui32InterruptSource)
1226
List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1227
&PVRSRVSystemLISR_ForEachVaCb,
1229
&ui32InterruptSource,
1230
&ui32ClearInterrupts);
1232
SysClearInterrupts(psSysData, ui32ClearInterrupts);
1239
static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1241
if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
1243
(*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
1247
IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
1249
SYS_DATA *psSysData = pvSysData;
1252
PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
1257
List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1258
&PVRSRVMISR_ForEachCb);
1261
if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
1263
PVRSRVProcessQueues(IMG_FALSE);
1267
if (psSysData->psGlobalEventObject)
1269
IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
1272
OSEventObjectSignalKM(hOSEventKM);
1279
PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
1281
return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
1286
IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
1288
PVRSRVPerProcessDataDisconnect(ui32PID);
1292
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
1293
IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
1295
IMG_SIZE_T uiBytesSaved = 0;
1296
IMG_PVOID pvLocalMemCPUVAddr;
1297
RA_SEGMENT_DETAILS sSegDetails;
1299
if (hArena == IMG_NULL)
1301
return (PVRSRV_ERROR_INVALID_PARAMS);
1304
sSegDetails.uiSize = 0;
1305
sSegDetails.sCpuPhyAddr.uiAddr = 0;
1306
sSegDetails.hSegment = 0;
1309
while (RA_GetNextLiveSegment(hArena, &sSegDetails))
1311
if (pbyBuffer == IMG_NULL)
1314
uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1318
if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
1320
return (PVRSRV_ERROR_OUT_OF_MEMORY);
1323
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
1326
pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
1328
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1330
if (pvLocalMemCPUVAddr == IMG_NULL)
1332
PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
1333
return (PVRSRV_ERROR_OUT_OF_MEMORY);
1339
OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
1340
pbyBuffer += sizeof(sSegDetails.uiSize);
1342
OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
1343
pbyBuffer += sSegDetails.uiSize;
1349
OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
1351
if (uiSize != sSegDetails.uiSize)
1353
PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
1357
pbyBuffer += sizeof(sSegDetails.uiSize);
1359
OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
1360
pbyBuffer += sSegDetails.uiSize;
1365
uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1367
OSUnMapPhysToLin(pvLocalMemCPUVAddr,
1369
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1374
if (pbyBuffer == IMG_NULL)
1376
*puiBufSize = uiBytesSaved;
1384
const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
1387
#include "pvrsrv_errors.h"
1390
static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1392
if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
1395
(*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
1399
IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
1401
SYS_DATA *psSysData;
1402
SysAcquireData(&psSysData);
1405
List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1406
&PVRSRVCommandCompleteCallbacks_ForEachCb);
1410
IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
1412
PVRSRVScheduleDeviceCallbacks();