summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLoren Huang <b02279@freescale.com>2014-01-09 17:38:37 +0800
committerLoren Huang <b02279@freescale.com>2014-01-09 19:04:49 +0800
commitf7b30810a7f083a454ea0942e60853dda6bd102a (patch)
treec30a90aeb6967ffc95725d09d366adb94c5b1d47 /drivers
parentbefff374e16bf590531827dc68e575aed5322ecd (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
Diffstat (limited to 'drivers')
-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 99b6bd12c77c..39290c9e45d9 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
@@ -1818,8 +1818,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 8e3c2f89a8a2..31422cee56af 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;