summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Xiao <b49994@freescale.com>2015-06-12 13:08:42 +0800
committerShawn Xiao <b49994@freescale.com>2015-06-12 13:14:49 +0800
commit6eefa0c21fd6b2ce9058ab53d375430ba13673d7 (patch)
tree7b4684dc2ffabb6030b0a440d45e39de03463e6e
parent6d5f951e94237c818576f4bcc6577d833f151804 (diff)
MGS-532 [#1630] P13 driver meet "AXI BUS ERROR" on GC2000rel_imx_3.10.17_1.0.3_patch
When run Antutu benchmark several times continuously, it will show "AXI BUS ERROR". The root cause is When unlock a surface, driver must flush its GPU cache. Otherwise, GPU may write out the cache after GPU address is freed, which will cause MMU Exception or AXI bus error. Even if GPU address isn't freed, data in cache may pollute memory after memory is used by another surface. The solution is Before an event is written to command buffer, driver checks the group of records linked to this event to find out which kinds of cache need to flush. This method doesn't care whether the record is from user side or kernel. And driver generates only one flush for a group of records. Date: Jun 11, 2015 Signed-off-by: Meng Mingming <b51843@freescale.com>
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c79
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c16
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c133
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c68
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h4
5 files changed, 189 insertions, 111 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index e6338d0386fd..d9b0acf1c37e 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -3720,10 +3720,13 @@ gckHARDWARE_Flush(
{
gctUINT32 pipe;
gctUINT32 flush = 0;
+ gctBOOL flushTileStatus;
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gceSTATUS status;
gctBOOL fcFlushStall;
- gctUINT32 reserveBytes = 8;
+ gctUINT32 reserveBytes
+ /* Semaphore/Stall */
+ = 4 * gcmSIZEOF(gctUINT32);
gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
@@ -3735,14 +3738,10 @@ gckHARDWARE_Flush(
pipe = Hardware->kernel->command->pipeSelect;
fcFlushStall
- = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))))
- && (Flush == gcvFLUSH_ALL)
- ;
+ = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))));
- if (fcFlushStall)
- {
- reserveBytes += 8;
- }
+ /* Flush tile status cache. */
+ flushTileStatus = (Flush & gcvFLUSH_TILE_STATUS) && fcFlushStall;
/* Flush 3D color cache. */
if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
@@ -3769,8 +3768,19 @@ gckHARDWARE_Flush(
flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
}
+ /* Determine reserve bytes. */
+ if (flush)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushTileStatus)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
/* See if there is a valid flush. */
- if (flush == 0)
+ if ((flush == 0) && (flushTileStatus == gcvFALSE))
{
if (Bytes != gcvNULL)
{
@@ -3790,29 +3800,52 @@ gckHARDWARE_Flush(
gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
}
- /* Append LOAD_STATE to AQFlush. */
- logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ if (flush)
+ {
+ /* Append LOAD_STATE to AQFlush. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- logical[1] = flush;
+ *logical++
+ = flush;
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "0x%x: FLUSH 0x%x", logical, flush);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", logical - 1, flush);
+ }
- if (fcFlushStall)
+ if (flushTileStatus)
{
- logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
- logical[3] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
+ "0x%x: FLUSH TILE STATUS 0x%x", logical - 1, logical[-1]);
}
+ /* Semaphore. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x05 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
}
if (Bytes != gcvNULL)
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
index 6a0f8e0e2856..69bbc1cf7295 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
@@ -1122,6 +1122,7 @@ gckKERNEL_DestroyProcessDB(
gcuVIDMEM_NODE_PTR node;
gckKERNEL kernel = Kernel;
gctUINT32 i;
+ gceSURF_TYPE type;
gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
@@ -1265,6 +1266,11 @@ gckKERNEL_DestroyProcessDB(
case gcvDB_VIDEO_MEMORY_LOCKED:
node = gcmUINT64_TO_PTR(record->data);
+
+ type = (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ ? node->VidMem.type
+ : node->Virtual.type;
+
/* Unlock what we still locked */
status = gckVIDMEM_Unlock(record->kernel,
node,
@@ -1273,11 +1279,11 @@ gckKERNEL_DestroyProcessDB(
if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
{
- /* TODO: we maybe need to schedule a event here */
- status = gckVIDMEM_Unlock(record->kernel,
- node,
- gcvSURF_TYPE_UNKNOWN,
- gcvNULL);
+
+ status = gckEVENT_Unlock(record->kernel->eventObj,
+ gcvKERNEL_PIXEL,
+ node,
+ type);
}
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
index 7b84245badc6..8d863d7a250c 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
@@ -378,6 +378,69 @@ _SubmitTimerFunction(
gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
}
+/*******************************************************************************
+**
+** _QueryFlush
+**
+** Check the type of surfaces which will be released by current event and
+** determine the cache needed to flush.
+**
+*/
+static gceSTATUS
+_QueryFlush(
+ IN gckEVENT Event,
+ IN gcsEVENT_PTR Record,
+ OUT gceKERNEL_FLUSH *Flush
+ )
+{
+ gceKERNEL_FLUSH flush = 0;
+ gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ while (Record != gcvNULL)
+ {
+ switch (Record->info.command)
+ {
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ switch(Record->info.u.UnlockVideoMemory.type)
+ {
+ case gcvSURF_TILE_STATUS:
+ flush |= gcvFLUSH_TILE_STATUS;
+ break;
+ case gcvSURF_RENDER_TARGET:
+ flush |= gcvFLUSH_COLOR;
+ break;
+ case gcvSURF_DEPTH:
+ flush |= gcvFLUSH_DEPTH;
+ break;
+ case gcvSURF_TEXTURE:
+ flush |= gcvFLUSH_TEXTURE;
+ break;
+ case gcvSURF_TYPE_UNKNOWN:
+ gcmkASSERT(0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case gcvHAL_UNMAP_USER_MEMORY:
+ *Flush = gcvFLUSH_ALL;
+ return gcvSTATUS_OK;
+ break;
+
+ default:
+ break;
+ }
+
+ Record = Record->next;
+ }
+
+ *Flush = flush;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
/******************************************************************************\
******************************* gckEVENT API Code *******************************
\******************************************************************************/
@@ -1504,10 +1567,19 @@ gckEVENT_Submit(
gctPOINTER buffer;
#endif
+ gctSIZE_T flushBytes;
+ gctUINT32 executeBytes;
+ gckHARDWARE hardware;
+
+ gceKERNEL_FLUSH flush = gcvFALSE;
+
gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
/* Get gckCOMMAND object. */
command = Event->kernel->command;
+ hardware = Event->kernel->hardware;
+
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
/* Are there event queues? */
if (Event->queueHead != gcvNULL)
@@ -1552,6 +1624,9 @@ gckEVENT_Submit(
gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
acquired = gcvFALSE;
+ /* Determine cache needed to flush. */
+ gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush));
+
#if gcdNULL_DRIVER
/* Notify immediately on infinite hardware. */
gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
@@ -1559,27 +1634,55 @@ gckEVENT_Submit(
gcmkONERROR(gckEVENT_Notify(Event, 0));
#else
/* Get the size of the hardware event. */
- gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
- gcvNULL,
- id,
- Event->queues[id].source,
- &bytes));
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ gcvNULL,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Get the size of flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ gcvNULL,
+ &flushBytes
+ ));
+
+ bytes += flushBytes;
+
+ /* Total bytes need to execute. */
+ executeBytes = bytes;
/* Reserve space in the command queue. */
- gcmkONERROR(gckCOMMAND_Reserve(command,
- bytes,
- &buffer,
- &bytes));
+ gcmkONERROR(gckCOMMAND_Reserve(command, bytes, &buffer, &bytes));
+
+ /* Set the flush in the command queue. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ buffer,
+ &flushBytes
+ ));
+
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + flushBytes;
/* Set the hardware event in the command queue. */
- gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
- buffer,
- id,
- Event->queues[id].source,
- &bytes));
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ buffer,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + bytes;
/* Execute the hardware event. */
- gcmkONERROR(gckCOMMAND_Execute(command, bytes));
+ gcmkONERROR(gckCOMMAND_Execute(command, executeBytes));
#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 f72e5bfcf1ae..9ca4853752ed 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
@@ -1924,10 +1924,7 @@ gckVIDMEM_Unlock(
{
gceSTATUS status;
gckHARDWARE hardware;
- gctPOINTER buffer;
- gctSIZE_T requested, bufferSize;
gckCOMMAND command = gcvNULL;
- gceKERNEL_FLUSH flush;
gckOS os = gcvNULL;
gctBOOL acquired = gcvFALSE;
gctBOOL commitEntered = gcvFALSE;
@@ -2125,70 +2122,7 @@ gckVIDMEM_Unlock(
Node->Virtual.physical,
Node->Virtual.bytes,
Node->Virtual.logical));
-
- if (!Node->Virtual.contiguous
- && (Node->Virtual.lockeds[Kernel->core] == 1)
-#if gcdENABLE_VG
- && (Kernel->vg == gcvNULL)
-#endif
- )
- {
- if (Type == gcvSURF_BITMAP)
- {
- /* Flush 2D cache. */
- flush = gcvFLUSH_2D;
- }
- else if (Type == gcvSURF_RENDER_TARGET)
- {
- /* Flush color cache. */
- flush = gcvFLUSH_COLOR;
- }
- else if (Type == gcvSURF_DEPTH)
- {
- /* Flush depth cache. */
- flush = gcvFLUSH_DEPTH;
- }
- else
- {
- /* No flush required. */
- flush = (gceKERNEL_FLUSH) 0;
- }
- if(hardware)
- {
- gcmkONERROR(
- gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested));
-
- if (requested != 0)
- {
- /* Acquire the command queue. */
- gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
- commitEntered = gcvTRUE;
-
- gcmkONERROR(gckCOMMAND_Reserve(
- command, requested, &buffer, &bufferSize
- ));
-
- gcmkONERROR(gckHARDWARE_Flush(
- hardware, flush, buffer, &bufferSize
- ));
-
- /* Mark node as pending. */
-#ifdef __QNXNTO__
- Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE;
-#endif
-
- gcmkONERROR(gckCOMMAND_Execute(command, requested));
-
- /* Release the command queue. */
- gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
- commitEntered = gcvFALSE;
- }
- }
- else
- {
- gckOS_Print("Hardware already is freed.\n");
- }
- }
+
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Scheduled unlock for virtual node 0x%x",
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 ec770ad69f24..692ac89dbdae 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -1664,10 +1664,12 @@ typedef enum _gceKERNEL_FLUSH
gcvFLUSH_DEPTH = 0x02,
gcvFLUSH_TEXTURE = 0x04,
gcvFLUSH_2D = 0x08,
+ gcvFLUSH_TILE_STATUS = 0x20,
gcvFLUSH_ALL = gcvFLUSH_COLOR
| gcvFLUSH_DEPTH
| gcvFLUSH_TEXTURE
- | gcvFLUSH_2D,
+ | gcvFLUSH_2D
+ | gcvFLUSH_TILE_STATUS
}
gceKERNEL_FLUSH;