aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Hillenbrand <daniel.hillenbrand@codeworkx.de>2012-07-23 15:25:22 +0200
committerDaniel Hillenbrand <daniel.hillenbrand@codeworkx.de>2012-07-23 15:25:22 +0200
commit2f1646a49c364bf302daef2944ba46c47175e650 (patch)
treee42b350975faa1fc7b206b4be17d3c65d0f39f4d
parent387fb3de82e56e2f7f79d9ee8f456f7f9cde5090 (diff)
downloadkernel_samsung_espresso10-2f1646a49c364bf302daef2944ba46c47175e650.tar.gz
kernel_samsung_espresso10-2f1646a49c364bf302daef2944ba46c47175e650.tar.bz2
kernel_samsung_espresso10-2f1646a49c364bf302daef2944ba46c47175e650.zip
updated pvr and omap2 video drivers from tuna
-rw-r--r--drivers/gpu/pvr/Kconfig14
-rw-r--r--drivers/gpu/pvr/Makefile4
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.c59
-rw-r--r--drivers/gpu/pvr/buffer_manager.c91
-rw-r--r--drivers/gpu/pvr/buffer_manager.h33
-rw-r--r--drivers/gpu/pvr/deviceclass.c35
-rw-r--r--drivers/gpu/pvr/devicemem.c87
-rw-r--r--drivers/gpu/pvr/ion.c18
-rw-r--r--drivers/gpu/pvr/ion.h3
-rw-r--r--drivers/gpu/pvr/mm.c1424
-rw-r--r--drivers/gpu/pvr/mm.h17
-rw-r--r--drivers/gpu/pvr/module.c21
-rw-r--r--drivers/gpu/pvr/omap4/sysconfig.c3
-rw-r--r--drivers/gpu/pvr/omap4/syslocal.h5
-rw-r--r--drivers/gpu/pvr/osfunc.c99
-rw-r--r--drivers/gpu/pvr/osfunc.h27
-rw-r--r--drivers/gpu/pvr/pdump_km.h2
-rw-r--r--drivers/gpu/pvr/pvr_bridge.h22
-rw-r--r--drivers/gpu/pvr/pvr_bridge_k.c18
-rw-r--r--drivers/gpu/pvr/pvr_bridge_km.h4
-rw-r--r--drivers/gpu/pvr/pvr_uaccess.h1
-rw-r--r--drivers/gpu/pvr/pvrversion.h6
-rw-r--r--drivers/gpu/pvr/queue.c10
-rw-r--r--drivers/gpu/pvr/refcount.c111
-rw-r--r--drivers/gpu/pvr/refcount.h86
-rw-r--r--drivers/gpu/pvr/resman.c30
-rw-r--r--drivers/gpu/pvr/servicesext.h3
-rw-r--r--drivers/gpu/pvr/servicesint.h17
-rw-r--r--drivers/gpu/pvr/sgx/bridged_sgx_bridge.c122
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c210
-rw-r--r--drivers/gpu/pvr/sgx/mmu.h2
-rw-r--r--drivers/gpu/pvr/sgx/sgxinfokm.h10
-rw-r--r--drivers/gpu/pvr/sgx/sgxinit.c89
-rw-r--r--drivers/gpu/pvr/sgx/sgxkick.c1
-rw-r--r--drivers/gpu/pvr/sgx/sgxpower.c1
-rw-r--r--drivers/gpu/pvr/sgx/sgxreset.c7
-rw-r--r--drivers/gpu/pvr/sgx/sgxtransfer.c2
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c671
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.h39
-rw-r--r--drivers/gpu/pvr/sgx_bridge.h70
-rw-r--r--drivers/gpu/pvr/sgx_mkif_km.h13
-rw-r--r--drivers/gpu/pvr/sgx_ukernel_status_codes.h940
-rw-r--r--drivers/gpu/pvr/sgxapi_km.h6
-rw-r--r--drivers/gpu/pvr/sgxerrata.h71
-rw-r--r--drivers/gpu/pvr/sgxfeaturedefs.h10
-rw-r--r--drivers/gpu/pvr/sgxinfo.h15
-rw-r--r--drivers/gpu/pvr/ttrace_common.h5
-rw-r--r--drivers/video/omap2/dss/dispc.c53
-rw-r--r--drivers/video/omap2/dss/dpi.c1
-rw-r--r--drivers/video/omap2/dss/dsi.c30
-rw-r--r--drivers/video/omap2/dss/hdmi.c23
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c14
-rw-r--r--drivers/video/omap2/dss/manager.c16
-rw-r--r--drivers/video/omap2/dsscomp/device.c11
-rw-r--r--drivers/video/omap2/dsscomp/gralloc.c3
-rw-r--r--drivers/video/omap2/dsscomp/queue.c1
-rw-r--r--drivers/video/omap2/hdcp/hdcp.h2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c18
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c49
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h7
-rw-r--r--include/linux/omapfb.h1
61 files changed, 3824 insertions, 939 deletions
diff --git a/drivers/gpu/pvr/Kconfig b/drivers/gpu/pvr/Kconfig
index aff423fbdda..0fe0d940a7e 100644
--- a/drivers/gpu/pvr/Kconfig
+++ b/drivers/gpu/pvr/Kconfig
@@ -126,3 +126,17 @@ config SGX_DVFS_IDLE_TIMEOUT
int "DVFS idle timeout (us)"
depends on PVR_SGX
default 1000
+
+config PVR_LINUX_MEM_AREA_POOL
+ bool "Enable uncached allocation pool"
+ depends on PVR_SGX
+ default n
+
+config PVR_LINUX_MEM_AREA_POOL_MAX_PAGES
+ int "Maximum number of pages in pool"
+ depends on PVR_LINUX_MEM_AREA_POOL
+ default 10800
+ help
+ Pool size in pages.
+ A size of 0 disables the pool.
+ A size of -1 allows the pool to grow indefinitely.
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile
index a9c7e4441a1..6a45523d24e 100644
--- a/drivers/gpu/pvr/Makefile
+++ b/drivers/gpu/pvr/Makefile
@@ -60,6 +60,10 @@ ccflags-$(CONFIG_PVR_DUMP_MK_TRACE) += -DPVRSRV_DUMP_MK_TRACE
ccflags-$(CONFIG_PVR_PDUMP) += \
-DPDUMP -DSUPPORT_DBGDRV_EVENT_OBJECTS -DSUPPORT_PDUMP_MULTI_PROCESS
+ccflags-$(CONFIG_PVR_LINUX_MEM_AREA_POOL) += \
+ -DPVR_LINUX_MEM_AREA_POOL_MAX_PAGES=CONFIG_PVR_LINUX_MEM_AREA_POOL_MAX_PAGES \
+ -DPVR_LINUX_MEM_AREA_USE_VMAP -DPVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK
+
pvrsrvkm-y := \
osfunc.o \
mutils.o \
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.c b/drivers/gpu/pvr/bridged_pvr_bridge.c
index 7a84ee86512..b585b99d539 100644
--- a/drivers/gpu/pvr/bridged_pvr_bridge.c
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.c
@@ -3568,40 +3568,6 @@ PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
-static IMG_INT
-MMU_GetPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
- PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN,
- PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT,
- PVRSRV_PER_PROCESS_DATA *psPerProc)
-{
- IMG_HANDLE hDevMemContextInt;
-
- PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR);
-
- psGetMmuPDDevPAddrOUT->eError =
- PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
- psGetMmuPDDevPAddrIN->hDevMemContext,
- PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
- if(psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK)
- {
- return 0;
- }
-
- psGetMmuPDDevPAddrOUT->sPDDevPAddr =
- BM_GetDeviceNode(hDevMemContextInt)->pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext(hDevMemContextInt));
- if(psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr)
- {
- psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK;
- }
- else
- {
- psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_INVALID_PHYS_ADDR;
- }
- return 0;
-}
-
-
-
IMG_INT
DummyBW(IMG_UINT32 ui32BridgeID,
IMG_VOID *psBridgeIn,
@@ -4062,6 +4028,7 @@ static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam,
OpFlushedComplete:
DoModifyCompleteSyncOps(psModSyncOpInfo);
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
}
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
@@ -4146,6 +4113,8 @@ PVRSRVDestroySyncInfoModObjBW(IMG_UINT32
return 0;
}
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
+
psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
@@ -4207,6 +4176,15 @@ PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID,
}
+ if (psKernelSyncInfo == IMG_NULL)
+ {
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo bad handle"));
+ return 0;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psKernelSyncInfo, IMG_NULL);
+
psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
@@ -4278,6 +4256,7 @@ PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID,
return 0;
}
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
@@ -4472,18 +4451,13 @@ FreeSyncInfoCallback(IMG_PVOID pvParam,
IMG_BOOL bDummy)
{
PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
- PVRSRV_ERROR eError;
PVR_UNREFERENCED_PARAMETER(ui32Param);
PVR_UNREFERENCED_PARAMETER(bDummy);
psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
- eError = PVRSRVFreeSyncInfoKM(psSyncInfo);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
return PVRSRV_OK;
}
@@ -4546,7 +4520,7 @@ PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32Bri
allocsyncinfo_errorexit_freesyncinfo:
- PVRSRVFreeSyncInfoKM(psSyncInfo);
+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
allocsyncinfo_errorexit:
@@ -4729,9 +4703,6 @@ CommonBridgeInit(IMG_VOID)
SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
-
- SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR, MMU_GetPDDevPAddrBW);
-
SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW);
SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW);
diff --git a/drivers/gpu/pvr/buffer_manager.c b/drivers/gpu/pvr/buffer_manager.c
index 27ed8a1e8db..ee65df07b45 100644
--- a/drivers/gpu/pvr/buffer_manager.c
+++ b/drivers/gpu/pvr/buffer_manager.c
@@ -1764,16 +1764,7 @@ static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
-static struct {
- IMG_UINT32 ui32RefCount;
- IMG_UINT32 ui32AllocFlags;
- IMG_UINT32 ui32Size;
- IMG_UINT32 ui32PageSize;
- RA_ARENA *psArena;
- IMG_SYS_PHYADDR sSysPAddr;
- IMG_VOID *pvCpuVAddr;
- IMG_HANDLE hOSMemHandle;
-} gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}};
+XPROC_DATA gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}};
PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
{
@@ -1888,7 +1879,7 @@ XProcWorkaroundAllocShareable(RA_ARENA *psArena,
*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
return PVRSRV_OK;
}
@@ -1969,7 +1960,7 @@ XProcWorkaroundAllocShareable(RA_ARENA *psArena,
*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
return PVRSRV_OK;
}
@@ -2009,52 +2000,78 @@ static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT3
return PVRSRV_OK;
}
-static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+#else
+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index)
+#endif
{
- IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
- PVRSRV_ERROR eError;
-
- eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "bad handle"));
- return;
- }
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+ PVRSRVBMXProcIncRef2(pszFile, iLine, ui32Index);
+#else
+ PVRSRVBMXProcIncRef(ui32Index);
+#endif
+}
- gXProcWorkaroundShareData[ui32SI].ui32RefCount--;
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+#else
+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index)
+#endif
+{
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+ PVRSRVBMXProcDecRef2(pszFile, iLine, ui32Index);
+#else
+ PVRSRVBMXProcDecRef(ui32Index);
+#endif
PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
- ui32SI, gXProcWorkaroundShareData[ui32SI].ui32RefCount+1, gXProcWorkaroundShareData[ui32SI].ui32RefCount));
+ ui32Index, gXProcWorkaroundShareData[ui32Index].ui32RefCount+1, gXProcWorkaroundShareData[ui32Index].ui32RefCount));
- if (gXProcWorkaroundShareData[ui32SI].ui32RefCount == 0)
+ if (gXProcWorkaroundShareData[ui32Index].ui32RefCount == 0)
{
- if (gXProcWorkaroundShareData[ui32SI].psArena != IMG_NULL)
+ if (gXProcWorkaroundShareData[ui32Index].psArena != IMG_NULL)
{
IMG_SYS_PHYADDR sSysPAddr;
- if (gXProcWorkaroundShareData[ui32SI].pvCpuVAddr != IMG_NULL)
+ if (gXProcWorkaroundShareData[ui32Index].pvCpuVAddr != IMG_NULL)
{
- OSUnReservePhys(gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
- gXProcWorkaroundShareData[ui32SI].ui32Size,
- gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
- gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+ OSUnReservePhys(gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32Index].ui32Size,
+ gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
}
- sSysPAddr = gXProcWorkaroundShareData[ui32SI].sSysPAddr;
- RA_Free (gXProcWorkaroundShareData[ui32SI].psArena,
+ sSysPAddr = gXProcWorkaroundShareData[ui32Index].sSysPAddr;
+ RA_Free (gXProcWorkaroundShareData[ui32Index].psArena,
sSysPAddr.uiAddr,
IMG_FALSE);
}
else
{
PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory"));
- OSFreePages(gXProcWorkaroundShareData[ui32SI].ui32AllocFlags,
- gXProcWorkaroundShareData[ui32SI].ui32PageSize,
- gXProcWorkaroundShareData[ui32SI].pvCpuVAddr,
- gXProcWorkaroundShareData[ui32SI].hOSMemHandle);
+ OSFreePages(gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32Index].ui32PageSize,
+ gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
}
}
}
+static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
+{
+ IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
+ PVRSRV_ERROR eError;
+
+ eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "bad handle"));
+ return;
+ }
+
+ BM_XProcIndexRelease(ui32SI);
+}
+
static IMG_BOOL
BM_ImportMemory (IMG_VOID *pH,
diff --git a/drivers/gpu/pvr/buffer_manager.h b/drivers/gpu/pvr/buffer_manager.h
index bf7c03887dd..b78b0ae3d3f 100644
--- a/drivers/gpu/pvr/buffer_manager.h
+++ b/drivers/gpu/pvr/buffer_manager.h
@@ -116,8 +116,18 @@ struct _BM_CONTEXT_
struct _BM_CONTEXT_ **ppsThis;
};
-
-
+typedef struct _XPROC_DATA_{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32AllocFlags;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32PageSize;
+ RA_ARENA *psArena;
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_VOID *pvCpuVAddr;
+ IMG_HANDLE hOSMemHandle;
+} XPROC_DATA;
+
+extern XPROC_DATA gXProcWorkaroundShareData[];
typedef IMG_VOID *BM_HANDLE;
#define BP_POOL_MASK 0x7
@@ -210,6 +220,25 @@ PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index);
PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index);
PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index);
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index);
+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index);
+
+#define BM_XProcIndexAcquire(x...) \
+ _BM_XProcIndexAcquireDebug(__FILE__, __LINE__, x)
+#define BM_XProcIndexRelease(x...) \
+ _BM_XProcIndexReleaseDebug(__FILE__, __LINE__, x)
+
+#else
+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index);
+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index);
+
+#define BM_XProcIndexAcquire(x...) \
+ _BM_XProcIndexAcquire( x)
+#define BM_XProcIndexRelease(x...) \
+ _BM_XProcIndexRelease( x)
+#endif
+
#if defined(__cplusplus)
}
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c
index 28342875f24..233ac08bfd2 100644
--- a/drivers/gpu/pvr/deviceclass.c
+++ b/drivers/gpu/pvr/deviceclass.c
@@ -581,10 +581,6 @@ static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
- if (psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
- }
psDCInfo->hDevMemContext = IMG_NULL;
psDCInfo->hExtDevice = IMG_NULL;
@@ -671,7 +667,7 @@ PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
psDCInfo->ui32RefCount--;
- PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
return eError;
}
@@ -681,11 +677,9 @@ PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer"));
psDCInfo->ui32RefCount--;
- PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
return eError;
}
-
- PVRSRVKernelSyncInfoIncRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
}
else
@@ -890,10 +884,6 @@ static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
- if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
- }
}
}
@@ -1097,8 +1087,6 @@ PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
goto ErrorExit;
}
- PVRSRVKernelSyncInfoIncRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
-
psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
@@ -1198,10 +1186,6 @@ ErrorExit:
if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
- if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
- }
}
}
@@ -1620,7 +1604,6 @@ PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
psCallbackData->pvPrivData = pvPrivData;
psCallbackData->ui32PrivDataLength = ui32PrivDataLength;
-
if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
sizeof(IMG_VOID *) * ui32NumMemSyncInfos,
(IMG_VOID **)&ppvMemInfos, IMG_NULL,
@@ -1662,7 +1645,6 @@ PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
ui32NumCompiledSyncInfos = ui32NumMemSyncInfos + ui32NumUniqueSyncInfos;
-
if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos,
(IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL,
@@ -1737,6 +1719,9 @@ PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos;
psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos;
+
+ psFlipCmd->hUnused = IMG_NULL;
+
SysAcquireData(&psSysData);
@@ -2137,10 +2122,6 @@ static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
- if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
- }
}
}
@@ -2262,8 +2243,6 @@ PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
goto ErrorExit;
}
-
- PVRSRVKernelSyncInfoIncRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
@@ -2306,10 +2285,6 @@ ErrorExit:
if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
- if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
- }
}
}
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c
index cd22faa7007..8874d614d84 100644
--- a/drivers/gpu/pvr/devicemem.c
+++ b/drivers/gpu/pvr/devicemem.c
@@ -516,7 +516,14 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
- psKernelSyncInfo->ui32RefCount = 0;
+ eError = OSAtomicAlloc(&psKernelSyncInfo->pvRefCount);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to allocate atomic"));
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
pBMContext = (BM_CONTEXT*)hDevMemContext;
@@ -541,6 +548,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+ OSAtomicFree(psKernelSyncInfo->pvRefCount);
OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
return PVRSRV_ERROR_OUT_OF_MEMORY;
@@ -558,6 +566,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
psSyncData->ui32ReadOps2Complete = 0;
psSyncData->ui32LastOpDumpVal = 0;
psSyncData->ui32LastReadOpDumpVal = 0;
+ psSyncData->ui64LastWrite = 0;
#if defined(PDUMP)
PDUMPCOMMENT("Allocating kernel sync object");
@@ -577,34 +586,34 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
+ OSAtomicInc(psKernelSyncInfo->pvRefCount);
+
*ppsKernelSyncInfo = psKernelSyncInfo;
return PVRSRV_OK;
}
-
IMG_EXPORT
-PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
+IMG_VOID PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
{
- PVRSRV_ERROR eError;
+ OSAtomicInc(psKernelSyncInfo->pvRefCount);
+}
- if (psKernelSyncInfo->ui32RefCount != 0)
+IMG_EXPORT
+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
+{
+ if (OSAtomicDecAndTest(psKernelSyncInfo->pvRefCount))
{
- PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
+ FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
+
+
+ psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL;
+ psKernelSyncInfo->psSyncData = IMG_NULL;
+ OSAtomicFree(psKernelSyncInfo->pvRefCount);
+ (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
- return PVRSRV_ERROR_OUT_OF_MEMORY;
}
-
- eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
-
-
- psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL;
- psKernelSyncInfo->psSyncData = IMG_NULL;
- (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
-
-
- return eError;
}
static IMG_VOID freeWrapped(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
@@ -661,7 +670,7 @@ PVRSRV_ERROR _PollUntilAtLeast(volatile IMG_UINT32* pui32WatchedValue,
if(psSysData->psGlobalEventObject)
{
eError = OSEventObjectOpenKM(psSysData->psGlobalEventObject, &hOSEventKM);
- if (eError |= PVRSRV_OK)
+ if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,
"_PollUntilAtLeast: OSEventObjectOpen failed"));
@@ -791,15 +800,11 @@ PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
case PVRSRV_MEMTYPE_WRAPPED:
freeWrapped(psMemInfo);
case PVRSRV_MEMTYPE_DEVICE:
+ case PVRSRV_MEMTYPE_DEVICECLASS:
if (psMemInfo->psKernelSyncInfo)
{
PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
- if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
- {
- eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
- }
}
- case PVRSRV_MEMTYPE_DEVICECLASS:
break;
default:
PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
@@ -921,8 +926,6 @@ PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
{
goto free_mainalloc;
}
-
- PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
}
@@ -957,6 +960,10 @@ PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
return (PVRSRV_OK);
free_mainalloc:
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
FreeDeviceMem(psMemInfo);
return eError;
@@ -1204,8 +1211,6 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
goto ErrorExitPhase4;
}
- PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
-
PVRSRVKernelMemInfoIncRef(psMemInfo);
@@ -1290,15 +1295,6 @@ static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
if( psMapData->psMemInfo->psKernelSyncInfo )
{
PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo);
- if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
- {
- eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
- if(eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
- return eError;
- }
- }
}
eError = FreeDeviceMem(psMapData->psMemInfo);
@@ -1723,6 +1719,12 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *
psMemInfo->uAllocSize = uByteSize;
psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
+ PVR_ASSERT(psMemInfo->psKernelSyncInfo != IMG_NULL);
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
psMemInfo->pvSysBackupBuffer = IMG_NULL;
@@ -1766,8 +1768,12 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *
#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
- PDUMPCOMMENT("Dump display surface");
- PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
+ if(psMemInfo->pvLinAddrKM)
+ {
+
+ PDUMPCOMMENT("Dump display surface");
+ PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
+ }
#endif
return PVRSRV_OK;
@@ -1775,6 +1781,11 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *
ErrorExitPhase3:
if(psMemInfo)
{
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
FreeDeviceMem(psMemInfo);
diff --git a/drivers/gpu/pvr/ion.c b/drivers/gpu/pvr/ion.c
index f897ffa11ea..b00fdb1e6c6 100644
--- a/drivers/gpu/pvr/ion.c
+++ b/drivers/gpu/pvr/ion.c
@@ -43,10 +43,9 @@
extern struct ion_client *gpsIONClient;
-struct ion_handle *
-PVRSRVExportFDToIONHandle(int fd, struct ion_client **client)
+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle *handles[2])
{
- struct ion_handle *psIONHandle = IMG_NULL;
PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
LinuxMemArea *psLinuxMemArea;
@@ -89,7 +88,8 @@ PVRSRVExportFDToIONHandle(int fd, struct ion_client **client)
goto err_fput;
}
- psIONHandle = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle;
+ handles[0] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0];
+ handles[1] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[1];
if(client)
*client = gpsIONClient;
@@ -98,7 +98,15 @@ err_fput:
err_unlock:
/* Allow PVRSRV clients to communicate with srvkm again */
LinuxUnLockMutex(&gPVRSRVLock);
- return psIONHandle;
}
+struct ion_handle *
+PVRSRVExportFDToIONHandle(int fd, struct ion_client **client)
+{
+ struct ion_handle *psHandles[2] = { IMG_NULL, IMG_NULL };
+ PVRSRVExportFDToIONHandles(fd, client, psHandles);
+ return psHandles[0];
+}
+
+EXPORT_SYMBOL(PVRSRVExportFDToIONHandles);
EXPORT_SYMBOL(PVRSRVExportFDToIONHandle);
diff --git a/drivers/gpu/pvr/ion.h b/drivers/gpu/pvr/ion.h
index 13f20e6051f..9b0868c9450 100644
--- a/drivers/gpu/pvr/ion.h
+++ b/drivers/gpu/pvr/ion.h
@@ -30,6 +30,9 @@
#include <linux/ion.h>
#include <linux/omap_ion.h>
+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle *handles[2]);
+
struct ion_handle *PVRSRVExportFDToIONHandle(int fd,
struct ion_client **client);
diff --git a/drivers/gpu/pvr/mm.c b/drivers/gpu/pvr/mm.c
index 9054a558096..5053a455436 100644
--- a/drivers/gpu/pvr/mm.c
+++ b/drivers/gpu/pvr/mm.c
@@ -24,6 +24,12 @@
*
******************************************************************************/
+
+
+
+
+
+
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
@@ -32,6 +38,14 @@
#endif
#endif
+#if !defined(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES)
+#define PVR_LINUX_MEM_AREA_POOL_MAX_PAGES 0
+#endif
+
+#include <linux/kernel.h>
+#include <asm/atomic.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -42,6 +56,10 @@
#include <linux/highmem.h>
#include <linux/sched.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0))
+#include <linux/shrinker.h>
+#endif
+
#include "img_defs.h"
#include "services.h"
#include "servicesint.h"
@@ -60,6 +78,8 @@
#include "lists.h"
#endif
+static atomic_t g_sPagePoolEntryCount = ATOMIC_INIT(0);
+
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
typedef enum {
DEBUG_MEM_ALLOC_TYPE_KMALLOC,
@@ -68,9 +88,12 @@ typedef enum {
DEBUG_MEM_ALLOC_TYPE_IOREMAP,
DEBUG_MEM_ALLOC_TYPE_IO,
DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE,
- DEBUG_MEM_ALLOC_TYPE_COUNT,
- DEBUG_MEM_ALLOC_TYPE_ION
-}DEBUG_MEM_ALLOC_TYPE;
+ DEBUG_MEM_ALLOC_TYPE_ION,
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ DEBUG_MEM_ALLOC_TYPE_VMAP,
+#endif
+ DEBUG_MEM_ALLOC_TYPE_COUNT
+} DEBUG_MEM_ALLOC_TYPE;
typedef struct _DEBUG_MEM_ALLOC_REC
{
@@ -86,7 +109,7 @@ typedef struct _DEBUG_MEM_ALLOC_REC
struct _DEBUG_MEM_ALLOC_REC *psNext;
struct _DEBUG_MEM_ALLOC_REC **ppsThis;
-}DEBUG_MEM_ALLOC_REC;
+} DEBUG_MEM_ALLOC_REC;
static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
@@ -100,8 +123,14 @@ static DEBUG_MEM_ALLOC_REC *g_MemoryRecords;
static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT];
-static IMG_UINT32 g_SysRAMWaterMark;
-static IMG_UINT32 g_SysRAMHighWaterMark;
+static IMG_UINT32 g_SysRAMWaterMark;
+static IMG_UINT32 g_SysRAMHighWaterMark;
+
+static inline IMG_UINT32
+SysRAMTrueWaterMark(void)
+{
+ return g_SysRAMWaterMark + PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount));
+}
static IMG_UINT32 g_IOMemWaterMark;
static IMG_UINT32 g_IOMemHighWaterMark;
@@ -120,7 +149,7 @@ static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_V
static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType);
-static struct proc_dir_entry *g_SeqFileMemoryRecords =0;
+static struct proc_dir_entry *g_SeqFileMemoryRecords;
static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off);
@@ -154,7 +183,7 @@ static IMG_UINT32 g_LinuxMemAreaWaterMark;
static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
-static struct proc_dir_entry *g_SeqFileMemArea=0;
+static struct proc_dir_entry *g_SeqFileMemArea;
static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
@@ -170,8 +199,19 @@ static PVRSRV_LINUX_MUTEX g_sDebugMutex;
static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
#endif
-static LinuxKMemCache *psLinuxMemAreaCache;
+typedef struct
+{
+
+ struct list_head sPagePoolItem;
+
+ struct page *psPage;
+} LinuxPagePoolEntry;
+static LinuxKMemCache *g_PsLinuxMemAreaCache;
+static LinuxKMemCache *g_PsLinuxPagePoolCache;
+
+static LIST_HEAD(g_sPagePoolList);
+static int g_iPagePoolMaxEntries;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length);
@@ -186,165 +226,26 @@ static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLin
static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea);
#endif
-PVRSRV_ERROR
-LinuxMMInit(IMG_VOID)
-{
-#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- LinuxInitMutex(&g_sDebugMutex);
-#endif
-
-#if defined(DEBUG_LINUX_MEM_AREAS)
- {
- g_SeqFileMemArea = CreateProcReadEntrySeq(
- "mem_areas",
- NULL,
- ProcSeqNextMemArea,
- ProcSeqShowMemArea,
- ProcSeqOff2ElementMemArea,
- ProcSeqStartstopDebugMutex
- );
- if(!g_SeqFileMemArea)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- }
-#endif
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- {
- g_SeqFileMemoryRecords =CreateProcReadEntrySeq(
- "meminfo",
- NULL,
- ProcSeqNextMemoryRecords,
- ProcSeqShowMemoryRecords,
- ProcSeqOff2ElementMemoryRecords,
- ProcSeqStartstopDebugMutex
- );
- if(!g_SeqFileMemoryRecords)
- {
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- }
-#endif
-
- psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
- if(!psLinuxMemAreaCache)
- {
- PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
- return PVRSRV_OK;
-}
-
-#if defined(DEBUG_LINUX_MEM_AREAS)
-static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
+static inline IMG_BOOL
+AreaIsUncached(IMG_UINT32 ui32AreaFlags)
{
- LinuxMemArea *psLinuxMemArea;
-
- psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
- PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
- __FUNCTION__,
- psCurrentRecord->psLinuxMemArea,
- LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
- psCurrentRecord->psLinuxMemArea->ui32ByteSize));
-
- LinuxMemAreaDeepFree(psLinuxMemArea);
-}
-#endif
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
-static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
-
-{
-
- PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
- "type=%s "
- "CpuVAddr=%p "
- "CpuPAddr=0x%08x, "
- "allocated @ file=%s,line=%d",
- __FUNCTION__,
- DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
- psCurrentRecord->pvCpuVAddr,
- psCurrentRecord->ulCpuPAddr,
- psCurrentRecord->pszFileName,
- psCurrentRecord->ui32Line));
- switch(psCurrentRecord->eAllocType)
- {
- case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
- KFreeWrapper(psCurrentRecord->pvCpuVAddr);
- break;
- case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
- IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
- break;
- case DEBUG_MEM_ALLOC_TYPE_IO:
-
- DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
- break;
- case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
- VFreeWrapper(psCurrentRecord->pvCpuVAddr);
- break;
- case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
-
- DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
- break;
- case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
- KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
- break;
- default:
- PVR_ASSERT(0);
- }
+ return (ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED)) != 0;
}
-#endif
-
-IMG_VOID
-LinuxMMCleanup(IMG_VOID)
+static inline IMG_BOOL
+CanFreeToPool(LinuxMemArea *psLinuxMemArea)
{
-
-#if defined(DEBUG_LINUX_MEM_AREAS)
- {
- if(g_LinuxMemAreaCount)
- {
- PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
- __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
- }
-
- List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords,
- LinuxMMCleanup_MemAreas_ForEachCb);
-
- RemoveProcEntrySeq( g_SeqFileMemArea );
- }
-#endif
-
-
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- {
-
-
- List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords,
- LinuxMMCleanup_MemRecords_ForEachVa);
-
- RemoveProcEntrySeq( g_SeqFileMemoryRecords );
- }
-#endif
-
- if(psLinuxMemAreaCache)
- {
- KMemCacheDestroyWrapper(psLinuxMemAreaCache);
- psLinuxMemAreaCache=NULL;
- }
+ return AreaIsUncached(psLinuxMemArea->ui32AreaFlags) && !psLinuxMemArea->bNeedsCacheInvalidate;
}
-
IMG_VOID *
_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
{
IMG_VOID *pvRet;
pvRet = kmalloc(ui32ByteSize, uFlags);
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- if(pvRet)
+ if (pvRet)
{
DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
pvRet,
@@ -354,7 +255,7 @@ _KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IM
ui32ByteSize,
pszFileName,
ui32Line
- );
+ );
}
#else
PVR_UNREFERENCED_PARAMETER(pszFileName);
@@ -407,27 +308,31 @@ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType,
List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord);
g_WaterMarkData[eAllocType] += ui32Bytes;
- if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
+ if (g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType])
{
g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType];
}
- if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+ if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
{
+ IMG_UINT32 ui32SysRAMTrueWaterMark;
+
g_SysRAMWaterMark += ui32Bytes;
- if(g_SysRAMWaterMark > g_SysRAMHighWaterMark)
+ ui32SysRAMTrueWaterMark = SysRAMTrueWaterMark();
+
+ if (ui32SysRAMTrueWaterMark > g_SysRAMHighWaterMark)
{
- g_SysRAMHighWaterMark = g_SysRAMWaterMark;
+ g_SysRAMHighWaterMark = ui32SysRAMTrueWaterMark;
}
}
- else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+ else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
{
g_IOMemWaterMark += ui32Bytes;
- if(g_IOMemWaterMark > g_IOMemHighWaterMark)
+ if (g_IOMemWaterMark > g_IOMemHighWaterMark)
{
g_IOMemHighWaterMark = g_IOMemWaterMark;
}
@@ -445,20 +350,20 @@ static IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrent
eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
pvKey = va_arg(va, IMG_VOID*);
- if(psCurrentRecord->eAllocType == eAllocType
+ if (psCurrentRecord->eAllocType == eAllocType
&& psCurrentRecord->pvKey == pvKey)
{
eAllocType = psCurrentRecord->eAllocType;
g_WaterMarkData[eAllocType] -= psCurrentRecord->ui32Bytes;
- if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
+ if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
{
g_SysRAMWaterMark -= psCurrentRecord->ui32Bytes;
}
- else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+ else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
|| eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
{
g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
@@ -482,7 +387,7 @@ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_
LinuxLockMutex(&g_sDebugMutex);
- if(!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
+ if (!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
DebugMemAllocRecordRemove_AnyVaCb,
eAllocType,
pvKey))
@@ -505,24 +410,22 @@ DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
"ALLOC_PAGES",
"IOREMAP",
"IO",
- "KMEM_CACHE_ALLOC"
+ "KMEM_CACHE_ALLOC",
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ "VMAP"
+#endif
};
return apszDebugMemoryRecordTypes[eAllocType];
}
#endif
-
-IMG_VOID *
-_VMallocWrapper(IMG_UINT32 ui32Bytes,
- IMG_UINT32 ui32AllocFlags,
- IMG_CHAR *pszFileName,
- IMG_UINT32 ui32Line)
+static IMG_BOOL
+AllocFlagsToPGProt(pgprot_t *pPGProtFlags, IMG_UINT32 ui32AllocFlags)
{
pgprot_t PGProtFlags;
- IMG_VOID *pvRet;
-
- switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
+
+ switch (ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK)
{
case PVRSRV_HAP_CACHED:
PGProtFlags = PAGE_KERNEL;
@@ -535,9 +438,28 @@ _VMallocWrapper(IMG_UINT32 ui32Bytes,
break;
default:
PVR_DPF((PVR_DBG_ERROR,
- "VMAllocWrapper: unknown mapping flags=0x%08x",
- ui32AllocFlags));
+ "%s: Unknown mapping flags=0x%08x",
+ __FUNCTION__, ui32AllocFlags));
dump_stack();
+ return IMG_FALSE;
+ }
+
+ *pPGProtFlags = PGProtFlags;
+
+ return IMG_TRUE;
+}
+
+IMG_VOID *
+_VMallocWrapper(IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32AllocFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ pgprot_t PGProtFlags;
+ IMG_VOID *pvRet;
+
+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags))
+ {
return NULL;
}
@@ -545,7 +467,7 @@ _VMallocWrapper(IMG_UINT32 ui32Bytes,
pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- if(pvRet)
+ if (pvRet)
{
DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC,
pvRet,
@@ -555,7 +477,7 @@ _VMallocWrapper(IMG_UINT32 ui32Bytes,
PAGE_ALIGN(ui32Bytes),
pszFileName,
ui32Line
- );
+ );
}
#else
PVR_UNREFERENCED_PARAMETER(pszFileName);
@@ -579,31 +501,475 @@ _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
}
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+static IMG_VOID *
+_VMapWrapper(struct page **ppsPageList, IMG_UINT32 ui32NumPages, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+ pgprot_t PGProtFlags;
+ IMG_VOID *pvRet;
+
+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags))
+ {
+ return NULL;
+ }
+
+ pvRet = vmap(ppsPageList, ui32NumPages, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if (pvRet)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMAP,
+ pvRet,
+ pvRet,
+ 0,
+ NULL,
+ PAGES_TO_BYTES(ui32NumPages),
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvRet;
+}
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags) _VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
+#else
+#define VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags) _VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags, NULL, 0)
+#endif
+
+
+static IMG_VOID
+_VUnmapWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMAP, pvCpuVAddr, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ vunmap(pvCpuVAddr);
+}
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, NULL, 0)
+#endif
+
+#endif
+
+
+IMG_VOID
+_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ kmem_cache_free(psCache, pvObject);
+}
+
+
+const IMG_CHAR *
+KMemCacheNameWrapper(LinuxKMemCache *psCache)
+{
+ PVR_UNREFERENCED_PARAMETER(psCache);
+
+
+ return "";
+}
+
+
+static LinuxPagePoolEntry *
+LinuxPagePoolEntryAlloc(IMG_VOID)
+{
+ return KMemCacheAllocWrapper(g_PsLinuxPagePoolCache, GFP_KERNEL);
+}
+
+static IMG_VOID
+LinuxPagePoolEntryFree(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ KMemCacheFreeWrapper(g_PsLinuxPagePoolCache, psPagePoolEntry);
+}
+
+
+static struct page *
+AllocPageFromLinux(void)
+{
+ struct page *psPage;
+
+ psPage = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
+ if (!psPage)
+ {
+ return NULL;
+
+ }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ SetPageReserved(psPage);
+#else
+ mem_map_reserve(psPage);
+#endif
+#endif
+ return psPage;
+}
+
+
+static IMG_VOID
+FreePageToLinux(struct page *psPage)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ ClearPageReserved(psPage);
+#else
+ mem_map_reserve(psPage);
+#endif
+#endif
+ __free_pages(psPage, 0);
+}
+
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+static DEFINE_MUTEX(g_sPagePoolMutex);
+
+static inline void
+PagePoolLock(void)
+{
+ mutex_lock(&g_sPagePoolMutex);
+}
+
+static inline void
+PagePoolUnlock(void)
+{
+ mutex_unlock(&g_sPagePoolMutex);
+}
+
+static inline int
+PagePoolTrylock(void)
+{
+ return mutex_trylock(&g_sPagePoolMutex);
+}
+
+#else
+static inline void
+PagePoolLock(void)
+{
+}
+
+static inline void
+PagePoolUnlock(void)
+{
+}
+
+static inline int
+PagePoolTrylock(void)
+{
+ return 1;
+}
+#endif
+
+
+static inline void
+AddEntryToPool(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ list_add_tail(&psPagePoolEntry->sPagePoolItem, &g_sPagePoolList);
+ atomic_inc(&g_sPagePoolEntryCount);
+}
+
+static inline void
+RemoveEntryFromPool(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ list_del(&psPagePoolEntry->sPagePoolItem);
+ atomic_dec(&g_sPagePoolEntryCount);
+}
+
+static inline LinuxPagePoolEntry *
+RemoveFirstEntryFromPool(void)
+{
+ LinuxPagePoolEntry *psPagePoolEntry;
+
+ if (list_empty(&g_sPagePoolList))
+ {
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+
+ return NULL;
+ }
+
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) > 0);
+
+ psPagePoolEntry = list_first_entry(&g_sPagePoolList, LinuxPagePoolEntry, sPagePoolItem);
+
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ return psPagePoolEntry;
+}
+
+static struct page *
+AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPagePool)
+{
+ struct page *psPage = NULL;
+
+
+ if (AreaIsUncached(ui32AreaFlags) && atomic_read(&g_sPagePoolEntryCount) != 0)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry;
+
+ PagePoolLock();
+ psPagePoolEntry = RemoveFirstEntryFromPool();
+ PagePoolUnlock();
+
+
+ if (psPagePoolEntry)
+ {
+ psPage = psPagePoolEntry->psPage;
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+ *pbFromPagePool = IMG_TRUE;
+ }
+ }
+
+ if (!psPage)
+ {
+ psPage = AllocPageFromLinux();
+ if (psPage)
+ {
+ *pbFromPagePool = IMG_FALSE;
+ }
+ }
+
+ return psPage;
+
+}
+
+static IMG_VOID
+FreePage(IMG_BOOL bToPagePool, struct page *psPage)
+{
+
+ if (bToPagePool && atomic_read(&g_sPagePoolEntryCount) < g_iPagePoolMaxEntries)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry = LinuxPagePoolEntryAlloc();
+ if (psPagePoolEntry)
+ {
+ psPagePoolEntry->psPage = psPage;
+
+ PagePoolLock();
+ AddEntryToPool(psPagePoolEntry);
+ PagePoolUnlock();
+
+ return;
+ }
+ }
+
+ FreePageToLinux(psPage);
+}
+
+static IMG_VOID
+FreePagePool(IMG_VOID)
+{
+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry;
+
+ PagePoolLock();
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ PVR_TRACE(("%s: Freeing %d pages from pool", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+#else
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+ PVR_ASSERT(list_empty(&g_sPagePoolList));
+#endif
+
+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem)
+ {
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ FreePageToLinux(psPagePoolEntry->psPage);
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+ }
+
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+
+ PagePoolUnlock();
+}
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+static struct shrinker g_sShrinker;
+#endif
+
+static int
+ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl)
+{
+ unsigned long uNumToScan = psShrinkControl->nr_to_scan;
+
+ PVR_ASSERT(psShrinker == &g_sShrinker);
+ (void)psShrinker;
+
+ if (uNumToScan != 0)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry;
+
+ PVR_TRACE(("%s: Number to scan: %ld", __FUNCTION__, uNumToScan));
+ PVR_TRACE(("%s: Pages in pool before scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+
+ if (!PagePoolTrylock())
+ {
+ PVR_TRACE(("%s: Couldn't get page pool lock", __FUNCTION__));
+ return -1;
+ }
+
+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem)
+ {
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ FreePageToLinux(psPagePoolEntry->psPage);
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+
+ if (--uNumToScan == 0)
+ {
+ break;
+ }
+ }
+
+ if (list_empty(&g_sPagePoolList))
+ {
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+ }
+
+ PagePoolUnlock();
+
+ PVR_TRACE(("%s: Pages in pool after scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+ }
+
+ return atomic_read(&g_sPagePoolEntryCount);
+}
+#endif
+
+static IMG_BOOL
+AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *phBlockPageList, IMG_UINT32 ui32NumPages, IMG_BOOL *pbFromPagePool)
+{
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+ IMG_INT32 i;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bFromPagePool = IMG_FALSE;
+
+ eError = OSAllocMem(0, sizeof(*ppsPageList) * ui32NumPages, (IMG_VOID **)&ppsPageList, &hBlockPageList,
+ "Array of pages");
+ if (eError != PVRSRV_OK)
+ {
+ goto failed_page_list_alloc;
+ }
+
+ *pbFromPagePool = IMG_TRUE;
+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++)
+ {
+ ppsPageList[i] = AllocPage(ui32AreaFlags, &bFromPagePool);
+ if (!ppsPageList[i])
+ {
+ goto failed_alloc_pages;
+ }
+ *pbFromPagePool &= bFromPagePool;
+ }
+
+ *pppsPageList = ppsPageList;
+ *phBlockPageList = hBlockPageList;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+ ppsPageList,
+ 0,
+ 0,
+ NULL,
+ PAGES_TO_BYTES(ui32NumPages),
+ "unknown",
+ 0
+ );
+#endif
+
+ return IMG_TRUE;
+
+failed_alloc_pages:
+ for(i--; i >= 0; i--)
+ {
+ FreePage(*pbFromPagePool, ppsPageList[i]);
+ }
+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList);
+
+failed_page_list_alloc:
+ return IMG_FALSE;
+}
+
+
+static IMG_VOID
+FreePages(IMG_BOOL bToPagePool, struct page **ppsPageList, IMG_HANDLE hBlockPageList, IMG_UINT32 ui32NumPages)
+{
+ IMG_INT32 i;
+
+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++)
+ {
+ FreePage(bToPagePool, ppsPageList[i]);
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, ppsPageList, __FILE__, __LINE__);
+#endif
+
+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList);
+}
+
+
LinuxMemArea *
NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
{
- LinuxMemArea *psLinuxMemArea;
+ LinuxMemArea *psLinuxMemArea = NULL;
IMG_VOID *pvCpuVAddr;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ IMG_UINT32 ui32NumPages = 0;
+ struct page **ppsPageList = NULL;
+ IMG_HANDLE hBlockPageList;
+#endif
+ IMG_BOOL bFromPagePool = IMG_FALSE;
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
goto failed;
}
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool))
+ {
+ goto failed;
+ }
+
+ pvCpuVAddr = VMapWrapper(ppsPageList, ui32NumPages, ui32AreaFlags);
+#else
pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
- if(!pvCpuVAddr)
+ if (!pvCpuVAddr)
{
goto failed;
}
-
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
ReservePages(pvCpuVAddr, ui32Bytes);
#endif
+#endif
psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ psLinuxMemArea->uData.sVmalloc.ppsPageList = ppsPageList;
+ psLinuxMemArea->uData.sVmalloc.hBlockPageList = hBlockPageList;
+#endif
psLinuxMemArea->ui32ByteSize = ui32Bytes;
psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
@@ -613,15 +979,26 @@ NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
#endif
- if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
+ if (AreaIsUncached(ui32AreaFlags) && !bFromPagePool)
+ {
OSInvalidateCPUCacheRangeKM(psLinuxMemArea, pvCpuVAddr, ui32Bytes);
+ }
return psLinuxMemArea;
failed:
PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
- if(psLinuxMemArea)
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ if (ppsPageList)
+ {
+ FreePages(bFromPagePool, ppsPageList, hBlockPageList, ui32NumPages);
+ }
+#endif
+ if (psLinuxMemArea)
+ {
LinuxMemAreaStructFree(psLinuxMemArea);
+ }
+
return NULL;
}
@@ -629,6 +1006,12 @@ failed:
IMG_VOID
FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
{
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+#endif
+
PVR_ASSERT(psLinuxMemArea);
PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC);
PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
@@ -637,14 +1020,25 @@ FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
#endif
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
+ __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
+
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ VUnmapWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+ ppsPageList = psLinuxMemArea->uData.sVmalloc.ppsPageList;
+ hBlockPageList = psLinuxMemArea->uData.sVmalloc.hBlockPageList;
+
+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages);
+#else
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
- UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
+ UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
psLinuxMemArea->ui32ByteSize);
#endif
- PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
- __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+#endif
LinuxMemAreaStructFree(psLinuxMemArea);
}
@@ -695,7 +1089,7 @@ _IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
{
IMG_VOID *pvIORemapCookie;
- switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ switch (ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK)
{
case PVRSRV_HAP_CACHED:
pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes);
@@ -712,7 +1106,7 @@ _IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
}
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- if(pvIORemapCookie)
+ if (pvIORemapCookie)
{
DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP,
pvIORemapCookie,
@@ -722,7 +1116,7 @@ _IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
ui32Bytes,
pszFileName,
ui32Line
- );
+ );
}
#else
PVR_UNREFERENCED_PARAMETER(pszFileName);
@@ -755,13 +1149,13 @@ NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
IMG_VOID *pvIORemapCookie;
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
return NULL;
}
pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags);
- if(!pvIORemapCookie)
+ if (!pvIORemapCookie)
{
LinuxMemAreaStructFree(psLinuxMemArea);
return NULL;
@@ -842,7 +1236,7 @@ LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *p
LinuxMemArea *psLinuxMemArea;
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
return NULL;
}
@@ -895,7 +1289,7 @@ NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
IMG_UINT32 ui32AreaFlags)
{
LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
return NULL;
}
@@ -916,7 +1310,7 @@ NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr,
ui32Bytes,
"unknown",
0
- );
+ );
#endif
#if defined(DEBUG_LINUX_MEM_AREAS)
@@ -951,68 +1345,33 @@ LinuxMemArea *
NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
{
LinuxMemArea *psLinuxMemArea;
- IMG_UINT32 ui32PageCount;
- struct page **pvPageList;
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
IMG_HANDLE hBlockPageList;
- IMG_INT32 i;
- PVRSRV_ERROR eError;
-
+ IMG_BOOL bFromPagePool;
+
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
goto failed_area_alloc;
}
- ui32PageCount = RANGE_TO_PAGES(ui32Bytes);
- eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList,
- "Array of pages");
- if(eError != PVRSRV_OK)
- {
- goto failed_page_list_alloc;
- }
-
- for(i=0; i<(IMG_INT32)ui32PageCount; i++)
- {
- pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
- if(!pvPageList[i])
- {
- goto failed_alloc_pages;
- }
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
- SetPageReserved(pvPageList[i]);
-#else
- mem_map_reserve(pvPageList[i]);
-#endif
-#endif
+ ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool))
+ {
+ goto failed_alloc_pages;
}
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
- pvPageList,
- 0,
- 0,
- NULL,
- PAGE_ALIGN(ui32Bytes),
- "unknown",
- 0
- );
-#endif
-
psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
- psLinuxMemArea->uData.sPageList.pvPageList = pvPageList;
+ psLinuxMemArea->uData.sPageList.ppsPageList = ppsPageList;
psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
psLinuxMemArea->ui32ByteSize = ui32Bytes;
psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
- if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
- {
- psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
- }
+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags) && !bFromPagePool;
#if defined(DEBUG_LINUX_MEM_AREAS)
DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
@@ -1021,13 +1380,6 @@ NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
return psLinuxMemArea;
failed_alloc_pages:
- for(i--; i >= 0; i--)
- {
- __free_pages(pvPageList[i], 0);
- }
- (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
- psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
-failed_page_list_alloc:
LinuxMemAreaStructFree(psLinuxMemArea);
failed_area_alloc:
PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
@@ -1039,10 +1391,9 @@ failed_area_alloc:
IMG_VOID
FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
{
- IMG_UINT32 ui32PageCount;
- struct page **pvPageList;
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
IMG_HANDLE hBlockPageList;
- IMG_INT32 i;
PVR_ASSERT(psLinuxMemArea);
PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
@@ -1051,29 +1402,12 @@ FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
#endif
- ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
- pvPageList = psLinuxMemArea->uData.sPageList.pvPageList;
+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+ ppsPageList = psLinuxMemArea->uData.sPageList.ppsPageList;
hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__);
-#endif
-
- for(i=0;i<(IMG_INT32)ui32PageCount;i++)
- {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
- ClearPageReserved(pvPageList[i]);
-#else
- mem_map_reserve(pvPageList[i]);
-#endif
-#endif
- __free_pages(pvPageList[i], 0);
- }
-
- (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList);
- psLinuxMemArea->uData.sPageList.pvPageList = IMG_NULL;
-
+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages);
+
LinuxMemAreaStructFree(psLinuxMemArea);
}
@@ -1090,62 +1424,86 @@ LinuxMemArea *
NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength)
{
- struct omap_ion_tiler_alloc_data sAllocData;
+ const IMG_UINT32 ui32AllocDataLen =
+ offsetof(struct omap_ion_tiler_alloc_data, handle);
+ struct omap_ion_tiler_alloc_data asAllocData[2] = {};
+ u32 *pu32PageAddrs[2] = { NULL, NULL };
+ IMG_UINT32 i, ui32NumHandlesPerFd;
+ IMG_BYTE *pbPrivData = pvPrivData;
+ IMG_CPU_PHYADDR *pCPUPhysAddrs;
+ int iNumPages[2] = { 0, 0 };
LinuxMemArea *psLinuxMemArea;
- u32 *pu32PageAddrs;
- int iNumPages;
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate LinuxMemArea struct", __func__));
goto err_out;
}
- BUG_ON(ui32PrivDataLength != offsetof(struct omap_ion_tiler_alloc_data, handle));
- memcpy(&sAllocData, pvPrivData, offsetof(struct omap_ion_tiler_alloc_data, handle));
+ BUG_ON(ui32PrivDataLength != ui32AllocDataLen &&
+ ui32PrivDataLength != ui32AllocDataLen * 2);
+ ui32NumHandlesPerFd = ui32PrivDataLength / ui32AllocDataLen;
- if(omap_ion_tiler_alloc(gpsIONClient, &sAllocData) < 0)
+
+ for(i = 0; i < ui32NumHandlesPerFd; i++)
{
- PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_tiler", __func__));
- goto err_free;
+ memcpy(&asAllocData[i], &pbPrivData[i * ui32AllocDataLen], ui32AllocDataLen);
+
+ if (omap_ion_tiler_alloc(gpsIONClient, &asAllocData[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_tiler", __func__));
+ goto err_free;
+ }
+
+ if (omap_tiler_pages(gpsIONClient, asAllocData[i].handle, &iNumPages[i],
+ &pu32PageAddrs[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute tiler pages", __func__));
+ goto err_free;
+ }
}
- if(omap_tiler_pages(gpsIONClient, sAllocData.handle, &iNumPages,
- &pu32PageAddrs) < 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute tiler pages", __func__));
- goto err_free;
- }
+
+ BUG_ON(ui32Bytes != (iNumPages[0] + iNumPages[1]) * PAGE_SIZE);
+ BUG_ON(sizeof(IMG_CPU_PHYADDR) != sizeof(int));
- BUG_ON(ui32Bytes != iNumPages * PAGE_SIZE);
+ pCPUPhysAddrs = vmalloc(sizeof(IMG_CPU_PHYADDR) * (iNumPages[0] + iNumPages[1]));
+ if (!pCPUPhysAddrs)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate page list", __func__));
+ goto err_free;
+ }
+ for(i = 0; i < iNumPages[0]; i++)
+ pCPUPhysAddrs[i].uiAddr = pu32PageAddrs[0][i];
+ for(i = 0; i < iNumPages[1]; i++)
+ pCPUPhysAddrs[iNumPages[0] + i].uiAddr = pu32PageAddrs[1][i];
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ION,
- sAllocData.handle,
+ asAllocData[0].handle,
0,
0,
NULL,
PAGE_ALIGN(ui32Bytes),
"unknown",
0
- );
+ );
#endif
+ for(i = 0; i < 2; i++)
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = asAllocData[i].handle;
+
psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ION;
- psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = (IMG_CPU_PHYADDR *)pu32PageAddrs;
- psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle = sAllocData.handle;
+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = pCPUPhysAddrs;
psLinuxMemArea->ui32ByteSize = ui32Bytes;
psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
- if(ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED))
- {
- psLinuxMemArea->bNeedsCacheInvalidate = IMG_TRUE;
- }
+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags);
#if defined(DEBUG_LINUX_MEM_AREAS)
DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
@@ -1164,21 +1522,29 @@ err_free:
IMG_VOID
FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea)
{
+ IMG_UINT32 i;
+
#if defined(DEBUG_LINUX_MEM_AREAS)
DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
#endif
- ion_free(gpsIONClient, psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle);
-
#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ION,
- psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle,
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0],
__FILE__, __LINE__);
#endif
+ for(i = 0; i < 2; i++)
+ {
+ if (!psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i])
+ break;
+ ion_free(gpsIONClient, psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i]);
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = IMG_NULL;
+ }
+
+ vfree(psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs);
psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = IMG_NULL;
- psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle = IMG_NULL;
LinuxMemAreaStructFree(psLinuxMemArea);
}
@@ -1192,11 +1558,11 @@ LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea,
IMG_UINT32 ui32PageIndex;
IMG_CHAR *pui8Addr;
- switch(psLinuxMemArea->eAreaType)
+ switch (psLinuxMemArea->eAreaType)
{
case LINUX_MEM_AREA_ALLOC_PAGES:
ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
- return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+ return psLinuxMemArea->uData.sPageList.ppsPageList[ui32PageIndex];
case LINUX_MEM_AREA_VMALLOC:
pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
@@ -1230,7 +1596,7 @@ KMemCacheCreateWrapper(IMG_CHAR *pszName,
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
, NULL
#endif
- );
+ );
}
@@ -1264,7 +1630,7 @@ _KMemCacheAllocWrapper(LinuxKMemCache *psCache,
kmem_cache_size(psCache),
pszFileName,
ui32Line
- );
+ );
#else
PVR_UNREFERENCED_PARAMETER(pszFileName);
PVR_UNREFERENCED_PARAMETER(ui32Line);
@@ -1274,30 +1640,6 @@ _KMemCacheAllocWrapper(LinuxKMemCache *psCache,
}
-IMG_VOID
-_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
-{
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
- DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line);
-#else
- PVR_UNREFERENCED_PARAMETER(pszFileName);
- PVR_UNREFERENCED_PARAMETER(ui32Line);
-#endif
-
- kmem_cache_free(psCache, pvObject);
-}
-
-
-const IMG_CHAR *
-KMemCacheNameWrapper(LinuxKMemCache *psCache)
-{
- PVR_UNREFERENCED_PARAMETER(psCache);
-
-
- return "";
-}
-
-
LinuxMemArea *
NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
IMG_UINT32 ui32ByteOffset,
@@ -1308,7 +1650,7 @@ NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize);
psLinuxMemArea = LinuxMemAreaStructAlloc();
- if(!psLinuxMemArea)
+ if (!psLinuxMemArea)
{
return NULL;
}
@@ -1353,12 +1695,12 @@ LinuxMemAreaStructAlloc(IMG_VOID)
{
#if 0
LinuxMemArea *psLinuxMemArea;
- psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL);
+ psLinuxMemArea = kmem_cache_alloc(g_PsLinuxMemAreaCache, GFP_KERNEL);
printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
dump_stack();
return psLinuxMemArea;
#else
- return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL);
+ return KMemCacheAllocWrapper(g_PsLinuxMemAreaCache, GFP_KERNEL);
#endif
}
@@ -1366,7 +1708,7 @@ LinuxMemAreaStructAlloc(IMG_VOID)
static IMG_VOID
LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
{
- KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea);
+ KMemCacheFreeWrapper(g_PsLinuxMemAreaCache, psLinuxMemArea);
}
@@ -1375,7 +1717,7 @@ LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
IMG_VOID
LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea)
{
- switch(psLinuxMemArea->eAreaType)
+ switch (psLinuxMemArea->eAreaType)
{
case LINUX_MEM_AREA_VMALLOC:
FreeVMallocLinuxMemArea(psLinuxMemArea);
@@ -1415,10 +1757,10 @@ DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
LinuxLockMutex(&g_sDebugMutex);
- if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
{
g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize;
- if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
+ if (g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark)
{
g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark;
}
@@ -1427,7 +1769,7 @@ DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
- if(psNewRecord)
+ if (psNewRecord)
{
psNewRecord->psLinuxMemArea = psLinuxMemArea;
@@ -1445,7 +1787,7 @@ DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags)
pi8FlagsString = HAPFlagsToString(ui32Flags);
- if(strstr(pi8FlagsString, "UNKNOWN"))
+ if (strstr(pi8FlagsString, "UNKNOWN"))
{
PVR_DPF((PVR_DBG_ERROR,
"%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p",
@@ -1466,7 +1808,7 @@ static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRe
LinuxMemArea *psLinuxMemArea;
psLinuxMemArea = va_arg(va, LinuxMemArea*);
- if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
+ if (psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
{
return psCurrentRecord;
}
@@ -1500,7 +1842,7 @@ DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
LinuxLockMutex(&g_sDebugMutex);
- if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
{
g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
}
@@ -1510,7 +1852,7 @@ DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
MatchLinuxMemArea_AnyVaCb,
psLinuxMemArea);
- if(psCurrentRecord)
+ if (psCurrentRecord)
{
List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
@@ -1530,7 +1872,7 @@ DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
IMG_VOID *
LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
{
- switch(psLinuxMemArea->eAreaType)
+ switch (psLinuxMemArea->eAreaType)
{
case LINUX_MEM_AREA_VMALLOC:
return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
@@ -1542,7 +1884,7 @@ LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea)
{
IMG_CHAR *pAddr =
LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
- if(!pAddr)
+ if (!pAddr)
{
return NULL;
}
@@ -1561,7 +1903,7 @@ LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
CpuPAddr.uiAddr = 0;
- switch(psLinuxMemArea->eAreaType)
+ switch (psLinuxMemArea->eAreaType)
{
case LINUX_MEM_AREA_IOREMAP:
{
@@ -1612,7 +1954,7 @@ LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
{
struct page *page;
IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
- page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex];
+ page = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PageIndex];
CpuPAddr.uiAddr = page_to_phys(page);
CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
break;
@@ -1627,9 +1969,8 @@ LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
}
default:
{
- PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)",
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
__FUNCTION__, psLinuxMemArea->eAreaType));
- dump_stack();
PVR_ASSERT(CpuPAddr.uiAddr);
break;
}
@@ -1642,7 +1983,7 @@ LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset)
IMG_BOOL
LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
{
- switch(psLinuxMemArea->eAreaType)
+ switch (psLinuxMemArea->eAreaType)
{
case LINUX_MEM_AREA_IOREMAP:
case LINUX_MEM_AREA_IO:
@@ -1661,7 +2002,7 @@ LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea)
return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea);
default:
- PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)",
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n",
__FUNCTION__, psLinuxMemArea->eAreaType));
break;
}
@@ -1673,7 +2014,7 @@ const IMG_CHAR *
LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
{
- switch(eMemAreaType)
+ switch (eMemAreaType)
{
case LINUX_MEM_AREA_IOREMAP:
return "LINUX_MEM_AREA_IOREMAP";
@@ -1700,7 +2041,7 @@ LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType)
#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start)
{
- if(start)
+ if (start)
{
LinuxLockMutex(&g_sDebugMutex);
}
@@ -1740,7 +2081,7 @@ static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off)
static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
{
DEBUG_LINUX_MEM_AREA_REC *psRecord;
- if(!off)
+ if (!off)
{
return PVR_PROC_SEQ_START_TOKEN;
}
@@ -1756,11 +2097,11 @@ static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
{
DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el;
- if(el == PVR_PROC_SEQ_START_TOKEN)
+ if (el == PVR_PROC_SEQ_START_TOKEN)
{
#if !defined(DEBUG_LINUX_XML_PROC_FILES)
- seq_printf( sfile,
+ seq_printf(sfile,
"Number of Linux Memory Areas: %u\n"
"At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n"
"At the highest water mark these areas corresponded to %u bytes (excluding SUB areas)\n"
@@ -1776,9 +2117,9 @@ static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
"Bytes",
"Pid",
"Flags"
- );
+ );
#else
- seq_printf( sfile,
+ seq_printf(sfile,
"<mem_areas_header>\n"
"\t<count>%u</count>\n"
"\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n"
@@ -1787,12 +2128,12 @@ static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
g_LinuxMemAreaCount,
g_LinuxMemAreaWaterMark,
g_LinuxMemAreaHighWaterMark
- );
+ );
#endif
return;
}
- seq_printf( sfile,
+ seq_printf(sfile,
#if !defined(DEBUG_LINUX_XML_PROC_FILES)
"%8p %-24s %8p %08x %-8d %-5u %08x=(%s)\n",
#else
@@ -1801,9 +2142,9 @@ static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
"\t<type>%s</type>\n"
"\t<cpu_virtual>%8p</cpu_virtual>\n"
"\t<cpu_physical>%08x</cpu_physical>\n"
- "\t<bytes>%ld</bytes>\n"
+ "\t<bytes>%d</bytes>\n"
"\t<pid>%u</pid>\n"
- "\t<flags>%08lx</flags>\n"
+ "\t<flags>%08x</flags>\n"
"\t<flags_string>%s</flags_string>\n"
"</linux_mem_area>\n",
#endif
@@ -1815,7 +2156,7 @@ static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
psRecord->pid,
psRecord->ui32Flags,
HAPFlagsToString(psRecord->ui32Flags)
- );
+ );
}
@@ -1847,9 +2188,9 @@ static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off
DecOffMemAllocRec_AnyVaCb,
&off);
#if defined(DEBUG_LINUX_XML_PROC_FILES)
- if(!psRecord)
+ if (!psRecord)
{
- seq_printf( sfile, "</meminfo>\n");
+ seq_printf(sfile, "</meminfo>\n");
}
#endif
@@ -1859,7 +2200,7 @@ static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off
static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
{
DEBUG_MEM_ALLOC_REC *psRecord;
- if(!off)
+ if (!off)
{
return PVR_PROC_SEQ_START_TOKEN;
}
@@ -1870,9 +2211,9 @@ static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
&off);
#if defined(DEBUG_LINUX_XML_PROC_FILES)
- if(!psRecord)
+ if (!psRecord)
{
- seq_printf( sfile, "</meminfo>\n");
+ seq_printf(sfile, "</meminfo>\n");
}
#endif
@@ -1882,64 +2223,76 @@ static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
{
DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
- if(el == PVR_PROC_SEQ_START_TOKEN)
+ if (el == PVR_PROC_SEQ_START_TOKEN)
{
#if !defined(DEBUG_LINUX_XML_PROC_FILES)
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes allocated via kmalloc",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated via kmalloc",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes allocated via vmalloc",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated via vmalloc",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes allocated via alloc_pages",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated via alloc_pages",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes allocated via ioremap",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated via ioremap",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes reserved for \"IO\" memory areas",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated for \"IO\" memory areas",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Current Water Mark of bytes allocated via kmem_cache_alloc",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"Highest Water Mark of bytes allocated via kmem_cache_alloc",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes mapped via vmap",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes mapped via vmap",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+#endif
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ seq_printf(sfile, "%-60s: %d pages\n",
+ "Number of pages in page pool",
+ atomic_read(&g_sPagePoolEntryCount));
+#endif
seq_printf( sfile, "\n");
-
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"The Current Water Mark for memory allocated from system RAM",
- g_SysRAMWaterMark);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ SysRAMTrueWaterMark());
+ seq_printf(sfile, "%-60s: %d bytes\n",
"The Highest Water Mark for memory allocated from system RAM",
g_SysRAMHighWaterMark);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"The Current Water Mark for memory allocated from IO memory",
g_IOMemWaterMark);
- seq_printf( sfile, "%-60s: %d bytes\n",
+ seq_printf(sfile, "%-60s: %d bytes\n",
"The Highest Water Mark for memory allocated from IO memory",
g_IOMemHighWaterMark);
seq_printf( sfile, "\n");
- seq_printf( sfile, "Details for all known allocations:\n"
+ seq_printf(sfile, "Details for all known allocations:\n"
"%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
"Type",
"CpuVAddr",
@@ -1952,67 +2305,78 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
#else
- seq_printf( sfile, "<meminfo>\n<meminfo_header>\n");
- seq_printf( sfile,
+ seq_printf(sfile, "<meminfo>\n<meminfo_header>\n");
+ seq_printf(sfile,
"<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n",
g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n",
g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
- seq_printf( sfile,"\n" );
-
- seq_printf( sfile,
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ seq_printf(sfile,
+ "<watermark key=\"mr12\" description=\"vmap_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+ seq_printf(sfile,
+ "<watermark key=\"mr13\" description=\"vmap_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+#endif
+ seq_printf(sfile,
"<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n",
- g_SysRAMWaterMark);
- seq_printf( sfile,
+ SysRAMTrueWaterMark());
+ seq_printf(sfile,
"<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n",
g_SysRAMHighWaterMark);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n",
g_IOMemWaterMark);
- seq_printf( sfile,
+ seq_printf(sfile,
"<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n",
g_IOMemHighWaterMark);
- seq_printf( sfile, "</meminfo_header>\n");
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ seq_printf(sfile,
+ "<watermark key=\"mr18\" description=\"page_pool_current\" bytes=\"%d\"/>\n",
+ PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount)));
+#endif
+ seq_printf(sfile, "</meminfo_header>\n");
#endif
return;
}
- if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+ if (psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
{
- seq_printf( sfile,
+ seq_printf(sfile,
#if !defined(DEBUG_LINUX_XML_PROC_FILES)
"%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
#else
@@ -2038,7 +2402,7 @@ static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
}
else
{
- seq_printf( sfile,
+ seq_printf(sfile,
#if !defined(DEBUG_LINUX_XML_PROC_FILES)
"%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
#else
@@ -2090,30 +2454,30 @@ HAPFlagsToString(IMG_UINT32 ui32Flags)
};
- if(ui32Flags & PVRSRV_HAP_UNCACHED){
- ui32CacheTypeIndex=0;
- }else if(ui32Flags & PVRSRV_HAP_CACHED){
- ui32CacheTypeIndex=1;
- }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){
- ui32CacheTypeIndex=2;
- }else{
- ui32CacheTypeIndex=3;
+ if (ui32Flags & PVRSRV_HAP_UNCACHED) {
+ ui32CacheTypeIndex = 0;
+ } else if (ui32Flags & PVRSRV_HAP_CACHED) {
+ ui32CacheTypeIndex = 1;
+ } else if (ui32Flags & PVRSRV_HAP_WRITECOMBINE) {
+ ui32CacheTypeIndex = 2;
+ } else {
+ ui32CacheTypeIndex = 3;
PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)",
__FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)));
}
- if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){
+ if (ui32Flags & PVRSRV_HAP_KERNEL_ONLY) {
ui32MapTypeIndex = 0;
- }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){
+ } else if (ui32Flags & PVRSRV_HAP_SINGLE_PROCESS) {
ui32MapTypeIndex = 1;
- }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){
+ } else if (ui32Flags & PVRSRV_HAP_MULTI_PROCESS) {
ui32MapTypeIndex = 2;
- }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){
+ } else if (ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS) {
ui32MapTypeIndex = 3;
- }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){
+ } else if (ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL) {
ui32MapTypeIndex = 4;
- }else{
+ } else {
ui32MapTypeIndex = 5;
PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)",
__FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)));
@@ -2135,3 +2499,213 @@ HAPFlagsToString(IMG_UINT32 ui32Flags)
}
#endif
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
+ __FUNCTION__,
+ psCurrentRecord->psLinuxMemArea,
+ LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
+ psCurrentRecord->psLinuxMemArea->ui32ByteSize));
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+}
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
+
+{
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
+ "type=%s "
+ "CpuVAddr=%p "
+ "CpuPAddr=0x%08x, "
+ "allocated @ file=%s,line=%d",
+ __FUNCTION__,
+ DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType),
+ psCurrentRecord->pvCpuVAddr,
+ psCurrentRecord->ulCpuPAddr,
+ psCurrentRecord->pszFileName,
+ psCurrentRecord->ui32Line));
+ switch (psCurrentRecord->eAllocType)
+ {
+ case DEBUG_MEM_ALLOC_TYPE_KMALLOC:
+ KFreeWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_IOREMAP:
+ IOUnmapWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_IO:
+
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_VMALLOC:
+ VFreeWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES:
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__);
+ break;
+ case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE:
+ KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr);
+ break;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ case DEBUG_MEM_ALLOC_TYPE_VMAP:
+ VUnmapWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+#endif
+ default:
+ PVR_ASSERT(0);
+ }
+}
+#endif
+
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+static struct shrinker g_sShrinker =
+{
+ .shrink = ShrinkPagePool,
+ .seeks = DEFAULT_SEEKS
+};
+
+static IMG_BOOL g_bShrinkerRegistered;
+#endif
+
+IMG_VOID
+LinuxMMCleanup(IMG_VOID)
+{
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ if (g_LinuxMemAreaCount)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
+ __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
+ }
+
+ List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords, LinuxMMCleanup_MemAreas_ForEachCb);
+
+ if (g_SeqFileMemArea)
+ {
+ RemoveProcEntrySeq(g_SeqFileMemArea);
+ }
+ }
+#endif
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+ if (g_bShrinkerRegistered)
+ {
+ unregister_shrinker(&g_sShrinker);
+ }
+#endif
+
+
+ FreePagePool();
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+
+
+ List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords, LinuxMMCleanup_MemRecords_ForEachVa);
+
+ if (g_SeqFileMemoryRecords)
+ {
+ RemoveProcEntrySeq(g_SeqFileMemoryRecords);
+ }
+ }
+#endif
+
+ if (g_PsLinuxMemAreaCache)
+ {
+ KMemCacheDestroyWrapper(g_PsLinuxMemAreaCache);
+ }
+
+ if (g_PsLinuxPagePoolCache)
+ {
+ KMemCacheDestroyWrapper(g_PsLinuxPagePoolCache);
+ }
+}
+
+PVRSRV_ERROR
+LinuxMMInit(IMG_VOID)
+{
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ LinuxInitMutex(&g_sDebugMutex);
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ g_SeqFileMemArea = CreateProcReadEntrySeq(
+ "mem_areas",
+ NULL,
+ ProcSeqNextMemArea,
+ ProcSeqShowMemArea,
+ ProcSeqOff2ElementMemArea,
+ ProcSeqStartstopDebugMutex
+ );
+ if (!g_SeqFileMemArea)
+ {
+ goto failed;
+ }
+ }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+ g_SeqFileMemoryRecords = CreateProcReadEntrySeq(
+ "meminfo",
+ NULL,
+ ProcSeqNextMemoryRecords,
+ ProcSeqShowMemoryRecords,
+ ProcSeqOff2ElementMemoryRecords,
+ ProcSeqStartstopDebugMutex
+ );
+ if (!g_SeqFileMemoryRecords)
+ {
+ goto failed;
+ }
+ }
+#endif
+
+ g_PsLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
+ if (!g_PsLinuxMemAreaCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate mem area kmem_cache", __FUNCTION__));
+ goto failed;
+ }
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ g_iPagePoolMaxEntries = PVR_LINUX_MEM_AREA_POOL_MAX_PAGES;
+ if (g_iPagePoolMaxEntries <= 0 || g_iPagePoolMaxEntries > INT_MAX/2)
+ {
+ g_iPagePoolMaxEntries = INT_MAX/2;
+ PVR_TRACE(("%s: No limit set for page pool size", __FUNCTION__));
+ }
+ else
+ {
+ PVR_TRACE(("%s: Maximum page pool size: %d", __FUNCTION__, g_iPagePoolMaxEntries));
+ }
+
+ g_PsLinuxPagePoolCache = KMemCacheCreateWrapper("img-mm-pool", sizeof(LinuxPagePoolEntry), 0, 0);
+ if (!g_PsLinuxPagePoolCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate page pool kmem_cache", __FUNCTION__));
+ goto failed;
+ }
+#endif
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+ register_shrinker(&g_sShrinker);
+ g_bShrinkerRegistered = IMG_TRUE;
+#endif
+
+ return PVRSRV_OK;
+
+failed:
+ LinuxMMCleanup();
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
diff --git a/drivers/gpu/pvr/mm.h b/drivers/gpu/pvr/mm.h
index dac7815b430..e62bf33d734 100644
--- a/drivers/gpu/pvr/mm.h
+++ b/drivers/gpu/pvr/mm.h
@@ -48,6 +48,8 @@
#define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
+#define PAGES_TO_BYTES(pages) ((pages) << PAGE_SHIFT)
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot)
#else
@@ -78,13 +80,16 @@ static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr)
typedef enum {
LINUX_MEM_AREA_IOREMAP,
- LINUX_MEM_AREA_EXTERNAL_KV,
+ LINUX_MEM_AREA_EXTERNAL_KV,
LINUX_MEM_AREA_IO,
LINUX_MEM_AREA_VMALLOC,
LINUX_MEM_AREA_ALLOC_PAGES,
LINUX_MEM_AREA_SUB_ALLOC,
- LINUX_MEM_AREA_TYPE_COUNT,
LINUX_MEM_AREA_ION,
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ LINUX_MEM_AREA_VMAP,
+#endif
+ LINUX_MEM_AREA_TYPE_COUNT
}LINUX_MEM_AREA_TYPE;
typedef struct _LinuxMemArea LinuxMemArea;
@@ -120,18 +125,22 @@ struct _LinuxMemArea {
{
IMG_VOID *pvVmallocAddress;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+#endif
}sVmalloc;
struct _sPageList
{
- struct page **pvPageList;
+ struct page **ppsPageList;
IMG_HANDLE hBlockPageList;
}sPageList;
struct _sIONTilerAlloc
{
IMG_CPU_PHYADDR *pCPUPhysAddrs;
- struct ion_handle *psIONHandle;
+ struct ion_handle *psIONHandle[2];
}sIONTilerAlloc;
struct _sSubAlloc
{
diff --git a/drivers/gpu/pvr/module.c b/drivers/gpu/pvr/module.c
index 91d61f2a747..9edee40becc 100644
--- a/drivers/gpu/pvr/module.c
+++ b/drivers/gpu/pvr/module.c
@@ -79,6 +79,10 @@
#include <asm/uaccess.h>
#endif
+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
+#include <asm/atomic.h>
+#endif
+
#include "img_defs.h"
#include "services.h"
#include "kerneldisplay.h"
@@ -99,6 +103,7 @@
#include "private_data.h"
#include "lock.h"
#include "linkage.h"
+#include "buffer_manager.h"
#if defined(SUPPORT_DRI_DRM)
#include "pvr_drm.h"
@@ -367,9 +372,17 @@ void PVRSRVDriverShutdown(struct drm_device *pDevice)
PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice)
#endif
{
+ static atomic_t sDriverIsShutdown = ATOMIC_INIT(1);
+
PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
- (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
+ if (atomic_dec_and_test(&sDriverIsShutdown))
+ {
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+ (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
+ }
}
#endif
@@ -560,6 +573,12 @@ static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
}
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ BM_XProcIndexRelease(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ }
+
+
if(FreeMemCallBackCommon(psKernelMemInfo, 0,
PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL) != PVRSRV_OK)
{
diff --git a/drivers/gpu/pvr/omap4/sysconfig.c b/drivers/gpu/pvr/omap4/sysconfig.c
index 797e3fed466..d4d2483a1ed 100644
--- a/drivers/gpu/pvr/omap4/sysconfig.c
+++ b/drivers/gpu/pvr/omap4/sysconfig.c
@@ -529,6 +529,9 @@ PVRSRV_ERROR SysFinalise(IMG_VOID)
return eError;
}
SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ SysEnableSGXInterrupts(gpsSysData);
+#endif
#endif
#if defined(__linux__)
diff --git a/drivers/gpu/pvr/omap4/syslocal.h b/drivers/gpu/pvr/omap4/syslocal.h
index 6a7a35b5a24..9221886ce42 100644
--- a/drivers/gpu/pvr/omap4/syslocal.h
+++ b/drivers/gpu/pvr/omap4/syslocal.h
@@ -77,16 +77,17 @@
#endif
#if !defined(NO_HARDWARE) && \
- defined(SYS_USING_INTERRUPTS) && \
- defined(SGX540)
+ defined(SYS_USING_INTERRUPTS)
#define SGX_OCP_REGS_ENABLED
#endif
#if defined(__linux__)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) && defined(SGX_OCP_REGS_ENABLED)
+#if !defined(SGX544)
#define SGX_OCP_NO_INT_BYPASS
#endif
#endif
+#endif
#if defined (__cplusplus)
extern "C" {
diff --git a/drivers/gpu/pvr/osfunc.c b/drivers/gpu/pvr/osfunc.c
index 13e4dd95db5..28e2b005840 100644
--- a/drivers/gpu/pvr/osfunc.c
+++ b/drivers/gpu/pvr/osfunc.c
@@ -73,6 +73,7 @@
#include "event.h"
#include "linkage.h"
#include "pvr_uaccess.h"
+#include "lock.h"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
@@ -2756,7 +2757,7 @@ static unsigned long AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea,
IMG_UINT32 ui32PageNum)
{
struct page *pPage;
- pPage = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageNumOffset + ui32PageNum];
+ pPage = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PageNumOffset + ui32PageNum];
return page_to_pfn(pPage) << PAGE_SHIFT;
}
@@ -3173,6 +3174,102 @@ IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
#endif
+typedef struct _AtomicStruct
+{
+ atomic_t RefCount;
+} AtomicStruct;
+
+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount)
+{
+ AtomicStruct *psRefCount;
+
+ psRefCount = kmalloc(sizeof(AtomicStruct), GFP_KERNEL);
+ if (psRefCount == NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ atomic_set(&psRefCount->RefCount, 0);
+
+ *ppvRefCount = psRefCount;
+ return PVRSRV_OK;
+}
+
+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ PVR_ASSERT(atomic_read(&psRefCount->RefCount) == 0);
+ kfree(psRefCount);
+}
+
+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ atomic_inc(&psRefCount->RefCount);
+}
+
+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ return atomic_dec_and_test(&psRefCount->RefCount) ? IMG_TRUE:IMG_FALSE;
+}
+
+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ return (IMG_UINT32) atomic_read(&psRefCount->RefCount);
+}
+
+IMG_VOID OSReleaseBridgeLock(IMG_VOID)
+{
+ LinuxUnLockMutex(&gPVRSRVLock);
+}
+
+IMG_VOID OSReacquireBridgeLock(IMG_VOID)
+{
+ LinuxLockMutex(&gPVRSRVLock);
+}
+
+typedef struct _OSTime
+{
+ unsigned long ulTime;
+} OSTime;
+
+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32USOffset)
+{
+ OSTime *psOSTime;
+
+ psOSTime = kmalloc(sizeof(OSTime), GFP_KERNEL);
+ if (psOSTime == IMG_NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psOSTime->ulTime = usecs_to_jiffies(jiffies_to_usecs(jiffies) + ui32USOffset);
+ *pvRet = psOSTime;
+ return PVRSRV_OK;
+}
+
+
+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData)
+{
+ OSTime *psOSTime = pvData;
+
+ if (time_is_before_jiffies(psOSTime->ulTime))
+ {
+ return IMG_TRUE;
+ }
+ return IMG_FALSE;
+}
+
+IMG_VOID OSTimeDestroy(IMG_PVOID pvData)
+{
+ kfree(pvData);
+}
+
PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
{
#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
diff --git a/drivers/gpu/pvr/osfunc.h b/drivers/gpu/pvr/osfunc.h
index 6e5cbd19608..70caf574b9a 100644
--- a/drivers/gpu/pvr/osfunc.h
+++ b/drivers/gpu/pvr/osfunc.h
@@ -613,6 +613,33 @@ static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { }
#endif
+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount);
+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount);
+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount);
+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount);
+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount);
+
+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32MSOffset);
+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData);
+IMG_VOID OSTimeDestroy(IMG_PVOID pvData);
+
+#if defined(__linux__)
+IMG_VOID OSReleaseBridgeLock(IMG_VOID);
+IMG_VOID OSReacquireBridgeLock(IMG_VOID);
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReleaseBridgeLock)
+#endif
+static INLINE IMG_VOID OSReleaseBridgeLock(IMG_VOID) { }
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReacquireBridgeLock)
+#endif
+static INLINE IMG_VOID OSReacquireBridgeLock(IMG_VOID) { }
+
+#endif
+
#if defined (__cplusplus)
}
#endif
diff --git a/drivers/gpu/pvr/pdump_km.h b/drivers/gpu/pvr/pdump_km.h
index 224e92232cd..6c516e01ace 100644
--- a/drivers/gpu/pvr/pdump_km.h
+++ b/drivers/gpu/pvr/pdump_km.h
@@ -337,6 +337,7 @@ extern IMG_UINT32 g_ui32EveryLineCounter;
#define PDUMPMALLOCPAGETABLE PDumpMallocPageTable
#define PDUMPSETMMUCONTEXT PDumpSetMMUContext
#define PDUMPCLEARMMUCONTEXT PDumpClearMMUContext
+ #define PDUMPPDDEVPADDR PDumpPDDevPAddrKM
#define PDUMPFREEPAGES PDumpFreePages
#define PDUMPFREEPAGETABLE PDumpFreePageTable
#define PDUMPPDREG PDumpPDReg
@@ -373,6 +374,7 @@ extern IMG_UINT32 g_ui32EveryLineCounter;
#define PDUMPMALLOCPAGETABLE(args...)
#define PDUMPSETMMUCONTEXT(args...)
#define PDUMPCLEARMMUCONTEXT(args...)
+ #define PDUMPPDDEVPADDR(args...)
#define PDUMPFREEPAGES(args...)
#define PDUMPFREEPAGETABLE(args...)
#define PDUMPPDREG(args...)
diff --git a/drivers/gpu/pvr/pvr_bridge.h b/drivers/gpu/pvr/pvr_bridge.h
index d3e5916a9db..443ad1eb596 100644
--- a/drivers/gpu/pvr/pvr_bridge.h
+++ b/drivers/gpu/pvr/pvr_bridge.h
@@ -191,11 +191,7 @@ extern "C" {
#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3)
-#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
-#define PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
-#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0)
-
-#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1)
#define PVRSRV_BRIDGE_INITSRV_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0)
#define PVRSRV_BRIDGE_INITSRV_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
#define PVRSRV_BRIDGE_INITSRV_CMD_LAST (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1)
@@ -1595,22 +1591,6 @@ typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG
PVRSRV_ERROR eError;
}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM;
-typedef struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR_TAG
-{
- IMG_UINT32 ui32BridgeFlags;
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hDevMemContext;
-#else
- IMG_HANDLE hDevMemContext;
-#endif
-}PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR;
-
-typedef struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR_TAG
-{
- IMG_DEV_PHYADDR sPDDevPAddr;
- PVRSRV_ERROR eError;
-}PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR;
-
typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG
{
IMG_UINT32 ui32BridgeFlags;
diff --git a/drivers/gpu/pvr/pvr_bridge_k.c b/drivers/gpu/pvr/pvr_bridge_k.c
index 6d51200e69b..9185df43288 100644
--- a/drivers/gpu/pvr/pvr_bridge_k.c
+++ b/drivers/gpu/pvr/pvr_bridge_k.c
@@ -37,6 +37,7 @@
#include "pvr_bridge_km.h"
#include "pvr_uaccess.h"
#include "refcount.h"
+#include "buffer_manager.h"
#if defined(SUPPORT_DRI_DRM)
#include <drm/drmP.h>
@@ -382,12 +383,19 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
(PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+ IMG_HANDLE hMemInfo;
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ if (pvr_get_user(hMemInfo, &psExportDeviceMemOUT->hMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
(IMG_PVOID *)&psKernelMemInfo,
- psExportDeviceMemOUT->hMemInfo,
+ hMemInfo,
PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
@@ -398,7 +406,13 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
PVRSRVKernelMemInfoIncRef(psKernelMemInfo);
- psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo;
+
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ BM_XProcIndexAcquire(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ }
+
+ psPrivateData->hKernelMemInfo = hMemInfo;
#if defined(SUPPORT_MEMINFO_IDS)
psPrivateData->ui64Stamp = ++ui64Stamp;
diff --git a/drivers/gpu/pvr/pvr_bridge_km.h b/drivers/gpu/pvr/pvr_bridge_km.h
index 184e999bd31..e14f2fd39c3 100644
--- a/drivers/gpu/pvr/pvr_bridge_km.h
+++ b/drivers/gpu/pvr/pvr_bridge_km.h
@@ -288,7 +288,9 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
IMG_HANDLE hDevMemContext,
PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo);
IMG_IMPORT
-PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
+IMG_VOID IMG_CALLCONV PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
+IMG_IMPORT
+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
IMG_IMPORT
#if defined (SUPPORT_SID_INTERFACE)
diff --git a/drivers/gpu/pvr/pvr_uaccess.h b/drivers/gpu/pvr/pvr_uaccess.h
index 4b7114e363e..6e7f1d30ddc 100644
--- a/drivers/gpu/pvr/pvr_uaccess.h
+++ b/drivers/gpu/pvr/pvr_uaccess.h
@@ -65,6 +65,7 @@ static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pv
}
#define pvr_put_user put_user
+#define pvr_get_user get_user
#endif
diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h
index 1065b1c14ab..28a2f452ba2 100644
--- a/drivers/gpu/pvr/pvrversion.h
+++ b/drivers/gpu/pvr/pvrversion.h
@@ -36,7 +36,7 @@
#define PVRVERSION_FAMILY "sgxddk"
#define PVRVERSION_BRANCHNAME "1.8"
-#define PVRVERSION_BUILD 785978
+#define PVRVERSION_BUILD 905891
#define PVRVERSION_BSCONTROL "CustomerGoogle_Android_ogles1_ogles2_GPL"
#define PVRVERSION_STRING "CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@" PVR_STR2(PVRVERSION_BUILD)
@@ -44,8 +44,8 @@
#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
-#define PVRVERSION_BUILD_HI 78
-#define PVRVERSION_BUILD_LO 5978
+#define PVRVERSION_BUILD_HI 90
+#define PVRVERSION_BUILD_LO 5891
#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
#endif /* _PVRVERSION_H_ */
diff --git a/drivers/gpu/pvr/queue.c b/drivers/gpu/pvr/queue.c
index 4682094df69..374bf7b2a64 100644
--- a/drivers/gpu/pvr/queue.c
+++ b/drivers/gpu/pvr/queue.c
@@ -25,6 +25,7 @@
******************************************************************************/
#include "services_headers.h"
+#include "pvr_bridge_km.h"
#include "lists.h"
#include "ttrace.h"
@@ -625,6 +626,8 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
+ PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL);
+
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
@@ -642,6 +645,8 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
+ PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL);
+
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
@@ -1003,6 +1008,8 @@ IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
{
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL);
+
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
PVRSRV_SYNCOP_COMPLETE);
@@ -1019,6 +1026,8 @@ IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
{
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++;
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL);
+
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
PVRSRV_SYNCOP_COMPLETE);
@@ -1185,6 +1194,7 @@ PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
if (psCmdCompleteData != IMG_NULL)
{
+ PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE);
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
psCmdCompleteData, IMG_NULL);
psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
diff --git a/drivers/gpu/pvr/refcount.c b/drivers/gpu/pvr/refcount.c
index 8b009725ec9..5bc9b4ada53 100644
--- a/drivers/gpu/pvr/refcount.c
+++ b/drivers/gpu/pvr/refcount.c
@@ -1,7 +1,27 @@
-/*************************************************************************/ /*!
-@Title Services reference count debugging
-@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License Strictly Confidential.
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
*/ /**************************************************************************/
#if defined(PVRSRV_REFCOUNT_DEBUG)
@@ -26,10 +46,11 @@ static DEFINE_MUTEX(gsCCBLock);
#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1)
#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2)
#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC (1U << 4)
#if defined(__linux__)
-#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 4)
-#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 5)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 16)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 17)
#else
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0
#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0
@@ -95,6 +116,8 @@ void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount);
+
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
goto skip;
@@ -111,8 +134,8 @@ void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
psKernelMemInfo,
NULL,
(psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
- psKernelSyncInfo->ui32RefCount,
- psKernelSyncInfo->ui32RefCount + 1,
+ ui32RefValue,
+ ui32RefValue + 1,
(psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
@@ -120,7 +143,7 @@ void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_UNLOCK_CCB();
skip:
- psKernelSyncInfo->ui32RefCount++;
+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo);
}
IMG_INTERNAL
@@ -128,6 +151,8 @@ void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount);
+
if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
goto skip;
@@ -144,8 +169,8 @@ void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
psKernelMemInfo,
(psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
NULL,
- psKernelSyncInfo->ui32RefCount,
- psKernelSyncInfo->ui32RefCount - 1,
+ ui32RefValue,
+ ui32RefValue - 1,
(psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
@@ -153,7 +178,7 @@ void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
PVRSRV_UNLOCK_CCB();
skip:
- psKernelSyncInfo->ui32RefCount--;
+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo);
}
IMG_INTERNAL
@@ -344,6 +369,68 @@ skip:
pBuf->ui32ExportCount--;
}
+IMG_INTERNAL
+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_XPROC",
+ NULL,
+ NULL,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle,
+ (IMG_VOID *) ui32Index,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount + 1,
+ gXProcWorkaroundShareData[ui32Index].ui32Size);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_XPROC",
+ NULL,
+ NULL,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle,
+ (IMG_VOID *) ui32Index,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount - 1,
+ gXProcWorkaroundShareData[ui32Index].ui32Size);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--;
+}
+
#if defined(__linux__)
/* mmap refcounting is Linux specific */
diff --git a/drivers/gpu/pvr/refcount.h b/drivers/gpu/pvr/refcount.h
index d2fd9c77e90..92de65c9015 100644
--- a/drivers/gpu/pvr/refcount.h
+++ b/drivers/gpu/pvr/refcount.h
@@ -1,12 +1,34 @@
-/*************************************************************************/ /*!
-@Title Services reference count debugging
-@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License Strictly Confidential.
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
*/ /**************************************************************************/
#ifndef __REFCOUNT_H__
#define __REFCOUNT_H__
+#include "pvr_bridge_km.h"
+
#if defined(PVRSRV_REFCOUNT_DEBUG)
void PVRSRVDumpRefCountCCB(void);
@@ -46,6 +68,10 @@ void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile,
IMG_INT iLine, BM_BUF *pBuf);
void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile,
IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ IMG_UINT32 ui32Index);
+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ IMG_UINT32 ui32Index);
#if defined(__linux__)
@@ -80,14 +106,14 @@ static INLINE void PVRSRVKernelSyncInfoIncRef(PVRSRV_KERNEL_SYNC_INFO *psKernelS
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
- psKernelSyncInfo->ui32RefCount++;
+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo);
}
static INLINE void PVRSRVKernelSyncInfoDecRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
- psKernelSyncInfo->ui32RefCount--;
+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo);
}
static INLINE void PVRSRVKernelMemInfoIncRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
@@ -100,49 +126,59 @@ static INLINE void PVRSRVKernelMemInfoDecRef(PVRSRV_KERNEL_MEM_INFO *psKernelMem
psKernelMemInfo->ui32RefCount--;
}
-#if defined(__linux__)
+static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount++;
+}
-/* mmap refcounting is Linux specific */
-#include "mmap.h"
+static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount--;
+}
-static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct)
+static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf)
{
- psOffsetStruct->ui32RefCount++;
+ pBuf->ui32ExportCount++;
}
-static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct)
+static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf)
{
- psOffsetStruct->ui32RefCount--;
+ pBuf->ui32ExportCount--;
}
-static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+static INLINE void PVRSRVBMXProcIncRef(IMG_UINT32 ui32Index)
{
- psOffsetStruct->ui32Mapped++;
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++;
}
-static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+static INLINE void PVRSRVBMXProcDecRef(IMG_UINT32 ui32Index)
{
- psOffsetStruct->ui32Mapped--;
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--;
}
-static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf)
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct)
{
- pBuf->ui32RefCount++;
+ psOffsetStruct->ui32RefCount++;
}
-static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf)
+static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct)
{
- pBuf->ui32RefCount--;
+ psOffsetStruct->ui32RefCount--;
}
-static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf)
+static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct)
{
- pBuf->ui32ExportCount++;
+ psOffsetStruct->ui32Mapped++;
}
-static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf)
+static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct)
{
- pBuf->ui32ExportCount--;
+ psOffsetStruct->ui32Mapped--;
}
#endif /* defined(__linux__) */
diff --git a/drivers/gpu/pvr/resman.c b/drivers/gpu/pvr/resman.c
index 5088c7fae09..8eddf7797da 100644
--- a/drivers/gpu/pvr/resman.c
+++ b/drivers/gpu/pvr/resman.c
@@ -598,17 +598,13 @@ static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
(IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
- List_RESMAN_ITEM_Remove(psItem);
-
-
-
RELEASE_SYNC_OBJ;
if (bExecuteCallback)
{
eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
- if (eError != PVRSRV_OK)
+ if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
{
PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
}
@@ -617,8 +613,14 @@ static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
ACQUIRE_SYNC_OBJ;
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ List_RESMAN_ITEM_Remove(psItem);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
+ }
return(eError);
}
@@ -679,7 +681,19 @@ static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext,
ui32Param)) != IMG_NULL
&& eError == PVRSRV_OK)
{
- eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
+ do
+ {
+ eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ RELEASE_SYNC_OBJ;
+ OSReleaseBridgeLock();
+
+ OSSleepms(MAX_CLEANUP_TIME_WAIT_US/1000);
+ OSReacquireBridgeLock();
+ ACQUIRE_SYNC_OBJ;
+ }
+ } while (eError == PVRSRV_ERROR_RETRY);
}
return eError;
diff --git a/drivers/gpu/pvr/servicesext.h b/drivers/gpu/pvr/servicesext.h
index af3e4aa129b..42558b9fec3 100644
--- a/drivers/gpu/pvr/servicesext.h
+++ b/drivers/gpu/pvr/servicesext.h
@@ -645,6 +645,9 @@ typedef struct _PVRSRV_SYNC_DATA_
IMG_UINT32 ui32LastOpDumpVal;
IMG_UINT32 ui32LastReadOpDumpVal;
+
+ IMG_UINT64 ui64LastWrite;
+
} PVRSRV_SYNC_DATA;
typedef struct _PVRSRV_CLIENT_SYNC_INFO_
diff --git a/drivers/gpu/pvr/servicesint.h b/drivers/gpu/pvr/servicesint.h
index c9b565e5352..afe2bcfadd7 100644
--- a/drivers/gpu/pvr/servicesint.h
+++ b/drivers/gpu/pvr/servicesint.h
@@ -33,6 +33,7 @@ extern "C" {
#include "services.h"
#include "sysinfo.h"
+#include "sysconfig.h"
#define HWREC_DEFAULT_TIMEOUT (500)
@@ -47,6 +48,10 @@ extern "C" {
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#define MAX_CLEANUP_TIME_US (MAX_HW_TIME_US * 4)
+#define MAX_CLEANUP_TRYS 100
+#define MAX_CLEANUP_TIME_WAIT_US (MAX_CLEANUP_TIME_US/MAX_CLEANUP_TRYS)
+
typedef enum _PVRSRV_MEMTYPE_
{
PVRSRV_MEMTYPE_UNKNOWN = 0,
@@ -144,7 +149,7 @@ typedef struct _PVRSRV_KERNEL_SYNC_INFO_
- IMG_UINT32 ui32RefCount;
+ IMG_PVOID pvRefCount;
IMG_HANDLE hResItem;
@@ -341,16 +346,6 @@ PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
PVRSRV_COMMAND *psCommand);
-
-IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
-PVRSRVGetMMUContextPDDevPAddr(const PVRSRV_CONNECTION *psConnection,
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hDevMemContext,
-#else
- IMG_HANDLE hDevMemContext,
-#endif
- IMG_DEV_PHYADDR *sPDDevPAddr);
-
IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
IMG_UINT32 ui32Flags,
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
index f616d83bc92..4e4cf248cbe 100644
--- a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
+++ b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
@@ -377,7 +377,7 @@ SGXDoKickBW(IMG_UINT32 ui32BridgeID,
}
#else
- if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS)
+ if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS_TA)
{
psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
return 0;
@@ -780,6 +780,90 @@ SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID,
return 0;
}
+static IMG_INT
+SGXSetTransferContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY *psSGXSetTransferContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hTransferContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetTransferContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->hHWTransferContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetTransferContextPriorityKM(
+ hDevCookieInt,
+ hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->ui32Priority,
+ psSGXSetTransferContextPriorityIN->ui32OffsetOfPriorityField);
+
+ return 0;
+}
+
+static IMG_INT
+SGXSetRenderContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY *psSGXSetRenderContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hRenderContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetRenderContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->hHWRenderContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetRenderContextPriorityKM(
+ hDevCookieInt,
+ hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->ui32Priority,
+ psSGXSetRenderContextPriorityIN->ui32OffsetOfPriorityField);
+
+ return 0;
+}
+
#if defined(SGX_FEATURE_2D_HARDWARE)
static IMG_INT
@@ -1288,7 +1372,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
#endif
-#if defined(FIX_HW_BRN_31542)
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
&hDummy,
psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
@@ -1356,7 +1440,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
}
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
&hDummy,
psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
@@ -1615,7 +1699,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
#endif
-#if defined(FIX_HW_BRN_31542)
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
#if defined (SUPPORT_SID_INTERFACE)
&asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo,
@@ -1713,7 +1797,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
bReleaseFailed = IMG_TRUE;
}
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
&psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
@@ -1943,7 +2027,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
#endif
#endif
-#if defined(FIX_HW_BRN_31542)
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
#if defined (SUPPORT_SID_INTERFACE)
eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo);
if (eError != PVRSRV_OK)
@@ -2026,7 +2110,7 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
#endif
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo);
bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
@@ -2176,8 +2260,12 @@ SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID,
hHWRenderContextInt =
SGXRegisterHWRenderContextKM(hDevCookieInt,
- &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr,
- psPerProc);
+ psSGXRegHWRenderContextIN->pHWRenderContextCpuVAddr,
+ psSGXRegHWRenderContextIN->ui32HWRenderContextSize,
+ psSGXRegHWRenderContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWRenderContextIN->hDevMemContext,
+ &psSGXRegHWRenderContextOUT->sHWRenderContextDevVAddr,
+ psPerProc);
if (hHWRenderContextInt == IMG_NULL)
{
@@ -2258,7 +2346,11 @@ SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID,
hHWTransferContextInt =
SGXRegisterHWTransferContextKM(hDevCookieInt,
- &psSGXRegHWTransferContextIN->sHWTransferContextDevVAddr,
+ psSGXRegHWTransferContextIN->pHWTransferContextCpuVAddr,
+ psSGXRegHWTransferContextIN->ui32HWTransferContextSize,
+ psSGXRegHWTransferContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWTransferContextIN->hDevMemContext,
+ &psSGXRegHWTransferContextOUT->sHWTransferContextDevVAddr,
psPerProc);
if (hHWTransferContextInt == IMG_NULL)
@@ -2345,7 +2437,11 @@ SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID,
hHW2DContextInt =
SGXRegisterHW2DContextKM(hDevCookieInt,
- &psSGXRegHW2DContextIN->sHW2DContextDevVAddr,
+ psSGXRegHW2DContextIN->pHW2DContextCpuVAddr,
+ psSGXRegHW2DContextIN->ui32HW2DContextSize,
+ psSGXRegHW2DContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHW2DContextIN->hDevMemContext,
+ &psSGXRegHW2DContextOUT->sHW2DContextDevVAddr,
psPerProc);
if (hHW2DContextInt == IMG_NULL)
@@ -3627,8 +3723,6 @@ IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW);
- SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW);
-
#if defined(TRANSFER_QUEUE)
SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW);
#endif
@@ -3653,6 +3747,8 @@ IMG_VOID SetSGXDispatchTableEntry(IMG_VOID)
SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY, SGXSetRenderContextPriorityBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY, SGXSetTransferContextPriorityBW);
#if defined(PDUMP)
SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW);
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
index 774026d2786..9d124f5d085 100644
--- a/drivers/gpu/pvr/sgx/mmu.c
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -248,6 +248,111 @@ static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
}
#endif
+#if defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND)
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#else
+#include <generated/autoconf.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_mkwrite(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+}
+
+static IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ OSWriteMemoryBarrier();
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_wrprotect(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+
+}
+
+#else
+
+static INLINE IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+static INLINE IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+#endif
IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap)
{
@@ -401,11 +506,13 @@ static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDInde
psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+ MakeKernelPageReadWrite(psMMUContextWalker->pvPDCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContextWalker->pvPDCpuVAddr);
PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -417,11 +524,13 @@ static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDInde
psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -461,6 +570,11 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
}
+
+
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+
if(psPTInfoList->PTPageCpuVAddr)
{
sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
@@ -518,6 +632,7 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
#endif
}
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
{
IMG_UINT32 *pui32Tmp;
@@ -540,6 +655,7 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
#endif
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
#if defined(PDUMP)
{
@@ -572,6 +688,9 @@ _FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
{
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+
+
OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
pMMUHeap->ui32PTSize,
psPTInfoList->PTPageCpuVAddr,
@@ -659,6 +778,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
while(psMMUContext)
{
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -675,6 +795,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32PDEntry[ui32PTIndex] = 0;
}
#endif
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
#if defined(PDUMP)
#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
@@ -692,6 +813,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
case DEVICE_MEMORY_HEAP_PERCONTEXT :
case DEVICE_MEMORY_HEAP_KERNEL :
{
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -709,6 +831,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32PDEntry[ui32PTIndex] = 0;
}
#endif
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -728,6 +851,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
{
IMG_PUINT32 pui32Tmp;
+ MakeKernelPageReadWrite(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
@@ -738,6 +862,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
@@ -1040,6 +1165,7 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
while(psMMUContext)
{
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -1048,6 +1174,7 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| pMMUHeap->ui32PDEPageSizeCtrl
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
#if defined(PDUMP)
#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
@@ -1069,11 +1196,12 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
case DEVICE_MEMORY_HEAP_PERCONTEXT :
case DEVICE_MEMORY_HEAP_KERNEL :
{
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| pMMUHeap->ui32PDEPageSizeCtrl
| SGX_MMU_PDE_VALID;
-
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -1185,13 +1313,14 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
PVR_ASSERT(psTempPTInfo != IMG_NULL);
+ MakeKernelPageReadWrite(psTempPTInfo->PTPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
PVR_ASSERT(pui32Tmp != IMG_NULL);
pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_DUMMY_PAGE
| SGX_MMU_PTE_READONLY
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(psTempPTInfo->PTPageCpuVAddr);
PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
}
@@ -1564,11 +1693,13 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
}
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
{
pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
}
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPageCpuVAddr);
PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
@@ -1659,6 +1790,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
@@ -1666,40 +1798,47 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_VALID;
}
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
if(!psDevInfo->pvMMUContextList)
{
+ MakeKernelPageReadWrite(psDevInfo->pvDummyPTPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
for(i=0; i<SGX_MMU_PT_SIZE; i++)
{
pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_VALID;
}
+ MakeKernelPageReadOnly(psDevInfo->pvDummyPTPageCpuVAddr);
PDUMPCOMMENT("Dummy Page table contents");
PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ MakeKernelPageReadWrite(psDevInfo->pvDummyDataPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
{
pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
}
+ MakeKernelPageReadOnly(psDevInfo->pvDummyDataPageCpuVAddr);
PDUMPCOMMENT("Dummy Data Page contents");
PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
}
#else
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
#endif
#if defined(PDUMP)
@@ -1721,12 +1860,13 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
PDUMPCOMMENT("BRN31620 Set up dummy PT");
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPTCpuVAddr);
pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_DUMMY_PAGE
| SGX_MMU_PTE_READONLY
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPTCpuVAddr);
#if defined(PDUMP)
@@ -1749,10 +1889,12 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
{
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
}
PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
ui32PDCount++;
@@ -1876,12 +2018,14 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
@@ -1892,6 +2036,7 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
#if defined(FIX_HW_BRN_31620)
PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
#endif
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
SGX_MMU_PAGE_SIZE,
psMMUContext->pvPDCpuVAddr,
@@ -2073,9 +2218,10 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
#endif
-
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
if (pui32PDCpuVAddr[ui32PDEntry])
{
@@ -2179,7 +2325,7 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
-
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
@@ -2192,7 +2338,7 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
pui32Tmp[ui32PTIndex] = 0;
#endif
#endif
-
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
}
@@ -2771,12 +2917,13 @@ MMU_MapPage (MMU_HEAP *pMMUHeap,
ppsPTInfoList[0]->ui32ValidPTECount++;
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
& ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
| SGX_MMU_PTE_VALID
| ui32MMUFlags;
-
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
}
@@ -3061,6 +3208,7 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap,
PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
@@ -3073,6 +3221,7 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap,
pui32Tmp[ui32PTIndex] = 0;
#endif
#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
@@ -3292,6 +3441,48 @@ IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
}
}
+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32FaultAddr)
+{
+ MMU_CONTEXT *psMMUContext = psDevInfo->pvMMUContextList;
+
+ while (psMMUContext && (psMMUContext->sPDDevPAddr.uiAddr != ui32PDDevPAddr))
+ {
+ psMMUContext = psMMUContext->psNext;
+ }
+
+ if (psMMUContext)
+ {
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 ui32PDIndex;
+
+ PVR_LOG(("Found MMU context for page fault 0x%08x", ui32FaultAddr));
+
+ ui32PTIndex = (ui32FaultAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+ ui32PDIndex = (ui32FaultAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PT_SHIFT + SGX_MMU_PAGE_SHIFT);
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ IMG_UINT32 *pui32Ptr = psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ IMG_UINT32 ui32PTE = pui32Ptr[ui32PTIndex];
+
+ PVR_LOG(("PDE valid: PTE = 0x%08x (PhysAddr = 0x%08x, %s)",
+ ui32PTE,
+ ui32PTE & SGX_MMU_PTE_ADDR_MASK,
+ ui32PTE & SGX_MMU_PTE_VALID?"valid":"Invalid"));
+ }
+ else
+ {
+ PVR_LOG(("Found PT info but no CPU address"));
+ }
+ }
+ else
+ {
+ PVR_LOG(("No PDE found"));
+ }
+ }
+}
#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode)
@@ -3597,10 +3788,11 @@ PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ MakeKernelPageReadWrite(pui32PT);
pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(pui32PT);
#if defined(PDUMP)
{
@@ -3676,7 +3868,9 @@ PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
}
}
+ MakeKernelPageReadWrite(pui32PT);
pui32PT[ui32PTIndex] = 0;
+ MakeKernelPageReadOnly(pui32PT);
PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
diff --git a/drivers/gpu/pvr/sgx/mmu.h b/drivers/gpu/pvr/sgx/mmu.h
index 59b24c44ad8..dd92bf0fd9a 100644
--- a/drivers/gpu/pvr/sgx/mmu.h
+++ b/drivers/gpu/pvr/sgx/mmu.h
@@ -147,6 +147,8 @@ IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr
#endif
+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32RegVal);
+
#if defined(PDUMP)
IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext);
#endif
diff --git a/drivers/gpu/pvr/sgx/sgxinfokm.h b/drivers/gpu/pvr/sgx/sgxinfokm.h
index 7e2b3f9e71a..44a48beb401 100644
--- a/drivers/gpu/pvr/sgx/sgxinfokm.h
+++ b/drivers/gpu/pvr/sgx/sgxinfokm.h
@@ -128,7 +128,7 @@ typedef struct _PVRSRV_SGXDEV_INFO_
#if defined(FIX_HW_BRN_29823)
PPVRSRV_KERNEL_MEM_INFO psKernelDummyTermStreamMemInfo;
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
PPVRSRV_KERNEL_MEM_INFO psKernelVDMSnapShotBufferMemInfo;
PPVRSRV_KERNEL_MEM_INFO psKernelVDMCtrlStreamBufferMemInfo;
#endif
@@ -139,9 +139,6 @@ typedef struct _PVRSRV_SGXDEV_INFO_
#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo;
#endif
-#if defined(SGX_FEATURE_OVERLAPPED_SPM)
- PPVRSRV_KERNEL_MEM_INFO psKernelTmpRgnHeaderMemInfo;
-#endif
IMG_UINT32 ui32ClientRefCount;
@@ -373,9 +370,6 @@ typedef struct _SGX_BRIDGE_INIT_INFO_KM_
#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
IMG_HANDLE hKernelEDMStatusBufferMemInfo;
#endif
-#if defined(SGX_FEATURE_OVERLAPPED_SPM)
- IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
-#endif
IMG_UINT32 ui32EDMTaskReg0;
IMG_UINT32 ui32EDMTaskReg1;
@@ -441,7 +435,7 @@ typedef struct _SGX_CCB_KICK_KM_
#else
IMG_UINT32 ui32NumSrcSyncs;
- IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
#endif
diff --git a/drivers/gpu/pvr/sgx/sgxinit.c b/drivers/gpu/pvr/sgx/sgxinit.c
index 934f88f3354..622b6f5bdde 100644
--- a/drivers/gpu/pvr/sgx/sgxinit.c
+++ b/drivers/gpu/pvr/sgx/sgxinit.c
@@ -53,6 +53,23 @@
#include "srvkm.h"
#include "ttrace.h"
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+
+static const IMG_CHAR *SGXUKernelStatusString(IMG_UINT32 code)
+{
+ switch(code)
+ {
+#define MKTC_ST(x) \
+ case x: \
+ return #x;
+#include "sgx_ukernel_status_codes.h"
+ default:
+ return "(Unknown)";
+ }
+}
+
+#endif
+
#define VAR(x) #x
@@ -161,7 +178,7 @@ static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
#if defined(FIX_HW_BRN_29823)
psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
psDevInfo->psKernelVDMSnapShotBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMSnapShotBufferMemInfo;
psDevInfo->psKernelVDMCtrlStreamBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMCtrlStreamBufferMemInfo;
#endif
@@ -172,9 +189,6 @@ static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
#endif
-#if defined(SGX_FEATURE_OVERLAPPED_SPM)
- psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;
-#endif
psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
@@ -1003,6 +1017,19 @@ static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
}
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+
+static IMG_VOID SGXDumpMasterDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32RegAddr)
+{
+ IMG_UINT32 ui32RegVal;
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+ PVR_LOG(("(HYD) %s%08X", pszName, ui32RegVal));
+}
+
+#endif
+
static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
IMG_UINT32 ui32CoreNum,
IMG_CHAR *pszName,
@@ -1030,7 +1057,27 @@ IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_ID: ", EUR_CR_CORE_ID);
SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_REVISION: ", EUR_CR_CORE_REVISION);
-
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_INT_STAT: ", EUR_CR_MASTER_BIF_INT_STAT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_FAULT: ",EUR_CR_MASTER_BIF_FAULT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_CLKGATESTATUS2: ",EUR_CR_MASTER_CLKGATESTATUS2 );
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_PIM_STATUS: ",EUR_CR_MASTER_VDM_PIM_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_BANK_SET: ",EUR_CR_MASTER_BIF_BANK_SET);
+
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS: ",EUR_CR_MASTER_EVENT_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS2: ",EUR_CR_MASTER_EVENT_STATUS2);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_MP_PRIMITIVE: ",EUR_CR_MASTER_MP_PRIMITIVE);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_DPLIST_STATUS: ",EUR_CR_MASTER_DPM_DPLIST_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC: ",EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_PAGE_MANAGEOP: ",EUR_CR_MASTER_DPM_PAGE_MANAGEOP);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_WAIT_FOR_KICK: ",EUR_CR_MASTER_VDM_WAIT_FOR_KICK);
+#endif
for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
{
@@ -1048,6 +1095,26 @@ IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE);
#endif
}
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && !defined(FIX_HW_BRN_31620)
+ {
+ IMG_UINT32 ui32RegVal;
+ IMG_UINT32 ui32PDDevPAddr;
+
+
+
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
+ if (ui32RegVal & EUR_CR_BIF_INT_STAT_PF_N_RW_MASK)
+ {
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
+ ui32RegVal &= EUR_CR_BIF_FAULT_ADDR_MASK;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0);
+ ui32PDDevPAddr &= EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK;
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32RegVal);
+ }
+ }
+#endif
}
@@ -1107,7 +1174,8 @@ IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
ui32WriteOffset = *pui32MKTraceBuffer;
pui32MKTraceBuffer++;
- PVR_LOG(("Last SGX microkernel status code: %08X", ui32LastStatusCode));
+ PVR_LOG(("Last SGX microkernel status code: %08X %s",
+ ui32LastStatusCode, SGXUKernelStatusString(ui32LastStatusCode)));
#if defined(PVRSRV_DUMP_MK_TRACE)
@@ -1122,8 +1190,9 @@ IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
IMG_UINT32 *pui32BufPtr;
pui32BufPtr = pui32MKTraceBuffer +
(((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
- PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X", ui32LoopCounter,
- pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0]));
+ PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X %s", ui32LoopCounter,
+ pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0],
+ SGXUKernelStatusString(pui32BufPtr[0])));
}
}
#endif
@@ -1297,14 +1366,14 @@ IMG_VOID SGXOSTimer(IMG_VOID *pvData)
ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_PAUSE_MASK);
- OSWaitus(200 * 1000000 / psDevInfo->ui32CoreClockSpeed);
+ SGXWaitClocks(psDevInfo, 200);
#endif
bBRN31093Inval = IMG_TRUE;
OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, EUR_CR_BIF_CTRL_INVAL_PTE_MASK);
- OSWaitus(200 * 1000000 / psDevInfo->ui32CoreClockSpeed);
+ SGXWaitClocks(psDevInfo, 200);
#if defined(FIX_HW_BRN_29997)
diff --git a/drivers/gpu/pvr/sgx/sgxkick.c b/drivers/gpu/pvr/sgx/sgxkick.c
index 019a75cbc9b..d5441b2dcf8 100644
--- a/drivers/gpu/pvr/sgx/sgxkick.c
+++ b/drivers/gpu/pvr/sgx/sgxkick.c
@@ -242,6 +242,7 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
if (psSyncInfo)
{
+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount;
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC,
psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
diff --git a/drivers/gpu/pvr/sgx/sgxpower.c b/drivers/gpu/pvr/sgx/sgxpower.c
index 696941f7a79..b647b68d5bb 100644
--- a/drivers/gpu/pvr/sgx/sgxpower.c
+++ b/drivers/gpu/pvr/sgx/sgxpower.c
@@ -271,6 +271,7 @@ PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle,
IMG_FALSE) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
PVR_DBG_BREAK;
}
#endif
diff --git a/drivers/gpu/pvr/sgx/sgxreset.c b/drivers/gpu/pvr/sgx/sgxreset.c
index 70503714e80..45e6d799430 100644
--- a/drivers/gpu/pvr/sgx/sgxreset.c
+++ b/drivers/gpu/pvr/sgx/sgxreset.c
@@ -29,6 +29,7 @@
#include "services_headers.h"
#include "sgxinfokm.h"
#include "sgxconfig.h"
+#include "sgxutils.h"
#include "pdump_km.h"
@@ -168,7 +169,7 @@ static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo,
#endif
- OSWaitus(100 * 1000000 / psDevInfo->ui32CoreClockSpeed);
+ SGXWaitClocks(psDevInfo, 100);
if (bPDump)
{
PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
@@ -570,7 +571,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
#if defined(SGX_FEATURE_SYSTEM_CACHE)
#if defined(SGX_BYPASS_SYSTEM_CACHE)
- #error SGX_BYPASS_SYSTEM_CACHE not supported
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK;
#else
ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
#if defined(FIX_HW_BRN_30954)
@@ -598,10 +599,10 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK |
EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK;
#endif
+ #endif
OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC bypass control\r\n");
PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
- #endif
#endif
SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
diff --git a/drivers/gpu/pvr/sgx/sgxtransfer.c b/drivers/gpu/pvr/sgx/sgxtransfer.c
index d40773e6dc7..f0ce1b516df 100644
--- a/drivers/gpu/pvr/sgx/sgxtransfer.c
+++ b/drivers/gpu/pvr/sgx/sgxtransfer.c
@@ -222,6 +222,8 @@ IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSF
{
psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount;
+
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC,
psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
index c9a733b16e8..528490ba84c 100644
--- a/drivers/gpu/pvr/sgx/sgxutils.c
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -49,6 +49,8 @@
#include <stdio.h>
#endif
+IMG_UINT64 ui64KickCount;
+
#if defined(SYS_CUSTOM_POWERDOWN)
PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID);
@@ -527,6 +529,7 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
*psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
#endif
+ ui64KickCount++;
Exit:
return eError;
}
@@ -563,11 +566,16 @@ PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
{
if (ui32CallerID == ISR_ID)
{
+ SYS_DATA *psSysData;
+
psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
eError = PVRSRV_OK;
+
+ SysAcquireData(&psSysData);
+ OSScheduleMISR(psSysData);
}
else
{
@@ -689,11 +697,18 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
#if defined(PDUMP)
+
+
+
+
+
+
+
PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
PDUMPMEMPOL(psHostCtlMemInfo,
offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
- PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
- PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
PDUMP_POLL_OPERATOR_EQUAL,
0,
MAKEUNIQUETAG(psHostCtlMemInfo));
@@ -704,8 +719,20 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
return eError;
}
}
+
+ if (psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_BUSY)
+ {
+
+ PVR_ASSERT((psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_DONE) == 0);
+ eError = PVRSRV_ERROR_RETRY;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_BUSY);
+ }
+ else
+ {
+ eError = PVRSRV_OK;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE);
+ }
- psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE);
PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo));
@@ -714,16 +741,18 @@ PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
#else
psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
#endif
- return PVRSRV_OK;
+ return eError;
}
typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
{
PVRSRV_DEVICE_NODE *psDeviceNode;
- IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
- IMG_HANDLE hBlockAlloc;
+ PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_RENDER_CONTEXT_CLEANUP;
@@ -737,15 +766,48 @@ static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
PVR_UNREFERENCED_PARAMETER(ui32Param);
eError = SGXCleanupRequest(psCleanup->psDeviceNode,
- &psCleanup->sHWRenderContextDevVAddr,
+ &psCleanup->psHWRenderContextMemInfo->sDevVAddr,
PVRSRV_CLEANUPCMD_RC,
bForceCleanup);
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
@@ -753,9 +815,11 @@ static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
{
PVRSRV_DEVICE_NODE *psDeviceNode;
- IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+ PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo;
IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
@@ -769,27 +833,73 @@ static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam,
PVR_UNREFERENCED_PARAMETER(ui32Param);
eError = SGXCleanupRequest(psCleanup->psDeviceNode,
- &psCleanup->sHWTransferContextDevVAddr,
+ &psCleanup->psHWTransferContextMemInfo->sDevVAddr,
PVRSRV_CLEANUPCMD_TC,
bForceCleanup);
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
IMG_EXPORT
-IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
PVRSRV_PER_PROCESS_DATA *psPerProc)
{
PVRSRV_ERROR eError;
IMG_HANDLE hBlockAlloc;
SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
PRESMAN_ITEM psResItem;
eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
@@ -801,12 +911,99 @@ IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
- return IMG_NULL;
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWRenderContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHWRenderContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWRenderContextMemInfo->pvLinAddrKM,
+ psHWRenderContextCpuVAddr,
+ ui32HWRenderContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
}
+
+ psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWRenderContextMemInfo,
+ 0,
+ ui32HWRenderContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW render context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWRenderContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
- psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_RENDER_CONTEXT,
@@ -814,21 +1011,27 @@ IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
0,
&SGXCleanupHWRenderContextCallback);
- if (psResItem == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
-
-
- return IMG_NULL;
- }
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
psCleanup->psResItem = psResItem;
return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+exit0:
+ return IMG_NULL;
}
IMG_EXPORT
@@ -854,13 +1057,26 @@ PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOO
IMG_EXPORT
-IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
PVRSRV_PER_PROCESS_DATA *psPerProc)
{
PVRSRV_ERROR eError;
IMG_HANDLE hBlockAlloc;
SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
PRESMAN_ITEM psResItem;
eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
@@ -872,12 +1088,100 @@ IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
- return IMG_NULL;
+ goto exit0;
}
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWTransferContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHWTransferContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWTransferContextMemInfo->pvLinAddrKM,
+ psHWTransferContextCpuVAddr,
+ ui32HWTransferContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+
+ psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWTransferContextMemInfo,
+ 0,
+ ui32HWTransferContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW transfer context");
+
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWTransferContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
- psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_TRANSFER_CONTEXT,
@@ -888,18 +1192,25 @@ IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
if (psResItem == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
-
-
- return IMG_NULL;
- }
+ goto exit2;
+ }
psCleanup->psResItem = psResItem;
return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+
+exit0:
+ return IMG_NULL;
}
IMG_EXPORT
@@ -923,13 +1234,99 @@ PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG
return eError;
}
+IMG_EXPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWTransferContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWTransferContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetTransferContextPriorityKM: invalid context prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWRenderContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWRenderContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+
+
+
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
#if defined(SGX_FEATURE_2D_HARDWARE)
typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
{
PVRSRV_DEVICE_NODE *psDeviceNode;
- IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+ PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo;
IMG_HANDLE hBlockAlloc;
PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
} SGX_HW_2D_CONTEXT_CLEANUP;
static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
@@ -941,28 +1338,73 @@ static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
PVR_UNREFERENCED_PARAMETER(ui32Param);
- eError = SGXCleanupRequest(psCleanup->psDeviceNode,
- &psCleanup->sHW2DContextDevVAddr,
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHW2DContextMemInfo->sDevVAddr,
PVRSRV_CLEANUPCMD_2DC,
bForceCleanup);
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
-
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+ }
return eError;
}
-IMG_EXPORT
-IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
PVRSRV_PER_PROCESS_DATA *psPerProc)
{
PVRSRV_ERROR eError;
IMG_HANDLE hBlockAlloc;
SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
PRESMAN_ITEM psResItem;
eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
@@ -974,12 +1416,98 @@ IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
- return IMG_NULL;
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HW2DContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ &psCleanup->psHW2DContextMemInfo,
+ "HW 2D Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHW2DContextMemInfo->pvLinAddrKM,
+ psHW2DContextCpuVAddr,
+ ui32HW2DContextSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
}
+
+
+ psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr;
+
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+
+
+
+
+
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHW2DContextMemInfo,
+ 0,
+ ui32HW2DContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo));
+
+
+ PDUMPCOMMENT("Page directory address in HW 2D transfer context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHW2DContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
psCleanup->hBlockAlloc = hBlockAlloc;
psCleanup->psDeviceNode = psDeviceNode;
- psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
psResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_HW_2D_CONTEXT,
@@ -990,18 +1518,24 @@ IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
if (psResItem == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
- psCleanup,
- psCleanup->hBlockAlloc);
-
-
- return IMG_NULL;
+ goto exit2;
}
psCleanup->psResItem = psResItem;
return (IMG_HANDLE)psCleanup;
+
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+
+exit0:
+ return IMG_NULL;
}
IMG_EXPORT
@@ -1142,6 +1676,15 @@ IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
}
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks)
+{
+
+
+ OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed));
+}
+
+
IMG_EXPORT
PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
diff --git a/drivers/gpu/pvr/sgx/sgxutils.h b/drivers/gpu/pvr/sgx/sgxutils.h
index bc60fdd9186..9017acf20e2 100644
--- a/drivers/gpu/pvr/sgx/sgxutils.h
+++ b/drivers/gpu/pvr/sgx/sgxutils.h
@@ -36,6 +36,8 @@
((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
(psCCBKick)->offset))
+extern IMG_UINT64 ui64KickCount;
+
IMG_IMPORT
IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode,
@@ -66,13 +68,21 @@ IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode);
IMG_IMPORT
IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
PVRSRV_PER_PROCESS_DATA *psPerProc);
IMG_IMPORT
-IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
- PVRSRV_PER_PROCESS_DATA *psPerProc);
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
IMG_IMPORT
PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo,
@@ -85,10 +95,26 @@ PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOO
IMG_IMPORT
PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup);
+IMG_IMPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
#if defined(SGX_FEATURE_2D_HARDWARE)
IMG_IMPORT
IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
- IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
PVRSRV_PER_PROCESS_DATA *psPerProc);
IMG_IMPORT
@@ -99,6 +125,9 @@ IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
IMG_UINT32 ui32TimeWraps,
IMG_UINT32 ui32Time);
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks);
+
PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
IMG_DEV_VIRTADDR *psHWDataDevVAddr,
IMG_UINT32 ui32CleanupType,
diff --git a/drivers/gpu/pvr/sgx_bridge.h b/drivers/gpu/pvr/sgx_bridge.h
index 204189c1d18..ec630a58192 100644
--- a/drivers/gpu/pvr/sgx_bridge.h
+++ b/drivers/gpu/pvr/sgx_bridge.h
@@ -50,8 +50,6 @@ extern "C" {
#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
-#define PVRSRV_BRIDGE_SGX_GETMMUPDADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+10)
-
#if defined(TRANSFER_QUEUE)
#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13)
#endif
@@ -75,20 +73,22 @@ extern "C" {
#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28)
-#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
+#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29)
+#define PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
+#define PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
#if defined(PDUMP)
-#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
-#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
-#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
-#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
-#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
-#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
+#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
+#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
+#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
+#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+37)
#endif
-#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+37)
typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
@@ -107,24 +107,34 @@ typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
-typedef struct PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR_TAG
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY_TAG
+ {
+ IMG_UINT32 ui32BridgeFlags;
+ #if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWTransferContext;
+ #else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWTransferContext;
+ #endif
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY;
+
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY_TAG
{
IMG_UINT32 ui32BridgeFlags;
#if defined (SUPPORT_SID_INTERFACE)
IMG_SID hDevCookie;
- IMG_SID hDevMemContext;
+ IMG_SID hHWRenderContext;
#else
IMG_HANDLE hDevCookie;
- IMG_HANDLE hDevMemContext;
+ IMG_HANDLE hHWRenderContext;
#endif
-}PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR;
-
-
-typedef struct PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR_TAG
-{
- IMG_DEV_PHYADDR sPDDevPAddr;
- PVRSRV_ERROR eError;
-}PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR;
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY;
typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
@@ -505,7 +515,10 @@ typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
#else
IMG_HANDLE hDevCookie;
#endif
- IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
+ IMG_CPU_VIRTADDR pHWRenderContextCpuVAddr;
+ IMG_UINT32 ui32HWRenderContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
@@ -516,6 +529,7 @@ typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
#else
IMG_HANDLE hHWRenderContext;
#endif
+ IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
@@ -539,7 +553,10 @@ typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
#else
IMG_HANDLE hDevCookie;
#endif
- IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+ IMG_CPU_VIRTADDR pHWTransferContextCpuVAddr;
+ IMG_UINT32 ui32HWTransferContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
@@ -550,6 +567,7 @@ typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
#else
IMG_HANDLE hHWTransferContext;
#endif
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
@@ -586,7 +604,10 @@ typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
#else
IMG_HANDLE hDevCookie;
#endif
- IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+ IMG_CPU_VIRTADDR pHW2DContextCpuVAddr;
+ IMG_UINT32 ui32HW2DContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
@@ -597,6 +618,7 @@ typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
#else
IMG_HANDLE hHW2DContext;
#endif
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
diff --git a/drivers/gpu/pvr/sgx_mkif_km.h b/drivers/gpu/pvr/sgx_mkif_km.h
index 2d78baa27f1..9f4f41f71f0 100644
--- a/drivers/gpu/pvr/sgx_mkif_km.h
+++ b/drivers/gpu/pvr/sgx_mkif_km.h
@@ -131,6 +131,8 @@ typedef struct _SGXMKIF_CMDTA_SHARED_
IMG_UINT32 ui323DTQSyncReadOpsPendingVal;
IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr;
+
+ PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency;
#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
@@ -143,12 +145,9 @@ typedef struct _SGXMKIF_CMDTA_SHARED_
#else
IMG_UINT32 ui32NumSrcSyncs;
- PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS];
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TA];
#endif
-
- PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency;
-
CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
@@ -170,11 +169,11 @@ typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
IMG_UINT32 ui32NumSrcSyncs;
- PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS];
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TQ];
IMG_UINT32 ui32NumDstSyncs;
- PVRSRV_DEVICE_SYNC_OBJECT asDstSyncs[SGX_MAX_DST_SYNCS];
+ PVRSRV_DEVICE_SYNC_OBJECT asDstSyncs[SGX_MAX_DST_SYNCS_TQ];
IMG_UINT32 ui32TASyncWriteOpsPendingVal;
IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr;
@@ -231,6 +230,8 @@ typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
#define PVRSRV_USSE_EDM_INTERRUPT_IDLE (1UL << 2)
#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE (1UL << 0)
+#define PVRSRV_USSE_EDM_CLEANUPCMD_BUSY (1UL << 1)
+#define PVRSRV_USSE_EDM_CLEANUPCMD_DONE (1UL << 2)
#if defined(FIX_HW_BRN_28889)
#define PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE (1UL << 0)
diff --git a/drivers/gpu/pvr/sgx_ukernel_status_codes.h b/drivers/gpu/pvr/sgx_ukernel_status_codes.h
new file mode 100644
index 00000000000..4a9eaf8d744
--- /dev/null
+++ b/drivers/gpu/pvr/sgx_ukernel_status_codes.h
@@ -0,0 +1,940 @@
+/**********************************************************************
+ *
+ * Copyright (C) Imagination Technologies Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful but, except
+ * as otherwise stated in writing, without any warranty; without even the
+ * implied warranty of merchantability or fitness for a particular purpose.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
+ *
+
+******************************************************************************/
+
+#ifndef __SGX_UKERNEL_STATUS_CODES_H__
+#define __SGX_UKERNEL_STATUS_CODES_H__
+
+/*
+ NOTE: Do not add any conditional macros to this file! There must be
+ no use of #if defined(). This file is included in srvkm to print
+ stringified ukernel status codes, it must build identically to
+ srvinit.
+*/
+
+/*
+ Users of this header might define this macro to do something
+ clever; the primary use right now is to generate a switch/case
+ LUT for debugging in srvkm. If you add a new code, make sure it
+ has a corresponding MKTC_ST.
+*/
+#ifndef MKTC_ST
+#define MKTC_ST(x)
+#endif
+
+/*
+ It would be nice to put these definitions into an enumeration, but USEASM
+ only has access to the C preprocessor so macros are required.
+*/
+
+/*
+ Bits 24-31 of these codes (0xAD) are a magic number used to help
+ distinguish between them and other debug information which can be
+ optionally dumped into the status buffer, e.g. sync object values.
+*/
+
+/*
+ Microkernel trace codes
+*/
+#define MKTC_EHEVENT_3DMEMFREE 0xAD000001
+MKTC_ST(MKTC_EHEVENT_3DMEMFREE)
+#define MKTC_EHEVENT_PIXELENDRENDER 0xAD000002
+MKTC_ST(MKTC_EHEVENT_PIXELENDRENDER)
+#define MKTC_EHEVENT_ISPBREAKPOINT 0xAD000004
+MKTC_ST(MKTC_EHEVENT_ISPBREAKPOINT)
+#define MKTC_EHEVENT_TAFINISHED 0xAD000005
+MKTC_ST(MKTC_EHEVENT_TAFINISHED)
+#define MKTC_EHEVENT_OUTOFMEM 0xAD000007
+MKTC_ST(MKTC_EHEVENT_OUTOFMEM)
+#define MKTC_EHEVENT_TATERMINATE 0xAD000008
+MKTC_ST(MKTC_EHEVENT_TATERMINATE)
+#define MKTC_EHEVENT_TIMER 0xAD000009
+MKTC_ST(MKTC_EHEVENT_TIMER)
+#define MKTC_EHEVENT_SWEVENT 0xAD00000A
+MKTC_ST(MKTC_EHEVENT_SWEVENT)
+#define MKTC_EHEVENT_2DCOMPLETE 0xAD00000B
+MKTC_ST(MKTC_EHEVENT_2DCOMPLETE)
+
+#define MKTC_3DEVENT_3DMEMFREE 0xAD000100
+MKTC_ST(MKTC_3DEVENT_3DMEMFREE)
+#define MKTC_3DEVENT_PIXELENDRENDER 0xAD000101
+MKTC_ST(MKTC_3DEVENT_PIXELENDRENDER)
+#define MKTC_3DEVENT_ISPBREAKPOINT 0xAD000102
+MKTC_ST(MKTC_3DEVENT_ISPBREAKPOINT)
+#define MKTC_3DEVENT_END 0xAD000104
+MKTC_ST(MKTC_3DEVENT_END)
+#define MKTC_3DLB_3DMEMFREE 0xAD000180
+MKTC_ST(MKTC_3DLB_3DMEMFREE)
+#define MKTC_3DLB_PIXELENDRENDER 0xAD000181
+MKTC_ST(MKTC_3DLB_PIXELENDRENDER)
+#define MKTC_3DLB_ISPBREAKPOINT 0xAD000182
+MKTC_ST(MKTC_3DLB_ISPBREAKPOINT)
+#define MKTC_3DLB_FIND3D 0xAD000183
+MKTC_ST(MKTC_3DLB_FIND3D)
+#define MKTC_3DLB_END 0xAD000184
+MKTC_ST(MKTC_3DLB_END)
+
+#define MKTC_TAEVENT_TAFINISHED 0xAD000200
+MKTC_ST(MKTC_TAEVENT_TAFINISHED)
+#define MKTC_TAEVENT_END 0xAD000202
+MKTC_ST(MKTC_TAEVENT_END)
+#define MKTC_TALB_TAFINISHED 0xAD000280
+MKTC_ST(MKTC_TALB_TAFINISHED)
+#define MKTC_TALB_FINDTA 0xAD000281
+MKTC_ST(MKTC_TALB_FINDTA)
+#define MKTC_TALB_END 0xAD000282
+MKTC_ST(MKTC_TALB_END)
+
+#define MKTC_CRRL_WRITEOPSBLOCKED 0xAD000300
+MKTC_ST(MKTC_CRRL_WRITEOPSBLOCKED)
+#define MKTC_CRRL_READOPSBLOCKED 0xAD000301
+MKTC_ST(MKTC_CRRL_READOPSBLOCKED)
+#define MKTC_CRRL_FOUNDRENDER 0xAD000302
+MKTC_ST(MKTC_CRRL_FOUNDRENDER)
+#define MKTC_CRRL_NORENDER 0xAD000303
+MKTC_ST(MKTC_CRRL_NORENDER)
+#define MKTC_CRRL_TARC_DIFFERENT 0xAD000304
+MKTC_ST(MKTC_CRRL_TARC_DIFFERENT)
+#define MKTC_CRRL_BLOCKEDRC 0xAD000309
+MKTC_ST(MKTC_CRRL_BLOCKEDRC)
+#define MKTC_CRRL_BLOCKEDRTDATA 0xAD00030A
+MKTC_ST(MKTC_CRRL_BLOCKEDRTDATA)
+#define MKTC_CRRL_CONTEXT_SUSPENDED 0xAD00030B
+MKTC_ST(MKTC_CRRL_CONTEXT_SUSPENDED)
+#define MKTC_CRRL_TAWAITINGFORMEM 0xAD00030C
+MKTC_ST(MKTC_CRRL_TAWAITINGFORMEM)
+#define MKTC_CRRL_TAOOMBUTPRIOINV 0xAD00030D
+MKTC_ST(MKTC_CRRL_TAOOMBUTPRIOINV)
+#define MKTC_CRRL_READOPS2BLOCKED 0xAD00030E
+MKTC_ST(MKTC_CRRL_READOPS2BLOCKED)
+#define MKTC_CRRL_SRC_WRITEOPSBLOCKED 0xAD00030F
+MKTC_ST(MKTC_CRRL_SRC_WRITEOPSBLOCKED)
+#define MKTC_CRRL_SRC_READOPSBLOCKED 0xAD000310
+MKTC_ST(MKTC_CRRL_SRC_READOPSBLOCKED)
+
+#define MKTC_KICKRENDER_START 0xAD000400
+MKTC_ST(MKTC_KICKRENDER_START)
+#define MKTC_KICKRENDER_OVERLAP 0xAD000401
+MKTC_ST(MKTC_KICKRENDER_OVERLAP)
+#define MKTC_KICKRENDER_ISP_START 0xAD000402
+MKTC_ST(MKTC_KICKRENDER_ISP_START)
+#define MKTC_KICKRENDER_RESUME 0xAD000403
+MKTC_ST(MKTC_KICKRENDER_RESUME)
+#define MKTC_KICKRENDER_CONFIG_REGION_HDRS 0xAD000404
+MKTC_ST(MKTC_KICKRENDER_CONFIG_REGION_HDRS)
+#define MKTC_KICKRENDER_END 0xAD000408
+MKTC_ST(MKTC_KICKRENDER_END)
+#define MKTC_KICKRENDER_RENDERCONTEXT 0xAD000409
+MKTC_ST(MKTC_KICKRENDER_RENDERCONTEXT)
+#define MKTC_KICKRENDER_RTDATA 0xAD00040A
+MKTC_ST(MKTC_KICKRENDER_RTDATA)
+#define MKTC_KICKRENDER_PID 0xAD00040B
+MKTC_ST(MKTC_KICKRENDER_PID)
+
+#define MKTC_RENDERFINISHED_START 0xAD000500
+MKTC_ST(MKTC_RENDERFINISHED_START)
+#define MKTC_RF_START_NEXT_MT 0xAD000501
+MKTC_ST(MKTC_RF_START_NEXT_MT)
+#define MKTC_RF_ALL_MTS_DONE 0xAD000502
+MKTC_ST(MKTC_RF_ALL_MTS_DONE)
+#define MKTC_RENDERFINISHED_END 0xAD000503
+MKTC_ST(MKTC_RENDERFINISHED_END)
+#define MKTC_VISQUERY_START 0xAD000504
+MKTC_ST(MKTC_VISQUERY_START)
+#define MKTC_VISQUERY_END 0xAD000505
+MKTC_ST(MKTC_VISQUERY_END)
+#define MKTC_TRANSFERRENDERFINISHED_START 0xAD000508
+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_START)
+#define MKTC_TRANSFERRENDERFINISHED_END 0xAD000509
+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_END)
+#define MKTC_TRF_UPDATESTATUSVALS 0xAD00050A
+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS)
+#define MKTC_TRF_UPDATESTATUSVALS_DONE 0xAD00050B
+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS_DONE)
+
+#define MKTC_PIXELENDRENDER_START 0xAD000600
+MKTC_ST(MKTC_PIXELENDRENDER_START)
+#define MKTC_PIXELENDRENDER_AFTERLOCK 0xAD000601
+MKTC_ST(MKTC_PIXELENDRENDER_AFTERLOCK)
+#define MKTC_PIXELENDRENDER_END 0xAD000602
+MKTC_ST(MKTC_PIXELENDRENDER_END)
+#define MKTC_PIXELENDRENDER_TLQEND 0xAD000603
+MKTC_ST(MKTC_PIXELENDRENDER_TLQEND)
+
+#define MKTC_3DMEMFREE_START 0xAD000700
+MKTC_ST(MKTC_3DMEMFREE_START)
+#define MKTC_3DMEMFREE_AFTERLOCK 0xAD000701
+MKTC_ST(MKTC_3DMEMFREE_AFTERLOCK)
+#define MKTC_3DMEMFREE_TESTEOR 0xAD000702
+MKTC_ST(MKTC_3DMEMFREE_TESTEOR)
+#define MKTC_3DMEMFREE_END 0xAD000703
+MKTC_ST(MKTC_3DMEMFREE_END)
+
+#define MKTC_KICKTA_START 0xAD000800
+MKTC_ST(MKTC_KICKTA_START)
+#define MKTC_KICKTA_OVERLAP 0xAD000801
+MKTC_ST(MKTC_KICKTA_OVERLAP)
+#define MKTC_KICKTA_RESETCONTEXT 0xAD000802
+MKTC_ST(MKTC_KICKTA_RESETCONTEXT)
+#define MKTC_KICKTA_VDM_START 0xAD000803
+MKTC_ST(MKTC_KICKTA_VDM_START)
+#define MKTC_KICKTA_END 0xAD000804
+MKTC_ST(MKTC_KICKTA_END)
+#define MKTC_KICKTA_RENDERCONTEXT 0xAD000805
+MKTC_ST(MKTC_KICKTA_RENDERCONTEXT)
+#define MKTC_KICKTA_RTDATA 0xAD000806
+MKTC_ST(MKTC_KICKTA_RTDATA)
+#define MKTC_KICKTA_RESET_VDMCSSTATUS 0xAD000807
+MKTC_ST(MKTC_KICKTA_RESET_VDMCSSTATUS)
+#define MKTC_KICKTA_RESET_BUFFERS 0xAD000808
+MKTC_ST(MKTC_KICKTA_RESET_BUFFERS)
+#define MKTC_KICKTA_PID 0xAD000809
+MKTC_ST(MKTC_KICKTA_PID)
+#define MKTC_KICKTA_TACMD_DEBUG 0xAD00080A
+MKTC_ST(MKTC_KICKTA_TACMD_DEBUG)
+#define MKTC_KICKTA_FREECONTEXT 0xAD00080B
+MKTC_ST(MKTC_KICKTA_FREECONTEXT)
+#define MKTC_KICKTA_PIM_PATCHING 0xAD00080C
+MKTC_ST(MKTC_KICKTA_PIM_PATCHING)
+
+#define MKTC_KICKTA_CHKPT_START_DUMMY_CS 0xAD0008A1
+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_CS)
+#define MKTC_KICKTA_CHKPT_START_DUMMY_TAK 0xAD0008A2
+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_TAK)
+#define MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK 0xAD0008A3
+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK)
+#define MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE 0xAD0008A4
+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE)
+#define MKTC_KICKTA_CHKPT_RESET_COMPLETE 0xAD0008A5
+MKTC_ST(MKTC_KICKTA_CHKPT_RESET_COMPLETE)
+#define MKTC_KICKTA_CHKPT_CHECK_SWITCH 0xAD0008A6
+MKTC_ST(MKTC_KICKTA_CHKPT_CHECK_SWITCH)
+
+#define MKTC_HOSTKICK_START 0xAD000900
+MKTC_ST(MKTC_HOSTKICK_START)
+#define MKTC_HOSTKICK_END 0xAD000901
+MKTC_ST(MKTC_HOSTKICK_END)
+#define MKTC_HOSTKICK_PROCESS_QUEUES_END 0xAD000902
+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES_END)
+#define MKTC_HOSTKICK_2D 0xAD000903
+MKTC_ST(MKTC_HOSTKICK_2D)
+#define MKTC_HOSTKICK_TRANSFER 0xAD000904
+MKTC_ST(MKTC_HOSTKICK_TRANSFER)
+#define MKTC_HOSTKICK_TA 0xAD000905
+MKTC_ST(MKTC_HOSTKICK_TA)
+#define MKTC_HOSTKICK_PROCESS_QUEUES 0xAD000906
+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES)
+#define MKTC_HOSTKICK_RESUME 0xAD000908
+MKTC_ST(MKTC_HOSTKICK_RESUME)
+#define MKTC_HOSTKICK_POWEROFF 0xAD000909
+MKTC_ST(MKTC_HOSTKICK_POWEROFF)
+#define MKTC_HOSTKICK_IDLE 0xAD00090A
+MKTC_ST(MKTC_HOSTKICK_IDLE)
+#define MKTC_HOSTKICK_CTXSUSPEND 0xAD00090B
+MKTC_ST(MKTC_HOSTKICK_CTXSUSPEND)
+#define MKTC_HOSTKICK_CTXRESUME 0xAD00090C
+MKTC_ST(MKTC_HOSTKICK_CTXRESUME)
+
+#define MKTC_TIMER_POTENTIAL_TA_LOCKUP 0xAD000A00
+MKTC_ST(MKTC_TIMER_POTENTIAL_TA_LOCKUP)
+#define MKTC_TIMER_POTENTIAL_3D_LOCKUP 0xAD000A01
+MKTC_ST(MKTC_TIMER_POTENTIAL_3D_LOCKUP)
+#define MKTC_TIMER_CTAL_START 0xAD000A02
+MKTC_ST(MKTC_TIMER_CTAL_START)
+#define MKTC_TIMER_CTAL_END 0xAD000A03
+MKTC_ST(MKTC_TIMER_CTAL_END)
+#define MKTC_TIMER_C3DL_START 0xAD000A04
+MKTC_ST(MKTC_TIMER_C3DL_START)
+#define MKTC_TIMER_C3DL_END 0xAD000A05
+MKTC_ST(MKTC_TIMER_C3DL_END)
+#define MKTC_TIMER_LOCKUP 0xAD000A0A
+MKTC_ST(MKTC_TIMER_LOCKUP)
+#define MKTC_TIMER_NOT_TA_LOCKUP 0xAD000A0B
+MKTC_ST(MKTC_TIMER_NOT_TA_LOCKUP)
+#define MKTC_TIMER_NOT_3D_LOCKUP 0xAD000A0C
+MKTC_ST(MKTC_TIMER_NOT_3D_LOCKUP)
+#define MKTC_TIMER_2D_LOCKUP 0xAD000A0D
+MKTC_ST(MKTC_TIMER_2D_LOCKUP)
+#define MKTC_TIMER_POTENTIAL_2D_LOCKUP 0xAD000A10
+MKTC_ST(MKTC_TIMER_POTENTIAL_2D_LOCKUP)
+#define MKTC_TIMER_C2DL_START 0xAD000A11
+MKTC_ST(MKTC_TIMER_C2DL_START)
+#define MKTC_TIMER_C2DL_END 0xAD000A12
+MKTC_ST(MKTC_TIMER_C2DL_END)
+#define MKTC_TIMER_NOT_2D_LOCKUP 0xAD000A13
+MKTC_ST(MKTC_TIMER_NOT_2D_LOCKUP)
+#define MKTC_TIMER_ABORTALL 0xAD000A0E
+MKTC_ST(MKTC_TIMER_ABORTALL)
+#define MKTC_TIMER_END 0xAD000A0F
+MKTC_ST(MKTC_TIMER_END)
+
+#define MKTC_HWR_START 0xAD000B00
+MKTC_ST(MKTC_HWR_START)
+#define MKTC_HWR_END 0xAD000B01
+MKTC_ST(MKTC_HWR_END)
+#define MKTC_HWR_HKS 0xAD000B02
+MKTC_ST(MKTC_HWR_HKS)
+#define MKTC_HWR_PRL 0xAD000B03
+MKTC_ST(MKTC_HWR_PRL)
+#define MKTC_HWR_PRL_DP 0xAD000B04
+MKTC_ST(MKTC_HWR_PRL_DP)
+#define MKTC_HWR_CRL 0xAD000B05
+MKTC_ST(MKTC_HWR_CRL)
+#define MKTC_HWR_CRL_DP 0xAD000B06
+MKTC_ST(MKTC_HWR_CRL_DP)
+#define MKTC_HWR_TRL 0xAD000B07
+MKTC_ST(MKTC_HWR_TRL)
+#define MKTC_HWR_TRL_DP 0xAD000B08
+MKTC_ST(MKTC_HWR_TRL_DP)
+#define MKTC_HWR_ISC 0xAD000B09
+MKTC_ST(MKTC_HWR_ISC)
+#define MKTC_HWR_2DL 0xAD000B0A
+MKTC_ST(MKTC_HWR_2DL)
+
+#define MKTC_URSV_START 0xAD000C00
+MKTC_ST(MKTC_URSV_START)
+#define MKTC_URSV_UPDATEWRITEOPS 0xAD000C01
+MKTC_ST(MKTC_URSV_UPDATEWRITEOPS)
+#define MKTC_URSV_UPDATESTATUSVALS 0xAD000C03
+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS)
+#define MKTC_URSV_UPDATESTATUSVALS_DONE 0xAD000C04
+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS_DONE)
+#define MKTC_URSV_END 0xAD000C05
+MKTC_ST(MKTC_URSV_END)
+
+#define MKTC_STORETACONTEXT_START 0xAD000D00
+MKTC_ST(MKTC_STORETACONTEXT_START)
+#define MKTC_STORETACONTEXT_END 0xAD000D01
+MKTC_ST(MKTC_STORETACONTEXT_END)
+#define MKTC_LOADTACONTEXT_START 0xAD000D02
+MKTC_ST(MKTC_LOADTACONTEXT_START)
+#define MKTC_LOADTACONTEXT_END 0xAD000D03
+MKTC_ST(MKTC_LOADTACONTEXT_END)
+#define MKTC_STORE3DCONTEXT_START 0xAD000D04
+MKTC_ST(MKTC_STORE3DCONTEXT_START)
+#define MKTC_STORE3DCONTEXT_END 0xAD000D05
+MKTC_ST(MKTC_STORE3DCONTEXT_END)
+#define MKTC_LOAD3DCONTEXT_START 0xAD000D06
+MKTC_ST(MKTC_LOAD3DCONTEXT_START)
+#define MKTC_LOAD3DCONTEXT_END 0xAD000D07
+MKTC_ST(MKTC_LOAD3DCONTEXT_END)
+
+#define MKTC_FINDTA_POWERREQUEST 0xAD000E00
+MKTC_ST(MKTC_FINDTA_POWERREQUEST)
+#define MKTC_FINDTA_TA3D_OVERLAP_BLOCKED 0xAD000E01
+MKTC_ST(MKTC_FINDTA_TA3D_OVERLAP_BLOCKED)
+#define MKTC_FINDTA_RTDATA_RENDERING 0xAD000E02
+MKTC_ST(MKTC_FINDTA_RTDATA_RENDERING)
+#define MKTC_FINDTA_3DRC_DIFFERENT 0xAD000E03
+MKTC_ST(MKTC_FINDTA_3DRC_DIFFERENT)
+#define MKTC_FINDTA_WRITEOPSBLOCKED 0xAD000E04
+MKTC_ST(MKTC_FINDTA_WRITEOPSBLOCKED)
+#define MKTC_FINDTA_READOPSBLOCKED 0xAD000E05
+MKTC_ST(MKTC_FINDTA_READOPSBLOCKED)
+#define MKTC_FINDTA_RESIZE_PB 0xAD000E06
+MKTC_ST(MKTC_FINDTA_RESIZE_PB)
+#define MKTC_FINDTA_RESIZE_PB_BLOCKED 0xAD000E07
+MKTC_ST(MKTC_FINDTA_RESIZE_PB_BLOCKED)
+#define MKTC_FINDTA_SHRINK_PB 0xAD000E08
+MKTC_ST(MKTC_FINDTA_SHRINK_PB)
+#define MKTC_FINDTA_TAPB_DIFFERENT 0xAD000E09
+MKTC_ST(MKTC_FINDTA_TAPB_DIFFERENT)
+#define MKTC_FINDTA_TACONTEXT_DIFFERENT 0xAD000E0A
+MKTC_ST(MKTC_FINDTA_TACONTEXT_DIFFERENT)
+#define MKTC_FINDTA_TA2D_OVERLAP_BLOCKED 0xAD000E0B
+MKTC_ST(MKTC_FINDTA_TA2D_OVERLAP_BLOCKED)
+#define MKTC_FINDTA_CONTEXT_SUSPENDED 0xAD000E0C
+MKTC_ST(MKTC_FINDTA_CONTEXT_SUSPENDED)
+#define MKTC_FINDTA_SRC_READOPSBLOCKED 0xAD000E0D
+MKTC_ST(MKTC_FINDTA_SRC_READOPSBLOCKED)
+#define MKTC_FINDTA_SRC_WRITEOPSBLOCKED 0xAD000E0E
+MKTC_ST(MKTC_FINDTA_SRC_WRITEOPSBLOCKED)
+#define MKTC_FINDTA_READOPS2BLOCKED 0xAD000E0F
+MKTC_ST(MKTC_FINDTA_READOPS2BLOCKED)
+
+#define MKTC_CTRL_SRCREADOPSBLOCKED 0xAD000F00
+MKTC_ST(MKTC_CTRL_SRCREADOPSBLOCKED)
+#define MKTC_CTRL_SRCWRITEOPSBLOCKED 0xAD000F01
+MKTC_ST(MKTC_CTRL_SRCWRITEOPSBLOCKED)
+#define MKTC_CTRL_DSTREADOPSBLOCKED 0xAD000F02
+MKTC_ST(MKTC_CTRL_DSTREADOPSBLOCKED)
+#define MKTC_CTRL_DSTWRITEOPSBLOCKED 0xAD000F03
+MKTC_ST(MKTC_CTRL_DSTWRITEOPSBLOCKED)
+#define MKTC_CTRL_TARC_DIFFERENT 0xAD000F04
+MKTC_ST(MKTC_CTRL_TARC_DIFFERENT)
+#define MKTC_CTRL_CONTEXT_SUSPENDED 0xAD000F05
+MKTC_ST(MKTC_CTRL_CONTEXT_SUSPENDED)
+#define MKTC_CTRL_SRCREADOPS2BLOCKED 0xAD000F06
+MKTC_ST(MKTC_CTRL_SRCREADOPS2BLOCKED)
+
+#define MKTC_DPTA_START 0xAD001000
+MKTC_ST(MKTC_DPTA_START)
+#define MKTC_DPTA_UPDATESTATUSVALS 0xAD001001
+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS)
+#define MKTC_DPTA_UPDATESTATUSVALS_DONE 0xAD001002
+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS_DONE)
+#define MKTC_DPTA_NORENDER 0xAD001003
+MKTC_ST(MKTC_DPTA_NORENDER)
+#define MKTC_DPTA_MEMFREE 0xAD001004
+MKTC_ST(MKTC_DPTA_MEMFREE)
+#define MKTC_DPTA_INC_COMPLETECOUNT 0xAD001005
+MKTC_ST(MKTC_DPTA_INC_COMPLETECOUNT)
+
+#define MKTC_INVALDC 0xAD001100
+MKTC_ST(MKTC_INVALDC)
+#define MKTC_INVALPT 0xAD001101
+MKTC_ST(MKTC_INVALPT)
+#define MKTC_INVALSLC 0xAD001102
+MKTC_ST(MKTC_INVALSLC)
+#define MKTC_INVALDATA 0xAD001103
+MKTC_ST(MKTC_INVALDATA)
+
+#define MKTC_RESTARTTA 0xAD001200
+MKTC_ST(MKTC_RESTARTTA)
+#define MKTC_CSABORTNONGBL 0xAD001201
+MKTC_ST(MKTC_CSABORTNONGBL)
+#define MKTC_CSABORTALL 0xAD001202
+MKTC_ST(MKTC_CSABORTALL)
+#define MKTC_CSRENDERINPROGRESS 0xAD001203
+MKTC_ST(MKTC_CSRENDERINPROGRESS)
+#define MKTC_TATERMRENDERINPROGRESS 0xAD001204
+MKTC_ST(MKTC_TATERMRENDERINPROGRESS)
+#define MKTC_RESTARTTANORENDER 0xAD001205
+MKTC_ST(MKTC_RESTARTTANORENDER)
+#define MKTC_SPM_KICKRENDER 0xAD001206
+MKTC_ST(MKTC_SPM_KICKRENDER)
+#define MKTC_SPM_RESUME_ABORTCOMPLETE 0xAD001208
+MKTC_ST(MKTC_SPM_RESUME_ABORTCOMPLETE)
+#define MKTC_RESUMEVDM 0xAD001209
+MKTC_ST(MKTC_RESUMEVDM)
+#define MKTC_REMOVE_RESERVE_MEM 0xAD00120A
+MKTC_ST(MKTC_REMOVE_RESERVE_MEM)
+#define MKTC_INCREASEZLSTHRESHOLD 0xAD00120B
+MKTC_ST(MKTC_INCREASEZLSTHRESHOLD)
+#define MKTC_CSFORCEABORTALL 0xAD00120C
+MKTC_ST(MKTC_CSFORCEABORTALL)
+
+#define MKTC_DUMMY_DEPTH 0xAD00120D
+MKTC_ST(MKTC_DUMMY_DEPTH)
+#define MKTC_DUMMY_DEPTH_CS 0xAD00120E
+MKTC_ST(MKTC_DUMMY_DEPTH_CS)
+
+#define MKTC_MTETE_OOM 0xAD00120F
+MKTC_ST(MKTC_MTETE_OOM)
+#define MKTC_MTETE_OOM_FIRST_STORE_REF 0xAD001210
+MKTC_ST(MKTC_MTETE_OOM_FIRST_STORE_REF)
+#define MKTC_MERGE_STATE_TABLES 0xAD001211
+MKTC_ST(MKTC_MERGE_STATE_TABLES)
+#define MKTC_NO_PAGES_LEFT_FOR_23055 0xAD001212
+MKTC_ST(MKTC_NO_PAGES_LEFT_FOR_23055)
+#define MKTC_NO_STATE_MODS 0xAD001213
+MKTC_ST(MKTC_NO_STATE_MODS)
+#define MKTC_FIND_MTE_PAGE_IN_STATE 0xAD001214
+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_STATE)
+#define MKTC_MTE_PAGE_FOUND 0xAD001215
+MKTC_ST(MKTC_MTE_PAGE_FOUND)
+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE 0xAD001216
+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE)
+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END 0xAD001217
+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END)
+#define MKTC_ZERO_ZLS_THRESHOLD 0xAD001218
+MKTC_ST(MKTC_ZERO_ZLS_THRESHOLD)
+#define MKTC_RESTORE_ZLS_THRESHOLD 0xAD001219
+MKTC_ST(MKTC_RESTORE_ZLS_THRESHOLD)
+#define MKTC_FIND_MTE_PAGE_IN_CSM 0xAD00121A
+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_CSM)
+#define MKTC_REISSUE_MTE_PAGE 0xAD00121B
+MKTC_ST(MKTC_REISSUE_MTE_PAGE)
+#define MKTC_REISSUE_MTE_PAGE_REQUIRED 0xAD00121C
+MKTC_ST(MKTC_REISSUE_MTE_PAGE_REQUIRED)
+#define MKTC_REISSUE_MTE_PAGE_END 0xAD00121D
+MKTC_ST(MKTC_REISSUE_MTE_PAGE_END)
+#define MKTC_RESET_TE_PSG 0xAD00121E
+MKTC_ST(MKTC_RESET_TE_PSG)
+
+#define MKTC_OOM_WRITEOPSBLOCKED 0xAD00121F
+MKTC_ST(MKTC_OOM_WRITEOPSBLOCKED)
+#define MKTC_OOM_READOPSBLOCKED 0xAD001220
+MKTC_ST(MKTC_OOM_READOPSBLOCKED)
+#define MKTC_OOM_SRC_WRITEOPSBLOCKED 0xAD001221
+MKTC_ST(MKTC_OOM_SRC_WRITEOPSBLOCKED)
+#define MKTC_OOM_SRC_READOPSBLOCKED 0xAD001222
+MKTC_ST(MKTC_OOM_SRC_READOPSBLOCKED)
+#define MKTC_OOM_SPM_DEADLOCK 0xAD001223
+MKTC_ST(MKTC_OOM_SPM_DEADLOCK)
+#define MKTC_OOM_SPM_DEADLOCK_MEM_ADDED 0xAD001224
+MKTC_ST(MKTC_OOM_SPM_DEADLOCK_MEM_ADDED)
+#define MKTC_RESET 0xAD001225
+MKTC_ST(MKTC_RESET)
+#define MKTC_SPM_INVALID_ZLSCONFIG 0xAD001226
+MKTC_ST(MKTC_SPM_INVALID_ZLSCONFIG)
+
+#define MKTC_OOM_TYPE_MT 0xAD00122A
+MKTC_ST(MKTC_OOM_TYPE_MT)
+#define MKTC_OOM_TYPE_GLOBAL 0xAD001230
+MKTC_ST(MKTC_OOM_TYPE_GLOBAL)
+#define MKTC_OOM_CAUSE_GBL_OOM 0xAD001231
+MKTC_ST(MKTC_OOM_CAUSE_GBL_OOM)
+#define MKTC_OOM_RESTORE_LIST_SIZE 0xAD001232
+MKTC_ST(MKTC_OOM_RESTORE_LIST_SIZE)
+
+#define MKTC_CHECK_MTE_PAGE_REISSUE 0xAD001240
+MKTC_ST(MKTC_CHECK_MTE_PAGE_REISSUE)
+#define MKTC_CPRI_VALID_ENTRIES 0xAD001241
+MKTC_ST(MKTC_CPRI_VALID_ENTRIES)
+#define MKTC_CPRI_STORE_DPLIST 0xAD001242
+MKTC_ST(MKTC_CPRI_STORE_DPLIST)
+#define MKTC_CPRI_STORE_OTPM_CSM 0xAD001243
+MKTC_ST(MKTC_CPRI_STORE_OTPM_CSM)
+#define MKTC_CPRI_ABORT_MT_IDX 0xAD001244
+MKTC_ST(MKTC_CPRI_ABORT_MT_IDX)
+#define MKTC_CPRI_ABORT_CORE_IDX 0xAD001245
+MKTC_ST(MKTC_CPRI_ABORT_CORE_IDX)
+#define MKTC_CPRI_CSM_TABLE_DATA 0xAD001246
+MKTC_ST(MKTC_CPRI_CSM_TABLE_DATA)
+#define MKTC_CPRI_PIM_DATA 0xAD001247
+MKTC_ST(MKTC_CPRI_PIM_DATA)
+#define MKTC_CPRI_DO_CIRCULAR_TEST 0xAD001248
+MKTC_ST(MKTC_CPRI_DO_CIRCULAR_TEST)
+#define MKTC_CPRI_WRITE_ENTRIES 0xAD001249
+MKTC_ST(MKTC_CPRI_WRITE_ENTRIES)
+
+#define MKTC_MTE_ENTRY_NOT_IN_ANY_LIST 0xAD001250
+MKTC_ST(MKTC_MTE_ENTRY_NOT_IN_ANY_LIST)
+
+#define MKTC_SPMAC_IGNORE_TERMINATE 0xAD001251
+MKTC_ST(MKTC_SPMAC_IGNORE_TERMINATE)
+
+#define MKTC_SPMAC_REQUEST_3D_TIMEOUT 0xAD001252
+MKTC_ST(MKTC_SPMAC_REQUEST_3D_TIMEOUT)
+#define MKTC_SPMAC_3D_TIMEOUT_COMPLETE 0xAD001253
+MKTC_ST(MKTC_SPMAC_3D_TIMEOUT_COMPLETE)
+#define MKTC_OOM_READOPS2BLOCKED 0xAD001254
+MKTC_ST(MKTC_OOM_READOPS2BLOCKED)
+
+/* PB Load/store status */
+#define MKTC_LOADTAPB_START 0xAD001300
+MKTC_ST(MKTC_LOADTAPB_START)
+#define MKTC_LOADTAPB_END 0xAD001301
+MKTC_ST(MKTC_LOADTAPB_END)
+#define MKTC_STORETAPB_START 0xAD001302
+MKTC_ST(MKTC_STORETAPB_START)
+#define MKTC_STORETAPB_END 0xAD001303
+MKTC_ST(MKTC_STORETAPB_END)
+#define MKTC_LOAD3DPB_START 0xAD001304
+MKTC_ST(MKTC_LOAD3DPB_START)
+#define MKTC_LOAD3DPB_END 0xAD001305
+MKTC_ST(MKTC_LOAD3DPB_END)
+#define MKTC_STORE3DPB_START 0xAD001306
+MKTC_ST(MKTC_STORE3DPB_START)
+#define MKTC_STORE3DPB_END 0xAD001307
+MKTC_ST(MKTC_STORE3DPB_END)
+#define MKTC_LOADTAPB_PAGETABLE_DONE 0xAD001308
+MKTC_ST(MKTC_LOADTAPB_PAGETABLE_DONE)
+#define MKTC_LOAD3DPB_PAGETABLE_DONE 0xAD001309
+MKTC_ST(MKTC_LOAD3DPB_PAGETABLE_DONE)
+
+#define MKTC_TIMER_RC_CLEANUP 0xAD001400
+MKTC_ST(MKTC_TIMER_RC_CLEANUP)
+#define MKTC_TIMER_RC_CLEANUP_DONE 0xAD001401
+MKTC_ST(MKTC_TIMER_RC_CLEANUP_DONE)
+#define MKTC_TIMER_RC_CLEANUP_BUSY 0xAD001402
+MKTC_ST(MKTC_TIMER_RC_CLEANUP_BUSY)
+#define MKTC_TIMER_RT_CLEANUP 0xAD001410
+MKTC_ST(MKTC_TIMER_RT_CLEANUP)
+#define MKTC_TIMER_RT_CLEANUP_DONE 0xAD001411
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_DONE)
+#define MKTC_TIMER_RT_CLEANUP_PENDING 0xAD001412
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_PENDING)
+#define MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST 0xAD001413
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST)
+#define MKTC_TIMER_RT_CLEANUP_BUSY 0xAD001414
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_BUSY)
+#define MKTC_TIMER_TC_CLEANUP 0xAD001420
+MKTC_ST(MKTC_TIMER_TC_CLEANUP)
+#define MKTC_TIMER_TC_CLEANUP_DONE 0xAD001421
+MKTC_ST(MKTC_TIMER_TC_CLEANUP_DONE)
+#define MKTC_TIMER_TC_CLEANUP_BUSY 0xAD001422
+MKTC_ST(MKTC_TIMER_TC_CLEANUP_BUSY)
+#define MKTC_TIMER_2DC_CLEANUP 0xAD001430
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP)
+#define MKTC_TIMER_2DC_CLEANUP_DONE 0xAD001431
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_DONE)
+#define MKTC_TIMER_2DC_CLEANUP_BUSY 0xAD001432
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_BUSY)
+#define MKTC_TIMER_SHAREDPBDESC_CLEANUP 0xAD001440
+MKTC_ST(MKTC_TIMER_SHAREDPBDESC_CLEANUP)
+
+
+#define MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP 0xAD001450
+MKTC_ST(MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP)
+#define MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH 0xAD001451
+MKTC_ST(MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH)
+
+#define MKTC_UTSO_UPDATEREADOPS 0xAD001600
+MKTC_ST(MKTC_UTSO_UPDATEREADOPS)
+#define MKTC_UTSO_UPDATEWRITEOPS 0xAD001601
+MKTC_ST(MKTC_UTSO_UPDATEWRITEOPS)
+
+#define MKTC_TAFINISHED_UPDATESTATUSVALS 0xAD001700
+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS)
+#define MKTC_TAFINISHED_UPDATESTATUSVALS_DONE 0xAD001701
+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS_DONE)
+#define MKTC_TAFINISHED_NORENDER 0xAD001702
+MKTC_ST(MKTC_TAFINISHED_NORENDER)
+#define MKTC_TAFINISHED_LASTKICK 0xAD001703
+MKTC_ST(MKTC_TAFINISHED_LASTKICK)
+#define MKTC_TAFINISHED_FINDRENDER 0xAD001704
+MKTC_ST(MKTC_TAFINISHED_FINDRENDER)
+#define MKTC_TAFINISHED_FINDTA 0xAD001705
+MKTC_ST(MKTC_TAFINISHED_FINDTA)
+#define MKTC_TAFINISHED_END 0xAD001706
+MKTC_ST(MKTC_TAFINISHED_END)
+#define MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED 0xAD001707
+MKTC_ST(MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED)
+#define MKTC_TAF_RESERVE_MEM 0xAD001708
+MKTC_ST(MKTC_TAF_RESERVE_MEM)
+#define MKTC_TAF_RESERVE_MEM_REQUEST_RENDER 0xAD001709
+MKTC_ST(MKTC_TAF_RESERVE_MEM_REQUEST_RENDER)
+#define MKTC_TAF_RESERVE_FREE_RENDER_FINISHED 0xAD00170A
+MKTC_ST(MKTC_TAF_RESERVE_FREE_RENDER_FINISHED)
+#define MKTC_TAF_RESERVE_FREE_DUMMY_RENDER 0xAD00170B
+MKTC_ST(MKTC_TAF_RESERVE_FREE_DUMMY_RENDER)
+#define MKTC_TAF_DEBUG_SAS 0xAD00170C
+MKTC_ST(MKTC_TAF_DEBUG_SAS)
+#define MKTC_TAFINISHED_NOCONTEXTSWITCH 0xAD00170D
+MKTC_ST(MKTC_TAFINISHED_NOCONTEXTSWITCH)
+
+#define MKTC_TAFINISHED_TERM_COMPLETE_START 0xAD001710
+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_START)
+#define MKTC_TAFINISHED_TERM_COMPLETE_END 0xAD001711
+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_END)
+
+#define MKTC_TAFINISHED_DPMPAGERECYCLING 0xAD001720
+MKTC_ST(MKTC_TAFINISHED_DPMPAGERECYCLING)
+
+#define MKTC_2DEVENT_2DCOMPLETE 0xAD001800
+MKTC_ST(MKTC_2DEVENT_2DCOMPLETE)
+#define MKTC_2DEVENT_END 0xAD001801
+MKTC_ST(MKTC_2DEVENT_END)
+#define MKTC_2DLB_2DCOMPLETE 0xAD001802
+MKTC_ST(MKTC_2DLB_2DCOMPLETE)
+#define MKTC_2DLB_FIND2D 0xAD001803
+MKTC_ST(MKTC_2DLB_FIND2D)
+#define MKTC_2DLB_END 0xAD001804
+MKTC_ST(MKTC_2DLB_END)
+#define MKTC_2DCOMPLETE_START 0xAD001805
+MKTC_ST(MKTC_2DCOMPLETE_START)
+#define MKTC_2DCOMPLETE_END 0xAD001806
+MKTC_ST(MKTC_2DCOMPLETE_END)
+#define MKTC_KICK2D_START 0xAD001807
+MKTC_ST(MKTC_KICK2D_START)
+#define MKTC_KICK2D_END 0xAD001808
+MKTC_ST(MKTC_KICK2D_END)
+#define MKTC_DUMMYPROC2D 0xAD001809
+MKTC_ST(MKTC_DUMMYPROC2D)
+#define MKTC_FTD_SRCREADOPSBLOCKED 0xAD00180A
+MKTC_ST(MKTC_FTD_SRCREADOPSBLOCKED)
+#define MKTC_FTD_SRCWRITEOPSBLOCKED 0xAD00180B
+MKTC_ST(MKTC_FTD_SRCWRITEOPSBLOCKED)
+#define MKTC_FTD_DSTREADOPSBLOCKED 0xAD00180C
+MKTC_ST(MKTC_FTD_DSTREADOPSBLOCKED)
+#define MKTC_FTD_DSTWRITEOPSBLOCKED 0xAD00180D
+MKTC_ST(MKTC_FTD_DSTWRITEOPSBLOCKED)
+#define MKTC_FTD_TA2D_OVERLAP_BLOCKED 0xAD00180E
+MKTC_ST(MKTC_FTD_TA2D_OVERLAP_BLOCKED)
+#define MKTC_U2DSO_UPDATEREADOPS 0xAD00180F
+MKTC_ST(MKTC_U2DSO_UPDATEREADOPS)
+#define MKTC_U2DSO_UPDATEWRITEOPS 0xAD001810
+MKTC_ST(MKTC_U2DSO_UPDATEWRITEOPS)
+#define MKTC_FTD_TAOPSBLOCKED 0xAD001811
+MKTC_ST(MKTC_FTD_TAOPSBLOCKED)
+#define MKTC_KICK2D_2DSLAVEPORT 0xAD001812
+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT)
+#define MKTC_KICK2D_2DSLAVEPORT_DONE 0xAD001813
+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT_DONE)
+#define MKTC_FTD_CONTEXT_SUSPENDED 0xAD001814
+MKTC_ST(MKTC_FTD_CONTEXT_SUSPENDED)
+#define MKTC_KICK2D_PID 0xAD001815
+MKTC_ST(MKTC_KICK2D_PID)
+#define MKTC_FIND2D_ADDR_SPACE_DIFFERENT 0xAD001816
+MKTC_ST(MKTC_FIND2D_ADDR_SPACE_DIFFERENT)
+#define MKTC_FTD_3DOPSBLOCKED 0xAD001817
+MKTC_ST(MKTC_FTD_3DOPSBLOCKED)
+#define MKTC_FTD_DSTREADOPS2BLOCKED 0xAD001818
+MKTC_ST(MKTC_FTD_DSTREADOPS2BLOCKED)
+
+#define MKTC_FCM_START 0xAD001900
+MKTC_ST(MKTC_FCM_START)
+#define MKTC_FCM_END 0xAD001901
+MKTC_ST(MKTC_FCM_END)
+
+#define MKTC_TIMER_ACTIVE_POWER 0xAD001A00
+MKTC_ST(MKTC_TIMER_ACTIVE_POWER)
+#define MKTC_TIMER_POWER_3D_ACTIVE 0xAD001A01
+MKTC_ST(MKTC_TIMER_POWER_3D_ACTIVE)
+#define MKTC_TIMER_POWER_TA_ACTIVE 0xAD001A02
+MKTC_ST(MKTC_TIMER_POWER_TA_ACTIVE)
+#define MKTC_TIMER_POWER_2D_ACTIVE 0xAD001A03
+MKTC_ST(MKTC_TIMER_POWER_2D_ACTIVE)
+#define MKTC_TIMER_POWER_PENDING_EVENTS 0xAD001A04
+MKTC_ST(MKTC_TIMER_POWER_PENDING_EVENTS)
+#define MKTC_TIMER_POWER_IDLE 0xAD001A05
+MKTC_ST(MKTC_TIMER_POWER_IDLE)
+#define MKTC_TIMER_POWER_OFF 0xAD001A06
+MKTC_ST(MKTC_TIMER_POWER_OFF)
+#define MKTC_TIMER_POWER_CCB_ERROR 0xAD001A07
+MKTC_ST(MKTC_TIMER_POWER_CCB_ERROR)
+#define MKTC_TIMER_POWER_RESTART_IMMEDIATE 0xAD001A08
+MKTC_ST(MKTC_TIMER_POWER_RESTART_IMMEDIATE)
+
+#define MKTC_3DCONTEXT_SWITCH 0xAD001B00
+MKTC_ST(MKTC_3DCONTEXT_SWITCH)
+#define MKTC_3DCONTEXT_SWITCH_END 0xAD001B01
+MKTC_ST(MKTC_3DCONTEXT_SWITCH_END)
+
+#define MKTC_TACONTEXT_SWITCH 0xAD001C00
+MKTC_ST(MKTC_TACONTEXT_SWITCH)
+#define MKTC_TACONTEXT_SWITCH_END 0xAD001C02
+MKTC_ST(MKTC_TACONTEXT_SWITCH_END)
+
+#define MKTC_GETMISCINFO_MEMREAD_START 0xAD001D00
+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_START)
+#define MKTC_GETMISCINFO_MEMREAD_END 0xAD001D01
+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_END)
+#define MKTC_GETMISCINFO_MEMWRITE_START 0xAD001D02
+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_START)
+#define MKTC_GETMISCINFO_MEMWRITE_END 0xAD001D03
+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_END)
+
+#define MKTC_HALTTA 0xAD001E00
+MKTC_ST(MKTC_HALTTA)
+#define MKTC_HTA_SET_FLAG 0xAD001E01
+MKTC_ST(MKTC_HTA_SET_FLAG)
+#define MKTC_HTA_SAVE_COMPLEX_PTR 0xAD001E02
+MKTC_ST(MKTC_HTA_SAVE_COMPLEX_PTR)
+#define MKTC_HALTTA_END 0xAD001E03
+MKTC_ST(MKTC_HALTTA_END)
+
+#define MKTC_RESUMETA 0xAD001F00
+MKTC_ST(MKTC_RESUMETA)
+#define MKTC_RTA_CONTEXT_LOADED 0xAD001F01
+MKTC_ST(MKTC_RTA_CONTEXT_LOADED)
+#define MKTC_RTA_MTE_STATE_KICKED 0xAD001F02
+MKTC_ST(MKTC_RTA_MTE_STATE_KICKED)
+#define MKTC_RTA_CMPLX_GEOM_PRESENT 0xAD001F03
+MKTC_ST(MKTC_RTA_CMPLX_GEOM_PRESENT)
+#define MKTC_RTA_CMPLX_STATE_KICKED 0xAD001F04
+MKTC_ST(MKTC_RTA_CMPLX_STATE_KICKED)
+#define MKTC_RTA_CHECK_NEXT_SA_PROG 0xAD001F05
+MKTC_ST(MKTC_RTA_CHECK_NEXT_SA_PROG)
+#define MKTC_RTA_CORE_COMPLETED 0xAD001F06
+MKTC_ST(MKTC_RTA_CORE_COMPLETED)
+#define MKTC_RTA_DEBUG_SAS 0xAD001F07
+MKTC_ST(MKTC_RTA_DEBUG_SAS)
+#define MKTC_RESUMETA_END 0xAD001F0F
+MKTC_ST(MKTC_RESUMETA_END)
+
+#define MKTC_RENDERHALT 0xAD002000
+MKTC_ST(MKTC_RENDERHALT)
+#define MKTC_RH_CLEARFLAGS 0xAD002001
+MKTC_ST(MKTC_RH_CLEARFLAGS)
+#define MKTC_RH_CTRL_ADDR 0xAD002002
+MKTC_ST(MKTC_RH_CTRL_ADDR)
+#define MKTC_RH_RGN_ADDR 0xAD002003
+MKTC_ST(MKTC_RH_RGN_ADDR)
+#define MKTC_RH_EMPTY_TILE 0xAD002004
+MKTC_ST(MKTC_RH_EMPTY_TILE)
+#define MKTC_RH_EMPTY_LAST_TILE 0xAD002005
+MKTC_ST(MKTC_RH_EMPTY_LAST_TILE)
+#define MKTC_RH_3D_TIMEOUT 0xAD002006
+MKTC_ST(MKTC_RH_3D_TIMEOUT)
+#define MKTC_RH_NOT_EMPTY 0xAD002007
+MKTC_ST(MKTC_RH_NOT_EMPTY)
+#define MKTC_RH_OBJECT_COMPLETE 0xAD002008
+MKTC_ST(MKTC_RH_OBJECT_COMPLETE)
+#define MKTC_RH_STREAM_LINK 0xAD002009
+MKTC_ST(MKTC_RH_STREAM_LINK)
+#define MKTC_RH_OBJECT_INCOMPLETE 0xAD00200A
+MKTC_ST(MKTC_RH_OBJECT_INCOMPLETE)
+#define MKTC_RH_PRIM_MASK_PRESENT 0xAD00200B
+MKTC_ST(MKTC_RH_PRIM_MASK_PRESENT)
+#define MKTC_RH_BYTE_MASK_PRESENT 0xAD00200C
+MKTC_ST(MKTC_RH_BYTE_MASK_PRESENT)
+#define MKTC_RH_BYTE_MASK_ZERO 0xAD00200D
+MKTC_ST(MKTC_RH_BYTE_MASK_ZERO)
+#define MKTC_RH_PRIM_MASK_ZERO 0xAD00200E
+MKTC_ST(MKTC_RH_PRIM_MASK_ZERO)
+#define MKTC_RH_INVALIDATE_OBJECTS 0xAD00200F
+MKTC_ST(MKTC_RH_INVALIDATE_OBJECTS)
+#define MKTC_RH_OBJECTS_INVALIDATED 0xAD002010
+MKTC_ST(MKTC_RH_OBJECTS_INVALIDATED)
+#define MKTC_RH_DPM_RGN_PARSER_IDLE 0xAD002011
+MKTC_ST(MKTC_RH_DPM_RGN_PARSER_IDLE)
+#define MKTC_RH_NEXT_RGN_BASE 0xAD002012
+MKTC_ST(MKTC_RH_NEXT_RGN_BASE)
+#define MKTC_RH_OCC_EXIT 0xAD002013
+MKTC_ST(MKTC_RH_OCC_EXIT)
+#define MKTC_RH_STILL_RUNNING 0xAD002020
+MKTC_ST(MKTC_RH_STILL_RUNNING)
+#define MKTC_RH_CLEARMCI 0xAD002021
+MKTC_ST(MKTC_RH_CLEARMCI)
+#define MKTC_RH_EOR 0xAD002022
+MKTC_ST(MKTC_RH_EOR)
+#define MKTC_RENDERHALT_END 0xAD002030
+MKTC_ST(MKTC_RENDERHALT_END)
+
+#define MKTC_FIND3D_POWERREQUEST 0xAD002100
+MKTC_ST(MKTC_FIND3D_POWERREQUEST)
+
+#define MKTC_FIND2D_POWERREQUEST 0xAD002200
+MKTC_ST(MKTC_FIND2D_POWERREQUEST)
+
+#define MKTC_UKERNEL_INIT 0xAD002300
+MKTC_ST(MKTC_UKERNEL_INIT)
+#define MKTC_UKERNEL_INIT_DCS_COMPLETE 0xAD002301
+MKTC_ST(MKTC_UKERNEL_INIT_DCS_COMPLETE)
+#define MKTC_UKERNEL_INIT_VDMKICK_COMPLETE 0xAD002303
+MKTC_ST(MKTC_UKERNEL_INIT_VDMKICK_COMPLETE)
+
+#define MKTC_KICKTRANSFERRENDER_START 0xAD002400
+MKTC_ST(MKTC_KICKTRANSFERRENDER_START)
+#define MKTC_KICKTRANSFERRENDER_ISP_START 0xAD002401
+MKTC_ST(MKTC_KICKTRANSFERRENDER_ISP_START)
+#define MKTC_KICKTRANSFERRENDER_END 0xAD002402
+MKTC_ST(MKTC_KICKTRANSFERRENDER_END)
+#define MKTC_DUMMYPROCTRANSFER 0xAD002403
+MKTC_ST(MKTC_DUMMYPROCTRANSFER)
+#define MKTC_KTR_TQFENCE 0xAD002404
+MKTC_ST(MKTC_KTR_TQFENCE)
+#define MKTC_KICKTRANSFERRENDER_PID 0xAD002405
+MKTC_ST(MKTC_KICKTRANSFERRENDER_PID)
+
+#define MKTC_HOSTKICK_CLEANUP_RT 0xAD002500
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RT)
+#define MKTC_HOSTKICK_CLEANUP_RC 0xAD002501
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RC)
+#define MKTC_HOSTKICK_CLEANUP_TC 0xAD002502
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_TC)
+#define MKTC_HOSTKICK_CLEANUP_2DC 0xAD002503
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_2DC)
+#define MKTC_HOSTKICK_CLEANUP_PB 0xAD002504
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_PB)
+#define MKTC_HOSTKICK_GETMISCINFO 0xAD002505
+MKTC_ST(MKTC_HOSTKICK_GETMISCINFO)
+#define MKTC_HOSTKICK_DATABREAKPOINT 0xAD002506
+MKTC_ST(MKTC_HOSTKICK_DATABREAKPOINT)
+#define MKTC_HOSTKICK_SETHWPERFSTATUS 0xAD002507
+MKTC_ST(MKTC_HOSTKICK_SETHWPERFSTATUS)
+
+#define MKTC_ZEROPC 0xAD002600
+MKTC_ST(MKTC_ZEROPC)
+
+#define MKTC_ASSERT_FAIL 0xAD002700
+MKTC_ST(MKTC_ASSERT_FAIL)
+
+#define MKTC_SDLB_ILLEGAL 0xAD002800
+MKTC_ST(MKTC_SDLB_ILLEGAL)
+
+#define MKTC_SPMEVENT_OUTOFMEM 0xAD002901
+MKTC_ST(MKTC_SPMEVENT_OUTOFMEM)
+#define MKTC_SPMEVENT_TATERMINATE 0xAD002902
+MKTC_ST(MKTC_SPMEVENT_TATERMINATE)
+#define MKTC_SPMEVENT_END 0xAD002904
+MKTC_ST(MKTC_SPMEVENT_END)
+
+#define MKTC_SPMLB_OUTOFMEM 0xAD002981
+MKTC_ST(MKTC_SPMLB_OUTOFMEM)
+#define MKTC_SPMLB_TATERMINATE 0xAD002982
+MKTC_ST(MKTC_SPMLB_TATERMINATE)
+#define MKTC_SPMLB_SPMRENDERFINSHED 0xAD002983
+MKTC_ST(MKTC_SPMLB_SPMRENDERFINSHED)
+#define MKTC_SPMLB_END 0xAD002985
+MKTC_ST(MKTC_SPMLB_END)
+
+#define MKTC_SPM_CHECK_MT_DEADLOCK 0xAD002991
+MKTC_ST(MKTC_SPM_CHECK_MT_DEADLOCK)
+#define MKTC_SPM_CHECK_GLOBAL_DEADLOCK 0xAD002992
+MKTC_ST(MKTC_SPM_CHECK_GLOBAL_DEADLOCK)
+#define MKTC_SPM_RESERVE_ADDED 0xAD002993
+MKTC_ST(MKTC_SPM_RESERVE_ADDED)
+#define MKTC_SPM_FORCE_GLOBAL_OOM_FAILED 0xAD00299E
+MKTC_ST(MKTC_SPM_FORCE_GLOBAL_OOM_FAILED)
+#define MKTC_SPM_DEADLOCK_MEM_FAILED 0xAD00299F
+MKTC_ST(MKTC_SPM_DEADLOCK_MEM_FAILED)
+
+#define MKTC_IBC_ILLEGAL 0xAD002A00
+MKTC_ST(MKTC_IBC_ILLEGAL)
+
+#define MKTC_HWP_CLEARCOUNTERS 0xAD002B00
+MKTC_ST(MKTC_HWP_CLEARCOUNTERS)
+
+#define MKTC_TA_FRAMENUM 0xAD002C00
+MKTC_ST(MKTC_TA_FRAMENUM)
+#define MKTC_3D_FRAMENUM 0xAD002C01
+MKTC_ST(MKTC_3D_FRAMENUM)
+#define MKTC_SPM3D_FRAMENUM 0xAD002C02
+MKTC_ST(MKTC_SPM3D_FRAMENUM)
+
+#define MKTC_HKTA_RENDERCONTEXT 0xAD002D00
+MKTC_ST(MKTC_HKTA_RENDERCONTEXT)
+#define MKTC_IDLECORE_REFCOUNT_FAIL 0xAD002E00
+MKTC_ST(MKTC_IDLECORE_REFCOUNT_FAIL)
+
+#define MKTC_MCISTATE_NOT_CLEARED 0xAD002F00
+MKTC_ST(MKTC_MCISTATE_NOT_CLEARED)
+
+#define MKTC_LOWERED_TO_PDS_THRESHOLD 0xAD003000
+MKTC_ST(MKTC_LOWERED_TO_PDS_THRESHOLD)
+#define MKTC_REDUCE_MAX_VTX_PARTITIONS 0xAD003001
+MKTC_ST(MKTC_REDUCE_MAX_VTX_PARTITIONS)
+#define MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS 0xAD003002
+MKTC_ST(MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS)
+#define MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS 0xAD003003
+MKTC_ST(MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS)
+
+#define MKTC_IPRB_NORENDERDETAILS 0xAD003010
+MKTC_ST(MKTC_IPRB_NORENDERDETAILS)
+#define MKTC_IPRB_HAVERENDERDETAILS 0xAD003011
+MKTC_ST(MKTC_IPRB_HAVERENDERDETAILS)
+
+#define MKTC_RENDER_OUT_OF_ORDER 0xAD003020
+MKTC_ST(MKTC_RENDER_OUT_OF_ORDER)
+#define MKTC_RENDER_NOT_OUT_OF_ORDER 0xAD003021
+MKTC_ST(MKTC_RENDER_NOT_OUT_OF_ORDER)
+
+#define MKTC_ZLS_IDLE_BEGIN 0xAD003030
+MKTC_ST(MKTC_ZLS_IDLE_BEGIN)
+#define MKTC_ZLS_ISP_CLK_GATING_EN 0xAD003031
+MKTC_ST(MKTC_ZLS_ISP_CLK_GATING_EN)
+#define MKTC_ZLS_IDLE_END 0xAD003032
+MKTC_ST(MKTC_ZLS_IDLE_END)
+
+#endif /* __SGX_UKERNEL_STATUS_CODES_H__ */
+
+/******************************************************************************
+ End of file (sgx_ukernel_status_codes.h)
+******************************************************************************/
diff --git a/drivers/gpu/pvr/sgxapi_km.h b/drivers/gpu/pvr/sgxapi_km.h
index bd8dcb0bfc1..eaf45eb3a83 100644
--- a/drivers/gpu/pvr/sgxapi_km.h
+++ b/drivers/gpu/pvr/sgxapi_km.h
@@ -102,9 +102,11 @@ extern "C" {
/* note: there is implicitly 1 3D Dst Sync */
#else
/* sync info structure array size */
-#define SGX_MAX_SRC_SYNCS 8
-#define SGX_MAX_DST_SYNCS 1
+#define SGX_MAX_SRC_SYNCS_TA 8
+#define SGX_MAX_DST_SYNCS_TA 1
/* note: there is implicitly 1 3D Dst Sync */
+#define SGX_MAX_SRC_SYNCS_TQ 8
+#define SGX_MAX_DST_SYNCS_TQ 1
#endif
diff --git a/drivers/gpu/pvr/sgxerrata.h b/drivers/gpu/pvr/sgxerrata.h
index 8a3632f9466..05fd45fdcab 100644
--- a/drivers/gpu/pvr/sgxerrata.h
+++ b/drivers/gpu/pvr/sgxerrata.h
@@ -39,7 +39,6 @@
#define FIX_HW_BRN_28889
#else
#if SGX_CORE_REV == 111
- #define FIX_HW_BRN_28889
#else
#if SGX_CORE_REV == SGX_CORE_REV_HEAD
@@ -267,7 +266,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31780
@@ -277,6 +276,7 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 122
#define FIX_HW_BRN_29954
@@ -287,7 +287,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31780
@@ -298,6 +298,7 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 1221
@@ -306,7 +307,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31542
#define FIX_HW_BRN_31671
@@ -317,6 +318,7 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 140
@@ -327,7 +329,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31780
@@ -338,6 +340,7 @@
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 1401
@@ -347,7 +350,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31542
@@ -358,30 +361,33 @@
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 141
#define FIX_HW_BRN_29954
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31671
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 142
#define FIX_HW_BRN_29954
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31671
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 211
@@ -390,7 +396,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31780
@@ -401,6 +407,7 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 2111
@@ -410,7 +417,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31620
#define FIX_HW_BRN_31780
@@ -421,12 +428,13 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 213
#define FIX_HW_BRN_31272
- #if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31671
#define FIX_HW_BRN_31780
@@ -435,12 +443,14 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 216
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 302
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
@@ -486,14 +496,14 @@
#if SGX_CORE_REV == 100
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#else
#if SGX_CORE_REV == 102
#define FIX_HW_BRN_29954
#define FIX_HW_BRN_31272
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31780
#define FIX_HW_BRN_32085
@@ -501,12 +511,15 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_36513
+ #endif
#else
#if SGX_CORE_REV == 103
#define FIX_HW_BRN_29954
#define FIX_HW_BRN_31272
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31780
#define FIX_HW_BRN_32085
@@ -514,6 +527,7 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 104
#define FIX_HW_BRN_29954
@@ -522,7 +536,7 @@
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31278
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31542
#define FIX_HW_BRN_31620
@@ -534,29 +548,28 @@
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 105
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33920
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == 106
#define FIX_HW_BRN_31272
#define FIX_HW_BRN_31780
- #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_33657
- #endif
#define FIX_HW_BRN_33920
#else
#if SGX_CORE_REV == 110
#define FIX_HW_BRN_31272
#if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
+ #define FIX_HW_BRN_31559
#endif
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
@@ -569,31 +582,28 @@
#define FIX_HW_BRN_33920
#else
#if SGX_CORE_REV == 114
- #if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
- #endif
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
#else
#if SGX_CORE_REV == 115
- #if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
- #endif
#define FIX_HW_BRN_31780
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #if defined(SGX_FEATURE_MP)
+ #if SGX_FEATURE_MP_CORE_COUNT > 1
+ #define FIX_HW_BRN_36513
+ #endif
+ #endif
#else
#if SGX_CORE_REV == 116
- #if defined(SGX_FEATURE_MP)
- #define FIX_HW_BRN_31425
- #endif
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
#define FIX_HW_BRN_33809
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == SGX_CORE_REV_HEAD
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
@@ -677,6 +687,7 @@
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
#define FIX_HW_BRN_33657
#endif
+ #define FIX_HW_BRN_36513
#else
#if SGX_CORE_REV == SGX_CORE_REV_HEAD
diff --git a/drivers/gpu/pvr/sgxfeaturedefs.h b/drivers/gpu/pvr/sgxfeaturedefs.h
index 255302249b2..0679671fc44 100644
--- a/drivers/gpu/pvr/sgxfeaturedefs.h
+++ b/drivers/gpu/pvr/sgxfeaturedefs.h
@@ -28,18 +28,21 @@
#define SGX_CORE_FRIENDLY_NAME "SGX520"
#define SGX_CORE_ID SGX_CORE_ID_520
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (1)
#define SGX_FEATURE_AUTOCLOCKGATING
#else
#if defined(SGX530)
#define SGX_CORE_FRIENDLY_NAME "SGX530"
#define SGX_CORE_ID SGX_CORE_ID_530
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
#define SGX_FEATURE_AUTOCLOCKGATING
#else
#if defined(SGX531)
#define SGX_CORE_FRIENDLY_NAME "SGX531"
#define SGX_CORE_ID SGX_CORE_ID_531
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SGX_FEATURE_MULTI_EVENT_KICK
#else
@@ -50,6 +53,7 @@
#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
#define SGX_FEATURE_BIF_NUM_DIRLISTS (16)
#define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_NUM_USE_PIPES (2)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SUPPORT_SGX_GENERAL_MAPPING_HEAP
#define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
@@ -58,6 +62,7 @@
#define SGX_CORE_FRIENDLY_NAME "SGX540"
#define SGX_CORE_ID SGX_CORE_ID_540
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (28)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SGX_FEATURE_MULTI_EVENT_KICK
#else
@@ -69,6 +74,7 @@
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
#define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SGX_FEATURE_MONOLITHIC_UKERNEL
#define SGX_FEATURE_MULTI_EVENT_KICK
@@ -95,6 +101,7 @@
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
#define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (4)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SGX_FEATURE_MONOLITHIC_UKERNEL
#define SGX_FEATURE_MULTI_EVENT_KICK
@@ -103,8 +110,8 @@
#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
#if defined(SGX_FEATURE_MP)
#define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
- #endif
#define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #endif
#define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
#endif
#else
@@ -146,6 +153,7 @@
#define SGX_FEATURE_ADDRESS_SPACE_SIZE (32)
#define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
#define SGX_FEATURE_BIF_NUM_DIRLISTS (8)
+ #define SGX_FEATURE_NUM_USE_PIPES (8)
#define SGX_FEATURE_AUTOCLOCKGATING
#define SGX_FEATURE_MONOLITHIC_UKERNEL
#define SGX_FEATURE_MULTI_EVENT_KICK
diff --git a/drivers/gpu/pvr/sgxinfo.h b/drivers/gpu/pvr/sgxinfo.h
index c32dc31ebb8..dec8577954f 100644
--- a/drivers/gpu/pvr/sgxinfo.h
+++ b/drivers/gpu/pvr/sgxinfo.h
@@ -135,7 +135,7 @@ typedef struct _SGX_BRIDGE_INIT_INFO_
#endif
#endif
-#if defined(FIX_HW_BRN_31542)
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
#if defined (SUPPORT_SID_INTERFACE)
IMG_SID hKernelClearClipWAVDMStreamMemInfo;
IMG_SID hKernelClearClipWAIndexStreamMemInfo;
@@ -157,7 +157,7 @@ typedef struct _SGX_BRIDGE_INIT_INFO_
#endif
#endif
-#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31425)
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
IMG_HANDLE hKernelVDMSnapShotBufferMemInfo;
IMG_HANDLE hKernelVDMCtrlStreamBufferMemInfo;
#endif
@@ -172,13 +172,6 @@ typedef struct _SGX_BRIDGE_INIT_INFO_
IMG_HANDLE hKernelEDMStatusBufferMemInfo;
#endif
#endif
-#if defined(SGX_FEATURE_OVERLAPPED_SPM)
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hKernelTmpRgnHeaderMemInfo;
-#else
- IMG_HANDLE hKernelTmpRgnHeaderMemInfo;
-#endif
-#endif
IMG_UINT32 ui32EDMTaskReg0;
IMG_UINT32 ui32EDMTaskReg1;
@@ -315,9 +308,9 @@ typedef struct _SGX_CCB_KICK_
IMG_UINT32 ui32NumSrcSyncs;
#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+ IMG_SID ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
#else
- IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS];
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
#endif
#endif
diff --git a/drivers/gpu/pvr/ttrace_common.h b/drivers/gpu/pvr/ttrace_common.h
index 5895b6c7545..5aa6fec62d1 100644
--- a/drivers/gpu/pvr/ttrace_common.h
+++ b/drivers/gpu/pvr/ttrace_common.h
@@ -76,6 +76,9 @@
#define PVRSRV_TRACE_SYNC_WO_DEV_VADDR 5
#define PVRSRV_TRACE_SYNC_RO_DEV_VADDR 6
#define PVRSRV_TRACE_SYNC_OP 7
-#define PVRSRV_TRACE_TYPE_SYNC_SIZE ((PVRSRV_TRACE_SYNC_OP + 1) * sizeof(IMG_UINT32))
+ #define PVRSRV_TRACE_SYNC_RO2P 8
+ #define PVRSRV_TRACE_SYNC_RO2C 9
+ #define PVRSRV_TRACE_SYNC_RO2_DEV_VADDR 10
+#define PVRSRV_TRACE_TYPE_SYNC_SIZE ((PVRSRV_TRACE_SYNC_RO2_DEV_VADDR + 1) * sizeof(IMG_UINT32))
#endif
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a861a81948b..e0af48fccd9 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -557,9 +557,6 @@ int dispc_runtime_get(void)
clkdm_deny_idle(l3_2_clkdm);
}
- /* Removes latency constraint */
- omap_pm_set_max_dev_wakeup_lat(&dispc.pdev->dev,
- &dispc.pdev->dev, -1);
r = dss_runtime_get();
if (r)
goto err_dss_get;
@@ -590,7 +587,6 @@ err_dss_get:
void dispc_runtime_put(void)
{
- struct powerdomain *dss_powerdomain = pwrdm_lookup("dss_pwrdm");
mutex_lock(&dispc.runtime_lock);
if (--dispc.runtime_count == 0) {
@@ -599,13 +595,6 @@ void dispc_runtime_put(void)
DSSDBG("dispc_runtime_put\n");
dispc_save_context();
- /* Sets DSS max latency constraint
- * * (allowing for deeper power state)
- * */
- omap_pm_set_max_dev_wakeup_lat(
- &dispc.pdev->dev,
- &dispc.pdev->dev,
- dss_powerdomain->wakeup_lat[PWRDM_FUNC_PWRST_OFF]);
r = pm_runtime_put_sync(&dispc.pdev->dev);
WARN_ON(r);
@@ -885,7 +874,6 @@ dispc_get_scaling_coef(u32 inc, bool five_taps)
};
inc >>= 7; /* /= 128 */
-
if (five_taps) {
if (inc > 26)
return coef_M32;
@@ -1469,11 +1457,16 @@ static void _dispc_set_scale_param(enum omap_plane plane,
enum omap_color_component color_comp)
{
int fir_hinc, fir_vinc;
+ int hscaleup, vscaleup;
+
+ hscaleup = orig_width <= out_width;
+ vscaleup = orig_height <= out_height;
+
+ _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp);
fir_hinc = 1024 * orig_width / out_width;
fir_vinc = 1024 * orig_height / out_height;
- _dispc_set_scale_coef(plane, fir_hinc, fir_vinc, five_taps, color_comp);
_dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp);
}
@@ -1487,8 +1480,9 @@ static void _dispc_set_scaling_common(enum omap_plane plane,
int accu0 = 0;
int accu1 = 0;
u32 l;
+ u16 y_adjust = color_mode == OMAP_DSS_COLOR_NV12 ? 2 : 0;
- _dispc_set_scale_param(plane, orig_width, orig_height,
+ _dispc_set_scale_param(plane, orig_width, orig_height - y_adjust,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_RGB_Y);
l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
@@ -1540,6 +1534,7 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
+ u16 y_adjust = 0;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
@@ -1556,6 +1551,7 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
orig_height >>= 1;
/* UV is subsampled by 2 horz.*/
orig_width >>= 1;
+ y_adjust = 1;
break;
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
@@ -1579,7 +1575,7 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
if (out_height != orig_height)
scale_y = true;
- _dispc_set_scale_param(plane, orig_width, orig_height,
+ _dispc_set_scale_param(plane, orig_width, orig_height - y_adjust,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_UV);
@@ -2166,8 +2162,8 @@ int dispc_scaling_decision(u16 width, u16 height,
if (!can_scale)
goto loop;
- if (out_width < in_width / maxdownscale ||
- out_height < in_height / maxdownscale)
+ if (out_width * maxdownscale < in_width ||
+ out_height * maxdownscale < in_height)
goto loop;
/* Use 5-tap filter unless must use 3-tap */
@@ -2525,7 +2521,6 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
r = omap_dispc_unregister_isr(dispc_disable_isr,
&frame_done_completion, irq);
- synchronize_irq(dispc.irq);
if (r)
DSSERR("failed to unregister FRAMEDONE isr\n");
@@ -2587,8 +2582,6 @@ static void dispc_enable_digit_out(enum omap_display_type type, bool enable)
&frame_done_completion,
DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
| DISPC_IRQ_FRAMEDONETV);
- synchronize_irq(dispc.irq);
-
if (r)
DSSERR("failed to unregister EVSYNC isr\n");
@@ -3741,8 +3734,8 @@ static void dispc_error_worker(struct work_struct *work)
mgr = omap_dss_get_overlay_manager(i);
if (mgr->id == OMAP_DSS_CHANNEL_LCD) {
- if (!mgr->device->first_vsync) {
- DSSERR("First SYNC_LOST.. ignoring\n");
+ if(!mgr->device->first_vsync){
+ DSSERR("First SYNC_LOST.. ignoring \n");
break;
}
@@ -3785,8 +3778,9 @@ static void dispc_error_worker(struct work_struct *work)
mgr = omap_dss_get_overlay_manager(i);
if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) {
- if (!mgr->device->first_vsync)
+ if(!mgr->device->first_vsync){
DSSERR("First SYNC_LOST..TV ignoring\n");
+ }
manager = mgr;
enable = mgr->device->state ==
@@ -3829,14 +3823,15 @@ static void dispc_error_worker(struct work_struct *work)
mgr = omap_dss_get_overlay_manager(i);
if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
- if (!mgr->device->first_vsync)
- DSSERR("First SYNC_LOST.. ignoring\n");
+ if(!mgr->device->first_vsync){
+ DSSERR("First SYNC_LOST.. ignoring \n");
+ break;
+ }
+
manager = mgr;
enable = mgr->device->state ==
OMAP_DSS_DISPLAY_ACTIVE;
- mgr->device->sync_lost_error = 1;
mgr->device->driver->disable(mgr->device);
- mgr->device->sync_lost_error = 0;
break;
}
}
@@ -3900,8 +3895,6 @@ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
- synchronize_irq(dispc.irq);
-
if (timeout == 0)
return -ETIMEDOUT;
@@ -3937,8 +3930,6 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
- synchronize_irq(dispc.irq);
-
if (timeout == 0)
r = -ETIMEDOUT;
else if (timeout == -ERESTARTSYS)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 02ba9e916d1..8f83a1111ee 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -208,6 +208,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_dsi_pll_init;
}
}
+
r = dpi_set_mode(dssdev);
if (r)
goto err_set_mode;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 318156c98d0..419612706d8 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3640,7 +3640,7 @@ static int dsi_cmd_proto_config(struct omap_dss_device *dssdev)
static int dispc_to_dsi_clock(int val, int bytes_per_pixel, int lanes)
{
- return (val * bytes_per_pixel) / lanes;
+ return (val * bytes_per_pixel + lanes / 2) / lanes;
}
static int dsi_video_proto_config(struct omap_dss_device *dssdev)
@@ -3650,8 +3650,7 @@ static int dsi_video_proto_config(struct omap_dss_device *dssdev)
int buswidth = 0;
u32 r;
int bytes_per_pixel;
- int hbp, hfp, hsa, tl, line;
- int lanes;
+ int hbp, hfp, hsa, tl;
dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32,
DSI_FIFO_SIZE_32,
@@ -3711,23 +3710,16 @@ static int dsi_video_proto_config(struct omap_dss_device *dssdev)
dsi_vc_initial_config(dsidev, 3);
}
- lanes = dsi_get_num_data_lanes_dssdev(dssdev);
-
- hbp = dispc_to_dsi_clock((timings->hsw - 1) + (timings->hbp - 1),
- bytes_per_pixel, lanes);
- hfp = dispc_to_dsi_clock(timings->hfp - 1, bytes_per_pixel, lanes);
- hsa = 0;
-
- line = timings->hbp + timings->hfp + timings->hsw + timings->x_res;
- WARN((line * bytes_per_pixel) % lanes != 0, "TL should be an exact "
- "integer, try changing DISPC horizontal blanking parameters");
-
- tl = dispc_to_dsi_clock(line, bytes_per_pixel, lanes);
+ hbp = dispc_to_dsi_clock(timings->hbp, bytes_per_pixel, 4);
+ hfp = dispc_to_dsi_clock(timings->hfp, bytes_per_pixel, 4);
+ hsa = dispc_to_dsi_clock(timings->hsw, bytes_per_pixel, 4);
+ tl = hbp + hfp + hsa +
+ dispc_to_dsi_clock(timings->x_res, bytes_per_pixel, 4);
r = dsi_read_reg(dsidev, DSI_VM_TIMING1);
- r = FLD_MOD(r, hbp, 11, 0); /* HBP */
- r = FLD_MOD(r, hfp, 23, 12); /* HFP */
- r = FLD_MOD(r, hsa, 31, 24); /* HSA */
+ r = FLD_MOD(r, hbp - 1, 11, 0); /* HBP */
+ r = FLD_MOD(r, hfp - 1, 23, 12); /* HFP */
+ r = FLD_MOD(r, hsa - 1, 31, 24); /* HSA */
dsi_write_reg(dsidev, DSI_VM_TIMING1, r);
r = dsi_read_reg(dsidev, DSI_VM_TIMING2);
@@ -3739,7 +3731,7 @@ static int dsi_video_proto_config(struct omap_dss_device *dssdev)
r = dsi_read_reg(dsidev, DSI_VM_TIMING3);
r = FLD_MOD(r, timings->y_res, 14, 0);
- r = FLD_MOD(r, tl, 31, 16);
+ r = FLD_MOD(r, tl - 1, 31, 16);
dsi_write_reg(dsidev, DSI_VM_TIMING3, r);
/* TODO: either calculate these values or make them configurable */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 592e1ab15b2..24787f63fe6 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -547,13 +547,12 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
- /* Select the dispc clock source as PRCM clock, to ensure that it is not
- * DSI PLL source as the clock selected by DSI PLL might not be
- * sufficient for the resolution selected / that can be changed
- * dynamically by user. This can be moved to single location , say
- * Boardfile.
- */
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+ /* Select the DISPC clock source as PRCM clock in case when both LCD
+ * panels are disabled and we cannot use DSI PLL for this purpose.*/
+ if (!dispc_is_channel_enabled(OMAP_DSS_CHANNEL_LCD) &&
+ !dispc_is_channel_enabled(OMAP_DSS_CHANNEL_LCD2))
+ dss_select_dispc_clk_source
+ (dssdev->clocks.dispc.dispc_fclk_src);
/* bypass TV gamma table */
dispc_enable_gamma_table(0);
@@ -564,6 +563,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, dssdev->type, 1);
+ /* Need signal stable time*/
+ msleep(500);
+
hdmi_ti_4xxx_wp_video_start(&hdmi.hdmi_data, 1);
if (hdmi.hdmi_start_frame_cb &&
@@ -579,13 +581,18 @@ err:
static void hdmi_power_off(struct omap_dss_device *dssdev)
{
+ enum hdmi_pwrchg_reasons reason = HDMI_PWRCHG_DEFAULT;
if (hdmi.hdmi_irq_cb)
hdmi.hdmi_irq_cb(HDMI_HPD_LOW);
hdmi_ti_4xxx_wp_video_start(&hdmi.hdmi_data, 0);
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, dssdev->type, 0);
- hdmi_ti_4xxx_phy_off(&hdmi.hdmi_data, hdmi.set_mode);
+ if (hdmi.set_mode)
+ reason = reason | HDMI_PWRCHG_MODE_CHANGE;
+ if (dssdev->sync_lost_error)
+ reason = reason | HDMI_PWRCHG_RESYNC;
+ hdmi_ti_4xxx_phy_off(&hdmi.hdmi_data, reason);
hdmi_ti_4xxx_set_pll_pwr(&hdmi.hdmi_data, HDMI_PLLPWRCMD_ALLOFF);
hdmi_runtime_put();
hdmi.deep_color = HDMI_DEEP_COLOR_24BIT;
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index c2f4a2abbfb..1bf4713a2f1 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -180,9 +180,8 @@ static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-/* Do not send HPD uevent when sleep and wakeup
hdmi_panel_hpd_handler(0);
-*/
+
omapdss_hdmi_display_disable(dssdev);
err:
mutex_unlock(&hdmi.hdmi_lock);
@@ -274,14 +273,12 @@ static void hdmi_hotplug_detect_worker(struct work_struct *work)
hdmi_send_audio_info(1);
#endif
goto done;
- } else if (state == HPD_STATE_EDID_TRYLAST) {
- pr_info("EDID read fail after %d times. Giving up",
- state - HPD_STATE_START);
+ } else if (state == HPD_STATE_EDID_TRYLAST){
+ pr_info("Failed to read EDID after %d times. Giving up.", state - HPD_STATE_START);
goto done;
}
if (atomic_add_unless(&d->state, 1, HPD_STATE_OFF))
- queue_delayed_work(my_workq, &d->dwork,
- msecs_to_jiffies(60));
+ queue_delayed_work(my_workq, &d->dwork, msecs_to_jiffies(60));
}
done:
mutex_unlock(&hdmi.hdmi_lock);
@@ -291,8 +288,7 @@ int hdmi_panel_hpd_handler(int hpd)
{
__cancel_delayed_work(&hpd_work.dwork);
atomic_set(&hpd_work.state, hpd ? HPD_STATE_START : HPD_STATE_OFF);
- queue_delayed_work(my_workq, &hpd_work.dwork,
- msecs_to_jiffies(hpd ? 40 : 30));
+ queue_delayed_work(my_workq, &hpd_work.dwork, msecs_to_jiffies(hpd ? 40 : 30));
return 0;
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index da756cbb2e1..58886887284 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -1388,9 +1388,9 @@ static void dss_completion_irq_handler(void *data, u32 mask)
const int num_mgrs = MAX_DSS_MANAGERS;
const u32 masks[] = {
DISPC_IRQ_FRAMEDONE | DISPC_IRQ_VSYNC,
+ DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2,
DISPC_IRQ_FRAMEDONETV | DISPC_IRQ_EVSYNC_EVEN |
- DISPC_IRQ_EVSYNC_ODD,
- DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2
+ DISPC_IRQ_EVSYNC_ODD
};
int i;
@@ -1428,9 +1428,9 @@ static void schedule_completion_irq(void)
const int num_mgrs = MAX_DSS_MANAGERS;
const u32 masks[] = {
DISPC_IRQ_FRAMEDONE | DISPC_IRQ_VSYNC,
+ DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2,
DISPC_IRQ_FRAMEDONETV | DISPC_IRQ_EVSYNC_EVEN |
- DISPC_IRQ_EVSYNC_ODD,
- DISPC_IRQ_FRAMEDONE2 | DISPC_IRQ_VSYNC2
+ DISPC_IRQ_EVSYNC_ODD
};
u32 mask = 0;
int i;
@@ -1606,11 +1606,7 @@ static int omap_dss_mgr_blank(struct omap_overlay_manager *mgr,
oc = &dss_cache.overlay_cache[ovl->id];
-
/* complete unconfigured info in cache */
- if (ovl->info_dirty)
- dss_ovl_cb(&ovl->info.cb, i,
- DSS_COMPLETION_ECLIPSED_SET);
dss_ovl_cb(&oc->cb.cache, i, DSS_COMPLETION_ECLIPSED_CACHE);
oc->cb.cache.fn = NULL;
@@ -1622,9 +1618,7 @@ static int omap_dss_mgr_blank(struct omap_overlay_manager *mgr,
/* dirty manager */
mc = &dss_cache.manager_cache[mgr->id];
- if (mgr->info_dirty)
- dss_ovl_cb(&mgr->info.cb, mgr->id, DSS_COMPLETION_ECLIPSED_SET);
- dss_ovl_cb(&mc->cb.cache, mgr->id, DSS_COMPLETION_ECLIPSED_CACHE);
+ dss_ovl_cb(&mc->cb.cache, i, DSS_COMPLETION_ECLIPSED_CACHE);
mc->cb.cache.fn = NULL;
mgr->info.cb.fn = NULL;
mc->dirty = true;
diff --git a/drivers/video/omap2/dsscomp/device.c b/drivers/video/omap2/dsscomp/device.c
index ec80ca51ae2..80cc21b7ce2 100644
--- a/drivers/video/omap2/dsscomp/device.c
+++ b/drivers/video/omap2/dsscomp/device.c
@@ -444,9 +444,18 @@ static long comp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct dsscomp_display_info *dis = NULL;
r = copy_from_user(&u.dis, ptr, sizeof(u.dis));
- if (!r)
+ if (!r) {
+ /* impose a safe limit on modedb_len to prevent
+ * wrap around/overflow calculation of the alloced
+ * size that would make it smaller than
+ * struct dsscomp_display_info and cause heap
+ * corruption.
+ */
+ u.dis.modedb_len = clamp_val(u.dis.modedb_len, 0, 256);
+
dis = kzalloc(sizeof(*dis->modedb) * u.dis.modedb_len +
sizeof(*dis), GFP_KERNEL);
+ }
if (dis) {
*dis = u.dis;
r = query_display(cdev, dis) ? :
diff --git a/drivers/video/omap2/dsscomp/gralloc.c b/drivers/video/omap2/dsscomp/gralloc.c
index cbc92036743..b75dfd9ad5e 100644
--- a/drivers/video/omap2/dsscomp/gralloc.c
+++ b/drivers/video/omap2/dsscomp/gralloc.c
@@ -115,6 +115,9 @@ int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_dispc_data *d)
s32 ret;
u32 i;
+ if (d->num_ovls > MAX_OVERLAYS)
+ return -EINVAL;
+
/* convert virtual addresses to physical and get tiler pa infos */
for (i = 0; i < d->num_ovls; i++) {
struct dss2_ovl_info *oi = d->ovls + i;
diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c
index 1da0062bb66..c25d65596c5 100644
--- a/drivers/video/omap2/dsscomp/queue.c
+++ b/drivers/video/omap2/dsscomp/queue.c
@@ -433,7 +433,6 @@ static u32 dsscomp_mgr_callback(void *data, int id, int status)
wk->comp = comp;
wk->status = status;
INIT_WORK(&wk->work, dsscomp_mgr_delayed_cb);
- BUG_ON((unsigned long *)&wk->work.data == NULL);
queue_work(cb_wkq, &wk->work);
}
diff --git a/drivers/video/omap2/hdcp/hdcp.h b/drivers/video/omap2/hdcp/hdcp.h
index 189c0d8d6a2..657f6ab1725 100644
--- a/drivers/video/omap2/hdcp/hdcp.h
+++ b/drivers/video/omap2/hdcp/hdcp.h
@@ -352,8 +352,8 @@ extern struct hdcp_sha_in sha_input;
((RD_REG_32(base, offset) & FLD_MASK(start, end)) >> (end))
+#undef HDCP_DEBUG
#undef DBG
-#define HDCP_DEBUG
#ifdef HDCP_DEBUG
#define DBG(format, ...) \
printk(KERN_INFO "HDCP: " format "\n", ## __VA_ARGS__)
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index cce6a698e00..8188e92a594 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -907,6 +907,24 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
+ case OMAPFB_ENABLEVSYNC:
+ if (get_user(p.crt, (__u32 __user *)arg)) {
+ r = -EFAULT;
+ break;
+ }
+
+ omapfb_lock(fbdev);
+ fbdev->vsync_active = !!p.crt;
+
+ if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
+ if (p.crt)
+ omapfb_enable_vsync(fbdev);
+ else
+ omapfb_disable_vsync(fbdev);
+ }
+ omapfb_unlock(fbdev);
+ break;
+
default:
dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
r = -EINVAL;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 61de449c34e..3562773b3a0 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -29,6 +29,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/omapfb.h>
+#include <linux/wait.h>
#include <video/omapdss.h>
#include <plat/vram.h>
@@ -763,6 +764,11 @@ static int omapfb_open(struct fb_info *fbi, int user)
static int omapfb_release(struct fb_info *fbi, int user)
{
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+
+ omapfb_disable_vsync(fbdev);
+
return 0;
}
@@ -1300,6 +1306,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
r = display->driver->enable(display);
}
+ if (fbdev->vsync_active)
+ omapfb_enable_vsync(fbdev);
+
break;
case FB_BLANK_NORMAL:
@@ -1308,6 +1317,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
+
+ if (fbdev->vsync_active)
+ omapfb_disable_vsync(fbdev);
+
if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
goto exit;
@@ -2278,6 +2291,40 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
return 0;
}
+static void omapfb_send_vsync_work(struct work_struct *work)
+{
+ struct omapfb2_device *fbdev =
+ container_of(work, typeof(*fbdev), vsync_work);
+ char buf[64];
+ char *envp[2];
+
+ snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ ktime_to_ns(fbdev->vsync_timestamp));
+ envp[0] = buf;
+ envp[1] = NULL;
+ kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE, envp);
+}
+static void omapfb_vsync_isr(void *data, u32 mask)
+{
+ struct omapfb2_device *fbdev = data;
+ fbdev->vsync_timestamp = ktime_get();
+ schedule_work(&fbdev->vsync_work);
+}
+
+int omapfb_enable_vsync(struct omapfb2_device *fbdev)
+{
+ int r;
+ /* TODO: should determine correct IRQ like dss_mgr_wait_for_vsync does*/
+ /* For T1 board DISPC_IRQ_VSYNC2 is the correct one */
+ r = omap_dispc_register_isr(omapfb_vsync_isr, fbdev, DISPC_IRQ_VSYNC2);
+ return r;
+}
+
+void omapfb_disable_vsync(struct omapfb2_device *fbdev)
+{
+ omap_dispc_unregister_isr(omapfb_vsync_isr, fbdev, DISPC_IRQ_VSYNC);
+}
+
static int omapfb_probe(struct platform_device *pdev)
{
struct omapfb2_device *fbdev = NULL;
@@ -2395,6 +2442,7 @@ static int omapfb_probe(struct platform_device *pdev)
goto cleanup;
}
+ INIT_WORK(&fbdev->vsync_work, omapfb_send_vsync_work);
return 0;
cleanup:
@@ -2409,6 +2457,7 @@ static int omapfb_remove(struct platform_device *pdev)
struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
/* FIXME: wait till completion of pending events */
+ /* TODO: terminate vsync thread */
omapfb_remove_sysfs(fbdev);
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index aa1b1d97427..649388fae10 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -97,6 +97,10 @@ struct omapfb2_device {
struct omap_dss_device *dssdev;
u8 bpp;
} bpp_overrides[10];
+
+ bool vsync_active;
+ ktime_t vsync_timestamp;
+ struct work_struct vsync_work;
};
struct omapfb_colormode {
@@ -128,6 +132,9 @@ int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
u16 posx, u16 posy, u16 outw, u16 outh);
+int omapfb_enable_vsync(struct omapfb2_device *fbdev);
+void omapfb_disable_vsync(struct omapfb2_device *fbdev);
+
/* find the display connected to this fb, if any */
static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
{
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index f12501dd431..80c5dc6b994 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -58,6 +58,7 @@
#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
+#define OMAPFB_ENABLEVSYNC OMAP_IOW(64, int)
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000