aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/sgx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/sgx')
-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
11 files changed, 1043 insertions, 111 deletions
diff --git a/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c b/drivers/gpu/pvr/sgx/bridged_sgx_bridge.c
index f616d83..4e4cf24 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 774026d..9d124f5 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 59b24c4..dd92bf0 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 7e2b3f9..44a48be 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 636620d..846035a 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,
@@ -1027,7 +1054,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++)
{
@@ -1045,6 +1092,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
}
@@ -1104,7 +1171,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)
@@ -1119,8 +1187,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
@@ -1294,14 +1363,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 019a75cb..d5441b2 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 696941f..b647b68 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 7050371..45e6d79 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 d40773e..f0ce1b5 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 c9a733b..528490b 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 bc60fdd..9017acf 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,