diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c | 5 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h | 6 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c | 120 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c | 3 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h | 9 | ||||
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h | 1 |
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; |