summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal
diff options
context:
space:
mode:
authorLoren Huang <b02279@freescale.com>2014-11-06 16:39:44 +0800
committerNitin Garg <nitin.garg@freescale.com>2015-04-14 14:00:59 -0500
commit3b3e7f0bbbf93a0ae65748e6a747e1037f626582 (patch)
tree475940119a8945da609a20b0aba3195a3904049e /drivers/mxc/gpu-viv/hal
parentc4c28fc1f5f1b54f4a21476062e62eb13b2a7efe (diff)
MGS-210 gpu:5.0.11.p4 gpu driver kernel part integration
Integrate 5.0.11.p4 kernel change. Date: Nov 6, 2014 Signed-off-by: Loren Huang <b02279@freescale.com> Acked-by: Shawn Guo (cherry picked from commit 4d1f341c418d70a73cded239a2bba554e25de5ac)
Diffstat (limited to 'drivers/mxc/gpu-viv/hal')
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c16
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c554
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c679
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c100
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h81
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c32
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c165
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c149
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c174
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h37
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h116
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h10
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h5
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h14
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h31
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c129
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c226
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c216
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h36
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c259
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c36
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c11
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config14
33 files changed, 2215 insertions, 907 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
index 3d8e062543ee..08644a7cf5e5 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
@@ -589,7 +589,7 @@ _InitializeContextBuffer(
#if gcdENABLE_3D
gctBOOL halti0, halti1, halti2, halti3;
gctUINT i;
- gctUINT vertexUniforms, fragmentUniforms, unifiedConst, vsConstBase, psConstBase, constMax;
+ gctUINT vertexUniforms, fragmentUniforms, vsConstBase, psConstBase, constMax;
gctBOOL unifiedUniform;
gctUINT fe2vsCount;
#endif
@@ -620,8 +620,9 @@ _InitializeContextBuffer(
halti3 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures5)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) );
/* Query how many uniforms can support for non-unified uniform mode. */
- { if (Context->hardware->identity.chipModel == gcv2000 && Context->hardware->identity.chipRevision == 0x5118) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else if (Context->hardware->identity.numConstants == 320) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else if (Context->hardware->identity.numConstants > 256 && Context->hardware->identity.chipModel == gcv1000) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else if (Context->hardware->identity.numConstants > 256) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 256; constMax = 512; } else if (Context->hardware->identity.numConstants == 256) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 256; constMax = 512; } else { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 168; fragmentUniforms = 64; constMax = 232; }};
+ {if (Context->hardware->identity.numConstants > 256){ unifiedUniform = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; constMax = Context->hardware->identity.numConstants; vertexUniforms = 256; fragmentUniforms = constMax - vertexUniforms;}else if (Context->hardware->identity.numConstants == 256){ if (Context->hardware->identity.chipModel == gcv2000 && Context->hardware->identity.chipRevision == 0x5118) { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 256; constMax = 512; }}else{ unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 168; fragmentUniforms = 64; constMax = 232;}};
+#if !gcdENABLE_UNIFIED_CONSTANT
if (Context->hardware->identity.numConstants > 256)
{
unifiedUniform = gcvTRUE;
@@ -630,6 +631,7 @@ _InitializeContextBuffer(
{
unifiedUniform = gcvFALSE;
}
+#endif
/* Store the 3D entry index. */
Context->entryOffset3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
@@ -1001,9 +1003,13 @@ _InitializeContextBuffer(
index += _CLOSE_RANGE();
}
}
-
- index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
+#if gcdENABLE_UNIFIED_CONSTANT
+ else
+#endif
+ {
+ index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
+ }
/* Store the index of the "XD" entry. */
Context->entryOffsetXDFrom3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
index cb88684b1e21..3a225a9a208d 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
@@ -1121,6 +1121,8 @@ gckHARDWARE_Construct(
hardware->endAfterFlushMmuCache = gcvFALSE;
}
+ gcmkONERROR(gckOS_QueryOption(Os, "mmu", (gctUINT32_PTR)&hardware->enableMMU));
+
hardware->minFscaleValue = 1;
/* Return pointer to the gckHARDWARE object. */
@@ -1434,7 +1436,8 @@ gckHARDWARE_InitializeHardware(
}
if (Hardware->identity.chipModel == gcv1000 &&
- Hardware->identity.chipRevision == 0x5039)
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
{
gctUINT32 pulseEater;
@@ -1483,19 +1486,9 @@ gckHARDWARE_InitializeHardware(
data));
}
- /* Test if MMU is initialized. */
- if ((Hardware->kernel != gcvNULL)
- && (Hardware->kernel->mmu != gcvNULL)
- )
- {
- /* Reset MMU. */
- if (Hardware->mmuVersion == 0)
- {
- gcmkONERROR(
- gckHARDWARE_SetMMU(Hardware,
- Hardware->kernel->mmu->pageTableLogical));
- }
- }
+ gcmkONERROR(
+ gckHARDWARE_SetMMU(Hardware,
+ Hardware->kernel->mmu->pageTableLogical));
if (Hardware->identity.chipModel >= gcv400
&& Hardware->identity.chipModel != gcv420)
@@ -1624,21 +1617,18 @@ gckHARDWARE_InitializeHardware(
if ((Hardware->identity.chipRevision > 0x5420)
&& gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D))
{
- gctUINT clock =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:1) - (0 ? 7:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:1) - (0 ? 7:1) + 1))))))) << (0 ? 7:1))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 7:1) - (0 ? 7:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:1) - (0 ? 7:1) + 1))))))) << (0 ? 7:1)));
-
- clock |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
- clock |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ &data));
- /* Write the clock control register. */
- gckOS_WriteRegister(Hardware->os,
- 0x0010C,
- ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))));
+ /* Disable internal DFS. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
- /* Done loading the frequency scaler. */
- gckOS_WriteRegister(Hardware->os,
- 0x0010C,
- ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ data));
}
#if gcdDEBUG_MODULE_CLOCK_GATING
@@ -3205,7 +3195,7 @@ gckHARDWARE_QueryShaderCaps(
Hardware, VertexUniforms,
FragmentUniforms, UnifiedUnforms);
- { if (Hardware->identity.chipModel == gcv2000 && Hardware->identity.chipRevision == 0x5118) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else if (Hardware->identity.numConstants == 320) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else if (Hardware->identity.numConstants > 256 && Hardware->identity.chipModel == gcv1000) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else if (Hardware->identity.numConstants > 256) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 256; ConstMax = 512; } else if (Hardware->identity.numConstants == 256) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 256; ConstMax = 512; } else { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 168; psConstMax = 64; ConstMax = 232; }};
+ {if (Hardware->identity.numConstants > 256){ unifiedConst = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; ConstMax = Hardware->identity.numConstants; vsConstMax = 256; psConstMax = ConstMax - vsConstMax;}else if (Hardware->identity.numConstants == 256){ if (Hardware->identity.chipModel == gcv2000 && Hardware->identity.chipRevision == 0x5118) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 256; ConstMax = 512; }}else{ unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 168; psConstMax = 64; ConstMax = 232;}};
if (VertexUniforms != gcvNULL)
{
@@ -3257,59 +3247,109 @@ gckHARDWARE_SetMMU(
{
gceSTATUS status;
gctUINT32 address = 0;
+ gctUINT32 idle;
+ gctUINT32 timer = 0, delay = 1;
gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
- gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- /* Convert the logical address into physical address. */
- gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Setting page table to 0x%08X",
- address);
+ /* Convert the logical address into physical address. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
- /* Write the AQMemoryFePageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00400,
- address));
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Setting page table to 0x%08X",
+ address);
- /* Write the AQMemoryRaPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00410,
- address));
+ /* Write the AQMemoryFePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00400,
+ address));
- /* Write the AQMemoryTxPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00404,
- address));
+ /* Write the AQMemoryRaPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00410,
+ address));
+ /* Write the AQMemoryTxPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00404,
+ address));
- /* Write the AQMemoryPePageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00408,
- address));
- /* Write the AQMemoryPezPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x0040C,
- address));
+ /* Write the AQMemoryPePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00408,
+ address));
+
+ /* Write the AQMemoryPezPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0040C,
+ address));
+ }
+ else if (Hardware->enableMMU == gcvTRUE)
+ {
+ /* Execute prepared command sequence. */
+ gcmkONERROR(gckHARDWARE_Execute(
+ Hardware,
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address,
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes
+ ));
+
+ /* Wait until MMU configure finishes. */
+ do
+ {
+ gckOS_Delay(Hardware->os, delay);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00004,
+ &idle));
+
+ timer += delay;
+ delay *= 2;
+
+#if gcdGPU_TIMEOUT
+ if (timer >= Hardware->kernel->timeOut)
+ {
+ /* Even if hardware is not reset correctly, let software
+ ** continue to avoid software stuck. Software will timeout again
+ ** and try to recover GPU in next timeout.
+ */
+ gcmkONERROR(gcvSTATUS_DEVICE);
+ }
+#endif
+ }
+ while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
+
+ /* Enable MMU. */
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0018C,
+ ((((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) ((gctUINT32) (gcvTRUE) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+ }
/* Return the status. */
gcmkFOOTER_NO();
- return status;
+ return gcvSTATUS_OK;
OnError:
/* Return the status. */
@@ -3646,272 +3686,6 @@ OnError:
return status;
}
-
-/*******************************************************************************
-**
-** gckHARDWARE_SetMMUv2
-**
-** Set the page table base address.
-**
-** INPUT:
-**
-** gckHARDWARE Harwdare
-** Pointer to an gckHARDWARE object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gckHARDWARE_SetMMUv2(
- IN gckHARDWARE Hardware,
- IN gctBOOL Enable,
- IN gctPOINTER MtlbAddress,
- IN gceMMU_MODE Mode,
- IN gctPOINTER SafeAddress,
- IN gctBOOL FromPower
- )
-{
- gceSTATUS status;
- gctUINT32 config, address;
- gckCOMMAND command;
- gctUINT32_PTR buffer;
- gctUINT32 bufferSize;
- gctBOOL commitEntered = gcvFALSE;
- gctPOINTER pointer = gcvNULL;
- gctBOOL acquired = gcvFALSE;
- gctBOOL ace;
- gctUINT32 reserveBytes = 16;
-
- gctBOOL config2D;
-
- gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-
- ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE);
-
- if (ace)
- {
- reserveBytes += 8;
- }
-
- config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
- && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
-
- if (config2D)
- {
- reserveBytes +=
- /* Pipe Select. */
- 4 * 4
- /* Configure MMU States. */
- + 4 * 4
- /* Semaphore stall */
- + 4 * 12;
- }
-
- /* Convert logical address into physical address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
-
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
-
- if (address & 0x3F)
- {
- gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
- }
-
- switch (Mode)
- {
- case gcvMMU_MODE_1K:
- if (config & 0x3FF)
- {
- gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
- }
-
- config |= ((((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)));
-
- break;
-
- case gcvMMU_MODE_4K:
- if (config & 0xFFF)
- {
- gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
- }
-
- config |= ((((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) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-
- break;
-
- default:
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
-
- /* Verify the gckCOMMAND object pointer. */
- command = Hardware->kernel->command;
-
- /* Acquire the command queue. */
- gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
- commitEntered = gcvTRUE;
-
- gcmkONERROR(gckCOMMAND_Reserve(
- command, reserveBytes, &pointer, &bufferSize
- ));
-
- buffer = pointer;
-
- *buffer++
- = ((((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) (0x0061) & ((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)));
-
- *buffer++ = config;
-
- *buffer++
- = ((((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) (0x0060) & ((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)));
-
- *buffer++ = address;
-
- if (ace)
- {
- *buffer++
- = ((((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) (0x0068) & ((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)));
-
- *buffer++ = 0;
- }
-
- if (config2D)
- {
- do{*buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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)));} while(0);;
-
- /* LoadState(AQPipeSelect, 1), pipe. */
- *buffer++
- = ((((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) (0x0E00) & ((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)));
-
- *buffer++ = 0x1;
-
- *buffer++
- = ((((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) (0x0061) & ((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)));
-
- *buffer++ = config;
-
- *buffer++
- = ((((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) (0x0060) & ((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)));
-
- *buffer++ = address;
-
- do{*buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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)));} while(0);;
-
- /* LoadState(AQPipeSelect, 1), pipe. */
- *buffer++
- = ((((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) (0x0E00) & ((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)));
-
- *buffer++ = 0x0;
-
- do{*buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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))); *buffer++ = ((((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)));} while(0);;
- }
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
-
- gcmkONERROR(gckCOMMAND_Execute(command, reserveBytes));
-
- if (FromPower == gcvFALSE)
- {
- /* Acquire global semaphore to suspend power management until MMU
- ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
- ** make sure GPU keeps ON. */
- gcmkONERROR(
- gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
-
- acquired = gcvTRUE;
- }
-
- /* Release the command queue. */
- gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
- commitEntered = gcvFALSE;
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "call gckCOMMAND_Stall to make sure the config is done.\n ");
-
-#if gcdMULTI_GPU
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower, gcvCORE_3D_ALL_MASK));
-#else
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
-#endif
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Enable MMU through GCREG_MMU_CONTROL.");
-
- /* Enable MMU. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x0018C,
- ((((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) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
-
- if (FromPower == gcvFALSE)
- {
- /* Relase global semaphore. */
- gcmkVERIFY_OK(
- gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
-
- acquired = gcvFALSE;
- }
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "call gckCOMMAND_Stall to check MMU available.\n");
-
-#if gcdMULTI_GPU
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower, gcvCORE_3D_ALL_MASK));
-#else
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
-#endif
-
-#if gcdPROCESS_ADDRESS_SPACE
- command->currentMmu = gcvNULL;
-#endif
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "The MMU is available.\n");
-
- /* Return the status. */
- gcmkFOOTER_NO();
- return status;
-
-OnError:
- if (commitEntered)
- {
- /* Release the command queue mutex. */
- gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
- FromPower));
- }
-
- if (acquired)
- {
- gcmkVERIFY_OK(
- gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
- }
-
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
#if gcdPROCESS_ADDRESS_SPACE
/*******************************************************************************
**
@@ -4336,7 +4110,6 @@ gckHARDWARE_Flush(
gctBOOL flushTileStatus;
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gceSTATUS status;
- gctBOOL fcFlushStall;
gctUINT32 reserveBytes
/* Semaphore/Stall */
= 4 * gcmSIZEOF(gctUINT32);
@@ -4350,11 +4123,8 @@ gckHARDWARE_Flush(
/* Get current pipe. */
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 tile status cache. */
- flushTileStatus = (Flush & gcvFLUSH_TILE_STATUS) && fcFlushStall;
+ flushTileStatus = Flush & gcvFLUSH_TILE_STATUS;
/* Flush 3D color cache. */
if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
@@ -5329,22 +5099,6 @@ gckHARDWARE_SetPowerManagementState(
gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
isrStarted = gcvTRUE;
}
-
-#if !gcdSECURITY
- /* Set NEW MMU. */
- if (Hardware->mmuVersion != 0 && configMmu)
- {
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- Hardware,
- gcvTRUE,
- Hardware->kernel->mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvTRUE
- ));
- }
-#endif
}
/* Get time until started. */
@@ -5506,7 +5260,6 @@ gckHARDWARE_QueryPowerManagementState(
** gckHARDWARE_SetPowerManagement
**
** Configure GPU power management function.
-** Only used in driver initialization stage.
**
** INPUT:
**
@@ -5527,19 +5280,53 @@ gckHARDWARE_SetPowerManagement(
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ if(!Hardware->powerManagementLock)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
- gcmkVERIFY_OK(
- gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
+ Hardware->powerManagement = PowerManagement;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagementLock
+**
+** Disable dynamic GPU power management switch.
+** Only used in driver initialization stage.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL Lock
+** Power Mangement Lock State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerManagementLock(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Lock
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
- Hardware->powerManagement = PowerManagement;
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ Hardware->powerManagementLock = Lock;
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
-
/*******************************************************************************
**
** gckHARDWARE_SetGpuProfiler
@@ -6859,8 +6646,6 @@ gckHARDWARE_Reset(
)
{
gceSTATUS status;
- gctUINT32 idle;
- gctUINT32 timer = 0, delay = 1;
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -6886,52 +6671,6 @@ gckHARDWARE_Reset(
/* Initialize hardware. */
gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
- /* TODO: Move mmu setting to gckHARDWARE_InitializeHardware. */
- if (Hardware->mmuVersion)
- {
- /* Execute prepared command sequence. */
- gcmkONERROR(gckHARDWARE_Execute(
- Hardware,
- Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address,
- Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes
- ));
-
- /* Wait until MMU configure finishes. */
- do
- {
- gckOS_Delay(Hardware->os, delay);
-
- gcmkONERROR(gckOS_ReadRegisterEx(
- Hardware->os,
- Hardware->core,
- 0x00004,
- &idle));
-
- timer += delay;
- delay *= 2;
-
-#if gcdGPU_TIMEOUT
- if (timer >= Hardware->kernel->timeOut)
- {
- /* Even if hardware is not reset correctly, let software
- ** continue to avoid software stuck. Software will timeout again
- ** and try to recover GPU in next timeout.
- */
- gcmkONERROR(gcvSTATUS_DEVICE);
- }
-#endif
- }
- while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
-
- /* Enable MMU. */
- gcmkONERROR(gckOS_WriteRegisterEx(
- Hardware->os,
- Hardware->core,
- 0x0018C,
- ((((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) ((gctUINT32) (gcvTRUE) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
- ));
- }
-
/* Jump to address into which GPU should run if it doesn't stuck. */
gcmkONERROR(gckHARDWARE_Execute(Hardware, Hardware->kernel->restoreAddress, 16));
@@ -7211,7 +6950,8 @@ gckHARDWARE_IsFeatureAvailable(
&& ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
if (Hardware->identity.chipModel == gcv1000 &&
- Hardware->identity.chipRevision == 0x5039)
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
{
available = gcvFALSE;
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
index 54784f13fdc1..2ffa1468b5e4 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
@@ -91,6 +91,11 @@ struct _gckHARDWARE
gctUINT32 mmuVersion;
+ /* Whether use new MMU. It is meaningless
+ ** for old MMU since old MMU is always enabled.
+ */
+ gctBOOL enableMMU;
+
/* Type */
gceHARDWARE_TYPE type;
@@ -110,6 +115,7 @@ struct _gckHARDWARE
#endif
gctBOOL powerManagement;
+ gctBOOL powerManagementLock;
gctBOOL gpuProfiler;
gctBOOL endAfterFlushMmuCache;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
new file mode 100644
index 000000000000..087fa8353ff1
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
@@ -0,0 +1,679 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+/*
+ * -----------------------
+ * HARDWARE STATE RECORDER
+ * -----------------------
+ *
+ * State mirror buffer is used to 'mirror' hardware states since hardware
+ * states can't be dumpped. It is a context buffer which stores 'global'
+ * context.
+ *
+ * For each commit, state recorder
+ * 1) Records context buffer (if there is) and command buffers in this commit.
+ * 2) Parse those buffers to estimate the state changed.
+ * 3) Stores result to a mirror buffer.
+ *
+ * == Commit 0 ====================================================================
+ *
+ * Context Buffer 0
+ *
+ * Command Buffer 0
+ *
+ * Mirror Buffer 0 <- Context Buffer 0 + Command Buffer 0
+ *
+ * == Commit 1 ====================================================================
+ *
+ * Command Buffer 1
+ *
+ * Mirror Buffer 1 <- Command buffer 1 + Mirror Buffer 0
+ *
+ * == Commit 2 ====================================================================
+ *
+ * Context Buffer 2 (optional)
+ *
+ * Command Buffer 2
+ *
+ * Mirror Buffer 2 <- Command buffer 2 + Context Buffer 2 + Mirror Buffer 1
+ *
+ * == Commit N ====================================================================
+ *
+ * For Commit N, these buffers are needed to reproduce hardware's behavior in
+ * this commit.
+ *
+ * Mirror Buffer [N - 1] : State Mirror accumlated by past commits,
+ * which is used to restore hardware state.
+ * Context Buffer [N] :
+ * Command Buffer [N] : Command buffer executed by hardware in this commit.
+ *
+ * If sequence of states programming matters, hardware's behavior can't be reproduced,
+ * but the state values stored in mirror buffer are assuring.
+ */
+
+/* Queue size. */
+#define gcdNUM_RECORDS 6
+
+typedef struct _gcsPARSER_HANDLER * gckPARSER_HANDLER;
+
+typedef void
+(*HandlerFunction)(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ );
+
+typedef struct _gcsPARSER_HANDLER
+{
+ gctUINT32 type;
+ gctUINT32 cmd;
+ gctPOINTER private;
+ HandlerFunction function;
+}
+gcsPARSER_HANDLER;
+
+typedef struct _gcsPARSER * gckPARSER;
+typedef struct _gcsPARSER
+{
+ gctUINT8_PTR currentCmdBufferAddr;
+
+ /* Current command. */
+ gctUINT32 lo;
+ gctUINT32 hi;
+
+ gctUINT8 cmdOpcode;
+ gctUINT16 cmdAddr;
+ gctUINT32 cmdSize;
+ gctUINT32 cmdRectCount;
+ gctUINT8 skip;
+ gctUINT32 skipCount;
+
+ gctBOOL allow;
+
+ /* Callback used by parser to handle a command. */
+ gckPARSER_HANDLER commandHandler;
+}
+gcsPARSER;
+
+typedef struct _gcsMIRROR
+{
+ gctUINT32_PTR logical[gcdNUM_RECORDS];
+ gctUINT32 bytes;
+ gcsSTATE_MAP_PTR map;
+ gctUINT32 stateCount;
+}
+gcsMIRROR;
+
+typedef struct _gcsDELTA
+{
+ gctUINT64 commitStamp;
+ gctUINT32_PTR command;
+ gctUINT32 commandBytes;
+ gctUINT32_PTR context;
+ gctUINT32 contextBytes;
+}
+gcsDELTA;
+
+typedef struct _gcsRECORDER
+{
+ gckOS os;
+ gcsMIRROR mirror;
+ gcsDELTA deltas[gcdNUM_RECORDS];
+
+ /* Index of current record. */
+ gctUINT index;
+
+ /* Number of records. */
+ gctUINT num;
+
+ /* Plugin used by gckPARSER. */
+ gcsPARSER_HANDLER recorderHandler;
+ gckPARSER parser;
+}
+gcsRECORDER;
+
+
+/******************************************************************************\
+***************************** Command Buffer Parser ****************************
+\******************************************************************************/
+
+/*
+** Command buffer parser checks command buffer in FE's view to make sure there
+** is no format error.
+**
+** Parser provide a callback mechnisam, so plug-in can be added to implement
+** other functions.
+*/
+
+static void
+_HandleLoadState(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT i;
+ gctUINT32_PTR data = (gctUINT32_PTR)Parser->currentCmdBufferAddr;
+ gctUINT32 cmdAddr = Parser->cmdAddr;
+
+ if (Parser->commandHandler == gcvNULL
+ || Parser->commandHandler->cmd != 0x01
+ )
+ {
+ /* No handler for this command. */
+ return;
+ }
+
+ for (i = 0; i < Parser->cmdSize; i++)
+ {
+ Parser->commandHandler->function(Parser->commandHandler, cmdAddr, *data);
+
+ /* Advance to next state. */
+ cmdAddr++;
+ data++;
+ }
+}
+
+static void
+_GetCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT32 * buffer = (gctUINT32 *)Parser->currentCmdBufferAddr;
+
+ gctUINT16 cmdRectCount;
+ gctUINT16 cmdDataCount;
+
+ Parser->hi = buffer[0];
+ Parser->lo = buffer[1];
+
+ Parser->cmdOpcode = (((((gctUINT32) (Parser->hi)) >> (0 ? 31:27)) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) );
+ Parser->cmdRectCount = 1;
+
+ switch (Parser->cmdOpcode)
+ {
+ case 0x01:
+ /* Extract count. */
+ Parser->cmdSize = (((((gctUINT32) (Parser->hi)) >> (0 ? 25:16)) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1)))))) );
+ if (Parser->cmdSize == 0)
+ {
+ /* 0 means 1024. */
+ Parser->cmdSize = 1024;
+ }
+ Parser->skip = (Parser->cmdSize & 0x1) ? 0 : 1;
+
+ /* Extract address. */
+ Parser->cmdAddr = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) );
+
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 4;
+ Parser->skipCount = Parser->cmdSize + Parser->skip;
+ break;
+
+ case 0x05:
+ Parser->cmdSize = 4;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x06:
+ Parser->cmdSize = 5;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x0C:
+ Parser->cmdSize = 3;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x09:
+ Parser->cmdSize = 2;
+ Parser->cmdAddr = 0x0F16;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x04:
+ Parser->cmdSize = 1;
+ Parser->cmdAddr = 0x0F06;
+
+ cmdRectCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
+ cmdDataCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 26:16)) & ((gctUINT32) ((((1 ? 26:16) - (0 ? 26:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:16) - (0 ? 26:16) + 1)))))) );
+
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2)
+ + cmdRectCount * 2
+ + gcmALIGN(cmdDataCount, 2);
+
+ Parser->cmdRectCount = cmdRectCount;
+ break;
+
+ case 0x03:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ case 0x02:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ default:
+ /* Unknown command is a risk. */
+ Parser->allow = gcvFALSE;
+ break;
+ }
+}
+
+static void
+_ParseCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ switch(Parser->cmdOpcode)
+ {
+ case 0x01:
+ _HandleLoadState(Parser);
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x0C:
+ break;
+ case 0x04:
+ break;
+ default:
+ break;
+ }
+
+ /* Advance to next command. */
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr
+ + (Parser->skipCount << 2);
+}
+
+gceSTATUS
+gckPARSER_Parse(
+ IN gckPARSER Parser,
+ IN gctUINT8_PTR Buffer,
+ IN gctUINT32 Bytes
+ )
+{
+ gckPARSER parser = Parser;
+ gctUINT8_PTR end = (gctUINT8_PTR)Buffer + Bytes;
+
+ /* Initialize parser. */
+ parser->currentCmdBufferAddr = (gctUINT8_PTR)Buffer;
+ parser->skip = 0;
+ parser->allow = gcvTRUE;
+
+ /* Go through command buffer until reaching the end
+ ** or meeting an error. */
+ do
+ {
+ _GetCommand(parser);
+
+ _ParseCommand(parser);
+ }
+ while ((parser->currentCmdBufferAddr < end) && (parser->allow == gcvTRUE));
+
+ if (parser->allow == gcvFALSE)
+ {
+ /* Error detected. */
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckPARSER_RegisterCommandHandler
+**
+** Register a command handler which will be called when parser get a command.
+**
+*/
+gceSTATUS
+gckPARSER_RegisterCommandHandler(
+ IN gckPARSER Parser,
+ IN gckPARSER_HANDLER Handler
+ )
+{
+ Parser->commandHandler = Handler;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckPARSER_Construct(
+ IN gckOS Os,
+ IN gckPARSER_HANDLER Handler,
+ OUT gckPARSER * Parser
+ )
+{
+ gceSTATUS status;
+ gckPARSER pointer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsPARSER), (gctPOINTER *)&pointer));
+
+ /* Put it here temp, should have a more general plug-in mechnisam. */
+ pointer->commandHandler = Handler;
+
+ *Parser = pointer;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckPARSER_Destroy(
+ IN gckOS Os,
+ IN gckPARSER Parser
+ )
+{
+ gcmkOS_SAFE_FREE(Os, Parser);
+}
+
+/******************************************************************************\
+**************************** Hardware States Recorder **************************
+\******************************************************************************/
+
+static void
+_RecodeState(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ )
+{
+ gcmkVERIFY_OK(gckRECORDER_UpdateMirror(Handler->private, Addr, Data));
+}
+
+static gctUINT
+_Previous(
+ IN gctUINT Index
+ )
+{
+ if (Index == 0)
+ {
+ return gcdNUM_RECORDS - 1;
+ }
+
+ return Index - 1;
+}
+
+static gctUINT
+_Next(
+ IN gctUINT Index
+ )
+{
+ return (Index + 1) % gcdNUM_RECORDS;
+}
+
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ )
+{
+ gceSTATUS status;
+ gckCONTEXT context = gcvNULL;
+ gckRECORDER recorder = gcvNULL;
+ gctUINT32 mapSize;
+ gctUINT i;
+ gctBOOL virtualCommandBuffer = Hardware->kernel->virtualCommandBuffer;
+
+ /* TODO: We only need context buffer and state map, it should be able to get without construct a
+ ** new context.
+ ** Now it is leaked, since we can't free it when command buffer is gone.
+ */
+
+ /* MMU is not ready now. */
+ Hardware->kernel->virtualCommandBuffer = gcvFALSE;
+
+ gcmkONERROR(gckCONTEXT_Construct(Os, Hardware, 0, &context));
+
+ /* Restore. */
+ Hardware->kernel->virtualCommandBuffer = virtualCommandBuffer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsRECORDER), (gctPOINTER *)&recorder));
+
+ gckOS_ZeroMemory(recorder, gcmSIZEOF(gcsRECORDER));
+
+ /* Copy state map. */
+ recorder->mirror.stateCount = context->stateCount;
+
+ mapSize = context->stateCount * gcmSIZEOF(gcsSTATE_MAP);
+
+ gcmkONERROR(gckOS_Allocate(Os, mapSize, (gctPOINTER *)&recorder->mirror.map));
+
+ gckOS_MemCopy(recorder->mirror.map, context->map, mapSize);
+
+ /* Copy context buffer. */
+ recorder->mirror.bytes = context->totalSize;
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->mirror.logical[i]));
+ gckOS_MemCopy(recorder->mirror.logical[i], context->buffer->logical, context->totalSize);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ /* TODO : Optimize size. */
+ gcmkONERROR(gckOS_Allocate(Os, gcdCMD_BUFFER_SIZE, (gctPOINTER *)&recorder->deltas[i].command));
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->deltas[i].context));
+ }
+
+ recorder->index = 0;
+ recorder->num = 0;
+
+ /* Initialize Parser plugin. */
+ recorder->recorderHandler.cmd = 0x01;
+ recorder->recorderHandler.private = recorder;
+ recorder->recorderHandler.function = _RecodeState;
+
+ gcmkONERROR(gckPARSER_Construct(Os, &recorder->recorderHandler, &recorder->parser));
+
+ recorder->os = Os;
+
+ *Recorder = recorder;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (recorder)
+ {
+ gckRECORDER_Destory(Os, recorder);
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT i;
+
+ if (Recorder->mirror.map)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.map);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->mirror.logical[i])
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.logical[i]);
+ }
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->deltas[i].command)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].command);
+ }
+
+ if (Recorder->deltas[i].context)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].context);
+ }
+ }
+
+ if (Recorder->parser)
+ {
+ gckPARSER_Destroy(Os, Recorder->parser);
+ }
+
+ gcmkOS_SAFE_FREE(Os, Recorder);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ IN gckRECORDER Recorder,
+ IN gctUINT32 State,
+ IN gctUINT32 Data
+ )
+{
+ gctUINT32 index;
+ gcsSTATE_MAP_PTR map = Recorder->mirror.map;
+ gctUINT32_PTR buffer = Recorder->mirror.logical[Recorder->index];
+
+ if (State >= Recorder->mirror.stateCount)
+ {
+ /* Ignore them just like HW does. */
+ return gcvSTATUS_OK;
+ }
+
+ index = map[State].index;
+
+ if (index)
+ {
+ buffer[index] = Data;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckRECORDER_AdvanceIndex(
+ IN gckRECORDER Recorder,
+ IN gctUINT64 CommitStamp
+ )
+{
+ /* Get next record. */
+ gctUINT next = (Recorder->index + 1) % gcdNUM_RECORDS;
+
+ /* Record stamp of this commit. */
+ Recorder->deltas[Recorder->index].commitStamp = CommitStamp;
+
+ /* Mirror of next record is mirror of this record and delta in next record. */
+ gckOS_MemCopy(Recorder->mirror.logical[next],
+ Recorder->mirror.logical[Recorder->index], Recorder->mirror.bytes);
+
+ /* Advance to next record. */
+ Recorder->index = next;
+
+ Recorder->num = gcmMIN(Recorder->num + 1, gcdNUM_RECORDS - 1);
+
+
+ /* Reset delta. */
+ Recorder->deltas[Recorder->index].commandBytes = 0;
+ Recorder->deltas[Recorder->index].contextBytes = 0;
+}
+
+void
+gckRECORDER_Record(
+ IN gckRECORDER Recorder,
+ IN gctUINT8_PTR CommandBuffer,
+ IN gctUINT32 CommandBytes,
+ IN gctUINT8_PTR ContextBuffer,
+ IN gctUINT32 ContextBytes
+ )
+{
+ gcsDELTA * delta = &Recorder->deltas[Recorder->index];
+
+ if (CommandBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, CommandBuffer, CommandBytes);
+ gckOS_MemCopy(delta->command, CommandBuffer, CommandBytes);
+ delta->commandBytes = CommandBytes;
+ }
+
+ if (ContextBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, ContextBuffer, ContextBytes);
+ gckOS_MemCopy(delta->context, ContextBuffer, ContextBytes);
+ delta->contextBytes = ContextBytes;
+ }
+}
+
+void
+gckRECORDER_Dump(
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT last = Recorder->index;
+ gctUINT previous;
+ gctUINT i;
+ gcsMIRROR *mirror = &Recorder->mirror;
+ gcsDELTA *delta;
+ gckOS os = Recorder->os;
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ last = _Previous(last);
+ }
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ delta = &Recorder->deltas[last];
+
+ /* Dump record */
+ gcmkPRINT("#[commit %llu]", delta->commitStamp);
+
+ if (delta->commitStamp)
+ {
+ previous = _Previous(last);
+
+ gcmkPRINT("#[mirror]");
+ gckOS_DumpBuffer(os, mirror->logical[previous], mirror->bytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ if (delta->contextBytes)
+ {
+ gckOS_DumpBuffer(os, delta->context, delta->contextBytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ gckOS_DumpBuffer(os, delta->command, delta->commandBytes, gceDUMP_BUFFER_USER, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+
+ last = _Next(last);
+ }
+}
+
+
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 adbff2a19b54..b14708d307d4 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -270,6 +270,11 @@ _DumpState(
/* Dump Process DB. */
gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
+
+#if gcdRECORD_COMMAND
+ /* Dump record. */
+ gckRECORDER_Dump(Kernel->command->recorder);
+#endif
}
/*******************************************************************************
@@ -336,8 +341,6 @@ gckKERNEL_Construct(
#endif
kernel->monitorTimer = gcvNULL;
- kernel->vidmemMutex = gcvNULL;
-
/* Initialize the gckKERNEL object. */
kernel->object.type = gcvOBJ_KERNEL;
kernel->os = Os;
@@ -406,6 +409,8 @@ gckKERNEL_Construct(
/* Construct the gckMMU object. */
gcmkONERROR(
gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
+
+ kernel->timeOut = gcdGPU_TIMEOUT;
}
else
#endif
@@ -417,9 +422,10 @@ gckKERNEL_Construct(
/* Set pointer to gckKERNEL object in gckHARDWARE object. */
kernel->hardware->kernel = kernel;
- /* Initialize the hardware. */
- gcmkONERROR(
- gckHARDWARE_InitializeHardware(kernel->hardware));
+ kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
+ ? gcdGPU_2D_TIMEOUT
+ : gcdGPU_TIMEOUT
+ ;
/* Initialize virtual command buffer. */
/* TODO: Remove platform limitation after porting. */
@@ -447,6 +453,12 @@ gckKERNEL_Construct(
gcmkVERIFY_OK(gckOS_GetTime(&kernel->resetTimeStamp));
+ gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware));
+
+ /* Initialize the hardware. */
+ gcmkONERROR(
+ gckHARDWARE_InitializeHardware(kernel->hardware));
+
#if gcdDVFS
if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
gcvFEATURE_DYNAMIC_FREQUENCY_SCALING))
@@ -455,8 +467,6 @@ gckKERNEL_Construct(
gcmkONERROR(gckDVFS_Start(kernel->dvfs));
}
#endif
-
- gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware));
}
#if VIVANTE_PROFILER
@@ -465,24 +475,10 @@ gckKERNEL_Construct(
kernel->profileCleanRegister = gcvTRUE;
#endif
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
#endif
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
- {
- kernel->timeOut = gcdGPU_TIMEOUT;
- }
- else
-#endif
- {
- kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
- ? gcdGPU_2D_TIMEOUT
- : gcdGPU_TIMEOUT
- ;
- }
-
kernel->recovery = gcvTRUE;
kernel->stuckDump = 1;
@@ -496,8 +492,6 @@ gckKERNEL_Construct(
/* Connect to security service for this GPU. */
gcmkONERROR(gckKERNEL_SecurityOpen(kernel, kernel->core, &kernel->securityChannel));
#endif
- /* Construct a video memory mutex. */
- gcmkONERROR(gckOS_GetVideoMemoryMutex(Os, &kernel->vidmemMutex));
#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC
if (kernel->timeOut)
@@ -586,7 +580,7 @@ OnError:
}
#endif
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
if (kernel->timeline)
{
gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Os, kernel->timeline));
@@ -658,11 +652,13 @@ gckKERNEL_Destroy(
{
databaseNext = database->next;
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->counterMutex));
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
}
if (Kernel->db->lastDatabase != gcvNULL)
{
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->lastDatabase->counterMutex));
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
}
@@ -730,7 +726,7 @@ gckKERNEL_Destroy(
}
#endif
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
#endif
@@ -1360,6 +1356,7 @@ gckKERNEL_QueryDatabase(
{
gceSTATUS status;
gctINT i;
+ gcuDATABASE_INFO tmp;
gceDATABASE_TYPE type[3] = {
gcvDB_VIDEO_MEMORY | (gcvPOOL_SYSTEM << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
@@ -1417,7 +1414,15 @@ gckKERNEL_QueryDatabase(
Interface->u.Database.processID,
!Interface->u.Database.validProcessID,
gcvDB_COMMAND_BUFFER,
- &Interface->u.Database.vidMemPool[2]));
+ &tmp));
+
+ Interface->u.Database.vidMemPool[2].counters.bytes += tmp.counters.bytes;
+ Interface->u.Database.vidMemPool[2].counters.maxBytes += tmp.counters.maxBytes;
+ Interface->u.Database.vidMemPool[2].counters.totalBytes += tmp.counters.totalBytes;
+
+ Interface->u.Database.vidMem.counters.bytes += tmp.counters.bytes;
+ Interface->u.Database.vidMem.counters.maxBytes += tmp.counters.maxBytes;
+ Interface->u.Database.vidMem.counters.totalBytes += tmp.counters.totalBytes;
#if gcmIS_DEBUG(gcdDEBUG_TRACE)
gckKERNEL_DumpVidMemUsage(Kernel, Interface->u.Database.processID);
@@ -2528,6 +2533,18 @@ gckKERNEL_Dispatch(
0));
break;
+ case gcvHAL_GET_VIDEO_MEMORY_FD:
+ gcmkONERROR(gckVIDMEM_NODE_GetFd(
+ Kernel,
+ Interface->u.GetVideoMemoryFd.handle,
+ &Interface->u.GetVideoMemoryFd.fd
+ ));
+
+ /* No need to add it to processDB because OS will release all fds when
+ ** process quits.
+ */
+ break;
+
case gcvHAL_QUERY_RESET_TIME_STAMP:
Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
break;
@@ -2556,7 +2573,7 @@ gckKERNEL_Dispatch(
gcmRELEASE_NAME(Interface->u.FreeVirtualCommandBuffer.physical);
break;
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
case gcvHAL_SYNC_POINT:
{
gctSYNC_POINT syncPoint;
@@ -3758,9 +3775,7 @@ gckKERNEL_AllocateVirtualCommandBuffer(
gctSIZE_T pageCount;
gctSIZE_T bytes = *Bytes;
gckVIRTUAL_COMMAND_BUFFER_PTR buffer = gcvNULL;
-#if gcdPROCESS_ADDRESS_SPACE
gckMMU mmu;
-#endif
gctUINT32 flag = gcvALLOC_FLAG_NON_CONTIGUOUS;
gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
@@ -3817,13 +3832,16 @@ gckKERNEL_AllocateVirtualCommandBuffer(
#if gcdPROCESS_ADDRESS_SPACE
gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+ buffer->mmu = mmu;
+#else
+ mmu = Kernel->mmu;
+#endif
gcmkONERROR(gckMMU_AllocatePages(mmu,
pageCount,
&buffer->pageTable,
&buffer->gpuAddress));
- buffer->mmu = mmu;
gcmkONERROR(gckOS_MapPagesEx(os,
Kernel->core,
@@ -3831,24 +3849,8 @@ gckKERNEL_AllocateVirtualCommandBuffer(
pageCount,
buffer->gpuAddress,
buffer->pageTable));
-#else
- gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
- pageCount,
- &buffer->pageTable,
- &buffer->gpuAddress));
- gcmkONERROR(gckOS_MapPagesEx(os,
- Kernel->core,
- buffer->physical,
- pageCount,
- buffer->pageTable));
-#endif
-
-#if gcdPROCESS_ADDRESS_SPACE
- gcmkONERROR(gckMMU_Flush(mmu));
-#else
- gcmkONERROR(gckMMU_Flush(Kernel->mmu, gcvSURF_INDEX));
-#endif
+ gcmkONERROR(gckMMU_Flush(mmu, gcvSURF_INDEX));
*Physical = buffer;
@@ -3949,6 +3951,8 @@ gckKERNEL_DestroyVirtualCommandBuffer(
gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
#endif
+ gcmkVERIFY_OK(gckOS_UnmapPages(os, buffer->pageCount, buffer->gpuAddress));
+
gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
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 1e0b4a3860f7..93764878a42d 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -215,6 +215,7 @@ typedef struct _gcsDATABASE
gcsDATABASE_COUNTERS vidMemType[gcvSURF_NUM_TYPES];
/* Counter for each video memory pool. */
gcsDATABASE_COUNTERS vidMemPool[gcvPOOL_NUMBER_OF_POOLS];
+ gctPOINTER counterMutex;
/* Idle time management. */
gctUINT64 lastIdle;
@@ -237,6 +238,15 @@ typedef struct _gcsDATABASE
}
gcsDATABASE;
+typedef struct _gcsRECORDER * gckRECORDER;
+
+typedef struct _gcsFDPRIVATE * gcsFDPRIVATE_PTR;
+typedef struct _gcsFDPRIVATE
+{
+ gctINT (* release) (gcsFDPRIVATE_PTR Private);
+}
+gcsFDPRIVATE;
+
/* Create a process database that will contain all its allocations. */
gceSTATUS
gckKERNEL_CreateProcessDB(
@@ -538,7 +548,7 @@ struct _gckKERNEL
gckDVFS dvfs;
#endif
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
gctHANDLE timeline;
#endif
@@ -564,8 +574,6 @@ struct _gckKERNEL
gctUINT32 timer;
gctUINT32 restoreAddress;
gctUINT32 restoreMask;
-
- gctPOINTER vidmemMutex;
};
struct _FrequencyHistory
@@ -804,6 +812,10 @@ struct _gckEVENT
#if gcdINTERRUPT_STATISTIC
gctPOINTER interruptCount;
#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER recorder;
+#endif
};
/* Free all events belonging to a process. */
@@ -959,6 +971,9 @@ struct _gckVIDMEM
/* Allocation threshold. */
gctSIZE_T threshold;
+
+ /* The heap mutex. */
+ gctPOINTER mutex;
};
typedef struct _gcsVIDMEM_NODE
@@ -966,6 +981,9 @@ typedef struct _gcsVIDMEM_NODE
/* Pointer to gcuVIDMEM_NODE. */
gcuVIDMEM_NODE_PTR node;
+ /* Mutex to protect node. */
+ gctPOINTER mutex;
+
/* Reference count. */
gctPOINTER reference;
@@ -1093,6 +1111,13 @@ gckVIDMEM_HANDLE_Lookup(
OUT gckVIDMEM_NODE * Node
);
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ );
+
#if gcdPROCESS_ADDRESS_SPACE
gceSTATUS
gckEVENT_DestroyMmu(
@@ -1180,6 +1205,13 @@ gckOS_DestroyUserVirtualMapping(
);
gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT *Fd
+ );
+
+gceSTATUS
gckKERNEL_AllocateVirtualCommandBuffer(
IN gckKERNEL Kernel,
IN gctBOOL InUserSpace,
@@ -1407,6 +1439,49 @@ gckENTRYQUEUE_Dequeue(
OUT gckENTRYDATA * Data
);
+/******************************************************************************\
+****************************** gckRECORDER Object ******************************
+\******************************************************************************/
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ );
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ );
+
+void
+gckRECORDER_AdvanceIndex(
+ gckRECORDER Recorder,
+ gctUINT64 CommitStamp
+ );
+
+void
+gckRECORDER_Record(
+ gckRECORDER Recorder,
+ gctUINT8_PTR CommandBuffer,
+ gctUINT32 CommandBytes,
+ gctUINT8_PTR ContextBuffer,
+ gctUINT32 ContextBytes
+ );
+
+void
+gckRECORDER_Dump(
+ gckRECORDER Recorder
+ );
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ gckRECORDER Recorder,
+ gctUINT32 State,
+ gctUINT32 Data
+ );
+
#ifdef __cplusplus
}
#endif
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 9c59525c90db..72aa966d6dad 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
@@ -605,6 +605,10 @@ gckCOMMAND_Construct(
));
}
+#if gcdRECORD_COMMAND
+ gcmkONERROR(gckRECORDER_Construct(os, Kernel->hardware, &command->recorder));
+#endif
+
/* No command queue in use yet. */
command->index = -1;
command->logical = gcvNULL;
@@ -772,6 +776,10 @@ gckCOMMAND_Destroy(
}
#endif
+#if gcdRECORD_COMMAND
+ gckRECORDER_Destory(Command->os, Command->recorder);
+#endif
+
/* Mark object as unknown. */
Command->object.type = gcvOBJ_UNKNOWN;
@@ -1869,6 +1877,16 @@ gckCOMMAND_Commit(
entryBytes - 8
);
#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ gcvNULL,
+ 0xFFFFFFFF,
+ entryLogical,
+ entryBytes - 8
+ );
+#endif
}
/* Same context. */
@@ -2223,6 +2241,20 @@ gckCOMMAND_Commit(
));
#endif
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ commandBufferLogical + offset,
+ commandBufferSize - offset - 8,
+ gcvNULL,
+ 0xFFFFFFFF
+ );
+
+ gckRECORDER_AdvanceIndex(Command->recorder, Command->commitStamp);
+
+ Command->commitStamp++;
+#endif
+
#if gcdSECURITY
/* Submit command buffer to trust zone. */
gckKERNEL_SecurityExecute(
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 c31d465ae761..10477a1d844d 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
@@ -100,6 +100,8 @@ gckKERNEL_NewDatabase(
gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsDATABASE));
database = pointer;
+
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->counterMutex));
}
/* Insert the database into the hash. */
@@ -167,6 +169,7 @@ gckKERNEL_FindDatabase(
gceSTATUS status;
gcsDATABASE_PTR database, previous;
gctSIZE_T slot;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
Kernel, ProcessID, LastProcessID);
@@ -174,6 +177,11 @@ gckKERNEL_FindDatabase(
/* Compute the hash for the database. */
slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Check whether we are getting the last known database. */
if (LastProcessID)
{
@@ -217,6 +225,9 @@ gckKERNEL_FindDatabase(
}
}
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Return the database. */
*Database = database;
@@ -225,6 +236,11 @@ gckKERNEL_FindDatabase(
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
/* Return the status. */
gcmkFOOTER();
@@ -255,10 +271,16 @@ gckKERNEL_DeleteDatabase(
)
{
gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
gcsDATABASE_PTR database;
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Check slot value. */
gcmkVERIFY_ARGUMENT(Database->slot < gcmCOUNTOF(Kernel->db->db));
@@ -317,11 +339,19 @@ gckKERNEL_DeleteDatabase(
Database->mmu = gcvNULL;
#endif
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
/* Return the status. */
gcmkFOOTER();
@@ -357,10 +387,16 @@ gckKERNEL_NewRecord(
)
{
gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record = gcvNULL;
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
if (Kernel->db->freeRecord != gcvNULL)
{
/* Allocate the record from the free list. */
@@ -383,6 +419,9 @@ gckKERNEL_NewRecord(
record->next = Database->list[Slot];
Database->list[Slot] = record;
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Return the record. */
*Record = record;
@@ -391,6 +430,11 @@ gckKERNEL_NewRecord(
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
if (record != gcvNULL)
{
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
@@ -436,12 +480,18 @@ gckKERNEL_DeleteRecord(
)
{
gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record, previous;
gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Scan the database for this record. */
for (record = Database->list[slot], previous = gcvNULL;
record != gcvNULL;
@@ -485,11 +535,19 @@ gckKERNEL_DeleteRecord(
record->next = Kernel->db->freeRecord;
Kernel->db->freeRecord = record;
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
/* Return the status. */
gcmkFOOTER();
@@ -531,12 +589,18 @@ gckKERNEL_FindRecord(
)
{
gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record;
gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Scan the database for this record. */
for (record = Database->list[slot];
record != gcvNULL;
@@ -565,11 +629,19 @@ gckKERNEL_FindRecord(
gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
}
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_ARG("Record=0x%x", Record);
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
/* Return the status. */
gcmkFOOTER();
@@ -773,7 +845,6 @@ gckKERNEL_AddProcessDB(
gcsDATABASE_COUNTERS * count;
gctUINT32 vidMemType;
gcePOOL vidMemPool;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
"Physical=0x%x Size=%lu",
@@ -788,11 +859,6 @@ gckKERNEL_AddProcessDB(
Type &= gcdDATABASE_TYPE_MASK;
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Special case the idle record. */
if (Type == gcvDB_IDLE)
{
@@ -847,8 +913,6 @@ gckKERNEL_AddProcessDB(
}
}
#endif
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
/* Success. */
gcmkFOOTER_NO();
@@ -903,6 +967,8 @@ gckKERNEL_AddProcessDB(
break;
}
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
if (count != gcvNULL)
{
/* Adjust counters. */
@@ -940,20 +1006,13 @@ gckKERNEL_AddProcessDB(
}
}
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
@@ -995,7 +1054,6 @@ gckKERNEL_RemoveProcessDB(
gctSIZE_T bytes = 0;
gctUINT32 vidMemType;
gcePOOL vidMempool;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
Kernel, ProcessID, Type, Pointer);
@@ -1010,11 +1068,6 @@ gckKERNEL_RemoveProcessDB(
Type &= gcdDATABASE_TYPE_MASK;
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1022,6 +1075,8 @@ gckKERNEL_RemoveProcessDB(
gcmkONERROR(
gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
/* Update counters. */
switch (Type)
{
@@ -1055,20 +1110,13 @@ gckKERNEL_RemoveProcessDB(
break;
}
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1110,7 +1158,6 @@ gckKERNEL_FindProcessDB(
{
gceSTATUS status;
gcsDATABASE_PTR database;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
Kernel, ProcessID, ThreadID, Type, Pointer);
@@ -1119,11 +1166,6 @@ gckKERNEL_FindProcessDB(
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1131,20 +1173,11 @@ gckKERNEL_FindProcessDB(
gcmkONERROR(
gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1184,18 +1217,12 @@ gckKERNEL_DestroyProcessDB(
gckKERNEL kernel = Kernel;
gctUINT32 handle;
gctUINT32 i;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1239,9 +1266,6 @@ gckKERNEL_DestroyProcessDB(
/* Next next record. */
next = record->next;
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- acquired = gcvFALSE;
-
/* Dispatch on record type. */
switch (record->type)
{
@@ -1430,7 +1454,7 @@ gckKERNEL_DestroyProcessDB(
gcmPTR2INT32(record->data), status);
break;
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
case gcvDB_SYNC_POINT:
/* Free the user signal. */
status = gckOS_DestroySyncPoint(Kernel->os,
@@ -1459,10 +1483,6 @@ gckKERNEL_DestroyProcessDB(
break;
}
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Delete the record. */
gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
database,
@@ -1476,20 +1496,11 @@ gckKERNEL_DestroyProcessDB(
/* Delete the database. */
gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1533,7 +1544,6 @@ gckKERNEL_QueryProcessDB(
gceSTATUS status;
gcsDATABASE_PTR database;
gcePOOL vidMemPool;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
Kernel, ProcessID, Type, Info);
@@ -1547,15 +1557,13 @@ gckKERNEL_QueryProcessDB(
Type &= gcdDATABASE_TYPE_MASK;
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Find the database. */
gcmkONERROR(
gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
/* Get pointer to counters. */
switch (Type)
{
@@ -1613,20 +1621,13 @@ gckKERNEL_QueryProcessDB(
break;
}
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if(acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
index 7813441a600c..b2b078e6c66c 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
@@ -2547,6 +2547,8 @@ gckOS_DebugStatus2Name(
return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
case gcvSTATUS_TOO_MANY_UNIFORMS:
return "gcvSTATUS_TOO_MANY_UNIFORMS";
+ case gcvSTATUS_TOO_MANY_SAMPLER:
+ return "gcvSTATUS_TOO_MANY_SAMPLER";
case gcvSTATUS_TOO_MANY_VARYINGS:
return "gcvSTATUS_TOO_MANY_VARYINGS";
case gcvSTATUS_UNDECLARED_VARYING:
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 3ceff80b7fbd..1c6300787fad 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
@@ -2987,7 +2987,7 @@ gckEVENT_Notify(
gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
break;
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
case gcvHAL_SYNC_POINT:
{
gctSYNC_POINT syncPoint;
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 fa9b9ada93d1..7f545f24a6e1 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
@@ -857,7 +857,11 @@ _Construct(
gctPOINTER pointer = gcvNULL;
#if gcdPROCESS_ADDRESS_SPACE
gctUINT32 i;
+ gctUINT32 physical;
#endif
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+ gctUINT32 gpuAddress;
gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
@@ -926,10 +930,6 @@ _Construct(
_WritePageEntry(map + 1, ~0U);
mmu->heapList = 0;
mmu->freeNodes = gcvFALSE;
-
- /* Set page table address. */
- gcmkONERROR(
- gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical));
}
else
{
@@ -959,10 +959,40 @@ _Construct(
}
_SetupProcessAddressSpace(mmu);
+
+ /* Map kernel command buffer in MMU. */
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ mmu->os,
+ Kernel->command->queues[i].logical,
+ &physical
+ ));
+
+ gcmkONERROR(gckMMU_FlatMapping(mmu, physical));
+ }
#else
/* Invalid all the entries. */
gcmkONERROR(
gckOS_ZeroMemory(pointer, mmu->mtlbSize));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physBase", &physBase));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physSize", &physSize));
+
+ gcmkONERROR(
+ gckOS_CPUPhysicalToGPUPhysical(mmu->os, physBase, &gpuAddress));
+
+ /* Setup [physBase - physSize) flat mapping. */
+ gcmkONERROR(_FillFlatMapping(
+ mmu,
+ gpuAddress,
+ physSize
+ ));
+
+ gcmkONERROR(_SetupDynamicSpace(mmu));
#endif
}
@@ -1243,12 +1273,6 @@ gckMMU_Construct(
gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
}
- else if (Kernel->hardware->mmuVersion == 0)
- {
- /* Set page table address. */
- gcmkONERROR(
- gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical));
- }
*Mmu = sharedPageTable->mmu;
@@ -1783,111 +1807,6 @@ gckMMU_FreePages(
}
gceSTATUS
-gckMMU_Enable(
- IN gckMMU Mmu,
- IN gctUINT32 PhysBaseAddr,
- IN gctUINT32 PhysSize
- )
-{
- gceSTATUS status;
-#if gcdSHARED_PAGETABLE
- gckHARDWARE hardware;
- gctINT i;
-#endif
-
- gcmkHEADER_ARG("Mmu=0x%x", Mmu);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
-
-#if gcdSHARED_PAGETABLE
- if (Mmu->enabled)
- {
- gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
- return gcvSTATUS_SKIP;
- }
-#endif
-
- if (Mmu->hardware->mmuVersion == 0)
- {
- /* Success. */
- gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
- return gcvSTATUS_SKIP;
- }
- else
- {
-#if gcdPROCESS_ADDRESS_SPACE
- gctUINT32 i;
- gctUINT32 physical;
- gckKERNEL kernel = Mmu->hardware->kernel;
-
- /* Map kernel command buffer in MMU. */
- for (i = 0; i < gcdCOMMAND_QUEUES; i++)
- {
- gcmkONERROR(gckOS_GetPhysicalAddress(
- Mmu->os,
- kernel->command->queues[i].logical,
- &physical
- ));
-
- gcmkONERROR(gckMMU_FlatMapping(Mmu, physical));
- }
-#else
- if (PhysSize != 0)
- {
- gcmkONERROR(_FillFlatMapping(
- Mmu,
- PhysBaseAddr,
- PhysSize
- ));
- }
-
- gcmkONERROR(_SetupDynamicSpace(Mmu));
-#endif
-
-#if gcdSHARED_PAGETABLE
- for(i = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- hardware = sharedPageTable->hardwares[i];
- if (hardware != gcvNULL)
- {
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- hardware,
- gcvTRUE,
- Mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvFALSE
- ));
- }
- }
-#else
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- Mmu->hardware,
- gcvTRUE,
- Mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvFALSE
- ));
-#endif
-
- Mmu->enabled = gcvTRUE;
-
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
-gceSTATUS
gckMMU_SetPage(
IN gckMMU Mmu,
IN gctUINT32 PageAddress,
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 4b03f1d7161e..237b85674906 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
@@ -383,6 +383,7 @@ gckVIDMEM_Construct(
memory->bytes = heapBytes;
memory->freeBytes = heapBytes;
memory->threshold = Threshold;
+ memory->mutex = gcvNULL;
BaseAddress = 0;
@@ -505,6 +506,9 @@ gckVIDMEM_Construct(
"[GALCORE] TILE_STATUS: bank %d",
memory->mapping[gcvSURF_TILE_STATUS]);
+ /* Allocate the mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
+
/* Return pointer to the gckVIDMEM object. */
*Memory = memory;
@@ -516,6 +520,12 @@ OnError:
/* Roll back. */
if (memory != gcvNULL)
{
+ if (memory->mutex != gcvNULL)
+ {
+ /* Delete the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
+ }
+
for (i = 0; i < banks; ++i)
{
/* Free the heap. */
@@ -582,6 +592,9 @@ gckVIDMEM_Destroy(
}
}
+ /* Free the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
+
/* Mark the object as unknown. */
Memory->object.type = gcvOBJ_UNKNOWN;
@@ -846,7 +859,7 @@ gckVIDMEM_AllocateLinear(
gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
/* Acquire the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
+ gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
acquired = gcvTRUE;
@@ -962,7 +975,7 @@ gckVIDMEM_AllocateLinear(
#endif
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
/* Return the pointer to the node. */
*Node = node;
@@ -979,7 +992,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
}
/* Return the status. */
@@ -1019,11 +1032,6 @@ gckVIDMEM_Free(
gcmkHEADER_ARG("Node=0x%x", Node);
- /* Acquire the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
- mutexAcquired = gcvTRUE;
-
/* Verify the arguments. */
if ((Node == gcvNULL)
|| (Node->VidMem.memory == gcvNULL)
@@ -1040,6 +1048,12 @@ gckVIDMEM_Free(
/* Extract pointer to gckVIDMEM object owning the node. */
memory = Node->VidMem.memory;
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+
+ mutexAcquired = gcvTRUE;
+
#ifdef __QNXNTO__
/* Unmap the video memory. */
if (Node->VidMem.logical != gcvNULL)
@@ -1124,7 +1138,7 @@ gckVIDMEM_Free(
}
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Node 0x%x is freed.",
@@ -1168,19 +1182,16 @@ gckVIDMEM_Free(
/* Destroy the gcuVIDMEM_NODE union. */
gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
-
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
-
if (mutexAcquired)
{
/* Release the mutex. */
gcmkVERIFY_OK(gckOS_ReleaseMutex(
- Kernel->os,Kernel->vidmemMutex
+ memory->os, memory->mutex
));
}
@@ -1429,10 +1440,6 @@ gckVIDMEM_Lock(
os = Kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
if ((node == gcvNULL)
|| (node->VidMem.memory == gcvNULL)
)
@@ -1441,6 +1448,10 @@ gckVIDMEM_Lock(
gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
}
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/**************************** Video Memory ********************************/
if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
@@ -1609,6 +1620,7 @@ gckVIDMEM_Lock(
Kernel->core,
node->Virtual.physical,
node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core],
node->Virtual.pageTables[Kernel->core]));
#if gcdENABLE_VG
@@ -1634,10 +1646,10 @@ gckVIDMEM_Lock(
#endif
}
- *PhysicalAddress = (gctUINT64)physicalAddress;
-
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+
+ *PhysicalAddress = (gctUINT64)physicalAddress;
/* Success. */
gcmkFOOTER_ARG("*Address=%08x", *Address);
@@ -1684,7 +1696,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
}
/* Return the status. */
@@ -1742,10 +1754,6 @@ gckVIDMEM_Unlock(
os = Kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Verify the arguments. */
if ((node == gcvNULL)
|| (node->VidMem.memory == gcvNULL)
@@ -1755,6 +1763,10 @@ gckVIDMEM_Unlock(
gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
}
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/**************************** Video Memory ********************************/
if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
@@ -1788,6 +1800,7 @@ gckVIDMEM_Unlock(
else
{
+
if (Asynchroneous == gcvNULL)
{
#if !gcdPROCESS_ADDRESS_SPACE
@@ -1832,6 +1845,13 @@ gckVIDMEM_Unlock(
node->Virtual.pageTables[Kernel->core],
node->Virtual.pageCount));
}
+
+ gcmkONERROR(gckOS_UnmapPages(
+ Kernel->os,
+ node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core]
+ ));
+
/* Mark page table as freed. */
node->Virtual.pageTables[Kernel->core] = gcvNULL;
node->Virtual.lockKernels[Kernel->core] = gcvNULL;
@@ -1864,7 +1884,7 @@ gckVIDMEM_Unlock(
}
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
acquired = gcvFALSE;
/* Success. */
@@ -1875,7 +1895,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
}
/* Return the status. */
@@ -2463,6 +2483,8 @@ gckVIDMEM_NODE_Allocate(
gcmkONERROR(gckOS_AtomConstruct(os, &node->reference));
+ gcmkONERROR(gckOS_CreateMutex(os, &node->mutex));
+
/* Reference is 1 by default . */
gckVIDMEM_NODE_Reference(Kernel, node);
@@ -2484,6 +2506,11 @@ OnError:
}
#endif
+ if (node->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex));
+ }
+
if (node->reference != gcvNULL)
{
gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference));
@@ -2528,6 +2555,7 @@ gckVIDMEM_NODE_Dereference(
#if gcdPROCESS_ADDRESS_SPACE
gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mapMutex));
#endif
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mutex));
gcmkOS_SAFE_FREE(Kernel->os, Node);
}
@@ -2685,3 +2713,95 @@ OnError:
return status;
}
+
+typedef struct _gcsVIDMEM_NODE_FDPRIVATE
+{
+ gcsFDPRIVATE base;
+ gckKERNEL kernel;
+ gckVIDMEM_NODE node;
+}
+gcsVIDMEM_NODE_FDPRIVATE;
+
+
+static gctINT
+_ReleaseFdPrivate(
+ gcsFDPRIVATE_PTR FdPrivate
+ )
+{
+ /* Cast private info. */
+ gcsVIDMEM_NODE_FDPRIVATE * private = (gcsVIDMEM_NODE_FDPRIVATE *) FdPrivate;
+
+ gckVIDMEM_NODE_Dereference(private->kernel, private->node);
+ gckOS_Free(private->kernel->os, private);
+
+ return 0;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_GetFd
+**
+** Attach a gckVIDMEM_NODE object to a native fd.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Handle
+** Handle to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Fd
+** Pointer to a variable receiving a native fd from os.
+*/
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctBOOL referenced = gcvFALSE;
+ gcsVIDMEM_NODE_FDPRIVATE * fdPrivate = gcvNULL;
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ /* Query and reference handle. */
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+ referenced = gcvTRUE;
+
+ /* Allocate memory for private info. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(gcsVIDMEM_NODE_FDPRIVATE),
+ (gctPOINTER *)&fdPrivate
+ ));
+
+ fdPrivate->base.release = _ReleaseFdPrivate;
+ fdPrivate->kernel = Kernel;
+ fdPrivate->node = node;
+
+ /* Allocated fd owns a reference. */
+ gcmkONERROR(gckOS_GetFd("vidmem", &fdPrivate->base, Fd));
+
+ gcmkFOOTER_ARG("*Fd=%d", *Fd);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (fdPrivate)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, fdPrivate));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
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 9e39fa10e78d..f4b7d9911282 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -393,12 +393,17 @@ gckOS_MapPagesEx(
IN gceCORE Core,
IN gctPHYS_ADDR Physical,
IN gctSIZE_T PageCount,
-#if gcdPROCESS_ADDRESS_SPACE
IN gctUINT32 Address,
-#endif
IN gctPOINTER PageTable
);
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ );
+
/* Unlock pages. */
gceSTATUS
gckOS_UnlockPages(
@@ -1341,6 +1346,13 @@ gckOS_GPUPhysicalToCPUPhysical(
IN gctUINT32_PTR CPUPhysical
);
+gceSTATUS
+gckOS_QueryOption(
+ IN gckOS Os,
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
+ );
+
/******************************************************************************\
** Debug Support
*/
@@ -1572,13 +1584,6 @@ gckOS_StopTimer(
IN gctPOINTER Timer
);
-/* Get the global video memory mutex. */
-gceSTATUS
-gckOS_GetVideoMemoryMutex(
- IN gckOS Os,
- OUT gctPOINTER *Mutex
- );
-
/******************************************************************************\
********************************* gckHEAP Object ********************************
\******************************************************************************/
@@ -2248,6 +2253,12 @@ gckHARDWARE_SetPowerManagement(
);
gceSTATUS
+gckHARDWARE_SetPowerManagementLock(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Lock
+ );
+
+gceSTATUS
gckHARDWARE_SetGpuProfiler(
IN gckHARDWARE Hardware,
IN gctBOOL GpuProfiler
@@ -2734,14 +2745,6 @@ gckMMU_Destroy(
IN gckMMU Mmu
);
-/* Enable the MMU. */
-gceSTATUS
-gckMMU_Enable(
- IN gckMMU Mmu,
- IN gctUINT32 PhysBaseAddr,
- IN gctUINT32 PhysSize
- );
-
/* Allocate pages inside the MMU. */
gceSTATUS
gckMMU_AllocatePages(
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
index 709c8a7763db..b798152523af 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
@@ -173,12 +173,12 @@ typedef enum _gcePATCH_ID
gcvPATCH_TITANPACKING,
gcvPATCH_BASEMARKOSIICN,
gcvPATCH_FRUITNINJA,
- gcvPATCH_QUICINC_VELLAMO,
#if defined(ANDROID)
gcePATCH_ANDROID_CTS_MEDIA_PRESENTATIONTIME,
#endif
gcvPATCH_ANDROID_COMPOSITOR,
gcvPATCH_CTS_TEXTUREVIEW,
+ gcvPATCH_WATER2_CHUKONG,
gcvPATCH_COUNT
} gcePATCH_ID;
@@ -337,6 +337,9 @@ typedef struct _gcsTLS
/* libGAL.so handle */
gctHANDLE handle;
+
+ /* If true, do not releas 2d engine and hardware in hal layer */
+ gctBOOL release2DUpper;
}
gcsTLS;
@@ -646,6 +649,12 @@ gcoHAL_ImportVideoMemory(
OUT gctUINT32 * Handle
);
+gceSTATUS
+gcoHAL_GetVideoMemoryFd(
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ );
+
/* Verify whether the specified feature is available in hardware. */
gceSTATUS
gcoHAL_IsFeatureAvailable(
@@ -747,6 +756,17 @@ gcoOS_FreeVideoMemory(
IN gctPOINTER Handle
);
+/* Lock video memory. */
+gceSTATUS
+gcoOS_LockVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical
+ );
+
/* Map user memory. */
gceSTATUS
gcoHAL_MapUserMemory(
@@ -954,12 +974,14 @@ gceSTATUS
gcoHAL_QueryChipLimits(
IN gcoHAL Hal,
IN gctINT32 Chip,
+ IN gctINT32 Mask,
OUT gcsHAL_LIMITS *Limits);
gceSTATUS
gcoHAL_QueryChipFeature(
IN gcoHAL Hal,
IN gctINT32 Chip,
+ IN gctINT32 Mask,
IN gceFEATURE Feature);
/*----------------------------------------------------------------------------*/
@@ -4491,28 +4513,24 @@ gckOS_DebugStatus2Name(
#define gcmkSAFECASTSIZET(x, y) \
do \
{ \
+ gctUINT32 tmp = (gctUINT32)(y); \
if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
{ \
- if (y) \
- { \
- gcmkASSERT((y) <= gcvMAXUINT32); \
+ gcmkASSERT(tmp <= gcvMAXUINT32); \
} \
- } \
- (x) = (gctUINT32)(y); \
+ (x) = tmp; \
} \
while (gcvFALSE)
#define gcmSAFECASTSIZET(x, y) \
do \
{ \
+ gctUINT32 tmp = (gctUINT32)(y); \
if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
{ \
- if (y) \
- { \
- gcmASSERT((y) <= gcvMAXUINT32); \
+ gcmASSERT(tmp <= gcvMAXUINT32); \
} \
- } \
- (x) = (gctUINT32)(y); \
+ (x) = tmp; \
} \
while (gcvFALSE)
@@ -5389,6 +5407,7 @@ struct _gcoOS_SymbolsList
**
** Configure uniforms according to chip and numConstants.
*/
+#if !gcdENABLE_UNIFIED_CONSTANT
#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \
UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
{ \
@@ -5448,61 +5467,39 @@ struct _gcoOS_SymbolsList
ConstMax = 232; \
} \
}
-
-/*******************************************************************************
-**
-** gcmGET_UNIFORM_INFO_FOR_NONUNIFIEDMODE
-**
-** Configure uniforms according to chip and numConstants.
-*/
-#define gcmGET_UNIFORM_INFO_FOR_NONUNIFIEDMODE(ChipModel, ChipRevision, NumConstants, \
+#else
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \
UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
{ \
- if (ChipModel == gcv2000 && ChipRevision == 0x5118) \
+ if (NumConstants > 256) \
{ \
- UnifiedConst = gcvFALSE; \
- VsConstBase = AQVertexShaderConstRegAddrs; \
- PsConstBase = AQPixelShaderConstRegAddrs; \
+ UnifiedConst = gcvTRUE; \
+ VsConstBase = gcregSHUniformsRegAddrs; \
+ PsConstBase = gcregSHUniformsRegAddrs; \
+ ConstMax = NumConstants; \
VsConstMax = 256; \
- PsConstMax = 64; \
- ConstMax = 320; \
- } \
- else if (NumConstants == 320) \
- { \
- UnifiedConst = gcvFALSE; \
- VsConstBase = AQVertexShaderConstRegAddrs; \
- PsConstBase = AQPixelShaderConstRegAddrs; \
- VsConstMax = 256; \
- PsConstMax = 64; \
- ConstMax = 320; \
- } \
- /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \
- else if (NumConstants > 256 && ChipModel == gcv1000) \
- { \
- UnifiedConst = gcvFALSE; \
- VsConstBase = AQVertexShaderConstRegAddrs; \
- PsConstBase = AQPixelShaderConstRegAddrs; \
- VsConstMax = 256; \
- PsConstMax = 64; \
- ConstMax = 320; \
- } \
- else if (NumConstants > 256) \
- { \
- UnifiedConst = gcvFALSE; \
- VsConstBase = AQVertexShaderConstRegAddrs; \
- PsConstBase = AQPixelShaderConstRegAddrs; \
- VsConstMax = 256; \
- PsConstMax = 256; \
- ConstMax = 512; \
+ PsConstMax = ConstMax - VsConstMax; \
} \
else if (NumConstants == 256) \
{ \
- UnifiedConst = gcvFALSE; \
- VsConstBase = AQVertexShaderConstRegAddrs; \
- PsConstBase = AQPixelShaderConstRegAddrs; \
- VsConstMax = 256; \
- PsConstMax = 256; \
- ConstMax = 512; \
+ if (ChipModel == gcv2000 && ChipRevision == 0x5118) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
} \
else \
{ \
@@ -5514,6 +5511,7 @@ struct _gcoOS_SymbolsList
ConstMax = 232; \
} \
}
+#endif
#ifdef __cplusplus
}
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 cf2227d8566b..345b4eaca17b 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
@@ -185,6 +185,9 @@ typedef enum _gceHAL_COMMAND_CODES
/* Config power management. */
gcvHAL_CONFIG_POWER_MANAGEMENT,
+
+ /* Connect a video node to an OS native fd. */
+ gcvHAL_GET_VIDEO_MEMORY_FD,
}
gceHAL_COMMAND_CODES;
@@ -1113,6 +1116,13 @@ typedef struct _gcsHAL_INTERFACE
IN gctBOOL enable;
}
ConfigPowerManagement;
+
+ struct _gcsHAL_GET_VIDEO_MEMORY_FD
+ {
+ IN gctUINT32 handle;
+ OUT gctINT fd;
+ }
+ GetVideoMemoryFd;
}
u;
}
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 411e9f88e49a..1f35873601d2 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
@@ -74,7 +74,7 @@ typedef struct _gcsWL_EGL_DISPLAY
struct wl_display* wl_display;
struct wl_viv* wl_viv;
struct wl_registry *registry;
- struct wl_event_queue *wl_queue;
+ struct wl_event_queue *wl_queue;
gctINT swapInterval;
} gcsWL_EGL_DISPLAY;
@@ -299,8 +299,7 @@ gceSTATUS
gcoOS_SetSwapIntervalEx(
IN HALNativeDisplayType Display,
IN gctINT Interval,
- IN gctPOINTER localDisplay
-);
+ IN gctPOINTER localDisplay);
gceSTATUS
gcoOS_GetSwapInterval(
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 775dec8d5dc7..700f7eb6d76a 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
@@ -1932,6 +1932,7 @@ gcoTEXTURE_IsRenderable(
gceSTATUS
gcoTEXTURE_IsComplete(
IN gcoTEXTURE Texture,
+ IN gcsTEXTURE_PTR Info,
IN gctINT BaseLevel,
IN gctINT MaxLevel
);
@@ -1992,6 +1993,17 @@ typedef enum _gceVERTEX_FORMAT
}
gceVERTEX_FORMAT;
+/* What the SW converting scheme to create temp attrib */
+typedef enum _gceATTRIB_SCHEME
+{
+ gcvATTRIB_SCHEME_KEEP = 0,
+ gcvATTRIB_SCHEME_2_10_10_10_REV_TO_FLOAT,
+ gcvATTRIB_SCHEME_BYTE_TO_INT,
+ gcvATTRIB_SCHEME_SHORT_TO_INT,
+ gcvATTRIB_SCHEME_UBYTE_TO_UINT,
+ gcvATTRIB_SCHEME_USHORT_TO_UINT,
+} gceATTRIB_SCHEME;
+
gceSTATUS
gcoSTREAM_Construct(
IN gcoHAL Hal,
@@ -2197,6 +2209,8 @@ typedef struct _gcsATTRIBUTE
/* Index to vertex array */
gctINT arrayIdx;
+ gceATTRIB_SCHEME convertScheme;
+
/* Pointer to the temporary buffer to be freed */
gcoBUFOBJ tempStream;
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 236c39b35bf8..6a722eeebfb6 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
@@ -195,6 +195,7 @@ typedef enum _gceFEATURE
gcvFEATURE_2D_COMPRESSION,
gcvFEATURE_TPC_COMPRESSION,
gcvFEATURE_2D_OPF_YUV_OUTPUT,
+ gcvFEATURE_2D_FILTERBLIT_A8_ALPHA,
gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
gcvFEATURE_V2_COMPRESSION_Z16_FIX,
@@ -1029,6 +1030,7 @@ typedef enum _gce2D_COMMAND
gcv2D_HOR_FILTER,
gcv2D_VER_FILTER,
gcv2D_MULTI_SOURCE_BLT,
+ gcv2D_FILTER_BLT,
}
gce2D_COMMAND;
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 2b416aad7b52..b93015d32f92 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
@@ -988,7 +988,7 @@
'acquireFenceFd' for framebuffer target for DC
*/
#ifndef gcdANDROID_NATIVE_FENCE_SYNC
-# define gcdANDROID_NATIVE_FENCE_SYNC 3
+# define gcdANDROID_NATIVE_FENCE_SYNC 0
#endif
/*
@@ -1013,6 +1013,15 @@
#endif
/*
+ * Implicit native buffer sync is not needed when ANDROID_native_fence_sync
+ * is available.
+ */
+#if gcdANDROID_NATIVE_FENCE_SYNC
+# undef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 0
+#endif
+
+/*
gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
Enable source surface address adjust when composition on android.
@@ -1239,4 +1248,24 @@
# define gcdENABLE_VG 0
#endif
+#ifndef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+#else
+#if (!((gcdENABLE_3D == 0) && (gcdENABLE_2D == 0) && (gcdENABLE_VG == 1)))
+# undef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+# endif
+#endif
+
+#ifndef gcdENABLE_UNIFIED_CONSTANT
+# define gcdENABLE_UNIFIED_CONSTANT 1
+#endif
+
+/*
+ gcdRECORD_COMMAND
+*/
+#ifndef gcdRECORD_COMMAND
+# define gcdRECORD_COMMAND 0
+#endif
+
#endif /* __gc_hal_options_h_ */
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 9325b1023b78..51a686cb7257 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
@@ -87,7 +87,9 @@ extern "C" {
/******************************************************************************\
************************************ Keyword ***********************************
\******************************************************************************/
-#if ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__APPLE__))
+#if defined(ANDROID) && defined(__BIONIC_FORTIFY)
+# define gcmINLINE __inline__ __attribute__ ((always_inline)) __attribute__ ((gnu_inline)) __attribute__ ((artificial))
+#elif ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__APPLE__))
# define gcmINLINE inline /* C99 keyword. */
#elif defined(__GNUC__)
# define gcmINLINE __inline__ /* GNU keyword. */
@@ -459,7 +461,6 @@ typedef enum _gceSTATUS
gcvSTATUS_LINK_INVALID_SHADERS = -1012,
gcvSTATUS_CS_NO_WORKGROUP_SIZE = -1013,
gcvSTATUS_LINK_LIB_ERROR = -1014,
-
gcvSTATUS_SHADER_VERSION_MISMATCH = -1015,
gcvSTATUS_TOO_MANY_INSTRUCTION = -1016,
gcvSTATUS_SSBO_MISMATCH = -1017,
@@ -468,6 +469,7 @@ typedef enum _gceSTATUS
gcvSTATUS_NOT_SUPPORT_CL = -1020,
gcvSTATUS_NOT_SUPPORT_INTEGER = -1021,
gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1022,
+ gcvSTATUS_TOO_MANY_SAMPLER = -1023,
/* Compiler errors. */
gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
index 7e281d25474d..4f95350184f7 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
@@ -28,9 +28,9 @@
#define gcvVERSION_PATCH 11
-#define gcvVERSION_BUILD 23085
+#define gcvVERSION_BUILD 25762
-#define gcvVERSION_STRING "5.0.11.p3.23085"
+#define gcvVERSION_STRING "5.0.11.p4.25762"
#define gcvVERSION_DATE __DATE__
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
index 1d44b59e1452..e419558a697f 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
@@ -30,6 +30,8 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#define _GC_OBJ_ZONE gcvZONE_OS
+
typedef struct _gcsCMA_PRIV * gcsCMA_PRIV_PTR;
typedef struct _gcsCMA_PRIV {
gctUINT32 cmasize;
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 d496593595ca..9a6bc97e4fad 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
@@ -655,15 +655,47 @@ _DebugFSWrite (
int dumpProcess = 0;
-static int vidmem_show(struct seq_file *file, void *unused)
+void
+_PrintCounter(
+ struct seq_file *file,
+ gcsDATABASE_COUNTERS * counter,
+ gctCONST_STRING Name
+ )
{
- gctUINT32 i = 0;
- gceSTATUS status;
- gcsDATABASE_PTR database;
- gcsDATABASE_COUNTERS * counter;
- gckGALDEVICE device = file->private;
+ seq_printf(file,"Counter: %s\n", Name);
- gckKERNEL kernel = device->kernels[gcvCORE_MAJOR];
+ seq_printf(file,"%-9s%10s","", "All");
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Current");
+
+ seq_printf(file,"%10lld", counter->bytes);
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Maximum");
+
+ seq_printf(file,"%10lld", counter->maxBytes);
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Total");
+
+ seq_printf(file,"%10lld", counter->totalBytes);
+
+ seq_printf(file, "\n");
+}
+
+void
+_ShowCounters(
+ struct seq_file *file,
+ gcsDATABASE_PTR database
+ )
+{
+ gctUINT i = 0;
+ gcsDATABASE_COUNTERS * counter;
+ gcsDATABASE_COUNTERS * nonPaged;
static gctCONST_STRING surfaceTypes[] = {
"UNKNOWN",
@@ -680,15 +712,13 @@ static int vidmem_show(struct seq_file *file, void *unused)
"HZDepth",
};
- /* Find the database. */
- gcmkONERROR(
- gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database));
-
- seq_printf(file, "VidMem Usage (Process %d):\n", dumpProcess);
-
/* Get pointer to counters. */
counter = &database->vidMem;
+ nonPaged = &database->nonPaged;
+
+ seq_printf(file,"Counter: vidMem (for each surface type)\n");
+
seq_printf(file,"%-9s%10s","", "All");
for (i = 1; i < gcvSURF_NUM_TYPES; i++)
@@ -739,6 +769,79 @@ static int vidmem_show(struct seq_file *file, void *unused)
seq_printf(file, "\n");
+ seq_printf(file,"Counter: vidMem (for each pool)\n");
+
+ seq_printf(file,"%-9s%10s","", "All");
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ seq_printf(file, "%10d", i);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Current");
+
+ seq_printf(file,"%10lld", database->vidMem.bytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->bytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Maximum");
+
+ seq_printf(file,"%10lld", database->vidMem.maxBytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->maxBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Total");
+
+ seq_printf(file,"%10lld", database->vidMem.totalBytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->totalBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ /* Print nonPaged. */
+ _PrintCounter(file, &database->nonPaged, "nonPaged");
+ _PrintCounter(file, &database->contiguous, "contiguous");
+ _PrintCounter(file, &database->mapUserMemory, "mapUserMemory");
+ _PrintCounter(file, &database->mapMemory, "mapMemory");
+}
+
+static int vidmem_show(struct seq_file *file, void *unused)
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gckGALDEVICE device = file->private;
+
+ gckKERNEL kernel = device->kernels[gcvCORE_MAJOR];
+
+ /* Find the database. */
+ gcmkONERROR(
+ gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database));
+
+ seq_printf(file, "VidMem Usage (Process %d):\n", dumpProcess);
+
+ _ShowCounters(file, database);
+
return 0;
OnError:
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 719ba33409b5..7addd63f503c 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
@@ -188,13 +188,13 @@ int gc_meminfo_show(struct seq_file* m, void* data)
if (gcmIS_SUCCESS(status))
{
gcmkVERIFY_OK(
- gckOS_AcquireMutex(kernel->os, kernel->vidmemMutex, gcvINFINITE));
+ gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
free = memory->freeBytes;
used = memory->bytes - memory->freeBytes;
total = memory->bytes;
- gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->vidmemMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
}
seq_printf(m, "VIDEO MEMORY:\n");
@@ -240,18 +240,129 @@ int gc_meminfo_show(struct seq_file* m, void* data)
return 0;
}
-int gc_idle_show(struct seq_file* m, void* data)
+static int
+_ShowRecord(
+ IN struct seq_file *file,
+ IN gcsDATABASE_RECORD_PTR record
+ )
+{
+ seq_printf(file, "%4d%8d%16p%16p%16zu\n",
+ record->type,
+ record->kernel->core,
+ record->data,
+ record->physical,
+ record->bytes
+ );
+
+ return 0;
+}
+
+static int
+_ShowRecords(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctUINT i;
+
+ seq_printf(File, "Records:\n");
+
+ seq_printf(File, "%s%8s%16s%16s%16s\n",
+ "Type", "GPU", "Data", "Physical", "Bytes");
+
+ for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+ {
+ gcsDATABASE_RECORD_PTR record = Database->list[i];
+
+ while (record != NULL)
+ {
+ _ShowRecord(File, record);
+ record = record->next;
+ }
+ }
+
+ return 0;
+}
+
+void
+_ShowCounters(
+ struct seq_file *File,
+ gcsDATABASE_PTR Database
+ );
+
+static void
+_ShowProcess(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctINT pid;
+ gctUINT8 name[24];
+
+ /* Process ID and name */
+ pid = Database->processID;
+ gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ seq_printf(File, "--------------------------------------------------------------------------------\n");
+ seq_printf(File, "Process: %-8d %s\n", pid, name);
+
+ /* Detailed records */
+ _ShowRecords(File, Database);
+
+ seq_printf(File, "Counters:\n");
+
+ _ShowCounters(File, Database);
+}
+
+static void
+_ShowProcesses(
+ IN struct seq_file * file,
+ IN gckKERNEL Kernel
+ )
+{
+ gcsDATABASE_PTR database;
+ gctINT i;
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+
+ /* Idle time since last call */
+ seq_printf(file, "GPU Idle: %llu ns\n", Kernel->db->idleTime);
+ Kernel->db->idleTime = 0;
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+ {
+ for (database = Kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ _ShowProcess(file, database);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+}
+
+static int
+gc_db_show(struct seq_file *m, void *data)
{
gcsINFO_NODE *node = m->private;
gckGALDEVICE device = node->device;
gckKERNEL kernel = _GetValidKernel(device);
- gcuDATABASE_INFO info;
-
- gckKERNEL_QueryProcessDB(kernel, 0, gcvFALSE, gcvDB_IDLE, &info);
+ _ShowProcesses(m, kernel);
+ return 0 ;
+}
- seq_printf(m, "%llu ns\n", info.time);
+static int
+gc_version_show(struct seq_file *m, void *data)
+{
+ seq_printf(m, "%s\n", gcvVERSION_STRING);
- return 0;
+ return 0 ;
}
static gcsINFO InfoList[] =
@@ -259,7 +370,8 @@ static gcsINFO InfoList[] =
{"info", gc_info_show},
{"clients", gc_clients_show},
{"meminfo", gc_meminfo_show},
- {"idle", gc_idle_show},
+ {"database", gc_db_show},
+ {"version", gc_version_show},
};
static gceSTATUS
@@ -1025,7 +1137,9 @@ gckGALDEVICE_Construct(
}
/* Set the base address */
- device->baseAddress = PhysBaseAddr;
+ device->baseAddress = device->physBase = PhysBaseAddr;
+ device->physSize = PhysSize;
+ device->mmu = Args->mmu;
/* Construct the gckOS object. */
gcmkONERROR(gckOS_Construct(device, &device->os));
@@ -1061,9 +1175,27 @@ gckGALDEVICE_Construct(
device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
));
- gcmkONERROR(gckHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
- ));
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE
+ ));
+ }
#if gcdENABLE_FSCALE_VAL_ADJUST
gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
@@ -1129,10 +1261,27 @@ gckGALDEVICE_Construct(
device->kernels[gcvCORE_OCL]->hardware, Args->gpu3DMinClock
));
#endif
-
- gcmkONERROR(gckHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_OCL]->hardware, PowerManagement
- ));
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_OCL]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_OCL]->hardware, gcvTRUE
+ ));
+ }
#if COMMAND_PROCESSOR_VERSION == 1
/* Start the command queue. */
@@ -1193,9 +1342,27 @@ gckGALDEVICE_Construct(
device
));
- gcmkONERROR(gckHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_2D]->hardware, PowerManagement
- ));
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_2D]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_2D]->hardware, gcvTRUE
+ ));
+ }
#if gcdENABLE_FSCALE_VAL_ADJUST
gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
@@ -1241,11 +1408,22 @@ gckGALDEVICE_Construct(
device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
}
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_VG]->vg->hardware,
+ PowerManagement
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_VG]->vg->hardware,
+ gcvTRUE
+ ));
+ }
+
- gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_VG]->vg->hardware,
- PowerManagement
- ));
#endif
}
else
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
index 95672253083d..089001584977 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -64,6 +64,9 @@ typedef struct _gckGALDEVICE
gctPOINTER registerBases[gcdMAX_GPU_COUNT];
gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
gctUINT32 baseAddress;
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+ gctBOOL mmu;
#if gcdMULTI_GPU
gctUINT32 requestedRegisterMemBase3D[gcdMULTI_GPU];
gctSIZE_T requestedRegisterMemSize3D[gcdMULTI_GPU];
@@ -127,6 +130,7 @@ typedef struct _gcsDEVICE_CONSTRUCT_ARGS
gctBOOL contiguousRequested;
gcsPLATFORM* platform;
+ gctBOOL mmu;
}
gcsDEVICE_CONSTRUCT_ARGS;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
new file mode 100644
index 000000000000..43202f6ff1d2
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
@@ -0,0 +1,216 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_device.h"
+
+#include <linux/iommu.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsIOMMU
+{
+ struct iommu_domain * domain;
+ struct device * device;
+}
+gcsIOMMU;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags,
+ void * args
+ )
+#else
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags
+ )
+#endif
+{
+ return 0;
+}
+
+static int
+_FlatMapping(
+ IN gckIOMMU Iommu
+ )
+{
+ gceSTATUS status;
+ gctUINT32 physical;
+
+ for (physical = 0; physical < 0x80000000; physical += PAGE_SIZE)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "Map %x => %x bytes = %d",
+ physical, physical, PAGE_SIZE
+ );
+
+ gcmkONERROR(gckIOMMU_Map(Iommu, physical, physical, PAGE_SIZE));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ )
+{
+ gcmkHEADER();
+
+ if (Iommu->domain && Iommu->device)
+ {
+ iommu_attach_device(Iommu->domain, Iommu->device);
+ }
+
+ if (Iommu->domain)
+ {
+ iommu_domain_free(Iommu->domain);
+ }
+
+ if (Iommu)
+ {
+ gcmkOS_SAFE_FREE(Os, Iommu);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ )
+{
+ gceSTATUS status;
+ gckIOMMU iommu = gcvNULL;
+ struct device *dev;
+ int ret;
+
+ gcmkHEADER();
+
+ dev = &Os->device->platform->device->dev;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsIOMMU), (gctPOINTER *)&iommu));
+
+ gckOS_ZeroMemory(iommu, gcmSIZEOF(gcsIOMMU));
+
+ iommu->domain = iommu_domain_alloc(&platform_bus_type);
+
+ if (!iommu->domain)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail");
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler, dev);
+#else
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler);
+#endif
+
+ ret = iommu_attach_device(iommu->domain, dev);
+
+ if (ret)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret);
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ iommu->device = dev;
+
+ _FlatMapping(iommu);
+
+ *Iommu = iommu;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gckIOMMU_Destory(Os, iommu);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ int ret;
+
+ gcmkHEADER_ARG("DomainAddress=%#X, Physical=%#X, Bytes=%d",
+ DomainAddress, Physical, Bytes);
+
+ ret = iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0);
+
+ if (ret)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gcmkFOOTER();
+ return status;
+
+}
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ )
+{
+ gcmkHEADER();
+
+ iommu_unmap(Iommu->domain, DomainAddress, Bytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
index 576ca30690b9..02847e90fad6 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
@@ -110,6 +110,8 @@
/******************************************************************************\
********************************** Structures **********************************
\******************************************************************************/
+typedef struct _gcsIOMMU * gckIOMMU;
+
typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
typedef struct _gcsUSER_MAPPING
{
@@ -168,7 +170,7 @@ struct _gckOS
/* signal id database. */
gcsINTEGER_DB signalDB;
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
/* Lock. */
gctPOINTER syncPointMutex;
@@ -201,7 +203,8 @@ struct _gckOS
/* External clock states. */
gctBOOL clockStates[gcdMAX_GPU_COUNT];
- gctPOINTER vidmemMutex;
+ /* IOMMU. */
+ gckIOMMU iommu;
};
typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
@@ -226,7 +229,7 @@ typedef struct _gcsSIGNAL
}
gcsSIGNAL;
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
typedef struct _gcsSYNC_POINT
{
@@ -364,6 +367,33 @@ is_vmalloc_addr(
}
#endif
+#ifdef CONFIG_IOMMU_SUPPORT
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ );
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ );
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ );
+#endif
#endif /* __gc_hal_kernel_linux_h_ */
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 81d4ee4e9821..f5dd13c559dc 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
@@ -34,7 +34,11 @@
#endif
#include <linux/delay.h>
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#include <linux/anon_inodes.h>
+#endif
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
#include <linux/file.h>
#include "gc_hal_kernel_sync.h"
#endif
@@ -651,7 +655,7 @@ gckOS_Construct(
/* Initialize signal id database. */
idr_init(&os->signalDB.idr);
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
/*
* Initialize the sync point manager.
*/
@@ -693,8 +697,22 @@ gckOS_Construct(
gckOS_ImportAllocators(os);
- /* Construct a video memory mutex. */
- gcmkONERROR(gckOS_CreateMutex(os, &os->vidmemMutex));
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (((gckGALDEVICE)(os->device))->mmu == gcvFALSE)
+ {
+ /* Only use IOMMU when internal MMU is not enabled. */
+ status = gckIOMMU_Construct(os, &os->iommu);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Fail to setup IOMMU",
+ __FUNCTION__, __LINE__
+ );
+ }
+ }
+#endif
/* Return pointer to the gckOS object. */
*Os = os;
@@ -705,7 +723,7 @@ gckOS_Construct(
OnError:
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
if (os->syncPointMutex != gcvNULL)
{
gcmkVERIFY_OK(
@@ -781,7 +799,7 @@ gckOS_Destroy(
Os->paddingPage = gcvNULL;
}
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
/*
* Destroy the sync point manager.
*/
@@ -804,9 +822,6 @@ gckOS_Destroy(
/* Destroy debug lock mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
- /* Destroy video memory mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->vidmemMutex));
-
/* Wait for all works done. */
flush_workqueue(Os->workqueue);
@@ -815,6 +830,13 @@ gckOS_Destroy(
gckOS_FreeAllocators(Os);
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gckIOMMU_Destory(Os, Os->iommu);
+ }
+#endif
+
/* Flush the debug cache. */
gcmkDEBUGFLUSH(~0U);
@@ -3927,9 +3949,7 @@ gckOS_MapPages(
gcvCORE_MAJOR,
Physical,
PageCount,
-#if gcdPROCESS_ADDRESS_SPACE
0,
-#endif
PageTable);
}
@@ -3939,9 +3959,7 @@ gckOS_MapPagesEx(
IN gceCORE Core,
IN gctPHYS_ADDR Physical,
IN gctSIZE_T PageCount,
-#if gcdPROCESS_ADDRESS_SPACE
IN gctUINT32 Address,
-#endif
IN gctPOINTER PageTable
)
{
@@ -4027,35 +4045,54 @@ gckOS_MapPagesEx(
gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
{
- for (i = 0; i < (PAGE_SIZE / 4096); i++)
- {
- gcmkONERROR(
- gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- phys + (i * 4096),
- table++));
- }
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Setup mapping in IOMMU %x => %x",
+ __FUNCTION__, __LINE__,
+ Address + (offset * PAGE_SIZE), phys
+ );
+
+ /* When use IOMMU, GPU use system PAGE_SIZE. */
+ gcmkONERROR(gckIOMMU_Map(
+ Os->iommu, Address + (offset * PAGE_SIZE), phys, PAGE_SIZE));
}
else
#endif
{
- for (i = 0; i < (PAGE_SIZE / 4096); i++)
+
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
+ {
+ gcmkONERROR(
+ gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
+ phys + (i * 4096),
+ table++));
+ }
+ }
+ else
+#endif
{
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
+ {
#if gcdPROCESS_ADDRESS_SPACE
- gctUINT32_PTR pageTableEntry;
- gckMMU_GetPageEntry(mmu, Address + (offset * 4096), &pageTableEntry);
- gcmkONERROR(
- gckMMU_SetPage(mmu,
- phys + (i * 4096),
- pageTableEntry));
+ gctUINT32_PTR pageTableEntry;
+ gckMMU_GetPageEntry(mmu, Address + (offset * 4096), &pageTableEntry);
+ gcmkONERROR(
+ gckMMU_SetPage(mmu,
+ phys + (i * 4096),
+ pageTableEntry));
#else
- gcmkONERROR(
- gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- phys + (i * 4096),
- table++));
+ gcmkONERROR(
+ gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+ phys + (i * 4096),
+ table++));
#endif
+ }
}
}
@@ -4085,6 +4122,24 @@ OnError:
return status;
}
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ )
+{
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gcmkVERIFY_OK(gckIOMMU_Unmap(
+ Os->iommu, Address, PageCount * PAGE_SIZE));
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
/*******************************************************************************
**
** gckOS_UnlockPages
@@ -5127,31 +5182,49 @@ OnError:
#endif
phys = page_to_phys(pages[i]);
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
{
- gcmkVERIFY_OK(
- gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
-
- /* Get the physical address from page struct. */
- gcmkONERROR(
- gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- phys,
- tab));
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Setup mapping in IOMMU %x => %x",
+ __FUNCTION__, __LINE__,
+ Address + (i * PAGE_SIZE), phys
+ );
+
+ gcmkONERROR(gckIOMMU_Map(
+ Os->iommu, address + i * PAGE_SIZE, phys, PAGE_SIZE));
}
else
#endif
{
- /* Get the physical address from page struct. */
- gcmkONERROR(
- gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- phys,
- tab));
- }
- for (j = 1; j < (PAGE_SIZE/4096); j++)
- {
- pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+ /* Get the physical address from page struct. */
+ gcmkONERROR(
+ gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
+ phys,
+ tab));
+ }
+ else
+#endif
+ {
+ /* Get the physical address from page struct. */
+ gcmkONERROR(
+ gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+ phys,
+ tab));
+ }
+
+ for (j = 1; j < (PAGE_SIZE/4096); j++)
+ {
+ pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
+ }
}
#if !gcdPROCESS_ADDRESS_SPACE
@@ -5443,6 +5516,12 @@ OnError:
pageCount * (PAGE_SIZE/4096)
));
#endif
+
+ gcmkERR_BREAK(gckOS_UnmapPages(
+ Os,
+ pageCount * (PAGE_SIZE/4096),
+ info->address
+ ));
}
#endif
@@ -8097,7 +8176,7 @@ gckOS_DetectProcessByName(
: gcvSTATUS_FALSE;
}
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
gceSTATUS
gckOS_CreateSyncPoint(
@@ -8254,8 +8333,8 @@ gckOS_SignalSyncPoint(
gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
- /* Get state. */
- atomic_set(&syncPoint->state, gcvTRUE);
+ /* Set signaled state. */
+ atomic_set(&syncPoint->state, 1);
/* Get parent timeline. */
timeline = syncPoint->timeline;
@@ -8584,15 +8663,75 @@ gckOS_PhysicalToPhysicalAddress(
}
gceSTATUS
-gckOS_GetVideoMemoryMutex(
+gckOS_QueryOption(
IN gckOS Os,
- OUT gctPOINTER *Mutex
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
)
{
- gcmkHEADER_ARG("Mutex=x%X", Mutex);
+ gckGALDEVICE device = Os->device;
- *Mutex = Os->vidmemMutex;
+ if (!strcmp(Option, "physBase"))
+ {
+ *Value = device->physBase;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "physSize"))
+ {
+ *Value = device->physSize;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "mmu"))
+ {
+#if gcdSECURITY
+ *Value = 0;
+#else
+ *Value = device->mmu;
+#endif
+ return gcvSTATUS_OK;
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static int
+fd_release(
+ struct inode *inode,
+ struct file *file
+ )
+{
+ gcsFDPRIVATE_PTR private = (gcsFDPRIVATE_PTR)file->private_data;
+
+ if (private && private->release)
+ {
+ return private->release(private);
+ }
+
+ return 0;
+}
+
+static const struct file_operations fd_fops = {
+ .release = fd_release,
+};
+
+gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT *Fd
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+ *Fd = anon_inode_getfd(Name, &fd_fops, Private, O_RDWR);
+
+ if (*Fd < 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
- gcmkFOOTER_NO();
return gcvSTATUS_OK;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
}
+
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
index 5d719374f497..23b7178d83ba 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
@@ -58,7 +58,7 @@ typedef struct _gcsMODULE_PARAMETERS
gctUINT recovery;
gctUINT stuckDump;
gctUINT showArgs;
-
+ gctUINT gpu3DMinClock;
}
gcsMODULE_PARAMETERS;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c
index 8d6ed1598ef2..054e32e8f6a5 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c
@@ -115,7 +115,7 @@ module_param(fastClear, int, 0644);
static int compression = -1;
module_param(compression, int, 0644);
-static int powerManagement = 1;
+static int powerManagement = -1;
module_param(powerManagement, int, 0644);
static int gpuProfiler = 0;
@@ -145,8 +145,10 @@ MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle,
static int showArgs = 0;
module_param(showArgs, int, 0644);
-static int initgpu3DMinClock = 1;
-module_param(initgpu3DMinClock, int, 0644);
+static int mmu = 1;
+module_param(mmu, int, 0644);
+
+static int gpu3DMinClock = 1;
static int contiguousRequested = 0;
@@ -215,6 +217,7 @@ _UpdateModuleParam(
stuckDump = Param->stuckDump;
showArgs = Param->showArgs;
contiguousRequested = Param->contiguousRequested;
+ gpu3DMinClock = Param->gpu3DMinClock;
}
void
@@ -808,9 +811,10 @@ static int drv_init(void)
gcsDEVICE_CONSTRUCT_ARGS args = {
.recovery = recovery,
.stuckDump = stuckDump,
- .gpu3DMinClock = initgpu3DMinClock,
+ .gpu3DMinClock = gpu3DMinClock,
.contiguousRequested = contiguousRequested,
.platform = &platform,
+ .mmu = mmu,
};
gcmkHEADER();
@@ -876,29 +880,6 @@ static int drv_init(void)
&& (device->kernels[gcvCORE_MAJOR] != gcvNULL)
&& (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
{
-#if !gcdSECURITY
- gctUINT32 gpuPhysical;
- gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(device->os, baseAddress, &gpuPhysical));
-
- status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, gpuPhysical, physSize);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
- "Enable new MMU: status=%d\n", status);
-
-#if gcdMULTI_GPU_AFFINITY
- status = gckMMU_Enable(device->kernels[gcvCORE_OCL]->mmu, gpuPhysical, physSize);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
- "Enable new MMU: status=%d\n", status);
-#endif
-
- if ((device->kernels[gcvCORE_2D] != gcvNULL)
- && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0))
- {
- status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, gpuPhysical, physSize);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
- "Enable new MMU for 2D: status=%d\n", status);
- }
-#endif
-
/* Reset the base address */
device->baseAddress = 0;
}
@@ -1047,6 +1028,7 @@ static int __devinit gpu_probe(struct platform_device *pdev)
.recovery = recovery,
.stuckDump = stuckDump,
.showArgs = showArgs,
+ .gpu3DMinClock = gpu3DMinClock,
};
gcmkHEADER();
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
index 83541732b488..0e5a81697423 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
@@ -22,7 +22,7 @@
#include <gc_hal.h>
#include <gc_hal_base.h>
-#if gcdANDROID_NATIVE_FENCE_SYNC && defined(ANDROID)
+#if gcdANDROID_NATIVE_FENCE_SYNC
#include <linux/kernel.h>
#include <linux/file.h>
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
index 3f3c666994e8..4778aa9e84d1 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
@@ -61,6 +61,9 @@ extern int unregister_thermal_notifier(struct notifier_block *nb);
#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
#endif
+static int initgpu3DMinClock = 1;
+module_param(initgpu3DMinClock, int, 0644);
+
struct platform_device *pdevice;
#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
@@ -193,12 +196,7 @@ _ShrinkMemory(
if (kernel != gcvNULL)
{
- /* Acquire the mutex. */
- gcmkVERIFY_OK(gckOS_AcquireMutex(kernel->os, kernel->vidmemMutex, gcvINFINITE));
-
force_contiguous_lowmem_shrink(kernel);
-
- gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->vidmemMutex));
}
else
{
@@ -322,10 +320,12 @@ struct imx_priv {
struct clk *clk_2d_axi;
struct clk *clk_vg_axi;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
/*Power management.*/
struct regulator *gpu_regulator;
#endif
+#endif
/*Run time pm*/
struct device *pmdev;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
@@ -406,6 +406,7 @@ gckPLATFORM_AdjustParam(
if (Args->contiguousSize == 0)
gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
+ Args->gpu3DMinClock = initgpu3DMinClock;
return gcvSTATUS_OK;
}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config
index 7782d76c830b..6575148b596e 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config
@@ -1,3 +1,15 @@
-EXTRA_CFLAGS += -DgcdDEFAULT_CONTIGUOUS_SIZE=134217728 -DLINUX_CMA_FSL=1
+EXTRA_CFLAGS += -DgcdDEFAULT_CONTIGUOUS_SIZE=134217728
+
+ifneq ($(CONFIG_ANDROID),)
+# build for android
+EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=3
+
+ifeq ($(CONFIG_SYNC),)
+$(warn CONFIG_SYNC is not set in kernel config)
+$(warn Android native fence sync needs CONFIG_SYNC)
+endif
+endif
+
+EXTRA_CFLAGS += -DLINUX_CMA_FSL=1
ALLOCATOR_ARRAY_H_LOCATION := $(OS_KERNEL_DIR)/allocator/freescale
CUSTOMER_ALLOCATOR_OBJS := $(ALLOCATOR_ARRAY_H_LOCATION)/gc_hal_kernel_allocator_cma.o