diff options
author | Loren Huang <b02279@freescale.com> | 2014-11-06 16:39:44 +0800 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2015-04-14 14:00:59 -0500 |
commit | 3b3e7f0bbbf93a0ae65748e6a747e1037f626582 (patch) | |
tree | 475940119a8945da609a20b0aba3195a3904049e /drivers/mxc/gpu-viv/hal | |
parent | c4c28fc1f5f1b54f4a21476062e62eb13b2a7efe (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')
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 |