summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoren Huang <b02279@freescale.com>2012-11-14 13:35:06 +0800
committerLoren Huang <b02279@freescale.com>2012-11-15 16:12:25 +0800
commit3a34fe70afc521a01f13cdd80bc2f5ae23e3b4c8 (patch)
treedff64baf52fd7b504feabf29727d0dcc326bf949
parentfbd07a2cc1959b74616548492e4c54e293560b21 (diff)
ENGR00233452 Integrate 4.6.9p9 GPU kernel part driver
Signed-off-by: Loren Huang <b02279@freescale.com> Acked-by: Lily Zhang
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c23
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c69
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c293
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h65
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c17
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c103
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c213
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h15
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h22
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h32
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h25
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h13
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h23
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h7
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c6
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c150
22 files changed, 979 insertions, 113 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
index d8898a376fe1..a52c1c817560 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
@@ -623,6 +623,7 @@ _InitializeContextBuffer(
index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02C00 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
@@ -905,6 +906,16 @@ _DestroyContext(
/* Free state delta map. */
if (buffer->logical != gcvNULL)
{
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+
+#else
gcmkONERROR(gckEVENT_FreeContiguousMemory(
Context->hardware->kernel->eventObj,
Context->totalSize,
@@ -912,6 +923,7 @@ _DestroyContext(
buffer->logical,
gcvKERNEL_PIXEL
));
+#endif
buffer->logical = gcvNULL;
}
@@ -1149,6 +1161,16 @@ gckCONTEXT_Construct(
));
/* Create a new physical context buffer. */
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ context->hardware->kernel,
+ gcvFALSE,
+ &context->totalSize,
+ &buffer->physical,
+ &pointer
+ ));
+
+#else
gcmkONERROR(gckOS_AllocateContiguous(
Os,
gcvFALSE,
@@ -1156,6 +1178,7 @@ gckCONTEXT_Construct(
&buffer->physical,
&pointer
));
+#endif
buffer->logical = pointer;
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 377ce32ed4c3..2812582ff7fc 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
@@ -221,17 +221,8 @@ _IdentifyHardware(
Identity->superTileMode = 0;
}
- /* If new HZ is available, disable other early z modes. */
- if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
- || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))))
- {
- /* Disable EZ. */
- Identity->chipFeatures
- = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
- }
-
/* Disable HZ when EZ is present for older chips. */
- else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
+ if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
{
/* Disable HIERARCHICAL_Z. */
Identity->chipMinorFeatures
@@ -408,7 +399,7 @@ _IdentifyHardware(
(instructionCount == 0) ? " (default)" : "");
/* Get the number of constants. */
- Identity->numConstants = numConstants;
+ Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
"Specs: numConstants=%u%s",
@@ -2344,25 +2335,32 @@ gckHARDWARE_ConvertLogical(
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
- /* Convert logical address into a physical address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
+#if gcdVIRTUAL_COMMAND_BUFFER
+ status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
- /* For old MMU, get GPU address according to baseAddress. */
- if (Hardware->mmuVersion == 0)
+ if (status == gcvSTATUS_INVALID_ADDRESS)
+#endif
{
- gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+ /* Convert logical address into a physical address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
- /* Subtract base address to get a GPU address. */
- gcmkASSERT(address >= baseAddress);
- address -= baseAddress;
- }
+ /* For old MMU, get GPU address according to baseAddress. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
- /* Return hardware specific address. */
- *Address = (Hardware->mmuVersion == 0)
- ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
- : address;
+ /* Subtract base address to get a GPU address. */
+ gcmkASSERT(address >= baseAddress);
+ address -= baseAddress;
+ }
+
+ /* Return hardware specific address. */
+ *Address = (Hardware->mmuVersion == 0)
+ ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
+ : address;
+ }
/* Success. */
gcmkFOOTER_ARG("*Address=0x%08x", *Address);
@@ -2621,7 +2619,7 @@ gckHARDWARE_QuerySystemMemory(
return gcvSTATUS_OK;
}
-#if !defined(VIVANTE_NO_3D)
+#ifndef VIVANTE_NO_3D
/*******************************************************************************
**
** gckHARDWARE_QueryShaderCaps
@@ -3393,8 +3391,13 @@ gckHARDWARE_SetFastClear(
/* Set fast clear bypass. */
debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
- /* Set compression bypass. */
- debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
+ if (
+ ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) ||
+ (Hardware->identity.chipModel >= gcv4000))
+ {
+ /* Set compression bypass. */
+ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
+ }
/* Write back AQMemoryDebug register. */
gcmkONERROR(
@@ -5250,6 +5253,7 @@ gckHARDWARE_DumpMMUException(
IN gckHARDWARE Hardware
)
{
+#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
gctUINT32 mmu, mmuStatus, address, i;
#if gcdDEBUG
gctUINT32 mtlb, stlb, offset;
@@ -5339,6 +5343,13 @@ gckHARDWARE_DumpMMUException(
}
gcmkFOOTER_NO();
+#else
+ /* If clock could be off automatically, we can't read mmu debug
+ ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
+ ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
+ gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
+#endif
+
return gcvSTATUS_OK;
}
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 15ed52c75208..3a5ba824188e 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -220,6 +220,14 @@ gckKERNEL_Construct(
/* Save context. */
kernel->context = Context;
+#if gcdVIRTUAL_COMMAND_BUFFER
+ kernel->virtualBufferHead =
+ kernel->virtualBufferTail = gcvNULL;
+
+ gcmkONERROR(
+ gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
+#endif
+
/* Construct atom holding number of clients. */
kernel->atomClients = gcvNULL;
gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
@@ -349,6 +357,14 @@ OnError:
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db));
}
+#if gcdVIRTUAL_COMMAND_BUFFER
+ if (kernel->virtualBufferLock != gcvNULL)
+ {
+ /* Destroy the virtual command buffer mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock));
+ }
+#endif
+
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel));
}
@@ -460,6 +476,10 @@ gckKERNEL_Destroy(
/* Detsroy the client atom. */
gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
+#endif
+
/* Mark the gckKERNEL object as unknown. */
Kernel->object.type = gcvOBJ_UNKNOWN;
@@ -830,6 +850,27 @@ gckKERNEL_Dispatch(
Interface->u.AllocateNonPagedMemory.bytes));
break;
+ case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkONERROR(
+ gckKERNEL_AllocateVirtualCommandBuffer(
+ Kernel,
+ FromUser,
+ &Interface->u.AllocateVirtualCommandBuffer.bytes,
+ &Interface->u.AllocateVirtualCommandBuffer.physical,
+ &Interface->u.AllocateVirtualCommandBuffer.logical));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_COMMAND_BUFFER,
+ Interface->u.AllocateVirtualCommandBuffer.logical,
+ Interface->u.AllocateVirtualCommandBuffer.physical,
+ Interface->u.AllocateVirtualCommandBuffer.bytes));
+#else
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
case gcvHAL_FREE_NON_PAGED_MEMORY:
physical = Interface->u.FreeNonPagedMemory.physical;
@@ -1199,7 +1240,7 @@ gckKERNEL_Dispatch(
{
gcmkONERROR(
gckOS_SignalQueryHardware(Kernel->os,
- (gctSIGNAL)Interface->u.UserSignal.id,
+ (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
&hardware));
if (hardware)
@@ -1251,8 +1292,8 @@ gckKERNEL_Dispatch(
case gcvUSER_SIGNAL_MAP:
gcmkONERROR(
gckOS_MapSignal(Kernel->os,
- (gctSIGNAL)Interface->u.UserSignal.id,
- (gctHANDLE)processID,
+ (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
+ (gctHANDLE)(gctUINTPTR_T)processID,
&signal));
gcmkVERIFY_OK(
@@ -2943,7 +2984,253 @@ gckKERNEL_SetTimeOut(
gcmkFOOTER_NO();
}
+#if gcdVIRTUAL_COMMAND_BUFFER
+gceSTATUS
+gckKERNEL_AllocateVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gckOS os = Kernel->os;
+ gceSTATUS status;
+ gctPOINTER logical;
+ gctSIZE_T pageCount;
+ gctSIZE_T bytes = *Bytes;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ os, InUserSpace, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gcmkONERROR(gckOS_Allocate(os,
+ sizeof(gckVIRTUAL_COMMAND_BUFFER),
+ (gctPOINTER)&buffer));
+
+ gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
+
+ gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
+ gcvFALSE,
+ bytes,
+ &buffer->physical));
+
+ if (InUserSpace)
+ {
+ gcmkONERROR(gckOS_LockPages(os,
+ buffer->physical,
+ bytes,
+ gcvFALSE,
+ &logical,
+ &pageCount));
+
+ *Logical =
+ buffer->userLogical = logical;
+ }
+ else
+ {
+ gcmkONERROR(
+ gckOS_CreateKernelVirtualMapping(buffer->physical,
+ &pageCount,
+ &logical));
+ *Logical =
+ buffer->kernelLogical = logical;
+ }
+
+ buffer->pageCount = pageCount;
+ buffer->kernel = Kernel;
+
+ gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
+
+ gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
+ pageCount,
+ &buffer->pageTable,
+ &buffer->gpuAddress));
+
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ buffer->physical,
+ pageCount,
+ buffer->pageTable));
+
+ gcmkONERROR(gckMMU_Flush(Kernel->mmu));
+
+ *Physical = buffer;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
+ buffer->gpuAddress, buffer->pageCount,
+ buffer->kernelLogical, buffer->userLogical);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
+
+ if (Kernel->virtualBufferHead == gcvNULL)
+ {
+ Kernel->virtualBufferHead =
+ Kernel->virtualBufferTail = buffer;
+ }
+ else
+ {
+ buffer->prev = Kernel->virtualBufferTail;
+ Kernel->virtualBufferTail->next = buffer;
+ Kernel->virtualBufferTail = buffer;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (buffer->gpuAddress)
+ {
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
+ }
+
+ if (buffer->userLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical));
+ }
+
+ if (buffer->kernelLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical));
+ }
+
+ if (buffer->physical)
+ {
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
+ }
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_DestroyVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ )
+{
+ gckOS os;
+ gckKERNEL kernel;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
+
+ kernel = buffer->kernel;
+ os = kernel->os;
+
+ if (buffer->userLogical)
+ {
+ gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical));
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical));
+ }
+
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
+
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
+
+ if (buffer == kernel->virtualBufferHead)
+ {
+ if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
+ {
+ kernel->virtualBufferTail = gcvNULL;
+ }
+ }
+ else
+ {
+ buffer->prev->next = buffer->next;
+
+ if (buffer == kernel->virtualBufferTail)
+ {
+ kernel->virtualBufferTail = buffer->prev;
+ }
+ else
+ {
+ buffer->next->prev = buffer->prev;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
+
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_GetGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ )
+{
+ gceSTATUS status;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+ gctPOINTER start;
+ gctINT pid;
+
+ gcmkHEADER_ARG("Logical = %x", Logical);
+
+ gckOS_GetProcessID(&pid);
+
+ status = gcvSTATUS_INVALID_ADDRESS;
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+
+ /* Walk all command buffer. */
+ for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
+ {
+ if (buffer->userLogical)
+ {
+ start = buffer->userLogical;
+ }
+ else
+ {
+ start = buffer->kernelLogical;
+ }
+
+ if (Logical >= start
+ && (Logical < (start + buffer->pageCount * 4096))
+ && pid == buffer->pid
+ )
+ {
+ * Address = buffer->gpuAddress + (Logical - start);
+ status = gcvSTATUS_OK;
+ break;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
+
+ gcmkFOOTER_NO();
+ return status;
+}
+#endif
/*******************************************************************************
***** Test Code ****************************************************************
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 1f3c9ccc20a8..908f925417b1 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -134,6 +134,7 @@ gcskSECURE_CACHE;
typedef enum _gceDATABASE_TYPE
{
gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
+ gcvDB_COMMAND_BUFFER, /* Command Buffer. */
gcvDB_NON_PAGED, /* Non paged memory. */
gcvDB_CONTIGUOUS, /* Contiguous memory. */
gcvDB_SIGNAL, /* Signal. */
@@ -292,6 +293,24 @@ struct _gckDB
gctUINT64 lastSlowdownIdle;
};
+#if gcdVIRTUAL_COMMAND_BUFFER
+typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
+typedef struct _gckVIRTUAL_COMMAND_BUFFER
+{
+ gctPHYS_ADDR physical;
+ gctPOINTER userLogical;
+ gctPOINTER kernelLogical;
+ gctSIZE_T pageCount;
+ gctPOINTER pageTable;
+ gctUINT32 gpuAddress;
+ gctUINT pid;
+ gckVIRTUAL_COMMAND_BUFFER_PTR next;
+ gckVIRTUAL_COMMAND_BUFFER_PTR prev;
+ gckKERNEL kernel;
+}
+gckVIRTUAL_COMMAND_BUFFER;
+#endif
+
/* gckKERNEL object. */
struct _gckKERNEL
{
@@ -350,6 +369,12 @@ struct _gckKERNEL
#if gcdENABLE_VG
gckVGKERNEL vg;
#endif
+
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
+ gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
+ gctPOINTER virtualBufferLock;
+#endif
};
/* gckCOMMAND object. */
@@ -452,6 +477,8 @@ typedef struct _gcsEVENT
/* Kernel. */
gckKERNEL kernel;
#endif
+
+ gctBOOL fromKernel;
}
gcsEVENT;
@@ -735,6 +762,44 @@ struct _gckMMU
#endif
};
+#if gcdVIRTUAL_COMMAND_BUFFER
+gceSTATUS
+gckOS_CreateKernelVirtualMapping(
+ IN gctPHYS_ADDR Physical,
+ OUT gctSIZE_T * PageCount,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckOS_DestroyKernelVirtualMapping(
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckKERNEL_AllocateVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ );
+
+gceSTATUS
+gckKERNEL_DestroyVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckKERNEL_GetGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ );
+#endif
+
gceSTATUS
gckKERNEL_AttachProcess(
IN gckKERNEL Kernel,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
index fbaff6666a10..f350f451882d 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
@@ -1971,7 +1971,7 @@ gckCOMMAND_Commit(
/* Append event record to event queue. */
gcmkONERROR(gckEVENT_AddList(
- Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE
+ Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE
));
/* Next record in the queue. */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
index e5b659262a46..b3e28ec09d80 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
@@ -915,7 +915,7 @@ _HardwareToKernel(
}
offset = Address - nodePhysical;
- *KernelPointer = (gctPOINTER)((gctUINT32)Node->VidMem.kernelVirtual + offset);
+ *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
#else
/* Determine the header offset within the pool it is allocated in. */
offset = Address - memory->baseAddress;
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 9dbb9d3cab25..9ab599b1da9f 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
@@ -1161,6 +1161,21 @@ gckKERNEL_DestroyProcessDB(
record->data, record->bytes, status);
break;
+#if gcdVIRTUAL_COMMAND_BUFFER
+ case gcvDB_COMMAND_BUFFER:
+ /* Free the command buffer. */
+ status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
+ record->bytes,
+ record->physical,
+ record->data,
+ gcvKERNEL_PIXEL);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
+ record->data, record->bytes, status);
+ break;
+#endif
+
case gcvDB_CONTIGUOUS:
/* Unmap user logical memory first. */
status = gckOS_UnmapUserLogical(Kernel->os,
@@ -1191,7 +1206,7 @@ gckKERNEL_DestroyProcessDB(
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: SIGNAL %d (status=%d)",
- (gctINT) record->data, status);
+ (gctINT)(gctUINTPTR_T)record->data, status);
break;
case gcvDB_VIDEO_MEMORY_LOCKED:
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 d38312d3bf9b..75647c0a4315 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
@@ -286,6 +286,21 @@ __RemoveRecordFromProcessDB(
while (Record != gcvNULL)
{
+ if (Record->info.command == gcvHAL_SIGNAL)
+ {
+ /* TODO: Find a better place to bind signal to hardware.*/
+ gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
+ Record->info.u.Signal.signal,
+ Event->kernel->hardware));
+ }
+
+ if (Record->fromKernel)
+ {
+ /* No need to check db if event is from kernel. */
+ Record = Record->next;
+ continue;
+ }
+
switch (Record->info.command)
{
case gcvHAL_FREE_NON_PAGED_MEMORY:
@@ -328,10 +343,12 @@ __RemoveRecordFromProcessDB(
Record->info.u.UnmapUserMemory.info));
break;
- case gcvHAL_SIGNAL:
- gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
- Record->info.u.Signal.signal,
- Event->kernel->hardware));
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Event->kernel,
+ Record->processID,
+ gcvDB_COMMAND_BUFFER,
+ Record->info.u.FreeVirtualCommandBuffer.logical));
break;
default:
@@ -883,7 +900,8 @@ gckEVENT_AddList(
IN gckEVENT Event,
IN gcsHAL_INTERFACE_PTR Interface,
IN gceKERNEL_WHERE FromWhere,
- IN gctBOOL AllocateAllowed
+ IN gctBOOL AllocateAllowed,
+ IN gctBOOL FromKernel
)
{
gceSTATUS status;
@@ -913,6 +931,7 @@ gckEVENT_AddList(
|| (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
|| (Interface->command == gcvHAL_TIMESTAMP)
|| (Interface->command == gcvHAL_COMMIT_DONE)
+ || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
);
/* Validate the source. */
@@ -928,6 +947,9 @@ gckEVENT_AddList(
/* Termninate the record. */
record->next = gcvNULL;
+ /* Record the committer. */
+ record->fromKernel = FromKernel;
+
/* Copy the event interface into the record. */
gcmkONERROR(gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info)));
@@ -1081,7 +1103,7 @@ gckEVENT_Unlock(
iface.u.UnlockVideoMemory.asynchroneous = 0;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1136,7 +1158,7 @@ gckEVENT_FreeVideoMemory(
iface.u.FreeVideoMemory.node = VideoMemory;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1200,7 +1222,48 @@ gckEVENT_FreeNonPagedMemory(
iface.u.FreeNonPagedMemory.logical = Logical;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckEVENT_DestroyVirtualCommandBuffer(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
+ "FromWhere=%d",
+ Event, Bytes, Physical, Logical, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+
+ /* Create an event. */
+ iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
+ iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
+ iface.u.FreeVirtualCommandBuffer.physical = Physical;
+ iface.u.FreeVirtualCommandBuffer.logical = Logical;
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1264,7 +1327,7 @@ gckEVENT_FreeContiguousMemory(
iface.u.FreeContiguousMemory.logical = Logical;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1325,7 +1388,7 @@ gckEVENT_Signal(
iface.u.Signal.process = gcvNULL;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1372,7 +1435,7 @@ gckEVENT_CommitDone(
iface.command = gcvHAL_COMMIT_DONE;
/* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
@@ -1624,7 +1687,7 @@ gckEVENT_Commit(
/* Append event record to event queue. */
gcmkONERROR(
- gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE));
+ gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
/* Next record in the queue. */
next = record->next;
@@ -2381,6 +2444,17 @@ gckEVENT_Notify(
}
break;
+#if gcdVIRTUAL_COMMAND_BUFFER
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkVERIFY_OK(
+ gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
+ record->info.u.FreeVirtualCommandBuffer.bytes,
+ record->info.u.FreeVirtualCommandBuffer.physical,
+ record->info.u.FreeVirtualCommandBuffer.logical
+ ));
+ break;
+#endif
+
case gcvHAL_COMMIT_DONE:
break;
@@ -2714,6 +2788,11 @@ _PrintRecord(
gcmkPRINT(" gcvHAL_COMMIT_DONE");
break;
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
+ record->info.u.FreeVirtualCommandBuffer.logical);
+ break;
+
default:
gcmkPRINT(" Illegal Event %d", record->info.command);
break;
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 9012599b1bef..72e2b4f8f308 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
@@ -78,6 +78,25 @@ gcsSharedPageTable;
static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
#endif
+#if gcdMIRROR_PAGETABLE
+typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR;
+typedef struct _gcsMirrorPageTable
+{
+ /* gckMMU objects. */
+ gckMMU mmus[gcdMAX_GPU_COUNT];
+
+ /* Hardwares which use this shared pagetable. */
+ gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
+
+ /* Number of cores use this shared pagetable. */
+ gctUINT32 reference;
+}
+gcsMirrorPageTable;
+
+static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
+static gctPOINTER mirrorPageTableMutex = gcvNULL;
+#endif
+
static gceSTATUS
_FillPageTable(
IN gctUINT32_PTR PageTable,
@@ -873,6 +892,47 @@ OnError:
gcmkFOOTER();
return status;
+#elif gcdMIRROR_PAGETABLE
+ gceSTATUS status;
+ gctPOINTER pointer;
+
+ gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
+
+ if (mirrorPageTable == gcvNULL)
+ {
+ gcmkONERROR(
+ gckOS_Allocate(Kernel->os,
+ sizeof(struct _gcsMirrorPageTable),
+ &pointer));
+ mirrorPageTable = pointer;
+
+ gcmkONERROR(
+ gckOS_ZeroMemory(mirrorPageTable,
+ sizeof(struct _gcsMirrorPageTable)));
+
+ gcmkONERROR(
+ gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex));
+ }
+
+ gcmkONERROR(_Construct(Kernel, MmuSize, Mmu));
+
+ mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu;
+
+ mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware;
+
+ mirrorPageTable->reference++;
+
+ gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (mirrorPageTable && mirrorPageTable->reference == 0)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable));
+ }
+
+ gcmkFOOTER();
+ return status;
#else
return _Construct(Kernel, MmuSize, Mmu);
#endif
@@ -897,6 +957,16 @@ gckMMU_Destroy(
}
return gcvSTATUS_OK;
+#elif gcdMIRROR_PAGETABLE
+ mirrorPageTable->reference--;
+
+ if (mirrorPageTable->reference == 0)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable));
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex));
+ }
+
+ return _Destroy(Mmu);
#else
return _Destroy(Mmu);
#endif
@@ -926,7 +996,7 @@ gckMMU_Destroy(
** Pointer to a variable that receives the hardware specific address.
*/
gceSTATUS
-gckMMU_AllocatePages(
+_AllocatePages(
IN gckMMU Mmu,
IN gctSIZE_T PageCount,
OUT gctPOINTER * PageTable,
@@ -949,6 +1019,9 @@ gckMMU_AllocatePages(
if (PageCount > Mmu->pageTableEntries)
{
+ gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
+ __FUNCTION__, __LINE__);
+
/* Not enough pages avaiable. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
@@ -1010,6 +1083,9 @@ gckMMU_AllocatePages(
}
else
{
+ gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
+ __FUNCTION__, __LINE__);
+
/* Out of resources. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
@@ -1122,7 +1198,7 @@ OnError:
** Nothing.
*/
gceSTATUS
-gckMMU_FreePages(
+_FreePages(
IN gckMMU Mmu,
IN gctPOINTER PageTable,
IN gctSIZE_T PageCount
@@ -1191,6 +1267,90 @@ OnError:
}
gceSTATUS
+gckMMU_AllocatePages(
+ IN gckMMU Mmu,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageTable,
+ OUT gctUINT32 * Address
+ )
+{
+#if gcdMIRROR_PAGETABLE
+ gceSTATUS status;
+ gctPOINTER pageTable;
+ gctUINT32 address;
+ gctINT i;
+ gckMMU mmu;
+
+ gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
+
+ /* Allocate page table for current MMU. */
+ for (i = 0; i < mirrorPageTable->reference; i++)
+ {
+ if (Mmu == mirrorPageTable->mmus[i])
+ {
+ gcmkONERROR(_AllocatePages(Mmu, PageCount, PageTable, Address));
+ }
+ }
+
+ /* Allocate page table for other MMUs. */
+ for (i = 0; i < mirrorPageTable->reference; i++)
+ {
+ mmu = mirrorPageTable->mmus[i];
+
+ if (Mmu != mmu)
+ {
+ gcmkONERROR(_AllocatePages(mmu, PageCount, &pageTable, &address));
+ gcmkASSERT(address == *Address);
+ }
+ }
+
+ gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+#else
+ return _AllocatePages(Mmu, PageCount, PageTable, Address);
+#endif
+}
+
+gceSTATUS
+gckMMU_FreePages(
+ IN gckMMU Mmu,
+ IN gctPOINTER PageTable,
+ IN gctSIZE_T PageCount
+ )
+{
+#if gcdMIRROR_PAGETABLE
+ gctINT i;
+ gctUINT32 offset;
+ gckMMU mmu;
+
+ gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
+
+ gcmkVERIFY_OK(_FreePages(Mmu, PageTable, PageCount));
+
+ offset = (gctUINT32)PageTable - (gctUINT32)Mmu->pageTableLogical;
+
+ for (i = 0; i < mirrorPageTable->reference; i++)
+ {
+ mmu = mirrorPageTable->mmus[i];
+
+ if (mmu != Mmu)
+ {
+ gcmkVERIFY_OK(_FreePages(mmu, mmu->pageTableLogical + offset/4, PageCount));
+ }
+ }
+
+ gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
+
+ return gcvSTATUS_OK;
+#else
+ return _FreePages(Mmu, PageTable, PageCount);
+#endif
+}
+
+gceSTATUS
gckMMU_Enable(
IN gckMMU Mmu,
IN gctUINT32 PhysBaseAddr,
@@ -1284,6 +1444,14 @@ gckMMU_SetPage(
IN gctUINT32 *PageEntry
)
{
+#if gcdMIRROR_PAGETABLE
+ gctUINT32_PTR pageEntry;
+ gctINT i;
+ gckMMU mmu;
+ gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical;
+#endif
+
+ gctUINT32 data;
gcmkHEADER_ARG("Mmu=0x%x", Mmu);
/* Verify the arguments. */
@@ -1293,13 +1461,40 @@ gckMMU_SetPage(
if (Mmu->hardware->mmuVersion == 0)
{
- *PageEntry = PageAddress;
+ data = PageAddress;
}
else
{
- *PageEntry = _SetPage(PageAddress);
+ data = _SetPage(PageAddress);
+ }
+
+ if (Mmu->hardware->bigEndian)
+ {
+ data = gcmSWAB32(data);
}
+ *PageEntry = data;
+#if gcdMIRROR_PAGETABLE
+ for (i = 0; i < mirrorPageTable->reference; i++)
+ {
+ mmu = mirrorPageTable->mmus[i];
+
+ if (mmu != Mmu)
+ {
+ pageEntry = mmu->pageTableLogical + offset / 4;
+
+ if (Mmu->hardware->mmuVersion == 0)
+ {
+ *pageEntry = PageAddress;
+ }
+ else
+ {
+ *pageEntry = _SetPage(PageAddress);
+ }
+ }
+
+ }
+#endif
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
@@ -1453,6 +1648,16 @@ gckMMU_Flush(
gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
}
}
+#elif gcdMIRROR_PAGETABLE
+ gctINT i;
+ for (i = 0; i < mirrorPageTable->reference; i++)
+ {
+ hardware = mirrorPageTable->hardwares[i];
+
+ /* Notify cores who use this page table. */
+ gcmkVERIFY_OK(
+ gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+ }
#else
hardware = Mmu->hardware;
gcmkVERIFY_OK(
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 5bf887054e04..5b90e2f8ec60 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -2114,7 +2114,8 @@ gckEVENT_AddList(
IN gckEVENT Event,
IN gcsHAL_INTERFACE_PTR Interface,
IN gceKERNEL_WHERE FromWhere,
- IN gctBOOL AllocateAllowed
+ IN gctBOOL AllocateAllowed,
+ IN gctBOOL FromKernel
);
/* Schedule a FreeNonPagedMemory event. */
@@ -2168,6 +2169,18 @@ gckEVENT_CommitDone(
IN gceKERNEL_WHERE FromWhere
);
+#if gcdVIRTUAL_COMMAND_BUFFER
+/* Schedule a FreeVirtualCommandBuffer event. */
+gceSTATUS
+gckEVENT_DestroyVirtualCommandBuffer(
+ IN gckEVENT Event,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gceKERNEL_WHERE FromWhere
+ );
+#endif
+
gceSTATUS
gckEVENT_Submit(
IN gckEVENT Event,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
index 8d50c977a95d..a089280c7ea5 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
@@ -340,6 +340,14 @@ struct _gcsHINT
/* Flag whether the VS has point size or not. */
gctBOOL vsHasPointSize;
+#if gcdUSE_WCLIP_PATCH
+ /* Flag whether the VS gl_position.z depends on gl_position.w
+ it's a hint for wclipping */
+ gctBOOL vsPositionZDependsOnW;
+#endif
+
+ gctBOOL clipW;
+
/* Element count. */
gctUINT32 elementCount;
@@ -511,6 +519,12 @@ typedef enum _gceSHADER_FLAGS
}
gceSHADER_FLAGS;
+gceSTATUS
+gcSHADER_CheckClipW(
+ IN gctCONST_STRING VertexSource,
+ IN gctCONST_STRING FragmentSource,
+ OUT gctBOOL * clipW);
+
/* Function argument qualifier */
typedef enum _gceINPUT_OUTPUT
{
@@ -2527,6 +2541,14 @@ gcSHADER_CheckValidity(
IN gcSHADER Shader
);
+#if gcdUSE_WCLIP_PATCH
+gceSTATUS
+gcATTRIBUTE_IsPosition(
+ IN gcATTRIBUTE Attribute,
+ OUT gctBOOL * IsPosition
+ );
+#endif
+
/*******************************************************************************
** gcATTRIBUTE_GetType
********************************************************************************
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
index 898bfb137a02..30b6b1858f2d 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
@@ -155,6 +155,10 @@ typedef enum _gceHAL_COMMAND_CODES
gcvHAL_DUMP_GPU_STATE,
gcvHAL_DUMP_EVENT,
+ /* Virtual command buffer. */
+ gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
+ gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
+
/* FSCALE_VAL. */
gcvHAL_SET_FSCALE_VALUE,
gcvHAL_GET_FSCALE_VALUE
@@ -475,6 +479,34 @@ typedef struct _gcsHAL_INTERFACE
}
FreeNonPagedMemory;
+ /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
+ struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
+ {
+ /* Number of bytes to allocate. */
+ IN OUT gctSIZE_T bytes;
+
+ /* Physical address of allocation. */
+ OUT gctPHYS_ADDR physical;
+
+ /* Logical address of allocation. */
+ OUT gctPOINTER logical;
+ }
+ AllocateVirtualCommandBuffer;
+
+ /* gcvHAL_FREE_NON_PAGED_MEMORY */
+ struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
+ {
+ /* Number of bytes allocated. */
+ IN gctSIZE_T bytes;
+
+ /* Physical address of allocation. */
+ IN gctPHYS_ADDR physical;
+
+ /* Logical address of allocation. */
+ IN gctPOINTER logical;
+ }
+ FreeVirtualCommandBuffer;
+
/* gcvHAL_EVENT_COMMIT. */
struct _gcsHAL_EVENT_COMMIT
{
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
index 86ab105b389a..f7934ea45e94 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
@@ -45,6 +45,12 @@ typedef struct __BITFIELDINFO{
RGBQUAD bmiColors[2];
} BITFIELDINFO;
+#elif defined(LINUX) && defined(EGL_API_DFB) && !defined(__APPLE__)
+#include <directfb.h>
+typedef IDirectFB * HALNativeDisplayType;
+typedef IDirectFBWindow * HALNativeWindowType;
+typedef struct _DFBPixmap * HALNativePixmapType;
+
#elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__)
#if defined(EGL_API_WL)
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
index 7400b3201b91..bbfdbc66c8e7 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
@@ -1221,6 +1221,13 @@ gco3D_SetWPlaneLimitX(
IN gctFIXED_POINT Value
);
+
+gceSTATUS
+gco3D_SetWPlaneLimit(
+ IN gco3D Engine,
+ IN gctFLOAT Value
+ );
+
/*----------------------------------------------------------------------------*/
/*-------------------------- gco3D Fragment Processor ------------------------*/
@@ -1478,6 +1485,14 @@ gcoTEXTURE_UploadCompressedSub(
IN gctSIZE_T Size
);
+/* GetImageFormat of texture. */
+gceSTATUS
+gcoTEXTURE_GetImageFormat(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ OUT gctINT * ImageFormat
+ );
+
/* Get gcoSURF object for a mipmap level. */
gceSTATUS
gcoTEXTURE_GetMipMap(
@@ -1779,6 +1794,10 @@ typedef struct _gcsVERTEXARRAY
/* Vertex shader linkage. */
gctUINT linkage;
+
+#if gcdUSE_WCLIP_PATCH
+ gctBOOL isPosition;
+#endif
}
gcsVERTEXARRAY,
* gcsVERTEXARRAY_PTR;
@@ -1805,7 +1824,13 @@ gcoVERTEXARRAY_Bind(
IN gcoINDEX IndexObject,
IN gctPOINTER IndexMemory,
IN OUT gcePRIMITIVE * PrimitiveType,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctUINT * PrimitiveCount,
+ IN OUT gctFLOAT * wLimitRms,
+ IN OUT gctBOOL * wLimitDirty
+#else
IN OUT gctUINT * PrimitiveCount
+#endif
);
gctUINT
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 d951c3a965d9..67ad54fce5a4 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
@@ -146,6 +146,8 @@ typedef enum _gceFEATURE
gcvFEATURE_PE_DITHER_FIX,
gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
gcvFEATURE_FRUSTUM_CLIP_FIX,
+ gcvFEATURE_TEXTURE_LINEAR,
+ gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
}
gceFEATURE;
@@ -477,6 +479,17 @@ typedef enum _gceSURF_ALIGNMENT
}
gceSURF_ALIGNMENT;
+
+/* Surface Addressing. */
+typedef enum _gceSURF_ADDRESSING
+{
+ gcvSURF_NO_STRIDE_TILED = 0,
+ gcvSURF_NO_STRIDE_LINEAR,
+ gcvSURF_STRIDE_TILED,
+ gcvSURF_STRIDE_LINEAR
+}
+gceSURF_ADDRESSING;
+
/* Transparency modes. */
typedef enum _gce2D_TRANSPARENCY
{
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
index 33fddfbbfed2..8b00ccd65a71 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
@@ -153,6 +153,15 @@
#endif
/*
+ gcdVIRTUAL_COMMAND_BUFFER
+ When set to 1, user command buffer and context buffer will be allocated
+ from gcvPOOL_VIRTUAL.
+*/
+#ifndef gcdVIRTUAL_COMMAND_BUFFER
+# define gcdVIRTUAL_COMMAND_BUFFER 0
+#endif
+
+/*
gcdENABLE_FSCALE_VAL_ADJUST
When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
*/
@@ -267,14 +276,28 @@
#endif
/*
+ gcdMIRROR_PAGETABLE
+
+ Enable it when GPUs with old MMU and new MMU exist at same SoC. It makes
+ each GPU use same virtual address to access same physical memory.
+*/
+#ifndef gcdMIRROR_PAGETABLE
+# define gcdMIRROR_PAGETABLE 0
+#endif
+
+/*
gcdMMU_SIZE
Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
virtual data.
*/
#ifndef gcdMMU_SIZE
+#if gcdMIRROR_PAGETABLE
+# define gcdMMU_SIZE 0x200000
+#else
# define gcdMMU_SIZE (2048 << 10)
#endif
+#endif
/*
gcdSECURE_USER
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
index e3ceadfce7ee..d9b29933ced6 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
@@ -954,7 +954,7 @@ gceSTATUS
gco2D_SetStateU32(
IN gco2D Engine,
IN gce2D_STATE State,
- IN OUT gctUINT32_PTR Value
+ IN gctUINT32 Value
);
#ifdef __cplusplus
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
index 4e063776cd44..f3d6fad30f42 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
@@ -146,6 +146,7 @@ typedef unsigned char gctUINT8;
typedef unsigned short gctUINT16;
typedef unsigned int gctUINT32;
typedef unsigned long long gctUINT64;
+typedef unsigned long gctUINTPTR_T;
typedef gctUINT * gctUINT_PTR;
typedef gctUINT8 * gctUINT8_PTR;
@@ -889,6 +890,12 @@ gceSTATUS;
gcmPTR2INT(& (((struct s *) 0)->field)) \
)
+#define gcmSWAB32(x) ((gctUINT32)( \
+ (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
+ (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
+ (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
+
/*******************************************************************************
***** Database ****************************************************************/
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
index 5a21a94ed7fd..99d7d9a3600a 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
@@ -167,7 +167,7 @@ static gcsDebugFileSystem gc_dbgfs ;
static caddr_t
_ReadFromNode (
gcsDebugFileSystemNode* Node ,
- int *Length ,
+ size_t *Length ,
loff_t *Offset
)
{
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index eba81b64be92..27c1e6fb7ef8 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -694,7 +694,7 @@ gckGALDEVICE_Construct(
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
- device->internalPhysical = (gctPHYS_ADDR) physical;
+ device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
physical += device->internalSize;
}
}
@@ -724,7 +724,7 @@ gckGALDEVICE_Construct(
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
- device->externalPhysical = (gctPHYS_ADDR) physical;
+ device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
physical += device->externalSize;
}
}
@@ -840,7 +840,7 @@ gckGALDEVICE_Construct(
}
#endif
- device->contiguousPhysical = (gctPHYS_ADDR) ContiguousBase;
+ device->contiguousPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) ContiguousBase;
device->contiguousSize = ContiguousSize;
device->contiguousMapped = gcvTRUE;
}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index b326463b8133..c7928dd3a6f9 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -650,7 +650,7 @@ static int drv_mmap(
ret = io_remap_pfn_range(
vma,
vma->vm_start,
- (gctUINT32) device->contiguousPhysical >> PAGE_SHIFT,
+ (gctUINTPTR_T) device->contiguousPhysical >> PAGE_SHIFT,
size,
vma->vm_page_prot
);
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index a44180bfc71a..7ebaab052ae2 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -582,7 +582,7 @@ _CreateMdl(
gcmkHEADER_ARG("ProcessID=%d", ProcessID);
- mdl = (PLINUX_MDL)kmalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN);
+ mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN);
if (mdl == gcvNULL)
{
gcmkFOOTER_NO();
@@ -1408,39 +1408,60 @@ gckOS_Destroy(
return gcvSTATUS_OK;
}
-#ifdef NO_DMA_COHERENT
static gctSTRING
_CreateKernelVirtualMapping(
- IN struct page * Page,
- IN gctINT NumPages
+ IN PLINUX_MDL Mdl
)
{
gctSTRING addr = 0;
+ gctINT numPages = Mdl->numPages;
#if gcdNONPAGED_MEMORY_CACHEABLE
- addr = page_address(Page);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+ if (Mdl->contiguous)
+ {
+ addr = page_address(Mdl->u.contiguousPages);
+ }
+ else
+ {
+ addr = vmap(Mdl->u.nonContiguousPages,
+ numPages,
+ 0,
+ PAGE_KERNEL);
+ }
+#else
struct page ** pages;
+ gctBOOL free = gcvFALSE;
gctINT i;
- pages = kmalloc(sizeof(struct page *) * NumPages, GFP_KERNEL | __GFP_NOWARN);
-
- if (!pages)
+ if (Mdl->contiguous)
{
- return gcvNULL;
- }
+ pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | __GFP_NOWARN);
- for (i = 0; i < NumPages; i++)
+ if (!pages)
+ {
+ return gcvNULL;
+ }
+
+ for (i = 0; i < numPages; i++)
+ {
+ pages[i] = nth_page(Mdl->u.contiguousPages, i);
+ }
+
+ free = gcvTRUE;
+ }
+ else
{
- pages[i] = nth_page(Page, i);
+ pages = Mdl->u.nonContiguousPages;
}
/* ioremap() can't work on system memory since 2.6.38. */
- addr = vmap(pages, NumPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+ addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+
+ if (free)
+ {
+ kfree(pages);
+ }
- kfree(pages);
-#else
- addr = gcmkIOREMAP(page_to_phys(Page), NumPages * PAGE_SIZE);
#endif
return addr;
@@ -1452,14 +1473,31 @@ _DestoryKernelVirtualMapping(
)
{
#if !gcdNONPAGED_MEMORY_CACHEABLE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
vunmap(Addr);
-# else
- iounmap(Addr);
-# endif
#endif
}
-#endif
+
+gceSTATUS
+gckOS_CreateKernelVirtualMapping(
+ IN gctPHYS_ADDR Physical,
+ OUT gctSIZE_T * PageCount,
+ OUT gctPOINTER * Logical
+ )
+{
+ *PageCount = ((PLINUX_MDL)Physical)->numPages;
+ *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DestroyKernelVirtualMapping(
+ IN gctPOINTER Logical
+ )
+{
+ _DestoryKernelVirtualMapping((gctSTRING)Logical);
+ return gcvSTATUS_OK;
+}
/*******************************************************************************
**
@@ -2136,7 +2174,9 @@ gckOS_AllocateNonPagedMemory(
}
vaddr = (gctPOINTER)page_address(page);
- addr = _CreateKernelVirtualMapping(page, mdl->numPages);
+ mdl->contiguous = gcvTRUE;
+ mdl->u.contiguousPages = page;
+ addr = _CreateKernelVirtualMapping(mdl);
mdl->dmaHandle = virt_to_phys(vaddr);
mdl->kaddr = vaddr;
mdl->u.contiguousPages = page;
@@ -3438,7 +3478,7 @@ gckOS_AtomicExchangePtr(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
/* Exchange the pair of pointers. */
- *OldValue = (gctPOINTER) atomic_xchg((atomic_t *) Target, (int) NewValue);
+ *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
/* Success. */
gcmkFOOTER_ARG("*OldValue=0x%X", *OldValue);
@@ -4343,8 +4383,8 @@ gckOS_LockPages(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
__FUNCTION__, __LINE__,
- (gctUINT32) mdlMap->vmaAddr,
- (gctUINT32) mdl
+ (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
+ (gctUINT32)(gctUINTPTR_T)mdl
);
if (IS_ERR(mdlMap->vmaAddr))
@@ -4441,10 +4481,10 @@ gckOS_LockPages(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X",
__FUNCTION__, __LINE__,
- (gctUINT32) Physical,
- (gctUINT32) *Logical,
- (gctUINT32) addr,
- (gctUINT32) start
+ (gctUINT32)(gctUINTPTR_T)Physical,
+ (gctUINT32)(gctUINTPTR_T)*Logical,
+ (gctUINT32)(gctUINTPTR_T)addr,
+ (gctUINT32)(gctUINTPTR_T)start
);
mdlMap->vmaAddr = gcvNULL;
@@ -4571,8 +4611,8 @@ gckOS_MapPagesEx(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d",
__FUNCTION__, __LINE__,
- (gctUINT32) Physical,
- (gctUINT32) PageCount,
+ (gctUINT32)(gctUINTPTR_T)Physical,
+ (gctUINT32)(gctUINTPTR_T)PageCount,
mdl->pagedMem
);
@@ -5430,7 +5470,7 @@ OnError:
gctSIZE_T pageCount, i, j;
gctUINT32_PTR pageTable;
gctUINT32 address = 0, physical = ~0U;
- gctUINT32 start, end, memory;
+ gctUINTPTR_T start, end, memory;
gctUINT32 offset;
gctINT result = 0;
@@ -5446,7 +5486,7 @@ OnError:
do
{
- memory = (gctUINT32) Memory;
+ memory = (gctUINTPTR_T) Memory;
/* Get the number of required pages. */
end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -5604,7 +5644,7 @@ OnError:
{
/* Flush(clean) the data cache. */
gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
- (gctPOINTER)(physical & PAGE_MASK),
+ (gctPOINTER)(gctUINTPTR_T)(physical & PAGE_MASK),
(gctPOINTER)(memory & PAGE_MASK),
PAGE_SIZE * pageCount));
}
@@ -5844,7 +5884,7 @@ OnError:
return status;
#else
{
- gctUINT32 memory, start, end;
+ gctUINTPTR_T memory, start, end;
gcsPageInfo_PTR info;
gctSIZE_T pageCount, i;
struct page **pages;
@@ -5877,7 +5917,7 @@ OnError:
return gcvSTATUS_OK;
}
- memory = (gctUINT32) Memory;
+ memory = (gctUINTPTR_T)Memory;
end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
start = memory >> PAGE_SHIFT;
pageCount = end - start;
@@ -6183,7 +6223,7 @@ _HandleOuterCache(
else
{
/* Non contiguous virtual memory */
- vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINT32)Logical, PAGE_SIZE);
+ vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE);
pageNum = GetPageCount(Bytes, 0);
for (i = 0; i < pageNum; i += 1)
@@ -7239,7 +7279,7 @@ gckOS_CreateSignal(
}
/* Save the process ID. */
- signal->process = (gctHANDLE) _GetProcessID();
+ signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID();
signal->manualReset = ManualReset;
signal->hardware = gcvNULL;
init_completion(&signal->obj);
@@ -7247,7 +7287,7 @@ gckOS_CreateSignal(
gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id));
- *Signal = (gctSIGNAL)signal->id;
+ *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
return gcvSTATUS_OK;
@@ -7279,7 +7319,7 @@ gckOS_SignalQueryHardware(
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
*Hardware = signal->hardware;
@@ -7306,7 +7346,7 @@ gckOS_SignalSetHardware(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
signal->hardware = Hardware;
@@ -7354,9 +7394,9 @@ gckOS_DestroySignal(
gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
acquired = gcvTRUE;
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
- gcmkASSERT(signal->id == (gctUINT32)Signal);
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
if (atomic_dec_and_test(&signal->ref))
{
@@ -7426,9 +7466,9 @@ gckOS_Signal(
gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
acquired = gcvTRUE;
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
- gcmkASSERT(signal->id == (gctUINT32)Signal);
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
if (State)
{
@@ -7475,7 +7515,7 @@ gckOS_SetSignalVG(
struct task_struct * userTask;
struct siginfo info;
- userTask = FIND_TASK_BY_PID((pid_t) Process);
+ userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
if (userTask != gcvNULL)
{
@@ -7554,7 +7594,7 @@ gckOS_UserSignal(
gctSIGNAL signal;
gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
- Os, Signal, (gctINT32) Process);
+ Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
/* Map the signal into kernel space. */
gcmkONERROR(gckOS_MapSignal(Os, Signal, Process, &signal));
@@ -7612,9 +7652,9 @@ gckOS_WaitSignal(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
- gcmkASSERT(signal->id == (gctUINT32)Signal);
+ gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
might_sleep();
@@ -7786,7 +7826,7 @@ gckOS_MapSignal(
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
- gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
if(atomic_inc_return(&signal->ref) <= 1)
{
@@ -7885,7 +7925,7 @@ gckOS_DestroyUserSignal(
IN gctINT SignalID
)
{
- return gckOS_DestroySignal(Os, (gctSIGNAL)SignalID);
+ return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID);
}
/*******************************************************************************
@@ -7917,7 +7957,7 @@ gckOS_WaitUserSignal(
IN gctUINT32 Wait
)
{
- return gckOS_WaitSignal(Os, (gctSIGNAL)SignalID, Wait);
+ return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, Wait);
}
/*******************************************************************************
@@ -7949,7 +7989,7 @@ gckOS_SignalUserSignal(
IN gctBOOL State
)
{
- return gckOS_Signal(Os, (gctSIGNAL)SignalID, State);
+ return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State);
}
#if gcdENABLE_VG
@@ -8082,7 +8122,7 @@ gckOS_SetSignal(
struct task_struct * userTask;
struct siginfo info;
- userTask = FIND_TASK_BY_PID((pid_t) Process);
+ userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
if (userTask != gcvNULL)
{