summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoren Huang <b02279@freescale.com>2014-01-09 17:38:37 +0800
committerRichard Liu <r66033@freescale.com>2014-05-15 15:07:09 +0800
commiteb955578de7088c054a9a3ace150e788b27cada6 (patch)
tree5a2beb77bfb7503bc3734044631afba6f2416f54
parent36a4377215ccb3bc30a9f906e65db920ebce8632 (diff)
ENGR00294354 gpu:Using vitural memory cause AXI bus error
There are two possible reasons to cause AXI bus error 1.Allocate Tile status buffer from virtual memory. It seems gc2000 and gc880 doesn't support tile status buffer from virtual memory. 2.Stream buffer using very beginning gpu mmu address. In this condition, a faked non gpu mmu address maybe generated and fill into gpu which cause AXI bus error. [DATE]09-01-2014 Signed-off-by: Loren Huang <b02279@freescale.com> Acked-by: Shawn Guo
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c5
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c120
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c3
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h9
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h1
6 files changed, 139 insertions, 5 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
index 88535488b916..b75e7f64030e 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -933,6 +933,7 @@ gckKERNEL_Dispatch(
#if !USE_NEW_LINUX_SIGNAL
gctSIGNAL signal;
#endif
+ gceSURF_TYPE type;
gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
Kernel, FromUser, Interface);
@@ -1169,6 +1170,8 @@ gckKERNEL_Dispatch(
break;
case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
+ type = Interface->u.AllocateLinearVideoMemory.type;
+
/* Allocate memory. */
gcmkONERROR(
_AllocateMemory(Kernel,
@@ -1181,6 +1184,7 @@ gckKERNEL_Dispatch(
if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
bytes = node->VidMem.bytes;
+ node->VidMem.type = type;
gcmkONERROR(
gckKERNEL_AddProcessDB(Kernel,
@@ -1192,6 +1196,7 @@ gckKERNEL_Dispatch(
else
{
bytes = node->Virtual.bytes;
+ node->Virtual.type = type;
if(node->Virtual.contiguous)
{
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
index 6126bae3201d..d7ff9cf16372 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -734,6 +734,9 @@ typedef union _gcuVIDMEM_NODE
#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
gctPOINTER kernelVirtual;
#endif
+
+ /* Surface type. */
+ gceSURF_TYPE type;
}
VidMem;
@@ -790,6 +793,9 @@ typedef union _gcuVIDMEM_NODE
/* */
gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
+
+ /* Surface type. */
+ gceSURF_TYPE type;
}
Virtual;
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
index e4ca49725dce..456ec246241e 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
@@ -46,6 +46,9 @@ gceMMU_TYPE;
# define gcdMMU_CLEAR_VALUE 0x00000ABC
#endif
+/* VIV: Start GPU address for gcvSURF_VERTEX. */
+#define gcdVERTEX_START (128 << 10)
+
typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
typedef struct _gcsMMU_STLB
@@ -973,6 +976,88 @@ _Destroy(
return gcvSTATUS_OK;
}
+/*******************************************************************************
+** _AdjstIndex
+**
+** Adjust the index from which we search for a usable node to make sure
+** index allocated is greater than Start.
+*/
+gceSTATUS
+_AdjustIndex(
+ IN gckMMU Mmu,
+ IN gctUINT32 Index,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 Start,
+ OUT gctUINT32 * IndexAdjusted
+ )
+{
+ gceSTATUS status;
+ gctUINT32 index = Index;
+ gctUINT32_PTR map = Mmu->pageTableLogical;
+
+ gcmkHEADER();
+
+ for (; index < Mmu->pageTableEntries;)
+ {
+ gctUINT32 result = 0;
+ gctUINT32 nodeSize = 0;
+
+ if (index >= Start)
+ {
+ break;
+ }
+
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ nodeSize = 1;
+ break;
+
+ case gcvMMU_FREE:
+ nodeSize = map[index] >> 8;
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ if (nodeSize > PageCount)
+ {
+ result = index + (nodeSize - PageCount);
+
+ if (result >= Start)
+ {
+ break;
+ }
+ }
+
+ switch (gcmENTRY_TYPE(map[index]))
+ {
+ case gcvMMU_SINGLE:
+ index = map[index] >> 8;
+ break;
+
+ case gcvMMU_FREE:
+ index = map[index + 1];
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ *IndexAdjusted = index;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
gceSTATUS
gckMMU_Construct(
IN gckKERNEL Kernel,
@@ -1136,6 +1221,7 @@ gceSTATUS
_AllocatePages(
IN gckMMU Mmu,
IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
OUT gctPOINTER * PageTable,
OUT gctUINT32 * Address
)
@@ -1170,8 +1256,21 @@ _AllocatePages(
/* Cast pointer to page table. */
for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;)
{
+ index = Mmu->heapList;
+
+ if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
+ {
+ gcmkONERROR(_AdjustIndex(
+ Mmu,
+ index,
+ PageCount,
+ gcdVERTEX_START / gcmSIZEOF(gctUINT32),
+ &index
+ ));
+ }
+
/* Walk the heap list. */
- for (index = Mmu->heapList; !gotIt && (index < Mmu->pageTableEntries);)
+ for (; !gotIt && (index < Mmu->pageTableEntries);)
{
/* Check the node type. */
switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
@@ -1423,6 +1522,19 @@ gckMMU_AllocatePages(
OUT gctUINT32 * Address
)
{
+ return gckMMU_AllocatePagesEx(
+ Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address);
+}
+
+gceSTATUS
+gckMMU_AllocatePagesEx(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
#if gcdMIRROR_PAGETABLE
gceSTATUS status;
gctPOINTER pageTable;
@@ -1440,7 +1552,7 @@ gckMMU_AllocatePages(
{
if (Mmu == mirrorPageTable->mmus[i])
{
- gcmkONERROR(_AllocatePages(Mmu, PageCount, PageTable, Address));
+ gcmkONERROR(_AllocatePages(Mmu, PageCount, Type, PageTable, Address));
allocated = gcvTRUE;
}
}
@@ -1452,7 +1564,7 @@ gckMMU_AllocatePages(
if (Mmu != mmu)
{
- gcmkONERROR(_AllocatePages(mmu, PageCount, &pageTable, &address));
+ gcmkONERROR(_AllocatePages(mmu, PageCount, Type, &pageTable, &address));
gcmkASSERT(address == *Address);
}
}
@@ -1478,7 +1590,7 @@ OnError:
return status;
#else
- return _AllocatePages(Mmu, PageCount, PageTable, Address);
+ return _AllocatePages(Mmu, PageCount, Type, PageTable, Address);
#endif
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
index 3b5dd82cbad0..3d861bece9c4 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
@@ -1814,8 +1814,9 @@ gckVIDMEM_Lock(
{
/* Allocate pages inside the MMU. */
gcmkONERROR(
- gckMMU_AllocatePages(Kernel->mmu,
+ gckMMU_AllocatePagesEx(Kernel->mmu,
Node->Virtual.pageCount,
+ Node->Virtual.type,
&Node->Virtual.pageTables[Kernel->core],
&Node->Virtual.addresses[Kernel->core]));
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
index 7312cc24d598..63d5dad3a75a 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -2562,6 +2562,15 @@ gckMMU_AllocatePages(
OUT gctUINT32 * Address
);
+gceSTATUS
+gckMMU_AllocatePagesEx(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ IN gceSURF_TYPE Type,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ );
+
/* Remove a page table from the MMU. */
gceSTATUS
gckMMU_FreePages(
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
index b2ffac335e22..522253779182 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
@@ -166,6 +166,7 @@ typedef enum _gceFEATURE
gcvFEATURE_LINEAR_RENDER_TARGET,
gcvFEATURE_BUG_FIXES8,
gcvFEATURE_HALTI2,
+ gcvFEATURE_MMU,
}
gceFEATURE;